]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
removed arbitrary limit on token size
authorBVK Chaitanya <bvk.groups@gmail.com>
Fri, 22 Jan 2010 18:44:00 +0000 (00:14 +0530)
committerBVK Chaitanya <bvk.groups@gmail.com>
Fri, 22 Jan 2010 18:44:00 +0000 (00:14 +0530)
include/grub/script_sh.h
script/lexer.c
script/yylex.l

index 889017d2a97d423b8329b948cd173d265652af69..1eb6d0bb81b9d18ba7678ededb2e6fcb68d5d756 100644 (file)
@@ -157,8 +157,10 @@ struct grub_lexer_param
   int merge_start;
   int merge_end;
 
-  /* Text of current token.  */
+  /* Part of a multi-part token.  */
   char *text;
+  unsigned used;
+  unsigned size;
 
   /* Type of text.  */
   grub_script_arg_type_t type;
@@ -168,12 +170,9 @@ struct grub_lexer_param
 
   /* Flex scanner buffer.  */
   void *buffer;
-
-  /* Length of current token text.  */
-  unsigned size;
 };
 
-#define GRUB_LEXER_TOKEN_MAX        256
+#define GRUB_LEXER_INITIAL_TEXT_SIZE 32
 #define GRUB_LEXER_RECORD_INCREMENT 256
 
 /* State of the parser as passes to the parser.  */
index d43c9f1570192c6328c34dc0964a04d914282074..179e1d1d2a43f024518695e03efabac7c0f676d0 100644 (file)
@@ -213,7 +213,8 @@ grub_script_lexer_init (struct grub_parser_param *parser, char *script,
   if (!lexerstate)
     return 0;
 
-  lexerstate->text = grub_malloc (GRUB_LEXER_TOKEN_MAX);
+  lexerstate->size = GRUB_LEXER_INITIAL_TEXT_SIZE;
+  lexerstate->text = grub_malloc (lexerstate->size);
   if (!lexerstate->text)
     {
       grub_free (lexerstate);
@@ -301,7 +302,7 @@ grub_script_yylex (union YYSTYPE *value,
   do
     {
       /* Empty lexerstate->text.  */
-      lexerstate->size = 0;
+      lexerstate->used = 1;
       lexerstate->text[0] = '\0';
 
       token = yylex (value, lexerstate->yyscanner);
@@ -311,7 +312,6 @@ grub_script_yylex (union YYSTYPE *value,
       /* Merging feature uses lexerstate->text instead of yytext.  */
       if (lexerstate->merge_start)
        {
-         lexerstate->text[lexerstate->size] = '\0';
          str = lexerstate->text;
          type = lexerstate->type;
        }
index 4f6c00e217d98d631e1363cd5fc8ddc5a391339e..c19461c9a63d0a623af6b8a9a350309c36205b1a 100644 (file)
     grub_printf ("fatal error: %s\n", msg);     \
   } while (0)
 
-#define PUSH(c)                                                                \
-  do {                                                                 \
-    if (yyextra->lexerstate->size >= GRUB_LEXER_TOKEN_MAX - 1)         \
-      grub_script_yyerror (yyextra, "token too long");                 \
-    else                                                               \
-      yyextra->lexerstate->text[yyextra->lexerstate->size++] = c;      \
-  } while (0)
-      
-#define COPY(str)                              \
-  do {                                         \
-    char *ptr = str;                           \
-    while (*ptr && ! yyextra->err)             \
-      {                                                \
-        PUSH (*ptr);                           \
-       ptr++;                                  \
-      }                                                \
+#define COPY(str, hint)                         \
+  do {                                          \
+    copy_string (yyextra, str, hint);           \
   } while (0)
 
-#define RECORD                                 \
-  do {                                         \
-    grub_script_lexer_record (yyextra, yytext);        \
+
+#define RECORD                                  \
+  do {                                          \
+    grub_script_lexer_record (yyextra, yytext); \
   } while (0)
 
-#define ARG(t)                       \
-  do {                               \
+#define ARG(t)                        \
+  do {                                \
     yyextra->lexerstate->type = t;    \
     return GRUB_PARSER_TOKEN_WORD;    \
   } while (0)
@@ -73,6 +61,8 @@
 static void  grub_lexer_yyfree (void *, yyscan_t yyscanner);
 static void* grub_lexer_yyalloc (yy_size_t, yyscan_t yyscanner);
 static void* grub_lexer_yyrealloc (void*, yy_size_t, yyscan_t yyscanner);
+static void  copy_string (struct grub_parser_param *, const char *,
+                          unsigned hint);
 
 %}
 
@@ -201,52 +191,47 @@ WORD            ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+
                   RECORD;
                   /* resplit yytext */
                   yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner);
-                 if (yy_scan_string (yytext, yyscanner))
-                   {
-                     yyextra->lexerstate->merge_start = 1;
-                     yy_push_state (SPLIT, yyscanner);
-                   }
-                 else
-                   {
-                     grub_script_yyerror (yyextra, 0);
-                     yypop_buffer_state (yyscanner);
-                     return GRUB_PARSER_TOKEN_WORD;
-                   }
+                  if (yy_scan_string (yytext, yyscanner))
+                    {
+                      yyextra->lexerstate->merge_start = 1;
+                      yy_push_state (SPLIT, yyscanner);
+                    }
+                  else
+                    {
+                      grub_script_yyerror (yyextra, 0);
+                      yypop_buffer_state (yyscanner);
+                      return GRUB_PARSER_TOKEN_WORD;
+                    }
                 }
 
 .|\n            {
                   grub_script_yyerror (yyextra, "unrecognized token");
-                 return GRUB_PARSER_TOKEN_BAD;
+                  return GRUB_PARSER_TOKEN_BAD;
                 }
 
 
  /* Split word into multiple args */
 
 <SPLIT>{
-  \\.           { PUSH (yytext[1]); }
+  \\.           { COPY (yytext + 1, yyleng - 1); }
   \"            {
-                 yy_push_state (DQUOTE, yyscanner);
+                  yy_push_state (DQUOTE, yyscanner);
                   ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
                 }
   \'            {
-                 yy_push_state (SQUOTE, yyscanner);
+                  yy_push_state (SQUOTE, yyscanner);
                   ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
                 }
   \$            {
                   yy_push_state (VAR, yyscanner);
                   ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
-               }
-  {CHAR}        { PUSH (yytext[0]); }
-  .|\n          {
-                  /* This cannot happen.  */
-                 grub_script_yyerror (yyextra, "internal error: unexpected characters in a word");
-                  return GRUB_PARSER_TOKEN_BAD;
-               }
-
+                }
+  \\            |
+  [^\"\'$\\]+   { COPY (yytext, yyleng); }
   <<EOF>>       {
-                 yy_pop_state (yyscanner);
-                 yypop_buffer_state (yyscanner);
-                 yyextra->lexerstate->merge_end = 1;
+                  yy_pop_state (yyscanner);
+                  yypop_buffer_state (yyscanner);
+                  yyextra->lexerstate->merge_end = 1;
                   ARG (GRUB_SCRIPT_ARG_TYPE_TEXT);
                 }
 }
@@ -255,23 +240,23 @@ WORD            ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+
   \?            |
   {DIGITS}      |
   {NAME}        {
-                  COPY (yytext);
-                 yy_pop_state (yyscanner);
-                 if (YY_START == SPLIT)
-                   ARG (GRUB_SCRIPT_ARG_TYPE_VAR);
-                 else
-                   ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR);
-               }
+                  COPY (yytext, yyleng);
+                  yy_pop_state (yyscanner);
+                  if (YY_START == SPLIT)
+                    ARG (GRUB_SCRIPT_ARG_TYPE_VAR);
+                  else
+                    ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR);
+                }
   \{\?\}        |
   \{{DIGITS}\}  |
   \{{NAME}\}    {
                   yytext[yyleng - 1] = '\0';
-                 COPY (yytext + 1);
+                  COPY (yytext + 1, yyleng - 2);
                   yy_pop_state (yyscanner);
-                 if (YY_START == SPLIT)
-                   ARG (GRUB_SCRIPT_ARG_TYPE_VAR);
-                 else
-                   ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR);
+                  if (YY_START == SPLIT)
+                    ARG (GRUB_SCRIPT_ARG_TYPE_VAR);
+                  else
+                    ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR);
                 }
   .|\n          { return GRUB_PARSER_TOKEN_BAD; }
 }
