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