e923f44c0ac32b5e20acab975364f7d4e7f1391d
[platform/upstream/glib.git] / glib / tests / mem-overflow.c
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 #pragma GCC optimize (1)
25
26 #include "glib.h"
27 #include <stdlib.h>
28
29 static gsize a = G_MAXSIZE / 10 + 10;
30 static gsize b = 10;
31 typedef char X[10];
32
33 #define MEM_OVERFLOW_TEST(name, code) \
34 static void                           \
35 mem_overflow_ ## name (void)          \
36 {                                     \
37   gpointer p;                         \
38   code;                               \
39   g_free (p);                         \
40   exit (0);                           \
41 }
42
43 MEM_OVERFLOW_TEST (malloc_n_a_a, p = g_malloc_n (a, a))
44 MEM_OVERFLOW_TEST (malloc_n_a_b, p = g_malloc_n (a, b))
45 MEM_OVERFLOW_TEST (malloc_n_b_a, p = g_malloc_n (b, a))
46 MEM_OVERFLOW_TEST (malloc_n_b_b, p = g_malloc_n (b, b))
47
48 MEM_OVERFLOW_TEST (malloc0_n_a_a, p = g_malloc0_n (a, a))
49 MEM_OVERFLOW_TEST (malloc0_n_a_b, p = g_malloc0_n (a, b))
50 MEM_OVERFLOW_TEST (malloc0_n_b_a, p = g_malloc0_n (b, a))
51 MEM_OVERFLOW_TEST (malloc0_n_b_b, p = g_malloc0_n (b, b))
52
53 MEM_OVERFLOW_TEST (realloc_n_a_a, p = g_malloc (1); p = g_realloc_n (p, a, a))
54 MEM_OVERFLOW_TEST (realloc_n_a_b, p = g_malloc (1); p = g_realloc_n (p, a, b))
55 MEM_OVERFLOW_TEST (realloc_n_b_a, p = g_malloc (1); p = g_realloc_n (p, b, a))
56 MEM_OVERFLOW_TEST (realloc_n_b_b, p = g_malloc (1); p = g_realloc_n (p, b, b))
57
58 MEM_OVERFLOW_TEST (new_a, p = g_new (X, a))
59 MEM_OVERFLOW_TEST (new_b, p = g_new (X, b))
60
61 MEM_OVERFLOW_TEST (new0_a, p = g_new0 (X, a))
62 MEM_OVERFLOW_TEST (new0_b, p = g_new0 (X, b))
63
64 MEM_OVERFLOW_TEST (renew_a, p = g_malloc (1); p = g_renew (X, p, a))
65 MEM_OVERFLOW_TEST (renew_b, p = g_malloc (1); p = g_renew (X, p, b))
66
67 static void
68 mem_overflow (void)
69 {
70   gpointer p, q;
71
72   /* "FAIL" here apparently means "fail to overflow"... */
73 #define CHECK_PASS(P)   p = (P); g_assert (p == NULL);
74 #define CHECK_FAIL(P)   p = (P); g_assert (p != NULL);
75
76   CHECK_PASS (g_try_malloc_n (a, a));
77   CHECK_PASS (g_try_malloc_n (a, b));
78   CHECK_PASS (g_try_malloc_n (b, a));
79   CHECK_FAIL (g_try_malloc_n (b, b));
80   g_free (p);
81
82   CHECK_PASS (g_try_malloc0_n (a, a));
83   CHECK_PASS (g_try_malloc0_n (a, b));
84   CHECK_PASS (g_try_malloc0_n (b, a));
85   CHECK_FAIL (g_try_malloc0_n (b, b));
86   g_free (p);
87
88   q = g_malloc (1);
89   CHECK_PASS (g_try_realloc_n (q, a, a));
90   CHECK_PASS (g_try_realloc_n (q, a, b));
91   CHECK_PASS (g_try_realloc_n (q, b, a));
92   CHECK_FAIL (g_try_realloc_n (q, b, b));
93   g_free (p);
94
95   CHECK_PASS (g_try_new (X, a));
96   CHECK_FAIL (g_try_new (X, b));
97   g_free (p);
98
99   CHECK_PASS (g_try_new0 (X, a));
100   CHECK_FAIL (g_try_new0 (X, b));
101   g_free (p);
102
103   q = g_try_malloc (1);
104   CHECK_PASS (g_try_renew (X, q, a));
105   CHECK_FAIL (g_try_renew (X, q, b));
106   free (p);
107
108 #define CHECK_SUBPROCESS_FAIL(name) do { \
109       if (g_test_undefined ()) \
110         { \
111           g_test_trap_subprocess ("/mem/overflow:" #name, 0, G_TEST_TRAP_SILENCE_STDERR); \
112           g_test_trap_assert_failed(); \
113         } \
114     } while (0)
115
116 #define CHECK_SUBPROCESS_PASS(name) do { \
117       if (g_test_undefined ()) \
118         { \
119           g_test_trap_subprocess ("/mem/overflow:" #name, 0, G_TEST_TRAP_SILENCE_STDERR); \
120           g_test_trap_assert_passed(); \
121         } \
122     } while (0)
123
124   CHECK_SUBPROCESS_FAIL (malloc_n_a_a);
125   CHECK_SUBPROCESS_FAIL (malloc_n_a_b);
126   CHECK_SUBPROCESS_FAIL (malloc_n_b_a);
127   CHECK_SUBPROCESS_PASS (malloc_n_b_b);
128
129   CHECK_SUBPROCESS_FAIL (malloc0_n_a_a);
130   CHECK_SUBPROCESS_FAIL (malloc0_n_a_b);
131   CHECK_SUBPROCESS_FAIL (malloc0_n_b_a);
132   CHECK_SUBPROCESS_PASS (malloc0_n_b_b);
133
134   CHECK_SUBPROCESS_FAIL (realloc_n_a_a);
135   CHECK_SUBPROCESS_FAIL (realloc_n_a_b);
136   CHECK_SUBPROCESS_FAIL (realloc_n_b_a);
137   CHECK_SUBPROCESS_PASS (realloc_n_b_b);
138
139   CHECK_SUBPROCESS_FAIL (new_a);
140   CHECK_SUBPROCESS_PASS (new_b);
141
142   CHECK_SUBPROCESS_FAIL (new0_a);
143   CHECK_SUBPROCESS_PASS (new0_b);
144
145   CHECK_SUBPROCESS_FAIL (renew_a);
146   CHECK_SUBPROCESS_PASS (renew_b);
147 }
148
149 typedef struct
150 {
151 } Empty;
152
153 static void
154 empty_alloc_child (void)
155 {
156   Empty *empty;
157
158   empty = g_new0 (Empty, 1);
159   g_assert (empty == NULL);
160   exit (0);
161 }
162
163 static void
164 empty_alloc (void)
165 {
166   g_test_bug ("615379");
167
168   g_assert_cmpint (sizeof (Empty), ==, 0);
169
170   g_test_trap_subprocess ("/mem/empty-alloc:child", 0, 0);
171   g_test_trap_assert_passed ();
172 }
173
174 int
175 main (int   argc,
176       char *argv[])
177 {
178   g_test_init (&argc, &argv, NULL);
179
180   g_test_bug_base ("http://bugzilla.gnome.org/");
181
182   g_test_add_func ("/mem/overflow", mem_overflow);
183   g_test_add_func ("/mem/overflow:malloc_n_a_a", mem_overflow_malloc_n_a_a);
184   g_test_add_func ("/mem/overflow:malloc_n_a_b", mem_overflow_malloc_n_a_b);
185   g_test_add_func ("/mem/overflow:malloc_n_b_a", mem_overflow_malloc_n_b_a);
186   g_test_add_func ("/mem/overflow:malloc_n_b_b", mem_overflow_malloc_n_b_b);
187   g_test_add_func ("/mem/overflow:malloc0_n_a_a", mem_overflow_malloc0_n_a_a);
188   g_test_add_func ("/mem/overflow:malloc0_n_a_b", mem_overflow_malloc0_n_a_b);
189   g_test_add_func ("/mem/overflow:malloc0_n_b_a", mem_overflow_malloc0_n_b_a);
190   g_test_add_func ("/mem/overflow:malloc0_n_b_b", mem_overflow_malloc0_n_b_b);
191   g_test_add_func ("/mem/overflow:realloc_n_a_a", mem_overflow_realloc_n_a_a);
192   g_test_add_func ("/mem/overflow:realloc_n_a_b", mem_overflow_realloc_n_a_b);
193   g_test_add_func ("/mem/overflow:realloc_n_b_a", mem_overflow_realloc_n_b_a);
194   g_test_add_func ("/mem/overflow:realloc_n_b_b", mem_overflow_realloc_n_b_b);
195   g_test_add_func ("/mem/overflow:new_a", mem_overflow_new_a);
196   g_test_add_func ("/mem/overflow:new_b", mem_overflow_new_b);
197   g_test_add_func ("/mem/overflow:new0_a", mem_overflow_new0_a);
198   g_test_add_func ("/mem/overflow:new0_b", mem_overflow_new0_b);
199   g_test_add_func ("/mem/overflow:renew_a", mem_overflow_renew_a);
200   g_test_add_func ("/mem/overflow:renew_b", mem_overflow_renew_b);
201
202   g_test_add_func ("/mem/empty-alloc", empty_alloc);
203   g_test_add_func ("/mem/empty-alloc:child", empty_alloc_child);
204
205   return g_test_run();
206 }