Work around unportable behavior of malloc(0) and realloc(NULL, 0).
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.
This commit is contained in:
parent
2164f9a125
commit
09ac603c36
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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");
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user