From cf24ed9e2a49a90cbdea466047f88cf097b8f181 Mon Sep 17 00:00:00 2001 From: phcoder Date: Wed, 17 Jun 2009 13:47:37 +0000 Subject: [PATCH] 2009-06-17 Vladimir Serbinenko Fix newline handling * include/grub/script_sh.h (grub_lexer_param): new field was_newline * script/sh/lexer.c (grub_script_lexer_init): initilaise was_newline (grub_script_yylex): don't segfault on unterminated script newline terminates command and variable --- ChangeLog | 9 +++++++++ include/grub/script_sh.h | 3 +++ script/sh/lexer.c | 27 +++++++++++++++++---------- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2254e5956..1a7a1c46b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-06-17 Vladimir Serbinenko + + Fix newline handling + + * include/grub/script_sh.h (grub_lexer_param): new field was_newline + * script/sh/lexer.c (grub_script_lexer_init): initilaise was_newline + (grub_script_yylex): don't segfault on unterminated script + newline terminates command and variable + 2009-06-17 Vladimir Serbinenko avoid double grub_adjust_range call. Bug reported by David Simner diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index ab5bf431a..f6177b02a 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -159,6 +159,9 @@ struct grub_lexer_param /* The token that is already parsed but not yet returned. */ int tokenonhold; + + /* Was the last token a newline? */ + int was_newline; }; /* State of the parser as passes to the parser. */ diff --git a/script/sh/lexer.c b/script/sh/lexer.c index 99bd3baac..17f18e203 100644 --- a/script/sh/lexer.c +++ b/script/sh/lexer.c @@ -64,6 +64,7 @@ grub_script_lexer_init (char *script, grub_reader_getline_t getline) param->recordpos = 0; param->recordlen = 0; param->tokenonhold = 0; + param->was_newline = 0; return param; } @@ -158,8 +159,7 @@ grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate) for (;! state->done; firstrun = 0) { - - if (! *state->script) + if (! state->script || ! *state->script) { /* Check if more tokens are requested by the parser. */ if (((state->refs && ! parsestate->err) @@ -169,7 +169,16 @@ grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate) && state->getline) { int doexit = 0; - while (!state->script || ! *state->script) + if (state->state != GRUB_PARSER_STATE_ESC + && state->state != GRUB_PARSER_STATE_QUOTE + && state->state != GRUB_PARSER_STATE_DQUOTE + && ! state->was_newline) + { + state->was_newline = 1; + state->tokenonhold = '\n'; + break; + } + while (! state->script || ! *state->script) { grub_free (state->newscript); state->newscript = 0; @@ -185,13 +194,10 @@ grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate) break; grub_dprintf ("scripting", "token=`\\n'\n"); recordchar (state, '\n'); - if (state->state != GRUB_PARSER_STATE_ESC - && state->state != GRUB_PARSER_STATE_DQUOTE - && state->state != GRUB_PARSER_STATE_QUOTE) - { - state->tokenonhold = '\n'; - break; - } + if (state->state == GRUB_PARSER_STATE_VARNAME) + state->state = GRUB_PARSER_STATE_TEXT; + if (state->state == GRUB_PARSER_STATE_QVARNAME) + state->state = GRUB_PARSER_STATE_DQUOTE; if (state->state == GRUB_PARSER_STATE_DQUOTE || state->state == GRUB_PARSER_STATE_QUOTE) yylval->arg = grub_script_arg_add (parsestate, yylval->arg, @@ -208,6 +214,7 @@ grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate) break; } } + state->was_newline = 0; newstate = grub_parser_cmdline_state (state->state, *state->script, &use);