Commit 2dd2e622 authored by Paul Eggert's avatar Paul Eggert
Browse files

Fix xpalloc confusion after memory is exhausted.

* alloc.c (xpalloc): Comment fix.
* charset.c (Fdefine_charset_internal): If xpalloc exhausts memory
and signals an error, do not clear charset_table_size, as
charset_table is still valid.
* doprnt.c (evxprintf): Clear *BUF after freeing it.
parent db47d5e9
2012-12-02 Paul Eggert <eggert@cs.ucla.edu> 2012-12-02 Paul Eggert <eggert@cs.ucla.edu>
   
Fix xpalloc confusion after memory is exhausted.
* alloc.c (xpalloc): Comment fix.
* charset.c (Fdefine_charset_internal): If xpalloc exhausts memory
and signals an error, do not clear charset_table_size, as
charset_table is still valid.
* doprnt.c (evxprintf): Clear *BUF after freeing it.
Use execve to avoid need to munge environ (Bug#13054). Use execve to avoid need to munge environ (Bug#13054).
* callproc.c (Fcall_process): * callproc.c (Fcall_process):
* process.c (create_process): * process.c (create_process):
......
...@@ -761,13 +761,17 @@ xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size) ...@@ -761,13 +761,17 @@ xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size)
infinity. infinity.
If PA is null, then allocate a new array instead of reallocating If PA is null, then allocate a new array instead of reallocating
the old one. Thus, to grow an array A without saving its old the old one.
contents, invoke xfree (A) immediately followed by xgrowalloc (0,
&NITEMS, ...).
Block interrupt input as needed. If memory exhaustion occurs, set Block interrupt input as needed. If memory exhaustion occurs, set
*NITEMS to zero if PA is null, and signal an error (i.e., do not *NITEMS to zero if PA is null, and signal an error (i.e., do not
return). */ return).
Thus, to grow an array A without saving its old contents, do
{ xfree (A); A = NULL; A = xpalloc (NULL, &AITEMS, ...); }.
The A = NULL avoids a dangling pointer if xpalloc exhausts memory
and signals an error, and later this code is reexecuted and
attempts to free A. */
void * void *
xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min,
......
...@@ -1142,12 +1142,14 @@ usage: (define-charset-internal ...) */) ...@@ -1142,12 +1142,14 @@ usage: (define-charset-internal ...) */)
example, the IDs are stuffed into struct example, the IDs are stuffed into struct
coding_system.charbuf[i] entries, which are 'int'. */ coding_system.charbuf[i] entries, which are 'int'. */
int old_size = charset_table_size; int old_size = charset_table_size;
ptrdiff_t new_size = old_size;
struct charset *new_table = struct charset *new_table =
xpalloc (0, &charset_table_size, 1, xpalloc (0, &new_size, 1,
min (INT_MAX, MOST_POSITIVE_FIXNUM), min (INT_MAX, MOST_POSITIVE_FIXNUM),
sizeof *charset_table); sizeof *charset_table);
memcpy (new_table, charset_table, old_size * sizeof *new_table); memcpy (new_table, charset_table, old_size * sizeof *new_table);
charset_table = new_table; charset_table = new_table;
charset_table_size = new_size;
/* FIXME: This leaks memory, as the old charset_table becomes /* FIXME: This leaks memory, as the old charset_table becomes
unreachable. If the old charset table is charset_table_init unreachable. If the old charset table is charset_table_init
then this leak is intentional; otherwise, it's unclear. then this leak is intentional; otherwise, it's unclear.
......
...@@ -521,7 +521,10 @@ evxprintf (char **buf, ptrdiff_t *bufsize, ...@@ -521,7 +521,10 @@ evxprintf (char **buf, ptrdiff_t *bufsize,
if (nbytes < *bufsize - 1) if (nbytes < *bufsize - 1)
return nbytes; return nbytes;
if (*buf != nonheapbuf) if (*buf != nonheapbuf)
xfree (*buf); {
xfree (*buf);
*buf = NULL;
}
*buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1); *buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1);
} }
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment