Fix handling of strings like \"hello\" and newlines in strings From: Vladimir 'phcoder' Serbinenko ChangeLog: * script/sh/lexer.c (check_textstate): accept GRUB_PARSER_STATE_ESC (grub_script_yylex): fix parsing of quoting, escaping and newline --- script/sh/lexer.c | 22 +++++++++++++++++----- 1 files changed, 17 insertions(+), 5 deletions(-) diff --git a/script/sh/lexer.c b/script/sh/lexer.c index aa8ac35..f8f1eaa 100644 --- a/script/sh/lexer.c +++ b/script/sh/lexer.c @@ -39,6 +39,7 @@ static int check_textstate (grub_parser_state_t state) { return (state == GRUB_PARSER_STATE_TEXT + || state == GRUB_PARSER_STATE_ESC || state == GRUB_PARSER_STATE_QUOTE || state == GRUB_PARSER_STATE_DQUOTE); } @@ -155,18 +156,20 @@ grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate) return token; } - for (;! state->done && (*state->script || firstrun); firstrun = 0) + for (;! state->done; firstrun = 0) { if (! *state->script) { /* Check if more tokens are requested by the parser. */ if (((state->refs && ! parsestate->err) - || state->state == GRUB_PARSER_STATE_ESC) + || state->state == GRUB_PARSER_STATE_ESC + || state->state == GRUB_PARSER_STATE_QUOTE + || state->state == GRUB_PARSER_STATE_DQUOTE) && state->getline) { int doexit = 0; - while (!state->script || ! grub_strlen (state->script)) + while (! state->script || ! *state->script) { grub_free (state->newscript); state->newscript = 0; @@ -182,11 +185,18 @@ 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) + 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_DQUOTE + || state->state == GRUB_PARSER_STATE_QUOTE) + yylval->arg = grub_script_arg_add (parsestate, yylval->arg, + GRUB_SCRIPT_ARG_TYPE_STR, + "\n"); } else { @@ -270,7 +280,9 @@ grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate) when a special token was found. It will be recognized next time when this function is called. */ if (newstate == GRUB_PARSER_STATE_TEXT - && state->state != GRUB_PARSER_STATE_ESC) + && state->state != GRUB_PARSER_STATE_ESC + && state->state != GRUB_PARSER_STATE_QUOTE + && state->state != GRUB_PARSER_STATE_DQUOTE) { int breakout = 0;