unit1307.c (15361B)
1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 #include "unitcheck.h" 25 26 #include "curl_fnmatch.h" 27 28 #ifndef CURL_DISABLE_FTP 29 30 /* 31 CURL_FNMATCH_MATCH 0 32 CURL_FNMATCH_NOMATCH 1 33 CURL_FNMATCH_FAIL 2 34 */ 35 36 #define MATCH CURL_FNMATCH_MATCH 37 #define NOMATCH CURL_FNMATCH_NOMATCH 38 39 #define LINUX_DIFFER 0x80 40 #define LINUX_SHIFT 8 41 #define LINUX_MATCH ((CURL_FNMATCH_MATCH << LINUX_SHIFT) | LINUX_DIFFER) 42 #define LINUX_NOMATCH ((CURL_FNMATCH_NOMATCH << LINUX_SHIFT) | LINUX_DIFFER) 43 #define LINUX_FAIL ((CURL_FNMATCH_FAIL << LINUX_SHIFT) | LINUX_DIFFER) 44 45 #define MAC_DIFFER 0x40 46 #define MAC_SHIFT 16 47 #define MAC_MATCH ((CURL_FNMATCH_MATCH << MAC_SHIFT) | MAC_DIFFER) 48 #define MAC_NOMATCH ((CURL_FNMATCH_NOMATCH << MAC_SHIFT) | MAC_DIFFER) 49 #define MAC_FAIL ((CURL_FNMATCH_FAIL << MAC_SHIFT) | MAC_DIFFER) 50 51 static const char *ret2name(int i) 52 { 53 switch(i) { 54 case 0: 55 return "MATCH"; 56 case 1: 57 return "NOMATCH"; 58 case 2: 59 return "FAIL"; 60 default: 61 return "unknown"; 62 } 63 /* not reached */ 64 } 65 66 static CURLcode test_unit1307(char *arg) 67 { 68 UNITTEST_BEGIN_SIMPLE 69 70 struct testcase { 71 const char *pattern; 72 const char *string; 73 int result; 74 }; 75 76 static const struct testcase tests[] = { 77 /* brackets syntax */ 78 {"*[*[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" 79 "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" 80 "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\001\177[[[[[[[[[[[[[[[[[[[[[", 81 "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" 82 "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" 83 "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[", 84 NOMATCH|MAC_FAIL}, 85 86 { "\\[", "[", MATCH }, 87 { "[", "[", NOMATCH|LINUX_MATCH|MAC_FAIL}, 88 { "[]", "[]", NOMATCH|LINUX_MATCH|MAC_FAIL}, 89 { "[][]", "[", MATCH }, 90 { "[][]", "]", MATCH }, 91 { "[[]", "[", MATCH }, 92 { "[[[]", "[", MATCH }, 93 { "[[[[]", "[", MATCH }, 94 { "[[[[]", "[", MATCH }, 95 96 { "[][[]", "]", MATCH }, 97 { "[][[[]", "[", MATCH }, 98 { "[[]", "]", NOMATCH }, 99 100 { "[a@]", "a", MATCH }, 101 102 { "[a-z]", "a", MATCH }, 103 { "[a-z]", "A", NOMATCH }, 104 { "?[a-z]", "?Z", NOMATCH }, 105 { "[A-Z]", "C", MATCH }, 106 { "[A-Z]", "c", NOMATCH }, 107 { "[0-9]", "7", MATCH }, 108 { "[7-8]", "7", MATCH }, 109 { "[7-]", "7", MATCH }, 110 { "[7-]", "-", MATCH }, 111 { "[7-]", "[", NOMATCH }, 112 { "[a-bA-F]", "F", MATCH }, 113 { "[a-bA-B9]", "9", MATCH }, 114 { "[a-bA-B98]", "8", MATCH }, 115 { "[a-bA-B98]", "C", NOMATCH }, 116 { "[a-bA-Z9]", "F", MATCH }, 117 { "[a-bA-Z9]ero*", "Zero chance.", MATCH }, 118 { "S[a-][x]opho*", "Saxophone", MATCH }, 119 { "S[a-][x]opho*", "SaXophone", NOMATCH }, 120 { "S[a-][x]*.txt", "S-x.txt", MATCH }, 121 { "[\\a-\\b]", "a", MATCH }, 122 { "[\\a-\\b]", "b", MATCH }, 123 { "[?*[][?*[][?*[]", "?*[", MATCH }, 124 { "[][?*-]", "]", MATCH }, 125 { "[][?*-]", "[", MATCH }, 126 { "[][?*-]", "?", MATCH }, 127 { "[][?*-]", "*", MATCH }, 128 { "[][?*-]", "-", MATCH }, 129 { "[]?*-]", "-", MATCH }, 130 { "[\xFF]", "\xFF", MATCH|LINUX_FAIL|MAC_FAIL}, 131 { "?/b/c", "a/b/c", MATCH }, 132 { "^_{}~", "^_{}~", MATCH }, 133 { "!#%+,-./01234567889", "!#%+,-./01234567889", MATCH }, 134 { "PQRSTUVWXYZ]abcdefg", "PQRSTUVWXYZ]abcdefg", MATCH }, 135 { ":;=@ABCDEFGHIJKLMNO", ":;=@ABCDEFGHIJKLMNO", MATCH }, 136 137 /* negate */ 138 { "[!a]", "b", MATCH }, 139 { "[!a]", "a", NOMATCH }, 140 { "[^a]", "b", MATCH }, 141 { "[^a]", "a", NOMATCH }, 142 { "[^a-z0-9A-Z]", "a", NOMATCH }, 143 { "[^a-z0-9A-Z]", "-", MATCH }, 144 { "curl[!a-z]lib", "curl lib", MATCH }, 145 { "curl[! ]lib", "curl lib", NOMATCH }, 146 { "[! ][ ]", " ", NOMATCH }, 147 { "[! ][ ]", "a ", MATCH }, 148 { "*[^a].t?t", "a.txt", NOMATCH }, 149 { "*[^a].t?t", "ba.txt", NOMATCH }, 150 { "*[^a].t?t", "ab.txt", MATCH }, 151 { "*[^a]", "", NOMATCH }, 152 { "[!\xFF]", "", NOMATCH|LINUX_FAIL}, 153 { "[!\xFF]", "\xFF", NOMATCH|LINUX_FAIL|MAC_FAIL}, 154 { "[!\xFF]", "a", MATCH|LINUX_FAIL|MAC_FAIL}, 155 { "[!?*[]", "?", NOMATCH }, 156 { "[!!]", "!", NOMATCH }, 157 { "[!!]", "x", MATCH }, 158 159 { "[[:alpha:]]", "a", MATCH }, 160 { "[[:alpha:]]", "9", NOMATCH }, 161 { "[[:alnum:]]", "a", MATCH }, 162 { "[[:alnum:]]", "[", NOMATCH }, 163 { "[[:alnum:]]", "]", NOMATCH }, 164 { "[[:alnum:]]", "9", MATCH }, 165 { "[[:digit:]]", "9", MATCH }, 166 { "[[:xdigit:]]", "9", MATCH }, 167 { "[[:xdigit:]]", "F", MATCH }, 168 { "[[:xdigit:]]", "G", NOMATCH }, 169 { "[[:upper:]]", "U", MATCH }, 170 { "[[:upper:]]", "u", NOMATCH }, 171 { "[[:lower:]]", "l", MATCH }, 172 { "[[:lower:]]", "L", NOMATCH }, 173 { "[[:print:]]", "L", MATCH }, 174 { "[[:print:]]", "\10", NOMATCH }, 175 { "[[:print:]]", "\10", NOMATCH }, 176 { "[[:space:]]", " ", MATCH }, 177 { "[[:space:]]", "x", NOMATCH }, 178 { "[[:graph:]]", " ", NOMATCH }, 179 { "[[:graph:]]", "x", MATCH }, 180 { "[[:blank:]]", "\t", MATCH }, 181 { "[[:blank:]]", " ", MATCH }, 182 { "[[:blank:]]", "\r", NOMATCH }, 183 { "[^[:blank:]]", "\t", NOMATCH }, 184 { "[^[:print:]]", "\10", MATCH }, 185 { "[[:lower:]][[:lower:]]", "ll", MATCH }, 186 { "[[:foo:]]", "bar", NOMATCH|MAC_FAIL}, 187 { "[[:foo:]]", "f]", MATCH|LINUX_NOMATCH|MAC_FAIL}, 188 189 { "Curl[[:blank:]];-)", "Curl ;-)", MATCH }, 190 { "*[[:blank:]]*", " ", MATCH }, 191 { "*[[:blank:]]*", "", NOMATCH }, 192 { "*[[:blank:]]*", "hi, im_Pavel", MATCH }, 193 194 /* common using */ 195 { "filename.dat", "filename.dat", MATCH }, 196 { "*curl*", "lets use curl!!", MATCH }, 197 { "filename.txt", "filename.dat", NOMATCH }, 198 { "*.txt", "text.txt", MATCH }, 199 { "*.txt", "a.txt", MATCH }, 200 { "*.txt", ".txt", MATCH }, 201 { "*.txt", "txt", NOMATCH }, 202 { "??.txt", "99.txt", MATCH }, 203 { "??.txt", "a99.txt", NOMATCH }, 204 { "?.???", "a.txt", MATCH }, 205 { "*.???", "somefile.dat", MATCH }, 206 { "*.???", "photo.jpeg", NOMATCH }, 207 { ".*", ".htaccess", MATCH }, 208 { ".*", ".", MATCH }, 209 { ".*", "..", MATCH }, 210 211 /* many stars => one star */ 212 { "**.txt", "text.txt", MATCH }, 213 { "***.txt", "t.txt", MATCH }, 214 { "****.txt", ".txt", MATCH }, 215 216 /* empty string or pattern */ 217 { "", "", MATCH }, 218 { "", "hello", NOMATCH }, 219 { "file", "", NOMATCH }, 220 { "?", "", NOMATCH }, 221 { "*", "", MATCH }, 222 { "x", "", NOMATCH }, 223 224 /* backslash */ 225 { "\\", "\\", MATCH|LINUX_NOMATCH}, 226 { "\\\\", "\\", MATCH }, 227 { "\\\\", "\\\\", NOMATCH }, 228 { "\\?", "?", MATCH }, 229 { "\\*", "*", MATCH }, 230 { "?.txt", "?.txt", MATCH }, 231 { "*.txt", "*.txt", MATCH }, 232 { "\\?.txt", "?.txt", MATCH }, 233 { "\\*.txt", "*.txt", MATCH }, 234 { "\\?.txt", "x.txt", NOMATCH }, 235 { "\\*.txt", "x.txt", NOMATCH }, 236 { "\\*\\\\.txt", "*\\.txt", MATCH }, 237 { "*\\**\\?*\\\\*", "cc*cc?cccc", NOMATCH }, 238 { "*\\?*\\**", "cc?cc", NOMATCH }, 239 { "\\\"\\$\\&\\'\\(\\)", "\"$&'()", MATCH }, 240 { "\\*\\?\\[\\\\\\`\\|", "*?[\\`|", MATCH }, 241 { "[\\a\\b]c", "ac", MATCH }, 242 { "[\\a\\b]c", "bc", MATCH }, 243 { "[\\a\\b]d", "bc", NOMATCH }, 244 { "[a-bA-B\\?]", "?", MATCH }, 245 { "cu[a-ab-b\\r]l", "curl", MATCH }, 246 { "[\\a-z]", "c", MATCH }, 247 248 { "?*?*?.*?*", "abc.c", MATCH }, 249 { "?*?*?.*?*", "abcc", NOMATCH }, 250 { "?*?*?.*?*", "abc.", NOMATCH }, 251 { "?*?*?.*?*", "abc.c++", MATCH }, 252 { "?*?*?.*?*", "abcdef.c++", MATCH }, 253 { "?*?*?.?", "abcdef.c", MATCH }, 254 { "?*?*?.?", "abcdef.cd", NOMATCH }, 255 256 /* https://codepoints.net/U+00E4 Latin Small Letter A with Diaeresis */ 257 { "Lindm\xc3\xa4tarv", "Lindm\xc3\xa4tarv", MATCH }, 258 259 { "", "", MATCH}, 260 {"**]*[*[\x13]**[*\x13)]*]*[**[*\x13~r-]*]**[.*]*[\xe3\xe3\xe3\xe3\xe3\xe3" 261 "\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3" 262 "\xe3\xe3\xe3\xe3\xe3*[\x13]**[*\x13)]*]*[*[\x13]*[~r]*]*\xba\x13\xa6~b-]" 263 "*", 264 "a", NOMATCH|LINUX_FAIL} 265 }; 266 267 int i; 268 269 enum system { 270 SYSTEM_CUSTOM, 271 SYSTEM_LINUX, 272 SYSTEM_MACOS 273 }; 274 275 enum system machine; 276 277 #ifdef HAVE_FNMATCH 278 #ifdef __APPLE__ 279 machine = SYSTEM_MACOS; 280 #else 281 machine = SYSTEM_LINUX; 282 #endif 283 printf("Tested with system fnmatch(), %s-style\n", 284 machine == SYSTEM_LINUX ? "linux" : "mac"); 285 #else 286 printf("Tested with custom fnmatch()\n"); 287 machine = SYSTEM_CUSTOM; 288 #endif 289 290 for(i = 0; i < (int)CURL_ARRAYSIZE(tests); i++) { 291 int result = tests[i].result; 292 int rc = Curl_fnmatch(NULL, tests[i].pattern, tests[i].string); 293 if(result & (LINUX_DIFFER|MAC_DIFFER)) { 294 if((result & LINUX_DIFFER) && (machine == SYSTEM_LINUX)) 295 result >>= LINUX_SHIFT; 296 else if((result & MAC_DIFFER) && (machine == SYSTEM_MACOS)) 297 result >>= MAC_SHIFT; 298 result &= 0x03; /* filter off all high bits */ 299 } 300 if(rc != result) { 301 printf("Curl_fnmatch(\"%s\", \"%s\") should return %s (returns %s)" 302 " [%d]\n", 303 tests[i].pattern, tests[i].string, ret2name(result), 304 ret2name(rc), i); 305 fail("pattern mismatch"); 306 } 307 } 308 309 UNITTEST_END_SIMPLE 310 } 311 312 #else 313 314 static CURLcode test_unit1307(char *arg) 315 { 316 UNITTEST_BEGIN_SIMPLE 317 UNITTEST_END_SIMPLE 318 } 319 320 #endif