dte test coverage


Directory: ./
File: src/util/xmalloc.c
Date: 2025-02-14 16:55: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 72880 static void *check_alloc(void *alloc)
11 {
12
1/2
✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→4) taken 72880 times.
72880 if (unlikely(alloc == NULL)) {
13 fatal_error(__func__, ENOMEM);
14 }
15 72880 return alloc;
16 }
17
18 16987 size_t xmul_(size_t a, size_t b)
19 {
20 16987 size_t result;
21
1/2
✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 16987 times.
16987 if (unlikely(size_multiply_overflows(a, b, &result))) {
22 fatal_error(__func__, EOVERFLOW);
23 }
24 16987 return result;
25 }
26
27 196129 size_t xadd(size_t a, size_t b)
28 {
29 196129 size_t result;
30
1/2
✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 196129 times.
196129 if (unlikely(size_add_overflows(a, b, &result))) {
31 fatal_error(__func__, EOVERFLOW);
32 }
33 196129 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 42100 void *xmalloc(size_t size)
39 {
40 42100 BUG_ON(size == 0);
41 42100 return check_alloc(malloc(size));
42 }
43
44 3706 void *xcalloc(size_t nmemb, size_t size)
45 {
46 3706 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 3706 xmul(nmemb, size);
50 }
51
52 3706 BUG_ON(nmemb == 0 || size == 0);
53 3706 return check_alloc(calloc(nmemb, size));
54 }
55
56 11527 void *xrealloc(void *ptr, size_t size)
57 {
58 11527 BUG_ON(size == 0);
59 11527 return check_alloc(realloc(ptr, size));
60 }
61
62 15547 char *xstrdup(const char *str)
63 {
64 15547 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 (2→3) not taken.
✓ Branch 1 (2→6) 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