diff options
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/alloc.c | 12 | ||||
| -rw-r--r-- | src/charset.c | 4 | ||||
| -rw-r--r-- | src/doprnt.c | 5 |
4 files changed, 22 insertions, 6 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 27453ab8a16..d5794b513e6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,12 @@ 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). * callproc.c (Fcall_process): * process.c (create_process): diff --git a/src/alloc.c b/src/alloc.c index 28c9b51dab4..e504b3d93ec 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -761,13 +761,17 @@ xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size) infinity. 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 - contents, invoke xfree (A) immediately followed by xgrowalloc (0, - &NITEMS, ...). + the old one. 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 - 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 * xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, diff --git a/src/charset.c b/src/charset.c index c9133c780e8..43be0e9c780 100644 --- a/src/charset.c +++ b/src/charset.c @@ -1142,12 +1142,14 @@ usage: (define-charset-internal ...) */) example, the IDs are stuffed into struct coding_system.charbuf[i] entries, which are 'int'. */ int old_size = charset_table_size; + ptrdiff_t new_size = old_size; struct charset *new_table = - xpalloc (0, &charset_table_size, 1, + xpalloc (0, &new_size, 1, min (INT_MAX, MOST_POSITIVE_FIXNUM), sizeof *charset_table); memcpy (new_table, charset_table, old_size * sizeof *new_table); charset_table = new_table; + charset_table_size = new_size; /* FIXME: This leaks memory, as the old charset_table becomes unreachable. If the old charset table is charset_table_init then this leak is intentional; otherwise, it's unclear. diff --git a/src/doprnt.c b/src/doprnt.c index caa56d6ae88..8cab219aafa 100644 --- a/src/doprnt.c +++ b/src/doprnt.c @@ -521,7 +521,10 @@ evxprintf (char **buf, ptrdiff_t *bufsize, if (nbytes < *bufsize - 1) return nbytes; if (*buf != nonheapbuf) - xfree (*buf); + { + xfree (*buf); + *buf = NULL; + } *buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1); } } |
