aboutsummaryrefslogtreecommitdiff
path: root/src/xz/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xz/util.c')
-rw-r--r--src/xz/util.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/xz/util.c b/src/xz/util.c
index 987b4430..35850f4c 100644
--- a/src/xz/util.c
+++ b/src/xz/util.c
@@ -26,9 +26,19 @@ xrealloc(void *ptr, size_t size)
{
assert(size > 0);
+ // Save ptr so that we can free it if realloc fails.
+ // The point is that message_fatal ends up calling stdio functions
+ // which in some libc implementations might allocate memory from
+ // the heap. Freeing ptr improves the chances that there's free
+ // memory for stdio functions if they need it.
+ void *p = ptr;
ptr = realloc(ptr, size);
- if (ptr == NULL)
- message_fatal("%s", strerror(errno));
+
+ if (ptr == NULL) {
+ const int saved_errno = errno;
+ free(p);
+ message_fatal("%s", strerror(saved_errno));
+ }
return ptr;
}