Line data Source code
1 : /*
2 : This file is part of TALER
3 : (C) 2026 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file util/test_slug.c
18 : * @brief Tests for slug and session ID validation
19 : * @author Christian Grothoff
20 : */
21 : #include "taler/taler_util.h"
22 :
23 :
24 : static unsigned int
25 1 : check_slug (void)
26 : {
27 : struct
28 : {
29 : const char *slug;
30 : bool expected;
31 1 : } tests[] = {
32 : /* Valid slugs */
33 : {"a", true},
34 : {"instance-1", true},
35 : {"2026.216-EV3XB88000000", true},
36 : {"A.b_c:d~e", true},
37 : {"0123456789", true},
38 : {"...", true},
39 :
40 : /* Invalid slugs */
41 : {"", false}, /* empty */
42 : {".", false}, /* special path component */
43 : {"..", false}, /* special path component */
44 : {"a/b", false}, /* not a single component */
45 : {"a%2Fb", false}, /* percent-encoding */
46 : {"a b", false},
47 : {"a+b", false},
48 : {"a=b", false}, /* '=' is only for session IDs */
49 : {"a?b", false},
50 : {"a#b", false},
51 : {"a&b", false},
52 : {"a@b", false},
53 : };
54 1 : unsigned int failed = 0;
55 :
56 19 : for (unsigned int i = 0; i<sizeof (tests) / sizeof (tests[0]); i++)
57 : {
58 18 : bool result = TALER_is_slug (tests[i].slug);
59 :
60 18 : if (result == tests[i].expected)
61 18 : continue;
62 0 : failed++;
63 0 : fprintf (stderr,
64 : "FAIL: slug \"%s\" -> %s (expected %s)\n",
65 : tests[i].slug,
66 : result ? "VALID" : "INVALID",
67 0 : tests[i].expected ? "VALID" : "INVALID");
68 : }
69 1 : return failed;
70 : }
71 :
72 :
73 : static unsigned int
74 1 : check_session_id (void)
75 : {
76 : struct
77 : {
78 : const char *session_id;
79 : bool expected;
80 1 : } tests[] = {
81 : /* Valid session IDs */
82 : {"", true}, /* not session-bound */
83 : {"session-1", true},
84 : {"4322-6hvIP7UnmNDVjp5Intuf9jFK7MzW0ycEyxf5Mszl3xs=", true}, /* Paivana ID */
85 : {"a", true},
86 : {"A.b_c:d~e=", true},
87 : {"0123456789", true},
88 : {"...", true},
89 :
90 : /* Invalid session IDs */
91 : {".", false}, /* special path component */
92 : {"..", false}, /* special path component */
93 : {"a/b", false}, /* not a single component */
94 : {"a%2Fb", false}, /* percent-encoding */
95 : {"a b", false},
96 : {"a+b", false},
97 : {"a?b", false},
98 : {"a#b", false},
99 : {"a&b", false},
100 : {"a@b", false},
101 : };
102 1 : unsigned int failed = 0;
103 :
104 18 : for (unsigned int i = 0; i<sizeof (tests) / sizeof (tests[0]); i++)
105 : {
106 17 : bool result = TALER_is_session_id (tests[i].session_id);
107 :
108 17 : if (result == tests[i].expected)
109 17 : continue;
110 0 : failed++;
111 0 : fprintf (stderr,
112 : "FAIL: session ID \"%s\" -> %s (expected %s)\n",
113 : tests[i].session_id,
114 : result ? "VALID" : "INVALID",
115 0 : tests[i].expected ? "VALID" : "INVALID");
116 : }
117 1 : return failed;
118 : }
119 :
120 :
121 : int
122 1 : main (int argc,
123 : const char *const argv[])
124 : {
125 : (void) argc;
126 : (void) argv;
127 1 : if (0 != check_slug ())
128 0 : return 1;
129 1 : if (0 != check_session_id ())
130 0 : return 1;
131 1 : return 0;
132 : }
|