test_slug.c (3690B)
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 check_slug (void) 26 { 27 struct 28 { 29 const char *slug; 30 bool expected; 31 } 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 unsigned int failed = 0; 55 56 for (unsigned int i = 0; i<sizeof (tests) / sizeof (tests[0]); i++) 57 { 58 bool result = TALER_is_slug (tests[i].slug); 59 60 if (result == tests[i].expected) 61 continue; 62 failed++; 63 fprintf (stderr, 64 "FAIL: slug \"%s\" -> %s (expected %s)\n", 65 tests[i].slug, 66 result ? "VALID" : "INVALID", 67 tests[i].expected ? "VALID" : "INVALID"); 68 } 69 return failed; 70 } 71 72 73 static unsigned int 74 check_session_id (void) 75 { 76 struct 77 { 78 const char *session_id; 79 bool expected; 80 } 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 unsigned int failed = 0; 103 104 for (unsigned int i = 0; i<sizeof (tests) / sizeof (tests[0]); i++) 105 { 106 bool result = TALER_is_session_id (tests[i].session_id); 107 108 if (result == tests[i].expected) 109 continue; 110 failed++; 111 fprintf (stderr, 112 "FAIL: session ID \"%s\" -> %s (expected %s)\n", 113 tests[i].session_id, 114 result ? "VALID" : "INVALID", 115 tests[i].expected ? "VALID" : "INVALID"); 116 } 117 return failed; 118 } 119 120 121 int 122 main (int argc, 123 const char *const argv[]) 124 { 125 (void) argc; 126 (void) argv; 127 if (0 != check_slug ()) 128 return 1; 129 if (0 != check_session_id ()) 130 return 1; 131 return 0; 132 }