From 9140b4b1656e28fd8763ebe53a22a2004feeff1a Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sun, 03 Oct 2021 14:23:41 -0400 Subject: [PATCH] Check for and abort on failed memory allocations This commit adds checks for memory allocation failures (i.e. malloc or calloc returns NULL), and cleanly exits the program in such a scenario. This removes several null-deference bugs. Signed-off-by: Sebastian --- include/util.h | 2 ++ src/main.c | 6 +++--- src/string.c | 17 ++++++----------- src/util.c | 18 ++++++++++++++++++ diff --git a/include/util.h b/include/util.h index fe50986736a4108788fa34ceee6fb21698bb2292..018bbe64510fc6e304219000c4f115271fb3d357 100644 --- a/include/util.h +++ b/include/util.h @@ -25,5 +25,7 @@ uint32_t parser_getch(struct parser *parser); void parser_pushch(struct parser *parser, uint32_t ch); void parser_pushstr(struct parser *parser, const char *str); int roff_macro(struct parser *p, char *cmd, ...); +void *xcalloc(size_t n, size_t s); +void *xrealloc(void *p, size_t s); #endif diff --git a/src/main.c b/src/main.c index d90681df2495877ffc19f7ce671a27004e4c5f6c..f11706ab1f17bcaa0952ea0ef1b56013cebfb774 100644 --- a/src/main.c +++ b/src/main.c @@ -493,12 +493,12 @@ case '\n': goto commit_table; case '|': prevrow = currow; - currow = calloc(1, sizeof(struct table_row)); + currow = xcalloc(1, sizeof(struct table_row)); if (prevrow) { // TODO: Verify the number of columns match prevrow->next = currow; } - curcell = calloc(1, sizeof(struct table_cell)); + curcell = xcalloc(1, sizeof(struct table_cell)); currow->cell = curcell; column = 0; if (!table) { @@ -511,7 +511,7 @@ parser_fatal(p, "Cannot start a column without " "starting a row first"); } else { struct table_cell *prev = curcell; - curcell = calloc(1, sizeof(struct table_cell)); + curcell = xcalloc(1, sizeof(struct table_cell)); if (prev) { prev->next = curcell; } diff --git a/src/string.c b/src/string.c index 0d1f38f53f8e08c0c89306adf3501c8f7c505fd8..2fbacbe3804c556267bb1feaf6a5d08c58db47be 100644 --- a/src/string.c +++ b/src/string.c @@ -2,22 +2,19 @@ #include #include #include "str.h" #include "unicode.h" +#include "util.h" -static int ensure_capacity(struct str *str, size_t len) { +static void ensure_capacity(struct str *str, size_t len) { if (len + 1 >= str->size) { - char *new = realloc(str->str, str->size * 2); - if (!new) { - return 0; - } + char *new = xrealloc(str->str, str->size * 2); str->str = new; str->size *= 2; } - return 1; } struct str *str_create() { - struct str *str = calloc(1, sizeof(struct str)); - str->str = malloc(16); + struct str *str = xcalloc(1, sizeof(struct str)); + str->str = xcalloc(16, 1); str->size = 16; str->len = 0; str->str[0] = '\0'; @@ -35,9 +32,7 @@ int size = utf8_chsize(ch); if (size <= 0) { return -1; } - if (!ensure_capacity(str, str->len + size)) { - return -1; - } + ensure_capacity(str, str->len + size); utf8_encode(&str->str[str->len], ch); str->len += size; str->str[str->len] = '\0'; diff --git a/src/util.c b/src/util.c index ec55abbe07ca9c08cc0ce7c80034e04729bca31e..15f592895ebc1e085b092e3302482da5c7bf08d2 100644 --- a/src/util.c +++ b/src/util.c @@ -69,3 +69,21 @@ va_end(ap); fputc('\n', f); return l + 1; } + +void *xcalloc(size_t n, size_t s) { + void *p = calloc(n, s); + if (!p) { + fputs("Out of memory\n", stderr); + abort(); + } + return p; +} + +void *xrealloc(void *p, size_t s) { + void *ret = realloc(p, s); + if (!ret) { + fputs("Out of memory\n", stderr); + abort(); + } + return ret; +} -- 2.48.1