diff options
| author | Paul Eggert | 2012-12-02 15:11:42 -0800 |
|---|---|---|
| committer | Paul Eggert | 2012-12-02 15:11:42 -0800 |
| commit | 2dd2e62273983693076360e1bc4e59a0f9184c68 (patch) | |
| tree | 5d841624594f6b9152ea619c8f663a189be95cdd /src | |
| parent | db47d5e975dc5bd647f7c6132e7f9eb196f2614f (diff) | |
| download | emacs-2dd2e62273983693076360e1bc4e59a0f9184c68.tar.gz emacs-2dd2e62273983693076360e1bc4e59a0f9184c68.zip | |
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.
Diffstat (limited to 'src')
| -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 @@ | |||
| 1 | 2012-12-02 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2012-12-02 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Fix xpalloc confusion after memory is exhausted. | ||
| 4 | * alloc.c (xpalloc): Comment fix. | ||
| 5 | * charset.c (Fdefine_charset_internal): If xpalloc exhausts memory | ||
| 6 | and signals an error, do not clear charset_table_size, as | ||
| 7 | charset_table is still valid. | ||
| 8 | * doprnt.c (evxprintf): Clear *BUF after freeing it. | ||
| 9 | |||
| 3 | Use execve to avoid need to munge environ (Bug#13054). | 10 | Use execve to avoid need to munge environ (Bug#13054). |
| 4 | * callproc.c (Fcall_process): | 11 | * callproc.c (Fcall_process): |
| 5 | * process.c (create_process): | 12 | * 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) | |||
| 761 | infinity. | 761 | infinity. |
| 762 | 762 | ||
| 763 | If PA is null, then allocate a new array instead of reallocating | 763 | If PA is null, then allocate a new array instead of reallocating |
| 764 | the old one. Thus, to grow an array A without saving its old | 764 | the old one. |
| 765 | contents, invoke xfree (A) immediately followed by xgrowalloc (0, | ||
| 766 | &NITEMS, ...). | ||
| 767 | 765 | ||
| 768 | Block interrupt input as needed. If memory exhaustion occurs, set | 766 | Block interrupt input as needed. If memory exhaustion occurs, set |
| 769 | *NITEMS to zero if PA is null, and signal an error (i.e., do not | 767 | *NITEMS to zero if PA is null, and signal an error (i.e., do not |
| 770 | return). */ | 768 | return). |
| 769 | |||
| 770 | Thus, to grow an array A without saving its old contents, do | ||
| 771 | { xfree (A); A = NULL; A = xpalloc (NULL, &AITEMS, ...); }. | ||
| 772 | The A = NULL avoids a dangling pointer if xpalloc exhausts memory | ||
| 773 | and signals an error, and later this code is reexecuted and | ||
| 774 | attempts to free A. */ | ||
| 771 | 775 | ||
| 772 | void * | 776 | void * |
| 773 | xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, | 777 | 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 ...) */) | |||
| 1142 | example, the IDs are stuffed into struct | 1142 | example, the IDs are stuffed into struct |
| 1143 | coding_system.charbuf[i] entries, which are 'int'. */ | 1143 | coding_system.charbuf[i] entries, which are 'int'. */ |
| 1144 | int old_size = charset_table_size; | 1144 | int old_size = charset_table_size; |
| 1145 | ptrdiff_t new_size = old_size; | ||
| 1145 | struct charset *new_table = | 1146 | struct charset *new_table = |
| 1146 | xpalloc (0, &charset_table_size, 1, | 1147 | xpalloc (0, &new_size, 1, |
| 1147 | min (INT_MAX, MOST_POSITIVE_FIXNUM), | 1148 | min (INT_MAX, MOST_POSITIVE_FIXNUM), |
| 1148 | sizeof *charset_table); | 1149 | sizeof *charset_table); |
| 1149 | memcpy (new_table, charset_table, old_size * sizeof *new_table); | 1150 | memcpy (new_table, charset_table, old_size * sizeof *new_table); |
| 1150 | charset_table = new_table; | 1151 | charset_table = new_table; |
| 1152 | charset_table_size = new_size; | ||
| 1151 | /* FIXME: This leaks memory, as the old charset_table becomes | 1153 | /* FIXME: This leaks memory, as the old charset_table becomes |
| 1152 | unreachable. If the old charset table is charset_table_init | 1154 | unreachable. If the old charset table is charset_table_init |
| 1153 | then this leak is intentional; otherwise, it's unclear. | 1155 | 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, | |||
| 521 | if (nbytes < *bufsize - 1) | 521 | if (nbytes < *bufsize - 1) |
| 522 | return nbytes; | 522 | return nbytes; |
| 523 | if (*buf != nonheapbuf) | 523 | if (*buf != nonheapbuf) |
| 524 | xfree (*buf); | 524 | { |
| 525 | xfree (*buf); | ||
| 526 | *buf = NULL; | ||
| 527 | } | ||
| 525 | *buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1); | 528 | *buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1); |
| 526 | } | 529 | } |
| 527 | } | 530 | } |