Return to check_fill.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers / regress / parser |
1.1 misho 1: /* 2: * Copyright (c) 2011 Todd C. Miller <Todd.Miller@courtesan.com> 3: * 4: * Permission to use, copy, modify, and distribute this software for any 5: * purpose with or without fee is hereby granted, provided that the above 6: * copyright notice and this permission notice appear in all copies. 7: * 8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15: */ 16: 17: #include <config.h> 18: 19: #include <sys/types.h> 20: #include <stdio.h> 21: #ifdef STDC_HEADERS 22: # include <stdlib.h> 23: # include <stddef.h> 24: #else 25: # ifdef HAVE_STDLIB_H 26: # include <stdlib.h> 27: # endif 28: #endif /* STDC_HEADERS */ 29: #ifdef HAVE_STRING_H 30: # include <string.h> 31: #endif /* HAVE_STRING_H */ 32: #ifdef HAVE_STRINGS_H 33: # include <strings.h> 34: #endif /* HAVE_STRINGS_H */ 35: #include <grp.h> 36: #include <pwd.h> 37: 38: #include "list.h" 39: #include "parse.h" 40: #include "toke.h" 41: #include "gram.h" 42: 43: /* 44: * TODO: test realloc 45: */ 46: 47: YYSTYPE yylval; 48: 49: struct fill_test { 50: const char *input; 51: const char *output; 52: int len; 53: int addspace; 54: }; 55: 56: /* 57: * In "normal" fill, anything can be escaped and hex chars are expanded. 58: */ 59: static struct fill_test txt_data[] = { 60: { "Embedded\\x20Space", "Embedded Space", 0 }, 61: { "\\x20Leading", " Leading", 0 }, 62: { "Trailing\\x20", "Trailing ", 0 }, 63: { "Multiple\\x20\\x20Spaces", "Multiple Spaces", 0 }, 64: { "Hexparse\\x200Check", "Hexparse 0Check", 0 }, 65: { "Escaped\\\\Escape", "Escaped\\Escape", 0 }, 66: { "LongGroupName", "LongGrou", 8 } 67: }; 68: 69: /* 70: * The only escaped chars in a command should be [,:= \t#] 71: * The rest are done by glob() or fnmatch(). 72: */ 73: static struct fill_test cmd_data[] = { 74: { "foo\\,bar", "foo,bar", 0 }, 75: { "this\\:that", "this:that", 0 }, 76: { "foo\\=bar", "foo=bar", 0 }, 77: { "tab\\\tstop", "tab\tstop", 0 }, 78: { "not a \\#comment", "not a #comment", 0 } 79: }; 80: 81: /* 82: * No escaped characters in command line args. 83: * Arguments get appended. 84: */ 85: static struct fill_test args_data[] = { 86: { "/", "/", 0, 0 }, 87: { "-type", "/ -type", 0, 1 }, 88: { "f", "/ -type f", 0, 1 }, 89: { "-exec", "/ -type f -exec", 0, 1 }, 90: { "ls", "/ -type f -exec ls", 0, 1 }, 91: { "{}", "/ -type f -exec ls {}", 0, 1 } 92: }; 93: 94: static int 95: check_fill(const char *input, int len, int addspace, const char *expect, char **resultp) 96: { 97: if (!fill(input, len)) 98: return -1; 99: *resultp = yylval.string; 100: return !strcmp(yylval.string, expect); 101: } 102: 103: static int 104: check_fill_cmnd(const char *input, int len, int addspace, const char *expect, char **resultp) 105: { 106: if (!fill_cmnd(input, len)) 107: return -1; 108: *resultp = yylval.command.cmnd; 109: return !strcmp(yylval.command.cmnd, expect); 110: } 111: 112: static int 113: check_fill_args(const char *input, int len, int addspace, const char *expect, char **resultp) 114: { 115: if (!fill_args(input, len, addspace)) 116: return -1; 117: *resultp = yylval.command.args; 118: return !strcmp(yylval.command.args, expect); 119: } 120: 121: static int 122: do_tests(int (*checker)(const char *, int, int, const char *, char **), 123: struct fill_test *data, size_t ntests) 124: { 125: int i, len; 126: int errors = 0; 127: char *result; 128: 129: for (i = 0; i < ntests; i++) { 130: if (data[i].len == 0) 131: len = strlen(data[i].input); 132: else 133: len = data[i].len; 134: 135: switch ((*checker)(data[i].input, len, data[i].addspace, data[i].output, &result)) { 136: case 0: 137: /* no match */ 138: fprintf(stderr, "Failed parsing %.*s: expected [%s], got [%s]\n", 139: (int)data[i].len, data[i].input, data[i].output, result); 140: errors++; 141: break; 142: case 1: 143: /* match */ 144: break; 145: default: 146: /* error */ 147: fprintf(stderr, "Failed parsing %.*s: fill function failure\n", 148: (int)data[i].len, data[i].input); 149: errors++; 150: break; 151: } 152: } 153: 154: return errors; 155: } 156: 157: int 158: main(int argc, char *argv[]) 159: { 160: int ntests, errors = 0; 161: 162: errors += do_tests(check_fill, txt_data, sizeof(txt_data) / sizeof(txt_data[0])); 163: errors += do_tests(check_fill_cmnd, cmd_data, sizeof(cmd_data) / sizeof(cmd_data[0])); 164: errors += do_tests(check_fill_args, args_data, sizeof(args_data) / sizeof(args_data[0])); 165: 166: ntests = sizeof(txt_data) / sizeof(txt_data[0]) + 167: sizeof(cmd_data) / sizeof(cmd_data[0]) + 168: sizeof(args_data) / sizeof(args_data[0]); 169: printf("check_fill: %d tests run, %d errors, %d%% success rate\n", 170: ntests, errors, (ntests - errors) * 100 / ntests); 171: 172: exit(errors); 173: } 174: 175: /* STUB */ 176: void 177: cleanup(int gotsig) 178: { 179: return; 180: } 181: 182: /* STUB */ 183: void 184: yyerror(const char *s) 185: { 186: return; 187: }