diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2024-01-16 17:17:13 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2024-01-16 17:17:13 -0800 |
commit | cb0e7a1ccc3940923f318db9b0d7022c4b176f55 (patch) | |
tree | d67084bd250bd7cf8d8c0602ff4ab8d25d8bf38c | |
parent | 9d4bdaa8a78859a007da379362112634897b93e4 (diff) | |
download | txr-cb0e7a1ccc3940923f318db9b0d7022c4b176f55.tar.gz txr-cb0e7a1ccc3940923f318db9b0d7022c4b176f55.tar.bz2 txr-cb0e7a1ccc3940923f318db9b0d7022c4b176f55.zip |
lib: avoid realloc with zero size.
I spotted in the N3096 draft of ISO C (April 2023) that
a zero size in realloc is no longer defined behavior,
like it used to be. I don't know exactly when it changed;
in C99 it is not mentioned. We call realloc only in
one place, so we can defend agains this.
* lib.c (chk_realloc): If the new size is zero, we
implement the C99 and older semantics: deallocate the
object, and then behave like malloc(0). In other
cases, we use realloc.
-rw-r--r-- | lib.c | 16 |
1 files changed, 13 insertions, 3 deletions
@@ -4509,12 +4509,22 @@ mem_t *chk_calloc(size_t n, size_t size) mem_t *chk_realloc(mem_t *old, size_t size) { - mem_t *newptr = convert(mem_t *, realloc(old, size)); + mem_t *newptr = 0; assert (!async_sig_enabled); - if (size != 0 && newptr == 0) - oom(); + /* We avoid calling realloc with size == 0. + * It was okay in C99; 2023 draft of ISO C says this is undefined. + */ + if (size == 0) { + free(old); + newptr = convert(mem_t *, malloc(0)); + } else { + newptr = convert(mem_t *, realloc(old, size)); + if (newptr == 0) + oom(); + } + malloc_bytes += size; return newptr; } |