summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2024-01-16 17:17:13 -0800
committerKaz Kylheku <kaz@kylheku.com>2024-01-16 17:17:13 -0800
commitcb0e7a1ccc3940923f318db9b0d7022c4b176f55 (patch)
treed67084bd250bd7cf8d8c0602ff4ab8d25d8bf38c
parent9d4bdaa8a78859a007da379362112634897b93e4 (diff)
downloadtxr-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.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/lib.c b/lib.c
index 3a704997..cc049cf3 100644
--- a/lib.c
+++ b/lib.c
@@ -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;
}