Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Work around unportable behavior of malloc(0) and realloc(NULL, 0).
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 2 Oct 2012 21:31:40 +0000 (17:31 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 2 Oct 2012 21:32:42 +0000 (17:32 -0400)
On some platforms these functions return NULL, rather than the more common
practice of returning a pointer to a zero-sized block of memory.  Hack our
various wrapper functions to hide the difference by substituting a size
request of 1.  This is probably not so important for the callers, who
should never touch the block anyway if they asked for size 0 --- but it's
important for the wrapper functions themselves, which mistakenly treated
the NULL result as an out-of-memory failure.  This broke at least pg_dump
for the case of no user-defined aggregates, as per report from
Matthew Carrington.

Back-patch to 9.2 to fix the pg_dump issue.  Given the lack of previous
complaints, it seems likely that there is no live bug in previous releases,
even though some of these functions were in place before that.

contrib/oid2name/oid2name.c
contrib/pg_upgrade/util.c
contrib/pgbench/pgbench.c
src/backend/utils/misc/guc.c
src/bin/initdb/initdb.c
src/bin/pg_basebackup/streamutil.c
src/bin/pg_ctl/pg_ctl.c
src/bin/pg_dump/dumpmem.c
src/bin/psql/common.c
src/bin/scripts/common.c
src/port/dirmod.c

index 17d4d80fc9089fbafe5902a140b1214246f7bd13..a666731e727b3faf5d27f98045494fc00533566d 100644 (file)
@@ -51,6 +51,7 @@ struct options
 static void help(const char *progname);
 void       get_opts(int, char **, struct options *);
 void      *pg_malloc(size_t size);
+void      *pg_realloc(void *ptr, size_t size);
 char      *pg_strdup(const char *str);
 void       add_one_elt(char *eltname, eary *eary);
 char      *get_comma_elts(eary *eary);
@@ -203,16 +204,37 @@ help(const char *progname)
 void *
 pg_malloc(size_t size)
 {
-   void       *ptr = malloc(size);
+   void       *ptr;
 
+   /* Avoid unportable behavior of malloc(0) */
+   if (size == 0)
+       size = 1;
+   ptr = malloc(size);
    if (!ptr)
    {
-       fprintf(stderr, "out of memory");
+       fprintf(stderr, "out of memory\n");
        exit(1);
    }
    return ptr;
 }
 
+void *
+pg_realloc(void *ptr, size_t size)
+{
+   void       *result;
+
+   /* Avoid unportable behavior of realloc(NULL, 0) */
+   if (ptr == NULL && size == 0)
+       size = 1;
+   result = realloc(ptr, size);
+   if (!result)
+   {
+       fprintf(stderr, "out of memory\n");
+       exit(1);
+   }
+   return result;
+}
+
 char *
 pg_strdup(const char *str)
 {
@@ -220,7 +242,7 @@ pg_strdup(const char *str)
 
    if (!result)
    {
-       fprintf(stderr, "out of memory");
+       fprintf(stderr, "out of memory\n");
        exit(1);
    }
    return result;
@@ -242,14 +264,8 @@ add_one_elt(char *eltname, eary *eary)
    else if (eary->num >= eary->alloc)
    {
        eary      ->alloc *= 2;
-       eary      ->array = (char **)
-       realloc(eary->array, eary->alloc * sizeof(char *));
-
-       if (!eary->array)
-       {
-           fprintf(stderr, "out of memory");
-           exit(1);
-       }
+       eary      ->array = (char **) pg_realloc(eary->array,
+                                                eary->alloc * sizeof(char *));
    }
 
    eary      ->array[eary->num] = pg_strdup(eltname);
index d879e762fa24915c4686fd7557770c1fb8efb099..1d4bc89f0bf7f1ff1639bbe2e53d52f9e20322e3 100644 (file)
@@ -192,33 +192,39 @@ get_user_info(char **user_name)
 
 
 void *
-pg_malloc(size_t n)
+pg_malloc(size_t size)
 {
-   void       *p = malloc(n);
+   void       *p;
 
+   /* Avoid unportable behavior of malloc(0) */
+   if (size == 0)
+       size = 1;
+   p = malloc(size);
    if (p == NULL)
        pg_log(PG_FATAL, "%s: out of memory\n", os_info.progname);
-
    return p;
 }
 
 void *
-pg_realloc(void *ptr, size_t n)
+pg_realloc(void *ptr, size_t size)
 {
-   void       *p = realloc(ptr, n);
+   void       *p;
 
+   /* Avoid unportable behavior of realloc(NULL, 0) */
+   if (ptr == NULL && size == 0)
+       size = 1;
+   p = realloc(ptr, size);
    if (p == NULL)
        pg_log(PG_FATAL, "%s: out of memory\n", os_info.progname);
-
    return p;
 }
 
 
 void
-pg_free(void *p)
+pg_free(void *ptr)
 {
-   if (p != NULL)
-       free(p);
+   if (ptr != NULL)
+       free(ptr);
 }
 
 
index 509472262bc9ce1601dd54b23d3061acb35bd302..a669cf406ba0b639cdb24e06aabeeea21f3262f2 100644 (file)
@@ -299,6 +299,9 @@ pg_malloc(size_t size)
 {
    void       *result;
 
+   /* Avoid unportable behavior of malloc(0) */
+   if (size == 0)
+       size = 1;
    result = malloc(size);
    if (!result)
    {
@@ -313,6 +316,9 @@ pg_realloc(void *ptr, size_t size)
 {
    void       *result;
 
+   /* Avoid unportable behavior of realloc(NULL, 0) */
+   if (ptr == NULL && size == 0)
+       size = 1;
    result = realloc(ptr, size);
    if (!result)
    {
index 48652b21ea45054075acad2a56a1b4f71087ae83..6b202e0425605a19be758806400bf4c806b5b926 100644 (file)
@@ -3358,6 +3358,9 @@ guc_malloc(int elevel, size_t size)
 {
    void       *data;
 
+   /* Avoid unportable behavior of malloc(0) */
+   if (size == 0)
+       size = 1;
    data = malloc(size);
    if (data == NULL)
        ereport(elevel,
@@ -3371,6 +3374,9 @@ guc_realloc(int elevel, void *old, size_t size)
 {
    void       *data;
 
+   /* Avoid unportable behavior of realloc(NULL, 0) */
+   if (old == NULL && size == 0)
+       size = 1;
    data = realloc(old, size);
    if (data == NULL)
        ereport(elevel,
index 11ff554d795a204aba7cbaeb7469dc5cdf1df1e4..c56f721e08f613840b3ff438be9c21542432d9d3 100644 (file)
@@ -294,6 +294,9 @@ pg_malloc(size_t size)
 {
    void       *result;
 
+   /* Avoid unportable behavior of malloc(0) */
+   if (size == 0)
+       size = 1;
    result = malloc(size);
    if (!result)
    {
index b6cc2a303e9fb05cb11f05ffe181db404e81a5f3..22f41281808d47ece9d1d3e8a1206def4f1bf456 100644 (file)
@@ -54,6 +54,9 @@ pg_malloc0(size_t size)
 {
    void       *result;
 
+   /* Avoid unportable behavior of malloc(0) */
+   if (size == 0)
+       size = 1;
    result = malloc(size);
    if (!result)
    {
index 6d74a154ab1e2c8ee7c175bf996bbe69863e2c62..23c47f62752bc54bb0182d4f948588a2e1d7d25a 100644 (file)
@@ -233,6 +233,9 @@ pg_malloc(size_t size)
 {
    void       *result;
 
+   /* Avoid unportable behavior of malloc(0) */
+   if (size == 0)
+       size = 1;
    result = malloc(size);
    if (!result)
    {
index 22637e26e480c44e76bdcc709f2d646fc252645a..08e82b269dc245d93b7c8e2f180fe7f2609ff998 100644 (file)
@@ -42,6 +42,9 @@ pg_malloc(size_t size)
 {
    void       *tmp;
 
+   /* Avoid unportable behavior of malloc(0) */
+   if (size == 0)
+       size = 1;
    tmp = malloc(size);
    if (!tmp)
        exit_horribly(NULL, "out of memory\n");
@@ -63,6 +66,9 @@ pg_realloc(void *ptr, size_t size)
 {
    void       *tmp;
 
+   /* Avoid unportable behavior of realloc(NULL, 0) */
+   if (ptr == NULL && size == 0)
+       size = 1;
    tmp = realloc(ptr, size);
    if (!tmp)
        exit_horribly(NULL, "out of memory\n");
index 1cb30088c484cfe397b986f522052af29476929a..179c1622793ea89449a5d87ffe4cb361d53d1433 100644 (file)
@@ -60,6 +60,9 @@ pg_malloc(size_t size)
 {
    void       *tmp;
 
+   /* Avoid unportable behavior of malloc(0) */
+   if (size == 0)
+       size = 1;
    tmp = malloc(size);
    if (!tmp)
    {
index 4a7d02f7771e8af63fe1cd5da273a415ac70591a..7d8875d81cd05dcf404434dce55538d804ec1c67 100644 (file)
@@ -304,6 +304,9 @@ pg_malloc(size_t size)
 {
    void       *tmp;
 
+   /* Avoid unportable behavior of malloc(0) */
+   if (size == 0)
+       size = 1;
    tmp = malloc(size);
    if (!tmp)
    {
index 22f5c591b07302748bbb89e37bcb6dca1e8b3f32..514424f82e635dd721b184e009dccce1a4d52bf7 100644 (file)
@@ -70,7 +70,11 @@ fe_palloc(Size size)
 {
    void       *res;
 
-   if ((res = malloc(size)) == NULL)
+   /* Avoid unportable behavior of malloc(0) */
+   if (size == 0)
+       size = 1;
+   res = malloc(size);
+   if (res == NULL)
    {
        fprintf(stderr, _("out of memory\n"));
        exit(1);
@@ -96,7 +100,11 @@ fe_repalloc(void *pointer, Size size)
 {
    void       *res;
 
-   if ((res = realloc(pointer, size)) == NULL)
+   /* Avoid unportable behavior of realloc(NULL, 0) */
+   if (pointer == NULL && size == 0)
+       size = 1;
+   res = realloc(pointer, size);
+   if (res == NULL)
    {
        fprintf(stderr, _("out of memory\n"));
        exit(1);