1 | /* Unit tests for g |
2 | * Copyright (C) 2010 Red Hat, Inc. |
3 | * |
4 | * This work is provided "as is"; redistribution and modification |
5 | * in whole or in part, in any medium, physical or electronic is |
6 | * permitted without restriction. |
7 | * |
8 | * This work is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
11 | * |
12 | * In no event shall the authors or contributors be liable for any |
13 | * direct, indirect, incidental, special, exemplary, or consequential |
14 | * damages (including, but not limited to, procurement of substitute |
15 | * goods or services; loss of use, data, or profits; or business |
16 | * interruption) however caused and on any theory of liability, whether |
17 | * in contract, strict liability, or tort (including negligence or |
18 | * otherwise) arising in any way out of the use of this software, even |
19 | * if advised of the possibility of such damage. |
20 | */ |
21 | |
22 | /* We test for errors in optimize-only definitions in gmem.h */ |
23 | |
24 | #if defined(__GNUC__) && __GNUC__ > 6 |
25 | #pragma GCC optimize (1) |
26 | #pragma GCC diagnostic push |
27 | #pragma GCC diagnostic ignored "-Walloc-size-larger-than=" |
28 | #endif |
29 | |
30 | #include "glib.h" |
31 | #include <stdlib.h> |
32 | |
33 | static gsize a = G_MAXSIZE / 10 + 10; |
34 | static gsize b = 10; |
35 | typedef char X[10]; |
36 | |
37 | #define MEM_OVERFLOW_TEST(name, code) \ |
38 | static void \ |
39 | mem_overflow_ ## name (void) \ |
40 | { \ |
41 | gpointer p; \ |
42 | code; \ |
43 | g_free (p); \ |
44 | exit (0); \ |
45 | } |
46 | |
47 | MEM_OVERFLOW_TEST (malloc_n_a_a, p = g_malloc_n (a, a)) |
48 | MEM_OVERFLOW_TEST (malloc_n_a_b, p = g_malloc_n (a, b)) |
49 | MEM_OVERFLOW_TEST (malloc_n_b_a, p = g_malloc_n (b, a)) |
50 | MEM_OVERFLOW_TEST (malloc_n_b_b, p = g_malloc_n (b, b)) |
51 | |
52 | MEM_OVERFLOW_TEST (malloc0_n_a_a, p = g_malloc0_n (a, a)) |
53 | MEM_OVERFLOW_TEST (malloc0_n_a_b, p = g_malloc0_n (a, b)) |
54 | MEM_OVERFLOW_TEST (malloc0_n_b_a, p = g_malloc0_n (b, a)) |
55 | MEM_OVERFLOW_TEST (malloc0_n_b_b, p = g_malloc0_n (b, b)) |
56 | |
57 | MEM_OVERFLOW_TEST (realloc_n_a_a, p = g_malloc (1); p = g_realloc_n (p, a, a)) |
58 | MEM_OVERFLOW_TEST (realloc_n_a_b, p = g_malloc (1); p = g_realloc_n (p, a, b)) |
59 | MEM_OVERFLOW_TEST (realloc_n_b_a, p = g_malloc (1); p = g_realloc_n (p, b, a)) |
60 | MEM_OVERFLOW_TEST (realloc_n_b_b, p = g_malloc (1); p = g_realloc_n (p, b, b)) |
61 | |
62 | MEM_OVERFLOW_TEST (new_a, p = g_new (X, a)) |
63 | MEM_OVERFLOW_TEST (new_b, p = g_new (X, b)) |
64 | |
65 | MEM_OVERFLOW_TEST (new0_a, p = g_new0 (X, a)) |
66 | MEM_OVERFLOW_TEST (new0_b, p = g_new0 (X, b)) |
67 | |
68 | MEM_OVERFLOW_TEST (renew_a, p = g_malloc (1); p = g_renew (X, p, a)) |
69 | MEM_OVERFLOW_TEST (renew_b, p = g_malloc (1); p = g_renew (X, p, b)) |
70 | |
71 | static void |
72 | mem_overflow_malloc_0 (void) |
73 | { |
74 | gpointer p; |
75 | |
76 | p = g_malloc (n_bytes: 0); |
77 | g_assert (p == NULL); |
78 | } |
79 | |
80 | static void |
81 | mem_overflow_realloc_0 (void) |
82 | { |
83 | gpointer p; |
84 | |
85 | p = g_malloc (n_bytes: 10); |
86 | g_assert (p != NULL); |
87 | p = g_realloc (mem: p, n_bytes: 0); |
88 | g_assert (p == NULL); |
89 | } |
90 | |
91 | static void |
92 | mem_overflow (void) |
93 | { |
94 | gpointer p, q; |
95 | |
96 | /* "FAIL" here apparently means "fail to overflow"... */ |
97 | #define CHECK_PASS(P) p = (P); g_assert (p == NULL); |
98 | #define CHECK_FAIL(P) p = (P); g_assert (p != NULL); |
99 | |
100 | CHECK_PASS (g_try_malloc_n (a, a)); |
101 | CHECK_PASS (g_try_malloc_n (a, b)); |
102 | CHECK_PASS (g_try_malloc_n (b, a)); |
103 | CHECK_FAIL (g_try_malloc_n (b, b)); |
104 | g_free (mem: p); |
105 | |
106 | CHECK_PASS (g_try_malloc0_n (a, a)); |
107 | CHECK_PASS (g_try_malloc0_n (a, b)); |
108 | CHECK_PASS (g_try_malloc0_n (b, a)); |
109 | CHECK_FAIL (g_try_malloc0_n (b, b)); |
110 | g_free (mem: p); |
111 | |
112 | q = g_malloc (n_bytes: 1); |
113 | CHECK_PASS (g_try_realloc_n (q, a, a)); |
114 | CHECK_PASS (g_try_realloc_n (q, a, b)); |
115 | CHECK_PASS (g_try_realloc_n (q, b, a)); |
116 | CHECK_FAIL (g_try_realloc_n (q, b, b)); |
117 | g_free (mem: p); |
118 | |
119 | CHECK_PASS (g_try_new (X, a)); |
120 | CHECK_FAIL (g_try_new (X, b)); |
121 | g_free (mem: p); |
122 | |
123 | CHECK_PASS (g_try_new0 (X, a)); |
124 | CHECK_FAIL (g_try_new0 (X, b)); |
125 | g_free (mem: p); |
126 | |
127 | q = g_try_malloc (n_bytes: 1); |
128 | CHECK_PASS (g_try_renew (X, q, a)); |
129 | CHECK_FAIL (g_try_renew (X, q, b)); |
130 | free (ptr: p); |
131 | |
132 | #define CHECK_SUBPROCESS_FAIL(name) do { \ |
133 | if (g_test_undefined ()) \ |
134 | { \ |
135 | g_test_trap_subprocess ("/mem/overflow/subprocess/" #name, 0, 0); \ |
136 | g_test_trap_assert_failed(); \ |
137 | } \ |
138 | } while (0) |
139 | |
140 | #define CHECK_SUBPROCESS_PASS(name) do { \ |
141 | if (g_test_undefined ()) \ |
142 | { \ |
143 | g_test_trap_subprocess ("/mem/overflow/subprocess/" #name, 0, 0); \ |
144 | g_test_trap_assert_passed(); \ |
145 | } \ |
146 | } while (0) |
147 | |
148 | CHECK_SUBPROCESS_FAIL (malloc_n_a_a); |
149 | CHECK_SUBPROCESS_FAIL (malloc_n_a_b); |
150 | CHECK_SUBPROCESS_FAIL (malloc_n_b_a); |
151 | CHECK_SUBPROCESS_PASS (malloc_n_b_b); |
152 | |
153 | CHECK_SUBPROCESS_FAIL (malloc0_n_a_a); |
154 | CHECK_SUBPROCESS_FAIL (malloc0_n_a_b); |
155 | CHECK_SUBPROCESS_FAIL (malloc0_n_b_a); |
156 | CHECK_SUBPROCESS_PASS (malloc0_n_b_b); |
157 | |
158 | CHECK_SUBPROCESS_FAIL (realloc_n_a_a); |
159 | CHECK_SUBPROCESS_FAIL (realloc_n_a_b); |
160 | CHECK_SUBPROCESS_FAIL (realloc_n_b_a); |
161 | CHECK_SUBPROCESS_PASS (realloc_n_b_b); |
162 | |
163 | CHECK_SUBPROCESS_FAIL (new_a); |
164 | CHECK_SUBPROCESS_PASS (new_b); |
165 | |
166 | CHECK_SUBPROCESS_FAIL (new0_a); |
167 | CHECK_SUBPROCESS_PASS (new0_b); |
168 | |
169 | CHECK_SUBPROCESS_FAIL (renew_a); |
170 | CHECK_SUBPROCESS_PASS (renew_b); |
171 | |
172 | CHECK_SUBPROCESS_PASS (malloc_0); |
173 | CHECK_SUBPROCESS_PASS (realloc_0); |
174 | } |
175 | |
176 | #ifdef __GNUC__ |
177 | typedef struct |
178 | { |
179 | } Empty; |
180 | |
181 | static void |
182 | empty_alloc_subprocess (void) |
183 | { |
184 | Empty *empty; |
185 | |
186 | empty = g_new0 (Empty, 1); |
187 | g_assert (empty == NULL); |
188 | exit (status: 0); |
189 | } |
190 | |
191 | static void |
192 | empty_alloc (void) |
193 | { |
194 | g_test_bug (bug_uri_snippet: "615379" ); |
195 | |
196 | g_assert_cmpint (sizeof (Empty), ==, 0); |
197 | |
198 | g_test_trap_subprocess (test_path: "/mem/empty-alloc/subprocess" , usec_timeout: 0, test_flags: 0); |
199 | g_test_trap_assert_passed (); |
200 | } |
201 | #endif |
202 | |
203 | #if defined(__GNUC__) && __GNUC__ > 6 |
204 | #pragma GCC diagnostic pop |
205 | #endif |
206 | |
207 | int |
208 | main (int argc, |
209 | char *argv[]) |
210 | { |
211 | g_test_init (argc: &argc, argv: &argv, NULL); |
212 | |
213 | g_test_bug_base (uri_pattern: "http://bugzilla.gnome.org/" ); |
214 | |
215 | g_test_add_func (testpath: "/mem/overflow" , test_func: mem_overflow); |
216 | g_test_add_func (testpath: "/mem/overflow/subprocess/malloc_n_a_a" , test_func: mem_overflow_malloc_n_a_a); |
217 | g_test_add_func (testpath: "/mem/overflow/subprocess/malloc_n_a_b" , test_func: mem_overflow_malloc_n_a_b); |
218 | g_test_add_func (testpath: "/mem/overflow/subprocess/malloc_n_b_a" , test_func: mem_overflow_malloc_n_b_a); |
219 | g_test_add_func (testpath: "/mem/overflow/subprocess/malloc_n_b_b" , test_func: mem_overflow_malloc_n_b_b); |
220 | g_test_add_func (testpath: "/mem/overflow/subprocess/malloc0_n_a_a" , test_func: mem_overflow_malloc0_n_a_a); |
221 | g_test_add_func (testpath: "/mem/overflow/subprocess/malloc0_n_a_b" , test_func: mem_overflow_malloc0_n_a_b); |
222 | g_test_add_func (testpath: "/mem/overflow/subprocess/malloc0_n_b_a" , test_func: mem_overflow_malloc0_n_b_a); |
223 | g_test_add_func (testpath: "/mem/overflow/subprocess/malloc0_n_b_b" , test_func: mem_overflow_malloc0_n_b_b); |
224 | g_test_add_func (testpath: "/mem/overflow/subprocess/realloc_n_a_a" , test_func: mem_overflow_realloc_n_a_a); |
225 | g_test_add_func (testpath: "/mem/overflow/subprocess/realloc_n_a_b" , test_func: mem_overflow_realloc_n_a_b); |
226 | g_test_add_func (testpath: "/mem/overflow/subprocess/realloc_n_b_a" , test_func: mem_overflow_realloc_n_b_a); |
227 | g_test_add_func (testpath: "/mem/overflow/subprocess/realloc_n_b_b" , test_func: mem_overflow_realloc_n_b_b); |
228 | g_test_add_func (testpath: "/mem/overflow/subprocess/new_a" , test_func: mem_overflow_new_a); |
229 | g_test_add_func (testpath: "/mem/overflow/subprocess/new_b" , test_func: mem_overflow_new_b); |
230 | g_test_add_func (testpath: "/mem/overflow/subprocess/new0_a" , test_func: mem_overflow_new0_a); |
231 | g_test_add_func (testpath: "/mem/overflow/subprocess/new0_b" , test_func: mem_overflow_new0_b); |
232 | g_test_add_func (testpath: "/mem/overflow/subprocess/renew_a" , test_func: mem_overflow_renew_a); |
233 | g_test_add_func (testpath: "/mem/overflow/subprocess/renew_b" , test_func: mem_overflow_renew_b); |
234 | g_test_add_func (testpath: "/mem/overflow/subprocess/malloc_0" , test_func: mem_overflow_malloc_0); |
235 | g_test_add_func (testpath: "/mem/overflow/subprocess/realloc_0" , test_func: mem_overflow_realloc_0); |
236 | |
237 | #ifdef __GNUC__ |
238 | g_test_add_func (testpath: "/mem/empty-alloc" , test_func: empty_alloc); |
239 | g_test_add_func (testpath: "/mem/empty-alloc/subprocess" , test_func: empty_alloc_subprocess); |
240 | #endif |
241 | |
242 | return g_test_run(); |
243 | } |
244 | |