~sircmpwn/scdoc

9140b4b1656e28fd8763ebe53a22a2004feeff1a — Sebastian a month ago c7cb8be
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 <sebastian@sebsite.pw>
4 files changed, 29 insertions(+), 14 deletions(-)

M include/util.h
M src/main.c
M src/string.c
M src/util.c
M include/util.h => include/util.h +2 -0
@@ 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

M src/main.c => src/main.c +3 -3
@@ 493,12 493,12 @@ static void parse_table(struct parser *p, uint32_t style) {
			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 @@ static void parse_table(struct parser *p, uint32_t style) {
						"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;
				}

M src/string.c => src/string.c +6 -11
@@ 2,22 2,19 @@
#include <stdint.h>
#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 str_append_ch(struct str *str, uint32_t 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';

M src/util.c => src/util.c +18 -0
@@ 69,3 69,21 @@ int roff_macro(struct parser *p, char *cmd, ...) {
	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;
}