On Wed, 2009-06-10 at 12:52 +0200, Vladimir 'phcoder' Serbinenko wrote:
> +       Fix handling of string like \"hello\" and "a
> +       b"
> +
> +       * script/sh/lexer.c (check_textstate): accept
> GRUB_PARSER_STATE_ESC
> +       (grub_script_yylex): fix parsing of quoting, escaping and
> newline

I needed to tweak the patch and remove a trivial chunk from it to make
it apply to the current sources.  The adjusted patch is attached.
ChangeLog entries should not be part of the patch.

I confirm that the patch doesn't introduce any compiler warnings.  The
patch does fix what it claims to fix.

But something is still wrong:

grub:sh > echo "a\"b""
a\b
grub:sh > echo "a\"b''c
a\bc

It looks like \" cancels quoting for the subsequent characters, but it
shouldn't.

-- 
Regards,
Pavel Roskin
Fix handling of strings like \"hello\" and newlines in strings

From: Vladimir 'phcoder' Serbinenko <phco...@gmail.com>

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;
 
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to