]> granicus.if.org Git - graphviz/commitdiff
ccomps: abort on all allocation failures
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sun, 25 Jul 2021 00:36:44 +0000 (17:36 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Tue, 27 Jul 2021 14:30:51 +0000 (07:30 -0700)
None of the allocations in ccomps could tolerate failure. So this change makes
them all call wrappers that cleanly abort in the event of out-of-memory. Note
that this also fixes an issue where ccomps incorrectly identified itself as `gc`
in one of the previous failure messages.

CHANGELOG.md
cmd/tools/ccomps.c

index a420d2658776a00dec1ef129086f7e92d38a293d..5a78175c81f3f9ea65531caf48756cfb6d1439ff 100644 (file)
@@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - gvpr doesn't build on macOS but MKDEFS_EXECUTABLE points to wrong
   directory #2101
 - the generated gdefs.h header is no longer installed
+- `ccomps` out-of-memory message no longer incorrectly refers to `gc`
 
 ## [2.48.0] - 2021-07-17
 
index f5c2c6a0bad2abe88339367cfc2a474c0d7b0dc2..7b466b3a23ff30d349613aaa2dc9f4a1a439eb44 100644 (file)
 #include "config.h"
 
 #include <ctype.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <cgraph/cgraph.h>
+#include <cgraph/likely.h>
+
+static void *xmalloc(size_t size) {
+  void *p = malloc(size);
+  if (UNLIKELY(size > 0 && p == NULL)) {
+    fprintf(stderr, "ccomps: out of memory\n");
+    exit(EXIT_FAILURE);
+  }
+  return p;
+}
+
+static void *xcalloc(size_t count, size_t size) {
+  void *p = calloc(count, size);
+  if (UNLIKELY(count > 0 && size > 0 && p == NULL)) {
+    fprintf(stderr, "ccomps: out of memory\n");
+    exit(EXIT_FAILURE);
+  }
+  return p;
+}
 
-#define N_NEW(n,t)       calloc((n),sizeof(t))
-#define NEW(t)           malloc(sizeof(t))
+static void *xrealloc(void *ptr, size_t size) {
+  void *p = realloc(ptr, size);
+  if (UNLIKELY(size > 0 && p == NULL)) {
+    fprintf(stderr, "ccomps: out of memory\n");
+    exit(EXIT_FAILURE);
+  }
+  return p;
+}
+
+#define N_NEW(n,t)       xcalloc((n),sizeof(t))
+#define NEW(t)           xmalloc(sizeof(t))
 
 typedef struct {
     Agrec_t h;
@@ -110,7 +139,7 @@ static void split(char *name)
     if (sfx) {
        suffix = sfx + 1;
        size = sfx - name;
-       path = malloc(size + 1);
+       path = xmalloc(size + 1);
        strncpy(path, name, size);
        *(path + size) = '\0';
     } else {
@@ -266,17 +295,9 @@ static void push(Agnode_t * np)
     if (Stk.curp == Stk.curblk->endp) {
        if (Stk.curblk->next == NULL) {
            blk_t *bp = NEW(blk_t);
-           if (bp == 0) {
-               fprintf(stderr, "gc: Out of memory\n");
-               exit(1);
-           }
            bp->prev = Stk.curblk;
            bp->next = NULL;
            bp->data = N_NEW(BIGBUF, Agnode_t *);
-           if (bp->data == 0) {
-               fprintf(stderr, "%s: Out of memory\n", Cmd);
-               exit(1);
-           }
            bp->endp = bp->data + BIGBUF;
            Stk.curblk->next = bp;
        }
@@ -350,7 +371,7 @@ static char *getName(void)
        name = outfile;
     else {
        if (!buf)
-           buf = malloc(strlen(outfile) + 20); /* enough to handle '_number' */
+           buf = xmalloc(strlen(outfile) + 20);        /* enough to handle '_number' */
        if (suffix)
            sprintf(buf, "%s_%d.%s", path, sufcnt, suffix);
        else
@@ -394,7 +415,7 @@ static char *getBuf(int n)
 
     if (n > len) {
        sz = n + 100;
-       buf = realloc(buf, sz);
+       buf = xrealloc(buf, sz);
        len = sz;
     }
     return buf;
@@ -880,7 +901,7 @@ chkGraphName (Agraph_t* g)
     if (*s != '%') return s;
     len = strlen(s) + 2;   /* plus '\0' and '_' */
     if (len > buflen) {
-       buf = realloc (buf, len);
+       buf = xrealloc (buf, len);
        buflen = len;
     }
     buf[0] = '_';