From 52f8121ba5ca548464e657996954dcac027c0793 Mon Sep 17 00:00:00 2001 From: marschap Date: Sun, 14 Dec 2008 09:33:01 +0000 Subject: [PATCH] fix issues in widget_create() in tight memory situations (Andre Guibert de Bruet) --- server/widget.c | 90 ++++++++++++++++++++++++++++++++++++++----------- server/widget.h | 23 +++++++------ 2 files changed, 84 insertions(+), 29 deletions(-) diff --git a/server/widget.c b/server/widget.c index cb69898..de8b825 100644 --- a/server/widget.c +++ b/server/widget.c @@ -9,6 +9,7 @@ * * Copyright (c) 1999, William Ferrell, Scott Scriven * 2002, Joris Robijn + * 2008, Peter Marschall */ #include @@ -24,16 +25,16 @@ #include "drivers/lcd.h" char *typenames[] = { - "none", - "string", - "hbar", - "vbar", - "icon", - "title", - "scroller", - "frame", - "num", - NULL, + "none", /* WID_NONE */ + "string", /* WID_STRING */ + "hbar", /* WID_HBAR */ + "vbar", /* WID_VBAR */ + "icon", /* WID_ICON */ + "title", /* WID_TITLE */ + "scroller", /* WID_SCROLLER */ + "frame", /* WID_FRAME */ + "num", /* WID_NUM */ + NULL, /* WID_NONE */ }; struct icontable { @@ -66,6 +67,12 @@ struct icontable { }; +/** Create a widget. + * \param id Widget identifier; it's name. + * \param type Widget type. + * \param screen Screen on which the widget is to be placed. + * \return Pointer to the freshly created widget. + */ Widget * widget_create(char *id, WidgetType type, Screen *screen) { @@ -75,14 +82,15 @@ widget_create(char *id, WidgetType type, Screen *screen) /* Create it */ w = malloc(sizeof(Widget)); - if (!w) { + if (w == NULL) { report(RPT_DEBUG, "%s: Error allocating", __FUNCTION__); return NULL; } w->id = strdup(id); - if (!w->id) { + if (w->id == NULL) { report(RPT_DEBUG, "%s: Error allocating", __FUNCTION__); + free(w); return NULL; } @@ -103,8 +111,14 @@ widget_create(char *id, WidgetType type, Screen *screen) if (w->type == WID_FRAME) { /* create a screen for the frame widget */ - char *frame_name; - frame_name = malloc(strlen("frame_") + strlen(id) + 1); + char *frame_name = malloc(strlen("frame_") + strlen(id) + 1); + + if (frame_name == NULL) { + report(RPT_DEBUG, "%s: Error allocating", __FUNCTION__); + free(w->id); + free(w); + return NULL; + } strcpy(frame_name, "frame_"); strcat(frame_name, id); @@ -115,6 +129,12 @@ widget_create(char *id, WidgetType type, Screen *screen) return w; } + +/** Destroy a widget. + * \param w Widget to destroy. + * \retval <0 Error; no widget given. + * \retval 0 Success. + */ int widget_destroy(Widget *w) { @@ -123,28 +143,39 @@ widget_destroy(Widget *w) if (!w) return -1; - if (w->id) + if (w->id != NULL) { free(w->id); - if (w->text) + w->id = NULL; + } + if (w->text != NULL) { free(w->text); + w->text = NULL; + } /* Free subscreen of frame widget too */ if (w->type == WID_FRAME) { screen_destroy(w->frame_screen); + w->frame_screen = NULL; } free(w); + w = NULL; return 0; } + +/** Convert a widget type name to a widget type. + * \param typename Name of the idget type. + * \return Widget type. + */ WidgetType widget_typename_to_type(char *typename) { WidgetType wid_type = WID_NONE; int i; - for (i = 0; typenames[i]; i++) { + for (i = 0; typenames[i] != NULL; i++) { if (strcmp(typenames[i], typename) == 0) { wid_type = i; break; /* it's valid: skip out...*/ @@ -153,12 +184,23 @@ widget_typename_to_type(char *typename) return wid_type; } + +/** Convert a widget type to the associated type name. + * \param t Widget type. + * \return Widget type's name. + */ char * widget_type_to_typename(WidgetType t) { return typenames[t]; } + +/** Find subordinate widgets of a widget by name. + * \param w Widget. + * \param id Name of the subiordinate widget. + * \return Pointer to the sub-widget; \c NULL if not found or on error. + */ Widget * widget_search_subs(Widget *w, char *id) { @@ -169,11 +211,16 @@ widget_search_subs(Widget *w, char *id) } } + +/** Find a widget icon by type. + * \param icon Icon type. + * \return Pointer to constant string containing the icon name. + */ char *widget_icon_to_iconname(int icon) { int i; - for (i = 0; icontable[i].iconname; i++) { + for (i = 0; icontable[i].iconname != NULL; i++) { if (icontable[i].icon == icon) { return icontable[i].iconname; } @@ -182,11 +229,16 @@ char *widget_icon_to_iconname(int icon) return NULL; } + +/** Find a widget icon by name. + * \param iconname Icon name. + * \return Icon type + */ int widget_iconname_to_icon(char *iconname) { int i; - for (i = 0; icontable[i].iconname; i++) { + for (i = 0; icontable[i].iconname != NULL; i++) { if (strcasecmp(icontable[i].iconname, iconname) == 0) { return icontable[i].icon; } diff --git a/server/widget.h b/server/widget.h index c67cb88..66db40f 100644 --- a/server/widget.h +++ b/server/widget.h @@ -1,4 +1,5 @@ /** \file server/widget.h + * Public interface to the widget methods. */ /* This file is part of LCDd, the lcdproc server. @@ -30,17 +31,19 @@ typedef enum WidgetType { WID_NUM } WidgetType; + +/** Widget structure */ typedef struct Widget { - char *id; - WidgetType type; - Screen *screen; /* What screen is this widget in ? */ - int x, y; /* Position */ - int width, height; /* Visible size */ - int left, top, right, bottom; /* bounding rectangle */ - int length; /* size or direction */ - int speed; /* For scroller... */ - char *text; /* text or binary data */ - struct Screen *frame_screen; /* frame widget get an associated screen */ + char *id; /**< the widget's name */ + WidgetType type; /**< the widget's type */ + Screen *screen; /**< What screen is this widget in ? */ + int x, y; /**< Position */ + int width, height; /**< Visible size */ + int left, top, right, bottom; /**< bounding rectangle */ + int length; /**< size or direction */ + int speed; /**< For scroller... */ + char *text; /**< text or binary data */ + struct Screen *frame_screen; /**< frame widget get an associated screen */ //LinkedList *kids; /* Frames can contain more widgets...*/ } Widget;