summaryrefslogtreecommitdiff
path: root/parse.lex
diff options
context:
space:
mode:
authorTodd C. Miller <Todd.Miller@courtesan.com>2007-08-21 11:55:15 +0000
committerTodd C. Miller <Todd.Miller@courtesan.com>2007-08-21 11:55:15 +0000
commitb909967072d692a53f9df428d05c58771ddc3c82 (patch)
tree2727f4f33c432736e3360c7b336f983feca9df7d /parse.lex
parent15f15f10e066e046c64bcfea0b9efe5a72e0f7f6 (diff)
downloadsudo-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.lex73
1 files changed, 58 insertions, 15 deletions
diff --git a/parse.lex b/parse.lex
index fd7ab7bea..57a30ec15 100644
--- a/parse.lex
+++ b/parse.lex
@@ -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