Fix null-pointer dereferences in case of out-of-memory in cord
authorIvan Maidanski <ivmai@mail.ru>
Thu, 11 Feb 2016 21:22:44 +0000 (00:22 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Thu, 11 Feb 2016 21:22:44 +0000 (00:22 +0300)
* 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).

cord/cordprnt.c
cord/cordxtra.c
cord/tests/cordtest.c
cord/tests/de.c
cord/tests/de_win.c

index 7e7745b..6e36c09 100644 (file)
 
 #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   */
                                 /* 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) {
index 610ea89..28ed886 100644 (file)
@@ -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);
index 906f739..4706c2b 100644 (file)
@@ -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");
index 28182dd..6f1a5e6 100644 (file)
 #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();
index a19ff49..ecbd604 100644 (file)
@@ -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);