rcx

library of miscellaneous bits of C code
git clone git://git.rr3.xyz/rcx
Log | Files | Refs | README | LICENSE

commit c7333b81160c0ae825586046cd02db441ae107e5
parent 34049bf63711ae6c17f03e2721055864a19ee917
Author: robert <robertrussell.72001@gmail.com>
Date:   Sat, 30 Jul 2022 16:15:20 -0700

alloc: make overflows nonfatal

Diffstat:
Msrc/alloc.c | 39+++++++++++++++++++++++++--------------
1 file changed, 25 insertions(+), 14 deletions(-)

diff --git a/src/alloc.c b/src/alloc.c @@ -1,3 +1,4 @@ +#include <errno.h> #include <stdlib.h> #include <string.h> @@ -9,21 +10,15 @@ * (but not conversely). This lets us avoid division in overflow checks. */ #define MUL_NO_OVERFLOW ((usize) 1 << (sizeof(usize) * 4)) -static bool +static inline bool mul_will_overflow(usize a, usize b) { return (a >= MUL_NO_OVERFLOW || b >= MUL_NO_OVERFLOW) && a > 0 && USIZE_MAX/a < b; } -#define FAIL_OVERFLOW() fatalf("allocation failure: overflow") - -/* Compute a + b*c with overflow checks. */ -static usize -addmul(usize a, usize b, usize c) { - if (mul_will_overflow(b, c)) FAIL_OVERFLOW(); - usize bc = b * c; - if (a > USIZE_MAX - bc) FAIL_OVERFLOW(); - return a + bc; +static inline bool +addmul_will_overflow(usize a, usize b, usize c) { /* a + b*c */ + return mul_will_overflow(b, c) || a > USIZE_MAX - b*c; } void * @@ -48,12 +43,20 @@ allocnz(usize len, usize size) { void * allocf(usize hsize, usize flen, usize fsize) { - return alloc(addmul(hsize, flen, fsize)); + if (addmul_will_overflow(hsize, flen, fsize)) { + errno = ENOMEM; + return 0; + } + return alloc(hsize + flen*fsize); } void * allocfz(usize hsize, usize flen, usize fsize) { - return allocz(addmul(hsize, flen, fsize)); + if (addmul_will_overflow(hsize, flen, fsize)) { + errno = ENOMEM; + return 0; + } + return allocz(hsize + flen*fsize); } void * @@ -76,12 +79,20 @@ reallocnz(void *p, usize olen, usize nlen, usize size) { void * reallocf(void *p, usize hsize, usize flen, usize fsize) { - return realloc(p, addmul(hsize, flen, fsize)); + if (addmul_will_overflow(hsize, flen, fsize)) { + errno = ENOMEM; + return 0; + } + return realloc(p, hsize + flen*fsize); } void * reallocfz(void *p, usize hsize, usize oflen, usize nflen, usize fsize) { - return reallocz(p, hsize + oflen*fsize, addmul(hsize, nflen, fsize)); + if (addmul_will_overflow(hsize, nflen, fsize)) { + errno = ENOMEM; + return 0; + } + return reallocz(p, hsize + oflen*fsize, hsize + nflen*fsize); } #define EALLOC(name, ...)\