diff options
author | Todd C. Miller <Todd.Miller@courtesan.com> | 2007-08-21 11:55:15 +0000 |
---|---|---|
committer | Todd C. Miller <Todd.Miller@courtesan.com> | 2007-08-21 11:55:15 +0000 |
commit | b909967072d692a53f9df428d05c58771ddc3c82 (patch) | |
tree | 2727f4f33c432736e3360c7b336f983feca9df7d /parse.lex | |
parent | 15f15f10e066e046c64bcfea0b9efe5a72e0f7f6 (diff) | |
download | sudo-b909967072d692a53f9df428d05c58771ddc3c82.tar.gz |
Properly deal with Defaults double-quoted strings that span multiple
lines using the line continuation char. Previously, the entire thing,
including the continuation char, newline, and spaces was stored as-is.
Diffstat (limited to 'parse.lex')
-rw-r--r-- | parse.lex | 73 |
1 files changed, 58 insertions, 15 deletions
@@ -67,12 +67,15 @@ static int sawspace = 0; static int arg_len = 0; static int arg_size = 0; -static void fill __P((char *, int)); +static void _fill __P((char *, int, int)); +static void append __P((char *, int)); static void fill_cmnd __P((char *, int)); static void fill_args __P((char *, int, int)); extern void reset_aliases __P((void)); extern void yyerror __P((char *)); +#define fill(a, b) _fill(a, b, 0) + /* realloc() to size + COMMANDARGINC to make room for command args */ #define COMMANDARGINC 64 @@ -90,7 +93,7 @@ IPV6ADDR \:\:|({HEXDIGIT}\:){7}{HEXDIGIT}|({HEXDIGIT}\:){5}{HEXDIGIT}\:{DOTTEDQ HOSTNAME [[:alnum:]_-]+ WORD ([^#>@!=:,\(\) \t\n\\]|\\[^\n])+ -ENVAR ([^#!=, \t\n\\]|\\[^\n])([^#=, \t\n\\]|\\[^\n])* +ENVAR ([^#!=, \t\n\\\"]|\\[^\n])([^#=, \t\n\\]|\\[^\n])* DEFVAR [a-z_]+ /* XXX - convert GOTRUNAS to exclusive state (GOTDEFS cannot be) */ @@ -99,6 +102,7 @@ DEFVAR [a-z_]+ %x GOTCMND %x STARTDEFS %x INDEFS +%x INSTR %% <GOTDEFS>[[:blank:]]+ BEGIN STARTDEFS; @@ -132,10 +136,10 @@ DEFVAR [a-z_]+ return('-'); } /* return '-' */ - \"([^\"]|\\\")+\" { - LEXTRACE("WORD(1) "); - fill(yytext + 1, yyleng - 2); - return(WORD); + \" { + LEXTRACE("BEGINSTR "); + yylval.string = NULL; + BEGIN INSTR; } {ENVAR} { @@ -145,6 +149,29 @@ DEFVAR [a-z_]+ } } +<INSTR>{ + \\\n[[:blank:]]* { + /* Line continuation char followed by newline. */ + ++sudolineno; + LEXTRACE("\n"); + } + + \" { + LEXTRACE("ENDSTR "); + BEGIN INDEFS; + return(WORD); + } + + ([^\"\n]|\\\")+ { + LEXTRACE("STRBODY "); + /* Push back line continuation char if present */ + if (yyleng > 2 && yytext[yyleng - 1] == '\\' && + isspace((unsigned char)yytext[yyleng - 2])) + yyless(yyleng - 1); + append(yytext, yyleng); + } +} + <GOTCMND>{ \\[\*\?\[\]\!] { /* quoted fnmatch glob char, pass verbatim */ @@ -394,26 +421,42 @@ sudoedit { %% static void -fill(s, len) - char *s; - int len; +_fill(src, len, olen) + char *src; + int len, olen; { int i, j; + char *dst; - yylval.string = (char *) malloc(len + 1); - if (yylval.string == NULL) { + dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1); + if (dst == NULL) { yyerror("unable to allocate memory"); return; } + yylval.string = dst; /* Copy the string and collapse any escaped characters. */ + dst += olen; for (i = 0, j = 0; i < len; i++, j++) { - if (s[i] == '\\' && i != len - 1) - yylval.string[j] = s[++i]; + if (src[i] == '\\' && i != len - 1) + dst[j] = src[++i]; else - yylval.string[j] = s[i]; + dst[j] = src[i]; } - yylval.string[j] = '\0'; + dst[j] = '\0'; +} + +static void +append(src, len) + char *src; + int len; +{ + int olen = 0; + + if (yylval.string != NULL) + olen = strlen(yylval.string); + + _fill(src, len, olen); } static void |