Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include <malloc.h>
4 : : #include <stdint.h>
5 : :
6 : : #include "alloc-util.h"
7 : : #include "macro.h"
8 : : #include "memory-util.h"
9 : : #include "random-util.h"
10 : : #include "tests.h"
11 : :
12 : 4 : static void test_alloca(void) {
13 : : static const uint8_t zero[997] = { };
14 : : char *t;
15 : :
16 [ - + ]: 4 : t = alloca_align(17, 512);
17 [ - + ]: 4 : assert_se(!((uintptr_t)t & 0xff));
18 [ + - ]: 4 : memzero(t, 17);
19 : :
20 [ - + ]: 4 : t = alloca0_align(997, 1024);
21 [ - + ]: 4 : assert_se(!((uintptr_t)t & 0x1ff));
22 [ - + ]: 4 : assert_se(!memcmp(t, zero, 997));
23 : 4 : }
24 : :
25 : 4 : static void test_GREEDY_REALLOC(void) {
26 : 4 : _cleanup_free_ int *a = NULL, *b = NULL;
27 : 4 : size_t n_allocated = 0, i, j;
28 : :
29 : : /* Give valgrind a chance to verify our realloc() operations */
30 : :
31 [ + + ]: 81924 : for (i = 0; i < 20480; i++) {
32 [ - + ]: 81920 : assert_se(GREEDY_REALLOC(a, n_allocated, i + 1));
33 [ - + ]: 81920 : assert_se(n_allocated >= i + 1);
34 [ - + ]: 81920 : assert_se(malloc_usable_size(a) >= (i + 1) * sizeof(int));
35 : 81920 : a[i] = (int) i;
36 [ - + ]: 81920 : assert_se(GREEDY_REALLOC(a, n_allocated, i / 2));
37 [ - + ]: 81920 : assert_se(n_allocated >= i / 2);
38 [ - + ]: 81920 : assert_se(malloc_usable_size(a) >= (i / 2) * sizeof(int));
39 : : }
40 : :
41 [ + + ]: 40964 : for (j = 0; j < i / 2; j++)
42 [ - + ]: 40960 : assert_se(a[j] == (int) j);
43 : :
44 [ + + ]: 11692 : for (i = 30, n_allocated = 0; i < 20480; i += 7) {
45 [ - + ]: 11688 : assert_se(GREEDY_REALLOC(b, n_allocated, i + 1));
46 [ - + ]: 11688 : assert_se(n_allocated >= i + 1);
47 [ - + ]: 11688 : assert_se(malloc_usable_size(b) >= (i + 1) * sizeof(int));
48 : 11688 : b[i] = (int) i;
49 [ - + ]: 11688 : assert_se(GREEDY_REALLOC(b, n_allocated, i / 2));
50 [ - + ]: 11688 : assert_se(n_allocated >= i / 2);
51 [ - + ]: 11688 : assert_se(malloc_usable_size(b) >= (i / 2) * sizeof(int));
52 : : }
53 : :
54 [ + + ]: 5840 : for (j = 30; j < i / 2; j += 7)
55 [ - + ]: 5836 : assert_se(b[j] == (int) j);
56 : 4 : }
57 : :
58 : 4 : static void test_memdup_multiply_and_greedy_realloc(void) {
59 : : static const int org[] = { 1, 2, 3 };
60 : 4 : _cleanup_free_ int *dup;
61 : : int *p;
62 : 4 : size_t i, allocated = 3;
63 : :
64 : 4 : dup = memdup_suffix0_multiply(org, sizeof(int), 3);
65 [ - + ]: 4 : assert_se(dup);
66 [ - + ]: 4 : assert_se(dup[0] == 1);
67 [ - + ]: 4 : assert_se(dup[1] == 2);
68 [ - + ]: 4 : assert_se(dup[2] == 3);
69 [ - + ]: 4 : assert_se(((uint8_t*) dup)[sizeof(int) * 3] == 0);
70 : 4 : free(dup);
71 : :
72 : 4 : dup = memdup_multiply(org, sizeof(int), 3);
73 [ - + ]: 4 : assert_se(dup);
74 [ - + ]: 4 : assert_se(dup[0] == 1);
75 [ - + ]: 4 : assert_se(dup[1] == 2);
76 [ - + ]: 4 : assert_se(dup[2] == 3);
77 : :
78 : 4 : p = dup;
79 [ - + ]: 4 : assert_se(greedy_realloc0((void**) &dup, &allocated, 2, sizeof(int)) == p);
80 : :
81 : 4 : p = (int *) greedy_realloc0((void**) &dup, &allocated, 10, sizeof(int));
82 [ - + ]: 4 : assert_se(p == dup);
83 [ - + ]: 4 : assert_se(allocated >= 10);
84 [ - + ]: 4 : assert_se(p[0] == 1);
85 [ - + ]: 4 : assert_se(p[1] == 2);
86 [ - + ]: 4 : assert_se(p[2] == 3);
87 [ + + ]: 80 : for (i = 3; i < allocated; i++)
88 [ - + ]: 76 : assert_se(p[i] == 0);
89 : 4 : }
90 : :
91 : 4 : static void test_bool_assign(void) {
92 : 4 : bool b, c, *cp = &c, d, e, f, g, h;
93 : :
94 : 4 : b = 123;
95 : 4 : *cp = -11;
96 : 4 : d = 0xF & 0xFF;
97 : 4 : e = b & d;
98 : 4 : f = 0x0;
99 : 4 : g = cp; /* cast from pointer */
100 : 4 : h = NULL; /* cast from pointer */
101 : :
102 [ - + ]: 4 : assert(b);
103 [ - + ]: 4 : assert(c);
104 [ - + ]: 4 : assert(d);
105 [ - + ]: 4 : assert(e);
106 [ - + ]: 4 : assert(!f);
107 [ - + ]: 4 : assert(g);
108 [ - + ]: 4 : assert(!h);
109 : 4 : }
110 : :
111 : : static int cleanup_counter = 0;
112 : :
113 : 8 : static void cleanup1(void *a) {
114 [ + - ]: 8 : log_info("%s(%p)", __func__, a);
115 [ - + ]: 8 : assert_se(++cleanup_counter == *(int*) a);
116 : 8 : }
117 : 4 : static void cleanup2(void *a) {
118 [ + - ]: 4 : log_info("%s(%p)", __func__, a);
119 [ - + ]: 4 : assert_se(++cleanup_counter == *(int*) a);
120 : 4 : }
121 : 4 : static void cleanup3(void *a) {
122 [ + - ]: 4 : log_info("%s(%p)", __func__, a);
123 [ - + ]: 4 : assert_se(++cleanup_counter == *(int*) a);
124 : 4 : }
125 : :
126 : 4 : static void test_cleanup_order(void) {
127 : 4 : _cleanup_(cleanup1) int x1 = 4, x2 = 3;
128 : 4 : _cleanup_(cleanup3) int z = 2;
129 : 8 : _cleanup_(cleanup2) int y = 1;
130 [ + - ]: 4 : log_debug("x1: %p", &x1);
131 [ + - ]: 4 : log_debug("x2: %p", &x2);
132 [ + - ]: 4 : log_debug("y: %p", &y);
133 [ + - ]: 4 : log_debug("z: %p", &z);
134 : 4 : }
135 : :
136 : 4 : static void test_auto_erase_memory(void) {
137 : 4 : _cleanup_(erase_and_freep) uint8_t *p1, *p2;
138 : :
139 [ - + ]: 4 : assert_se(p1 = new(uint8_t, 1024));
140 [ - + ]: 4 : assert_se(p2 = new(uint8_t, 1024));
141 : :
142 [ - + ]: 4 : assert_se(genuine_random_bytes(p1, 1024, RANDOM_BLOCK) == 0);
143 : :
144 : : /* before we exit the scope, do something with this data, so that the compiler won't optimize this away */
145 : 4 : memcpy(p2, p1, 1024);
146 [ + + ]: 4100 : for (size_t i = 0; i < 1024; i++)
147 [ - + ]: 4096 : assert_se(p1[i] == p2[i]);
148 : 4 : }
149 : :
150 : 4 : int main(int argc, char *argv[]) {
151 : 4 : test_setup_logging(LOG_DEBUG);
152 : :
153 : 4 : test_alloca();
154 : 4 : test_GREEDY_REALLOC();
155 : 4 : test_memdup_multiply_and_greedy_realloc();
156 : 4 : test_bool_assign();
157 : 4 : test_cleanup_order();
158 : 4 : test_auto_erase_memory();
159 : :
160 : 4 : return 0;
161 : : }
|