summaryrefslogtreecommitdiff
path: root/cord
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2016-02-12 00:22:44 +0300
committerIvan Maidanski <ivmai@mail.ru>2016-02-12 00:22:44 +0300
commit390be5517ebd2dc233f7eb7f4487ba870ae938d2 (patch)
treeaab984525eed29ce4bf21718248705e13dad3bf9 /cord
parent9c6d1b3060bda68570e4a0c80412ba8df4deaeb2 (diff)
downloadbdwgc-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.c12
-rw-r--r--cord/cordxtra.c1
-rw-r--r--cord/tests/cordtest.c6
-rw-r--r--cord/tests/de.c11
-rw-r--r--cord/tests/de_win.c15
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);