diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2016-02-12 00:22:44 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2016-02-12 00:22:44 +0300 |
commit | 390be5517ebd2dc233f7eb7f4487ba870ae938d2 (patch) | |
tree | aab984525eed29ce4bf21718248705e13dad3bf9 /cord | |
parent | 9c6d1b3060bda68570e4a0c80412ba8df4deaeb2 (diff) | |
download | bdwgc-390be5517ebd2dc233f7eb7f4487ba870ae938d2.tar.gz |
Fix null-pointer dereferences in case of out-of-memory in cord
* cord/cordprnt.c: Include <stdlib.h> (for abort() declaration).
* cord/cordprnt.c (OUT_OF_MEMORY): New macro.
* cord/tests/de.c (OUT_OF_MEMORY): Likewise.
* cord/cordprnt.c (CORD_vsprintf): Execute OUT_OF_MEMORY if
GC_MALLOC_ATOMIC returns NULL.
* cord/cordxtra.c (CORD_ec_flush_buf): Likewise.
* cord/tests/de.c (replace_line, main): Likewise.
* tests/cordtest.c (test_extras): Declare "u" local variable; do ABORT
if CORD_substr returns NULL (to avoid null pointer dereference in
strcmp).
* cord/tests/de_win.c (plain_chars, control_chars): Return NULL if
GC_MALLOC_ATOMIC returns NULL.
* cord/tests/de_win.c (WndProc): Execute de_error() (with the
appropriate message) if plain_chars() or control_chars() returned
NULL (and do not call the corresponding TextOutA in such a case).
Diffstat (limited to 'cord')
-rw-r--r-- | cord/cordprnt.c | 12 | ||||
-rw-r--r-- | cord/cordxtra.c | 1 | ||||
-rw-r--r-- | cord/tests/cordtest.c | 6 | ||||
-rw-r--r-- | cord/tests/de.c | 11 | ||||
-rw-r--r-- | cord/tests/de_win.c | 15 |
5 files changed, 37 insertions, 8 deletions
diff --git a/cord/cordprnt.c b/cord/cordprnt.c index 7e7745b1..6e36c09c 100644 --- a/cord/cordprnt.c +++ b/cord/cordprnt.c @@ -30,9 +30,12 @@ #include "cord.h" #include "ec.h" -#include <stdio.h> + #include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> #include <string.h> + #include "gc.h" #define CONV_SPEC_LEN 50 /* Maximum length of a single */ @@ -41,6 +44,11 @@ /* conversion with default */ /* width and prec. */ +#define OUT_OF_MEMORY do { \ + if (CORD_oom_fn != 0) (*CORD_oom_fn)(); \ + fprintf(stderr, "Out of memory\n"); \ + abort(); \ + } while (0) static int ec_len(CORD_ec x) { @@ -225,6 +233,7 @@ int CORD_vsprintf(CORD * out, CORD format, va_list args) if (width != NONE && len < (size_t)width) { char * blanks = GC_MALLOC_ATOMIC(width-len+1); + if (NULL == blanks) OUT_OF_MEMORY; memset(blanks, ' ', width-len); blanks[width-len] = '\0'; if (left_adj) { @@ -281,6 +290,7 @@ int CORD_vsprintf(CORD * out, CORD format, va_list args) max_size += CONV_RESULT_LEN; if (max_size >= CORD_BUFSZ) { buf = GC_MALLOC_ATOMIC(max_size + 1); + if (NULL == buf) OUT_OF_MEMORY; } else { if (CORD_BUFSZ - (result[0].ec_bufptr-result[0].ec_buf) < max_size) { diff --git a/cord/cordxtra.c b/cord/cordxtra.c index 610ea893..28ed886c 100644 --- a/cord/cordxtra.c +++ b/cord/cordxtra.c @@ -428,6 +428,7 @@ void CORD_ec_flush_buf(CORD_ec x) if (len == 0) return; s = GC_MALLOC_ATOMIC(len+1); + if (NULL == s) OUT_OF_MEMORY; memcpy(s, x[0].ec_buf, len); s[len] = '\0'; x[0].ec_cord = CORD_cat_char_star(x[0].ec_cord, s, len); diff --git a/cord/tests/cordtest.c b/cord/tests/cordtest.c index 906f739d..4706c2b4 100644 --- a/cord/tests/cordtest.c +++ b/cord/tests/cordtest.c @@ -128,7 +128,7 @@ void test_extras(void) register int i; CORD y = "abcdefghijklmnopqrstuvwxyz0123456789"; CORD x = "{}"; - CORD w, z; + CORD u, w, z; FILE *f; FILE *f1a, *f1b, *f2; @@ -180,7 +180,9 @@ void test_extras(void) ABORT("file substr wrong"); if (strcmp(CORD_to_char_star(CORD_substr(w, 1000*36, 36)), y) != 0) ABORT("char * file substr wrong"); - if (strcmp(CORD_substr(w, 1000*36, 2), "ab") != 0) + u = CORD_substr(w, 1000*36, 2); + if (!u) ABORT("CORD_substr returned NULL"); + if (strcmp(u, "ab") != 0) ABORT("short file substr wrong"); if (CORD_str(x,1,"9a") != 35) ABORT("CORD_str failed 1"); if (CORD_str(x,0,"9abcdefghijk") != 35) ABORT("CORD_str failed 2"); diff --git a/cord/tests/de.c b/cord/tests/de.c index 28182ddd..6f1a5e6a 100644 --- a/cord/tests/de.c +++ b/cord/tests/de.c @@ -67,6 +67,11 @@ #endif #include "de_cmds.h" +#define OUT_OF_MEMORY do { \ + fprintf(stderr, "Out of memory\n"); \ + exit(3); \ + } while (0) + /* List of line number to position mappings, in descending order. */ /* There may be holes. */ typedef struct LineMapRep { @@ -215,6 +220,7 @@ void replace_line(int i, CORD s) if (screen == 0 || LINES > screen_size) { screen_size = LINES; screen = (CORD *)GC_MALLOC(screen_size * sizeof(CORD)); + if (NULL == screen) OUT_OF_MEMORY; } # if !defined(MACINTOSH) /* A gross workaround for an apparent curses bug: */ @@ -562,6 +568,7 @@ int argc; char ** argv; { int c; + void *buf; #if defined(MACINTOSH) console_options.title = "\pDumb Editor"; @@ -572,7 +579,9 @@ char ** argv; if (argc != 2) goto usage; arg_file_name = argv[1]; - setvbuf(stdout, GC_MALLOC_ATOMIC(8192), _IOFBF, 8192); + buf = GC_MALLOC_ATOMIC(8192); + if (NULL == buf) OUT_OF_MEMORY; + setvbuf(stdout, buf, _IOFBF, 8192); initscr(); noecho(); nonl(); cbreak(); generic_init(); diff --git a/cord/tests/de_win.c b/cord/tests/de_win.c index a19ff495..ecbd6044 100644 --- a/cord/tests/de_win.c +++ b/cord/tests/de_win.c @@ -131,6 +131,7 @@ char * plain_chars(char * text, size_t len) char * result = GC_MALLOC_ATOMIC(len + 1); register size_t i; + if (NULL == result) return NULL; for (i = 0; i < len; i++) { if (iscntrl(((unsigned char *)text)[i])) { result[i] = ' '; @@ -149,6 +150,7 @@ char * control_chars(char * text, size_t len) char * result = GC_MALLOC_ATOMIC(len + 1); register size_t i; + if (NULL == result) return NULL; for (i = 0; i < len; i++) { if (iscntrl(((unsigned char *)text)[i])) { result[i] = text[i] + 0x40; @@ -317,20 +319,25 @@ LRESULT CALLBACK WndProc (HWND hwnd, UINT message, char * blanks = CORD_to_char_star(CORD_chars(' ', COLS - len)); char * control = control_chars(text, len); + if (NULL == plain || NULL == control) + de_error("Out of memory!"); + # define RED RGB(255,0,0) SetBkMode(dc, OPAQUE); SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT)); - TextOutA(dc, this_line.left, this_line.top, - plain, (int)len); + if (plain != NULL) + TextOutA(dc, this_line.left, this_line.top, + plain, (int)len); TextOutA(dc, this_line.left + (int)len * char_width, this_line.top, blanks, (int)(COLS - len)); SetBkMode(dc, TRANSPARENT); SetTextColor(dc, RED); - TextOutA(dc, this_line.left, this_line.top, - control, (int)strlen(control)); + if (control != NULL) + TextOutA(dc, this_line.left, this_line.top, + control, (int)strlen(control)); } } EndPaint(hwnd, &ps); |