gkdbus: Fix underflow and unreachable code bug
[platform/upstream/glib.git] / glib / tests / error.c
1 #include <glib.h>
2
3 #include "glib-private.h"
4
5 static void
6 test_overwrite (void)
7 {
8   GError *error, *dest, *src;
9
10   if (!g_test_undefined ())
11     return;
12
13   error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
14
15   g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
16                          "*set over the top*");
17   g_set_error_literal (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "bla");
18   g_test_assert_expected_messages ();
19
20   g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
21   g_error_free (error);
22
23
24   error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
25
26   g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
27                          "*set over the top*");
28   g_set_error (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "bla");
29   g_test_assert_expected_messages ();
30
31   g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
32   g_error_free (error);
33
34
35   dest = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
36   src = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "bla");
37
38   g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
39                          "*set over the top*");
40   g_propagate_error (&dest, src);
41   g_test_assert_expected_messages ();
42
43   g_assert_error (dest, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
44   g_error_free (dest);
45 }
46
47 static void
48 test_prefix (void)
49 {
50   GError *error;
51   GError *dest, *src;
52
53   error = NULL;
54   g_prefix_error (&error, "foo %d %s: ", 1, "two");
55   g_assert (error == NULL);
56
57   error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
58   g_prefix_error (&error, "foo %d %s: ", 1, "two");
59   g_assert_cmpstr (error->message, ==, "foo 1 two: bla");
60   g_error_free (error);
61
62   dest = NULL;
63   src = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
64   g_propagate_prefixed_error (&dest, src, "foo %d %s: ", 1, "two");
65   g_assert_cmpstr (dest->message, ==, "foo 1 two: bla");
66   g_error_free (dest);
67
68   src = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
69   g_propagate_prefixed_error (NULL, src, "foo %d %s: ", 1, "two");
70 }
71
72 static void
73 test_prefix_literal (void)
74 {
75   GError *error = NULL;
76
77   g_prefix_error_literal (NULL, "foo: ");
78
79   g_prefix_error_literal (&error, "foo: ");
80   g_assert_null (error);
81
82   error = NULL;
83   g_prefix_error_literal (&error, "foo: ");
84   g_assert_null (error);
85
86   error = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "bla");
87   g_assert_nonnull (error);
88   g_prefix_error_literal (&error, "foo: ");
89   g_assert_cmpstr (error->message, ==, "foo: bla");
90   g_error_free (error);
91 }
92
93 static void
94 test_literal (void)
95 {
96   GError *error;
97
98   error = NULL;
99   g_set_error_literal (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "%s %d %x");
100   g_assert_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
101   g_assert_cmpstr (error->message, ==, "%s %d %x");
102   g_error_free (error);
103 }
104
105 static void
106 test_copy (void)
107 {
108   GError *error;
109   GError *copy;
110
111   error = NULL;
112   g_set_error_literal (&error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "%s %d %x");
113   copy = g_error_copy (error);
114
115   g_assert_error (copy, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY);
116   g_assert_cmpstr (copy->message, ==, "%s %d %x");
117
118   g_error_free (error);
119   g_error_free (copy);
120 }
121
122 static void
123 test_new_valist_invalid_va (gpointer dummy,
124                          ...)
125 {
126 #if defined(__linux__) && defined(__GLIBC__)
127   /* Only worth testing this on Linux with glibc; if other platforms regress on
128    * this legacy behaviour, we don’t care. In particular, calling
129    * g_error_new_valist() with a %NULL format will crash on FreeBSD as its
130    * implementation of vasprintf() is less forgiving than Linux’s. That’s
131    * fine: it’s a programmer error in either case. */
132
133   g_test_summary ("Test that g_error_new_valist() rejects invalid input");
134
135   if (!g_test_undefined ())
136     {
137       g_test_skip ("Not testing response to programmer error");
138       return;
139     }
140
141     {
142       GError *error = NULL;
143       va_list ap;
144
145       va_start (ap, dummy);
146
147 #pragma GCC diagnostic push
148 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
149 #pragma GCC diagnostic ignored "-Wformat-extra-args"
150
151       g_test_expect_message (G_LOG_DOMAIN,
152                              G_LOG_LEVEL_CRITICAL,
153                              "*g_error_new_valist: assertion 'format != NULL' failed*");
154       error = g_error_new_valist (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, NULL, ap);
155       g_test_assert_expected_messages ();
156       g_assert_null (error);
157
158 #pragma GCC diagnostic pop
159
160       va_end (ap);
161     }
162
163     {
164       GError *error = NULL, *error_copy = NULL;
165       va_list ap;
166
167       va_start (ap, dummy);
168
169 #pragma GCC diagnostic push
170 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
171
172       g_test_expect_message (G_LOG_DOMAIN,
173                              G_LOG_LEVEL_WARNING,
174                              "*g_error_new_valist: runtime check failed*");
175       error = g_error_new_valist (0, G_MARKUP_ERROR_EMPTY, "Message", ap);
176       g_test_assert_expected_messages ();
177       g_assert_nonnull (error);
178
179 #pragma GCC diagnostic pop
180
181       g_test_expect_message (G_LOG_DOMAIN,
182                              G_LOG_LEVEL_WARNING,
183                              "*g_error_copy: runtime check failed*");
184       error_copy = g_error_copy (error);
185       g_test_assert_expected_messages ();
186       g_assert_nonnull (error_copy);
187
188       g_clear_error (&error);
189       g_clear_error (&error_copy);
190
191       va_end (ap);
192     }
193 #else  /* if !__linux__ || !__GLIBC__ */
194   g_test_skip ("g_error_new_valist() programmer error handling is only relevant on Linux with glibc");
195 #endif /* !__linux__ || ! __GLIBC__ */
196 }
197
198 static void
199 test_new_valist_invalid (void)
200 {
201   /* We need a wrapper function so we can build a va_list */
202   test_new_valist_invalid_va (NULL);
203 }
204
205 static void
206 test_matches (void)
207 {
208   GError *error = NULL;
209
210   g_test_summary ("Test g_error_matches()");
211
212   error = g_error_new (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "Oh no!");
213
214   g_assert_true (g_error_matches (error, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY));
215   g_assert_false (g_error_matches (NULL, G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY));
216   g_assert_false (g_error_matches (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE));  /* same numeric value as G_MARKUP_ERROR_EMPTY */
217   g_assert_false (g_error_matches (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED));  /* different numeric value from G_MARKUP_ERROR_EMPTY */
218   g_assert_false (g_error_matches (error, G_MARKUP_ERROR, G_MARKUP_ERROR_BAD_UTF8));
219
220   g_error_free (error);
221 }
222
223 static void
224 test_clear (void)
225 {
226   GError *error = NULL;
227
228   g_test_summary ("Test g_error_clear()");
229
230   g_clear_error (&error);
231   g_assert_null (error);
232
233   g_clear_error (NULL);
234
235   error = g_error_new (G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, "Oh no!");
236   g_clear_error (&error);
237   g_assert_null (error);
238 }
239
240 typedef struct
241 {
242   int init_called;
243   int copy_called;
244   int free_called;
245 } TestErrorCheck;
246
247 static TestErrorCheck *init_check;
248
249 GQuark test_error_quark (void);
250 #define TEST_ERROR (test_error_quark ())
251
252 typedef struct
253 {
254   int foo;
255   TestErrorCheck *check;
256 } TestErrorPrivate;
257
258 static void
259 test_error_private_init (TestErrorPrivate *priv)
260 {
261   priv->foo = 13;
262   /* If that triggers, it's test bug.
263    */
264   g_assert_nonnull (init_check);
265   /* Using global init_check, because error->check is still nil at
266    * this point.
267    */
268   init_check->init_called++;
269 }
270
271 static void
272 test_error_private_copy (const TestErrorPrivate *src_priv,
273                          TestErrorPrivate       *dest_priv)
274 {
275   dest_priv->foo = src_priv->foo;
276   dest_priv->check = src_priv->check;
277
278   dest_priv->check->copy_called++;
279 }
280
281 static void
282 test_error_private_clear (TestErrorPrivate *priv)
283 {
284   priv->check->free_called++;
285 }
286
287 G_DEFINE_EXTENDED_ERROR (TestError, test_error)
288
289 static TestErrorPrivate *
290 fill_test_error (GError *error, TestErrorCheck *check)
291 {
292   TestErrorPrivate *test_error = test_error_get_private (error);
293
294   test_error->check = check;
295
296   return test_error;
297 }
298
299 static void
300 test_extended (void)
301 {
302   TestErrorCheck check = { 0, 0, 0 };
303   GError *error;
304   TestErrorPrivate *test_priv;
305   GError *copy_error;
306   TestErrorPrivate *copy_test_priv;
307
308   init_check = &check;
309   error = g_error_new_literal (TEST_ERROR, 0, "foo");
310   test_priv = fill_test_error (error, &check);
311
312   g_assert_cmpint (check.init_called, ==, 1);
313   g_assert_cmpint (check.copy_called, ==, 0);
314   g_assert_cmpint (check.free_called, ==, 0);
315
316   g_assert_cmpuint (error->domain, ==, TEST_ERROR);
317   g_assert_cmpint (test_priv->foo, ==, 13);
318
319   copy_error = g_error_copy (error);
320   g_assert_cmpint (check.init_called, ==, 2);
321   g_assert_cmpint (check.copy_called, ==, 1);
322   g_assert_cmpint (check.free_called, ==, 0);
323
324   g_assert_cmpuint (error->domain, ==, copy_error->domain);
325   g_assert_cmpint (error->code, ==, copy_error->code);
326   g_assert_cmpstr (error->message, ==, copy_error->message);
327
328   copy_test_priv = test_error_get_private (copy_error);
329   g_assert_cmpint (test_priv->foo, ==, copy_test_priv->foo);
330
331   g_error_free (error);
332   g_error_free (copy_error);
333
334   g_assert_cmpint (check.init_called, ==, 2);
335   g_assert_cmpint (check.copy_called, ==, 1);
336   g_assert_cmpint (check.free_called, ==, 2);
337 }
338
339 static void
340 test_extended_duplicate (void)
341 {
342   g_test_summary ("Test that registering a duplicate extended error domain doesn’t work");
343
344   if (!g_test_subprocess ())
345     {
346       /* Spawn a subprocess and expect it to fail. */
347       g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
348       g_test_trap_assert_failed ();
349       g_test_trap_assert_stderr ("*CRITICAL*Attempted to register an extended error domain for TestError more than once*");
350     }
351   else
352     {
353       GQuark q;
354       guint i;
355
356       for (i = 0; i < 2; i++)
357         {
358           q = g_error_domain_register_static ("TestError",
359                                               sizeof (TestErrorPrivate),
360                                               g_error_with_test_error_private_init,
361                                               g_error_with_test_error_private_copy,
362                                               g_error_with_test_error_private_clear);
363           g_assert_cmpstr (g_quark_to_string (q), ==, "TestError");
364         }
365     }
366 }
367
368 typedef struct
369 {
370   int dummy;
371 } TestErrorNonStaticPrivate;
372
373 static void test_error_non_static_private_init (GError *error) {}
374 static void test_error_non_static_private_copy (const GError *src_error, GError *dest_error) {}
375 static void test_error_non_static_private_clear (GError *error) {}
376
377 static void
378 test_extended_non_static (void)
379 {
380   gchar *domain_name = g_strdup ("TestErrorNonStatic");
381   GQuark q;
382   GError *error = NULL;
383
384   g_test_summary ("Test registering an extended error domain with a non-static name");
385
386   q = g_error_domain_register (domain_name,
387                                sizeof (TestErrorNonStaticPrivate),
388                                test_error_non_static_private_init,
389                                test_error_non_static_private_copy,
390                                test_error_non_static_private_clear);
391   g_free (domain_name);
392
393   error = g_error_new (q, 0, "Test error: %s", "hello");
394   g_assert_true (g_error_matches (error, q, 0));
395   g_assert_cmpstr (g_quark_to_string (q), ==, "TestErrorNonStatic");
396   g_error_free (error);
397 }
398
399 int
400 main (int argc, char *argv[])
401 {
402   g_test_init (&argc, &argv, NULL);
403
404   g_test_add_func ("/error/overwrite", test_overwrite);
405   g_test_add_func ("/error/prefix", test_prefix);
406   g_test_add_func ("/error/prefix-literal", test_prefix_literal);
407   g_test_add_func ("/error/literal", test_literal);
408   g_test_add_func ("/error/copy", test_copy);
409   g_test_add_func ("/error/matches", test_matches);
410   g_test_add_func ("/error/clear", test_clear);
411   g_test_add_func ("/error/new-valist/invalid", test_new_valist_invalid);
412   g_test_add_func ("/error/extended", test_extended);
413   g_test_add_func ("/error/extended/duplicate", test_extended_duplicate);
414   g_test_add_func ("/error/extended/non-static", test_extended_non_static);
415
416   return g_test_run ();
417 }