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 1 : static void test_alloca(void) {
13 : static const uint8_t zero[997] = { };
14 : char *t;
15 :
16 1 : t = alloca_align(17, 512);
17 1 : assert_se(!((uintptr_t)t & 0xff));
18 1 : memzero(t, 17);
19 :
20 1 : t = alloca0_align(997, 1024);
21 1 : assert_se(!((uintptr_t)t & 0x1ff));
22 1 : assert_se(!memcmp(t, zero, 997));
23 1 : }
24 :
25 1 : static void test_GREEDY_REALLOC(void) {
26 1 : _cleanup_free_ int *a = NULL, *b = NULL;
27 1 : size_t n_allocated = 0, i, j;
28 :
29 : /* Give valgrind a chance to verify our realloc() operations */
30 :
31 20481 : for (i = 0; i < 20480; i++) {
32 20480 : assert_se(GREEDY_REALLOC(a, n_allocated, i + 1));
33 20480 : assert_se(n_allocated >= i + 1);
34 20480 : assert_se(malloc_usable_size(a) >= (i + 1) * sizeof(int));
35 20480 : a[i] = (int) i;
36 20480 : assert_se(GREEDY_REALLOC(a, n_allocated, i / 2));
37 20480 : assert_se(n_allocated >= i / 2);
38 20480 : assert_se(malloc_usable_size(a) >= (i / 2) * sizeof(int));
39 : }
40 :
41 10241 : for (j = 0; j < i / 2; j++)
42 10240 : assert_se(a[j] == (int) j);
43 :
44 2923 : for (i = 30, n_allocated = 0; i < 20480; i += 7) {
45 2922 : assert_se(GREEDY_REALLOC(b, n_allocated, i + 1));
46 2922 : assert_se(n_allocated >= i + 1);
47 2922 : assert_se(malloc_usable_size(b) >= (i + 1) * sizeof(int));
48 2922 : b[i] = (int) i;
49 2922 : assert_se(GREEDY_REALLOC(b, n_allocated, i / 2));
50 2922 : assert_se(n_allocated >= i / 2);
51 2922 : assert_se(malloc_usable_size(b) >= (i / 2) * sizeof(int));
52 : }
53 :
54 1460 : for (j = 30; j < i / 2; j += 7)
55 1459 : assert_se(b[j] == (int) j);
56 1 : }
57 :
58 1 : static void test_memdup_multiply_and_greedy_realloc(void) {
59 : static const int org[] = { 1, 2, 3 };
60 1 : _cleanup_free_ int *dup;
61 : int *p;
62 1 : size_t i, allocated = 3;
63 :
64 1 : dup = memdup_suffix0_multiply(org, sizeof(int), 3);
65 1 : assert_se(dup);
66 1 : assert_se(dup[0] == 1);
67 1 : assert_se(dup[1] == 2);
68 1 : assert_se(dup[2] == 3);
69 1 : assert_se(((uint8_t*) dup)[sizeof(int) * 3] == 0);
70 1 : free(dup);
71 :
72 1 : dup = memdup_multiply(org, sizeof(int), 3);
73 1 : assert_se(dup);
74 1 : assert_se(dup[0] == 1);
75 1 : assert_se(dup[1] == 2);
76 1 : assert_se(dup[2] == 3);
77 :
78 1 : p = dup;
79 1 : assert_se(greedy_realloc0((void**) &dup, &allocated, 2, sizeof(int)) == p);
80 :
81 1 : p = (int *) greedy_realloc0((void**) &dup, &allocated, 10, sizeof(int));
82 1 : assert_se(p == dup);
83 1 : assert_se(allocated >= 10);
84 1 : assert_se(p[0] == 1);
85 1 : assert_se(p[1] == 2);
86 1 : assert_se(p[2] == 3);
87 20 : for (i = 3; i < allocated; i++)
88 19 : assert_se(p[i] == 0);
89 1 : }
90 :
91 1 : static void test_bool_assign(void) {
92 1 : bool b, c, *cp = &c, d, e, f, g, h;
93 :
94 1 : b = 123;
95 1 : *cp = -11;
96 1 : d = 0xF & 0xFF;
97 1 : e = b & d;
98 1 : f = 0x0;
99 1 : g = cp; /* cast from pointer */
100 1 : h = NULL; /* cast from pointer */
101 :
102 1 : assert(b);
103 1 : assert(c);
104 1 : assert(d);
105 1 : assert(e);
106 1 : assert(!f);
107 1 : assert(g);
108 1 : assert(!h);
109 1 : }
110 :
111 : static int cleanup_counter = 0;
112 :
113 2 : static void cleanup1(void *a) {
114 2 : log_info("%s(%p)", __func__, a);
115 2 : assert_se(++cleanup_counter == *(int*) a);
116 2 : }
117 1 : static void cleanup2(void *a) {
118 1 : log_info("%s(%p)", __func__, a);
119 1 : assert_se(++cleanup_counter == *(int*) a);
120 1 : }
121 1 : static void cleanup3(void *a) {
122 1 : log_info("%s(%p)", __func__, a);
123 1 : assert_se(++cleanup_counter == *(int*) a);
124 1 : }
125 :
126 1 : static void test_cleanup_order(void) {
127 1 : _cleanup_(cleanup1) int x1 = 4, x2 = 3;
128 1 : _cleanup_(cleanup3) int z = 2;
129 2 : _cleanup_(cleanup2) int y = 1;
130 1 : log_debug("x1: %p", &x1);
131 1 : log_debug("x2: %p", &x2);
132 1 : log_debug("y: %p", &y);
133 1 : log_debug("z: %p", &z);
134 1 : }
135 :
136 1 : static void test_auto_erase_memory(void) {
137 1 : _cleanup_(erase_and_freep) uint8_t *p1, *p2;
138 :
139 1 : assert_se(p1 = new(uint8_t, 1024));
140 1 : assert_se(p2 = new(uint8_t, 1024));
141 :
142 1 : 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 1 : memcpy(p2, p1, 1024);
146 1025 : for (size_t i = 0; i < 1024; i++)
147 1024 : assert_se(p1[i] == p2[i]);
148 1 : }
149 :
150 1 : int main(int argc, char *argv[]) {
151 1 : test_setup_logging(LOG_DEBUG);
152 :
153 1 : test_alloca();
154 1 : test_GREEDY_REALLOC();
155 1 : test_memdup_multiply_and_greedy_realloc();
156 1 : test_bool_assign();
157 1 : test_cleanup_order();
158 1 : test_auto_erase_memory();
159 :
160 1 : return 0;
161 : }
|