commit c7333b81160c0ae825586046cd02db441ae107e5
parent 34049bf63711ae6c17f03e2721055864a19ee917
Author: robert <robertrussell.72001@gmail.com>
Date: Sat, 30 Jul 2022 16:15:20 -0700
alloc: make overflows nonfatal
Diffstat:
| M | src/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, ...)\