From: Robert Gill Date: Wed, 18 Jun 2025 20:54:37 +0000 (+0000) Subject: improve handling of malloc failures X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;ds=sidebyside;p=thirdparty%2Fnewt.git improve handling of malloc failures Return NULL on malloc failures when creating new components and from newtReflowText. Internal buffers are still not checked, but this should allow some memory allocation errors to be made more obvious and possibly caught without breaking current API compatibility. [ML: fixed fields deallocation in newtCreateGrid()] --- diff --git a/buttonbar.c b/buttonbar.c index cf48609..e602acd 100644 --- a/buttonbar.c +++ b/buttonbar.c @@ -1,4 +1,5 @@ #include +#include #include "newt.h" @@ -21,6 +22,8 @@ newtGrid newtButtonBarv(char * button1, newtComponent * b1comp, va_list args) { } grid = newtCreateGrid(num, 1); + if (grid == NULL) + return NULL; for (i = 0; i < num; i++) { *buttons[i].compPtr = newtButton(-1, -1, buttons[i].name); diff --git a/checkbox.c b/checkbox.c index 1590762..0130d3d 100644 --- a/checkbox.c +++ b/checkbox.c @@ -45,6 +45,8 @@ newtComponent newtRadiobutton(int left, int top, const char * text, int isDefaul initialValue = ' '; co = newtCheckbox(left, top, text, initialValue, " *", NULL); + if (co == NULL) + return NULL; rb = co->data; rb->type = RADIO; diff --git a/checkboxtree.c b/checkboxtree.c index 95156eb..f9c2f3e 100644 --- a/checkboxtree.c +++ b/checkboxtree.c @@ -332,7 +332,13 @@ newtComponent newtCheckboxTreeMulti(int left, int top, int height, char *seq, in struct CheckboxTree * ct; co = malloc(sizeof(*co)); + if (co == NULL) + return NULL; ct = malloc(sizeof(struct CheckboxTree)); + if (ct == NULL) { + free(co); + return NULL; + } co->callback = NULL; co->destroyCallback = NULL; co->data = ct; diff --git a/entry.c b/entry.c index 8dad8c8..815be52 100644 --- a/entry.c +++ b/entry.c @@ -71,7 +71,13 @@ newtComponent newtEntry(int left, int top, const char * initialValue, int width, struct entry * en; co = malloc(sizeof(*co)); + if (co == NULL) + return NULL; en = malloc(sizeof(struct entry)); + if (en == NULL) { + free(co); + return NULL; + } co->data = en; co->top = top; @@ -100,6 +106,11 @@ newtComponent newtEntry(int left, int top, const char * initialValue, int width, en->bufAlloced = strlen(initialValue) + 1; } en->buf = malloc(en->bufAlloced); + if (en->buf == NULL) { + free(en); + free(co); + return NULL; + } en->resultPtr = resultPtr; if (en->resultPtr) *en->resultPtr = en->buf; diff --git a/form.c b/form.c index 24c601d..ad425af 100644 --- a/form.c +++ b/form.c @@ -445,7 +445,15 @@ newtComponent newtForm(newtComponent vertBar, void * help, int flags) { struct form * form; co = malloc(sizeof(*co)); + if (co == NULL) + return NULL; + form = malloc(sizeof(*form)); + if (form == NULL) { + free(co); + return NULL; + } + co->data = form; co->width = 0; co->height = 0; @@ -458,6 +466,9 @@ newtComponent newtForm(newtComponent vertBar, void * help, int flags) { co->callback = NULL; co->destroyCallback = NULL; + form->elements = NULL; + form->hotKeys = NULL; + form->help = help; form->flags = flags; form->numCompsAlloced = 5; @@ -470,9 +481,12 @@ newtComponent newtForm(newtComponent vertBar, void * help, int flags) { form->maxFd = 0; form->fds = NULL; form->elements = malloc(sizeof(*(form->elements)) * form->numCompsAlloced); + if (form->elements == NULL) goto error; form->background = COLORSET_WINDOW; form->hotKeys = malloc(sizeof(int)); + if (form->hotKeys == NULL) goto error; + form->numHotKeys = 0; form->timer = 0; form->lastTimeout.tv_sec = form->lastTimeout.tv_usec = 0; @@ -489,6 +503,14 @@ newtComponent newtForm(newtComponent vertBar, void * help, int flags) { form->helpCb = helpCallback; return co; + +error: + free(form->hotKeys); + free(form->elements); + free(form); + free(co); + + return NULL; } newtComponent newtFormGetCurrent(newtComponent co) { diff --git a/grid.c b/grid.c index 6f79ce4..2c193d1 100644 --- a/grid.c +++ b/grid.c @@ -33,12 +33,26 @@ newtGrid newtCreateGrid(int cols, int rows) { newtGrid grid; grid = malloc(sizeof(*grid)); + if (grid == NULL) + return NULL; grid->rows = rows; grid->cols = cols; grid->fields = malloc(sizeof(*grid->fields) * cols); + if (grid->fields == NULL) { + free(grid); + return NULL; + } + while (cols--) { grid->fields[cols] = malloc(sizeof(**(grid->fields)) * rows); + if (grid->fields[cols] == NULL) { + for (cols++; cols < grid->cols; cols++) + free(grid->fields[cols]); + free(grid->fields); + free(grid); + return NULL; + } memset(grid->fields[cols], 0, sizeof(**(grid->fields)) * rows); } @@ -299,6 +313,8 @@ static newtGrid stackem(int isVert, enum newtGridElement type1, void * what1, } grid = newtCreateGrid(isVert ? 1 : num, isVert ? num : 1); + if (grid == NULL) + return NULL; for (i = 0; i < num; i++) { newtGridSetField(grid, isVert ? 0 : i, isVert ? i : 0, @@ -367,6 +383,9 @@ newtGrid newtGridBasicWindow(newtComponent text, newtGrid middle, newtGrid grid; grid = newtCreateGrid(1, 3); + if (grid == NULL) + return NULL; + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, middle, @@ -382,6 +401,9 @@ newtGrid newtGridSimpleWindow(newtComponent text, newtComponent middle, newtGrid grid; grid = newtCreateGrid(1, 3); + if (grid == NULL) + return NULL; + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, middle, diff --git a/label.c b/label.c index 85fa518..1c58480 100644 --- a/label.c +++ b/label.c @@ -27,7 +27,13 @@ newtComponent newtLabel(int left, int top, const char * text) { struct label * la; co = malloc(sizeof(*co)); + if (co == NULL) + return NULL; la = malloc(sizeof(struct label)); + if (la == NULL) { + free(co); + return NULL; + } co->data = la; co->destroyCallback = NULL; diff --git a/scale.c b/scale.c index 35dcdde..63b4243 100644 --- a/scale.c +++ b/scale.c @@ -28,7 +28,13 @@ newtComponent newtScale(int left, int top, int width, long long fullValue) { struct scale * sc; co = malloc(sizeof(*co)); + if (co == NULL) + return NULL; sc = malloc(sizeof(struct scale)); + if (sc == NULL) { + free(co); + return NULL; + } co->data = sc; co->destroyCallback = NULL; diff --git a/scrollbar.c b/scrollbar.c index 0c706b3..90cd2fe 100644 --- a/scrollbar.c +++ b/scrollbar.c @@ -44,7 +44,13 @@ newtComponent newtVerticalScrollbar(int left, int top, int height, struct scrollbar * sb; co = malloc(sizeof(*co)); + if (co == NULL) + return NULL; sb = malloc(sizeof(*sb)); + if (sb == NULL) { + free(co); + return NULL; + } co->data = sb; co->destroyCallback = NULL; diff --git a/textbox.c b/textbox.c index b6fedd6..3f7f845 100644 --- a/textbox.c +++ b/textbox.c @@ -79,8 +79,15 @@ newtComponent newtTextboxReflowed(int left, int top, char * text, int width, reflowedText = newtReflowText(text, width, flexDown, flexUp, &actWidth, &actHeight); + if (reflowedText == NULL) + return NULL; co = newtTextbox(left, top, actWidth, actHeight, NEWT_FLAG_WRAP); + if (co == NULL) { + free(reflowedText); + return NULL; + } + newtTextboxSetText(co, reflowedText); free(reflowedText); @@ -92,7 +99,13 @@ newtComponent newtTextbox(int left, int top, int width, int height, int flags) { struct textbox * tb; co = malloc(sizeof(*co)); + if (co == NULL) + return NULL; tb = malloc(sizeof(*tb)); + if (tb == NULL) { + free(co); + return NULL; + } co->data = tb; if (width < 1) @@ -147,10 +160,15 @@ static char * expandTabs(const char * text) { int i; buf = malloc(bufAlloced + 1); + if (buf == NULL) + return NULL; + for (src = text, dest = buf; *src; src++) { if ((bufUsed + 10) > bufAlloced) { bufAlloced += strlen(text) / 2; buf = realloc(buf, bufAlloced + 1); + if (buf == NULL) + return NULL; dest = buf + bufUsed; } if (*src == '\t') { @@ -189,7 +207,10 @@ static void doReflow(const char * text, char ** resultPtr, int width, result = malloc(strlen(text) + (strlen(text) / (width - 1)) + 2); } else result = malloc(strlen(text) * 2 + 2); + *resultPtr = result; + if (result == NULL) + return; } memset(&ps,0,sizeof(mbstate_t)); @@ -287,6 +308,8 @@ char * newtReflowText(char * text, int width, int flexDown, int flexUp, width = 1; expandedText = expandTabs(text); + if (expandedText == NULL) + return NULL; if (flexDown || flexUp) { min = width - flexDown;