dte test coverage


Directory: ./
File: src/util/xmalloc.c
Date: 2024-12-21 16:03:22
Exec Total Coverage
Lines: 40 40 100.0%
Functions: 9 9 100.0%
Branches: 4 8 50.0%

Line Branch Exec Source
1 #include <errno.h>
2 #include <limits.h>
3 #include <stdarg.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include "xmalloc.h"
7 #include "debug.h"
8 #include "xsnprintf.h"
9
10 75450 static void *check_alloc(void *alloc)
11 {
12
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 75450 times.
75450 if (unlikely(alloc == NULL)) {
13 fatal_error(__func__, ENOMEM);
14 }
15 75450 return alloc;
16 }
17
18 17479 size_t xmul_(size_t a, size_t b)
19 {
20 17479 size_t result;
21
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17479 times.
17479 if (unlikely(size_multiply_overflows(a, b, &result))) {
22 fatal_error(__func__, EOVERFLOW);
23 }
24 17479 return result;
25 }
26
27 190268 size_t xadd(size_t a, size_t b)
28 {
29 190268 size_t result;
30
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 190268 times.
190268 if (unlikely(size_add_overflows(a, b, &result))) {
31 fatal_error(__func__, EOVERFLOW);
32 }
33 190268 return result;
34 }
35
36 // Like malloc(3), but calling fatal_error() on OOM and forbidding
37 // zero-sized allocations (thus never returning NULL)
38 41009 void *xmalloc(size_t size)
39 {
40 41009 BUG_ON(size == 0);
41 41009 return check_alloc(malloc(size));
42 }
43
44 3575 void *xcalloc(size_t nmemb, size_t size)
45 {
46 3575 if (__STDC_VERSION__ < 202311L) {
47 // ISO C23 (ยง7.24.3.2) requires calloc() to check for integer
48 // overflow in `nmemb * size`, but older C standards don't
49 3575 xmul(nmemb, size);
50 }
51
52 3575 BUG_ON(nmemb == 0 || size == 0);
53 3575 return check_alloc(calloc(nmemb, size));
54 }
55
56 11262 void *xrealloc(void *ptr, size_t size)
57 {
58 11262 BUG_ON(size == 0);
59 11262 return check_alloc(realloc(ptr, size));
60 }
61
62 19604 char *xstrdup(const char *str)
63 {
64 19604 return check_alloc(strdup(str));
65 }
66
67 VPRINTF(1)
68 2 static char *xvasprintf(const char *format, va_list ap)
69 {
70 2 va_list ap2;
71 2 va_copy(ap2, ap);
72 2 int n = vsnprintf(NULL, 0, format, ap2);
73 2 va_end(ap2);
74
75
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(n < 0 || n == INT_MAX)) {
76 fatal_error(__func__, n < 0 ? errno : EOVERFLOW);
77 }
78
79 2 char *str = xmalloc(n + 1);
80 2 size_t m = xvsnprintf(str, n + 1, format, ap);
81 2 BUG_ON(m != n);
82 2 return str;
83 }
84
85 2 char *xasprintf(const char *format, ...)
86 {
87 2 va_list ap;
88 2 va_start(ap, format);
89 2 char *str = xvasprintf(format, ap);
90 2 va_end(ap);
91 2 return str;
92 }
93