From f168c10b52325b00da6355989a18a11743b33f89 Mon Sep 17 00:00:00 2001 From: Comtea04 Date: Sun, 27 Sep 2026 15:06:22 +0900 Subject: bytearray: Handle realloc() failure in byte_array_grow() byte_array_grow() assigned the result of realloc() directly to ba->data and increased the capacity even if realloc() failed, so the following memcpy() in byte_array_append() wrote to NULL + len. On failure, free the old buffer and leave the byte array in a failed state (data == NULL), which byte_array_append() already ignores. The callers check for that state: - the writers (bin, xml, json, openstep and the text output formats) return PLIST_ERR_NO_MEM instead of handing out a NULL/truncated buffer - node_to_xml() base64-encodes directly into the grown buffer, so it must bail out there (only guarded by assert() before) - the OpenStep parser returns PLIST_ERR_NO_MEM for instead of silently returning truncated data Co-Authored-By: Claude Opus 5.5 --- src/bytearray.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/bytearray.c') diff --git a/src/bytearray.c b/src/bytearray.c index 39fad5f..05ea0bb 100644 --- a/src/bytearray.c +++ b/src/bytearray.c @@ -54,11 +54,21 @@ void byte_array_free(bytearray_t *ba) void byte_array_grow(bytearray_t *ba, size_t amount) { - if (ba->stream) { + if (ba->stream || !ba->data) { return; } size_t increase = (amount > PAGE_SIZE) ? (amount+(PAGE_SIZE-1)) & (~(PAGE_SIZE-1)) : PAGE_SIZE; - ba->data = realloc(ba->data, ba->capacity + increase); + void *newdata = realloc(ba->data, ba->capacity + increase); + if (!newdata) { + /* out of memory: put the array into a failed state (data == NULL), + * further appends are ignored and callers must check ba->data */ + free(ba->data); + ba->data = NULL; + ba->len = 0; + ba->capacity = 0; + return; + } + ba->data = newdata; ba->capacity += increase; } @@ -76,6 +86,9 @@ void byte_array_append(bytearray_t *ba, void *buf, size_t len) if (len > remaining) { size_t needed = len - remaining; byte_array_grow(ba, needed); + if (!ba->data) { + return; + } } memcpy(((char*)ba->data) + ba->len, buf, len); } -- cgit v1.1-32-gdbae