1 /* Check _dl_exception_create_format.
2    Copyright (C) 2018-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <ldsodefs.h>
20 #include <array_length.h>
21 
22 #include <support/check.h>
23 #include <support/xunistd.h>
24 #include <support/capture_subprocess.h>
25 
26 #define TEST(es, objn, fmt, ...)					\
27   ({									\
28      struct dl_exception exception;					\
29      _dl_exception_create_format (&exception, objn, fmt, __VA_ARGS__);	\
30      TEST_COMPARE_STRING (exception.objname, objn == NULL ? "" : objn);	\
31      TEST_COMPARE_STRING (exception.errstring, es);			\
32      _dl_exception_free (&exception);					\
33    })
34 
35 static void
do_test_invalid_conversion(void * closure)36 do_test_invalid_conversion (void *closure)
37 {
38   TEST ("(null)", NULL, "%p", NULL);
39 }
40 
41 /* Exit status after abnormal termination.  */
42 static int invalid_status;
43 
44 static void
init_invalid_status(void)45 init_invalid_status (void)
46 {
47   pid_t pid = xfork ();
48   if (pid == 0)
49     _exit (127);
50   xwaitpid (pid, &invalid_status, 0);
51   if (WIFEXITED (invalid_status))
52     invalid_status = WEXITSTATUS (invalid_status);
53 }
54 
55 static int
do_test(void)56 do_test (void)
57 {
58   init_invalid_status ();
59 
60   TEST ("test",      NULL,   "%s",      "test");
61   TEST ("test-test", NULL,   "%s-test", "test");
62   TEST ("test",      "test", "%s",      "test");
63   TEST ("test-test", "test", "%s-test", "test");
64 
65   TEST ("test%",      NULL,   "%s%%",      "test");
66   TEST ("test%-test", NULL,   "%s%%-test", "test");
67   TEST ("test%",      "test", "%s%%",      "test");
68   TEST ("test%-test", "test", "%s%%-test", "test");
69 
70   TEST ("0000007b",      NULL,   "%x",      123);
71   TEST ("0000007b-test", NULL,   "%x-test", 123);
72   TEST ("0000007b",      "test", "%x",      123);
73   TEST ("0000007b-test", "test", "%x-test", 123);
74 
75 #define TEST_LONG(es, objn, fmt, ...)				\
76   ({								\
77      if (sizeof (int) == sizeof (long int))			\
78        TEST (es, objn, fmt, __VA_ARGS__);			\
79      else							\
80        TEST ("ffffffff" es, objn, fmt, __VA_ARGS__);		\
81    })
82 
83   TEST_LONG ("fffffffd",      NULL,   "%lx",      (long int)~2ul);
84   TEST_LONG ("fffffffd-test", NULL,   "%lx-test", (long int)~2ul);
85   TEST_LONG ("fffffffd",      "test", "%lx",      (long int)~2ul);
86   TEST_LONG ("fffffffd-test", "test", "%lx-test", (long int)~2ul);
87 
88   TEST_LONG ("fffffffe",      NULL,   "%zx",      (size_t)~1ul);
89   TEST_LONG ("fffffffe-test", NULL,   "%zx-test", (size_t)~1ul);
90   TEST_LONG ("fffffffe",      "test", "%zx",      (size_t)~1ul);
91   TEST_LONG ("fffffffe-test", "test", "%zx-test", (size_t)~1ul);
92 
93   struct support_capture_subprocess result;
94   result = support_capture_subprocess (do_test_invalid_conversion, NULL);
95   support_capture_subprocess_check (&result, "dl-exception",
96 				    invalid_status, sc_allow_stderr);
97   TEST_COMPARE_STRING (result.err.buffer,
98 		       "Fatal error: invalid format in exception string\n");
99 
100   return 0;
101 }
102 
103 #include <support/test-driver.c>
104