valid_filename.c (2055B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #include "common.h" 5 6 struct test_case { 7 const char *name; 8 const char *filename; 9 int expected; 10 }; 11 12 static const struct test_case tests[] = { 13 /* Valid filenames. */ 14 { "simple filename", "file.txt", 1 }, 15 { "alphanumeric", "file123", 1 }, 16 { "hyphen", "my-file.txt", 1 }, 17 { "underscore", "my_file.txt", 1 }, 18 { "multiple dots", "archive.tar.gz", 1 }, 19 { "space", "my file.txt", 1 }, 20 { "ampersand", "&file.txt", 1 }, 21 22 /* Invalid filenames. */ 23 { "NULL", NULL, 0 }, 24 { "empty", "", 0 }, 25 { "dot", ".", 0 }, 26 { "dot dot", "..", 0 }, 27 { "slash", "file/name.txt", 0 }, 28 { "leading slash", "/file.txt", 0 }, 29 { "trailing slash", "file.txt/", 0 }, 30 { "parent traversal", "../file.txt", 0 }, 31 { "embedded traversal", "foo/../file.txt", 0 }, 32 { "backslash", "foo\\bar.txt", 0 }, 33 { "double quote", "foo\"bar.txt", 0 }, 34 { "quote with header syntax", "foo\"; x=\"bar", 0 }, 35 { "carriage return", "foo\rbar.txt", 0 }, 36 { "line feed", "foo\nbar.txt", 0 }, 37 { "tab", "foo\tbar.txt", 0 }, 38 { "control character", "foo\x01" "bar.txt", 0 }, 39 { "DEL character", "foo\x7f" "bar.txt", 0 }, 40 }; 41 42 int 43 main(void) 44 { 45 size_t i; 46 int failures = 0; 47 int got; 48 49 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { 50 got = valid_filename(tests[i].filename); 51 52 if (got != tests[i].expected) { 53 fprintf(stderr, 54 "FAIL: %s: valid_filename(%s) returned %d, " 55 "expected %d\n", 56 tests[i].name, 57 tests[i].filename != NULL ? 58 tests[i].filename : "NULL", 59 got, 60 tests[i].expected); 61 failures++; 62 } else { 63 printf("ok: %s\n", tests[i].name); 64 } 65 } 66 67 if (failures != 0) { 68 fprintf(stderr, "%d test(s) failed\n", failures); 69 return EXIT_FAILURE; 70 } 71 72 printf("all tests passed\n"); 73 return EXIT_SUCCESS; 74 75 }