@@ -279,33 +264,34 @@ WORD            ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+
 <SQUOTE>{
   \'            {
                   yy_pop_state (yyscanner);
-                 ARG (GRUB_SCRIPT_ARG_TYPE_SQSTR);
+                  ARG (GRUB_SCRIPT_ARG_TYPE_SQSTR);
                 }
-  (.|\n)        { PUSH (yytext[0]); }
+  [^\']+        { COPY (yytext, yyleng); }
 }
 
 <DQUOTE>{
   \"            {
                   yy_pop_state (yyscanner);
-                 ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR);
+                  ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR);
                 }
   \$            {
                   yy_push_state (VAR, yyscanner);
-                 ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR);
-               }
-  \\\\          { PUSH ('\\'); }
-  \\\"          { PUSH ('\"'); }
+                  ARG (GRUB_SCRIPT_ARG_TYPE_DQSTR);
+                }
+  \\\\          { COPY ("\\", 1); }
+  \\\"          { COPY ("\"", 1); }
   \\\n          { /* ignore */ }
-  (.|\n)        { PUSH (yytext[0]); }
+  [^\"$\\\n]+   { COPY (yytext, yyleng); }
+  (.|\n)        { COPY (yytext, yyleng); }
 }
 
 <<EOF>>         {
-                 yypop_buffer_state (yyscanner);
-                 if (! grub_script_lexer_yywrap (yyextra))
-                   {
-                     yyextra->lexerstate->eof = 1;
-                     return GRUB_PARSER_TOKEN_EOF;
-                   }
+                  yypop_buffer_state (yyscanner);
+                  if (! grub_script_lexer_yywrap (yyextra))
+                    {
+                      yyextra->lexerstate->eof = 1;
+                      return GRUB_PARSER_TOKEN_EOF;
+                    }
                 }
 
 %%
@@ -329,3 +315,26 @@ grub_lexer_yyrealloc (void *ptr, yy_size_t size,
   return grub_realloc (ptr, size);
 }
 
+static void copy_string (struct grub_parser_param *parser, const char *str, unsigned hint)
+{
+  int len;
+  int size;
+  char *ptr;
+
+  len = hint ? hint : grub_strlen (str);
+  if (parser->lexerstate->used + len >= parser->lexerstate->size)
+    {
+      size = parser->lexerstate->size * 2;
+      ptr = grub_realloc (parser->lexerstate->text, size);
+      if (!ptr)
+        {
+          grub_script_yyerror (parser, 0);
+          return;
+        }
+
+      parser->lexerstate->text = ptr;
+      parser->lexerstate->size = size;
+    }
+  grub_strcpy (parser->lexerstate->text + parser->lexerstate->used - 1, str);
+  parser->lexerstate->used += len;
+}