diff options
author | Martijn van Beurden <mvanb1@gmail.com> | 2022-08-03 13:52:19 +0200 |
---|---|---|
committer | Martijn van Beurden <mvanb1@gmail.com> | 2022-08-20 16:03:53 +0200 |
commit | 21fe95ee828b0b9b944f6aa0bb02d24fbb981815 (patch) | |
tree | 781a94a1982b0f5e69f163658781b0d686792a8c /include | |
parent | b715d7b9fe90f5b411ae1c159553c7c287f0789a (diff) | |
download | flac-21fe95ee828b0b9b944f6aa0bb02d24fbb981815.tar.gz |
Add and use _nofree variants of safe_realloc functions
Parts of the code use realloc like
x = safe_realloc(x, somesize);
when this is the case, the safe_realloc variant used must free the
old memory block in case it fails, otherwise it will leak. However,
there are also instances in the code where handling is different:
if (0 == (x = safe_realloc(y, somesize)))
return false
in this case, y should not be freed, as y is not set to NULL we
could encounter double frees. Here the safe_realloc_nofree
functions are used.
Diffstat (limited to 'include')
-rw-r--r-- | include/share/alloc.h | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/include/share/alloc.h b/include/share/alloc.h index 9b53b010..74f444d6 100644 --- a/include/share/alloc.h +++ b/include/share/alloc.h @@ -161,17 +161,30 @@ static inline void *safe_realloc_(void *ptr, size_t size) free(oldptr); return newptr; } -static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) +static inline void *safe_realloc_nofree_add_2op_(void *ptr, size_t size1, size_t size2) +{ + size2 += size1; + if(size2 < size1) + return 0; + return realloc(ptr, size2); +} + +static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) { size2 += size1; if(size2 < size1) { free(ptr); return 0; } - return realloc(ptr, size2); + size3 += size2; + if(size3 < size2) { + free(ptr); + return 0; + } + return safe_realloc_(ptr, size3); } -static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) +static inline void *safe_realloc_nofree_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) { size2 += size1; if(size2 < size1) @@ -182,7 +195,7 @@ static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, return realloc(ptr, size3); } -static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) +static inline void *safe_realloc_nofree_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) { size2 += size1; if(size2 < size1) @@ -207,6 +220,15 @@ static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) return safe_realloc_(ptr, size1*size2); } +static inline void *safe_realloc_nofree_mul_2op_(void *ptr, size_t size1, size_t size2) +{ + if(!size1 || !size2) + return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ + if(size1 > SIZE_MAX / size2) + return 0; + return realloc(ptr, size1*size2); +} + /* size1 * (size2 + size3) */ static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) { @@ -220,4 +242,15 @@ static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, return safe_realloc_mul_2op_(ptr, size1, size2); } +/* size1 * (size2 + size3) */ +static inline void *safe_realloc_nofree_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) +{ + if(!size1 || (!size2 && !size3)) + return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ + size2 += size3; + if(size2 < size3) + return 0; + return safe_realloc_nofree_mul_2op_(ptr, size1, size2); +} + #endif |