[PATCH] discover/grub: Fix handling of empty strings

Sam Mendoza-Jonas sam at mendozajonas.com
Tue Feb 9 13:15:47 AEDT 2016


If "" or '' are used in a statement to omit a word, we must still
return a TOKEN_WORD for an empty string.

In particular this fixes an issue where Petitboot would fail to parse
the grub.cfg included in the Debian 8.2 install image, which includes a
menuentry statement with an empty name.

Signed-off-by: Sam Mendoza-Jonas <sam at mendozajonas.com>
---
 discover/grub2/grub2-lexer.l               | 7 +++++++
 test/parser/test-grub2-menuentry-formats.c | 5 ++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/discover/grub2/grub2-lexer.l b/discover/grub2/grub2-lexer.l
index 52575e3..81dc5fe 100644
--- a/discover/grub2/grub2-lexer.l
+++ b/discover/grub2/grub2-lexer.l
@@ -23,6 +23,7 @@ void yyerror(struct grub2_parser *parser, const char *fmt, ...);
 
 WORD	[^{}|&$;<> \t\n'"#]+
 DELIM	[ \t]+
+BLANK	["]{2}|[']{2}
 VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
 
 %%
@@ -52,6 +53,12 @@ VARNAME ([[:alpha:]][_[:alnum:]]*|[0-9]|[\?@\*#])
 "until"      return TOKEN_UTIL;
 "while"      return TOKEN_WHILE;
 
+ /* ignore quoted empty strings */
+{BLANK} {
+		yylval->word = create_word_text(yyget_extra(yyscanner), "");
+		yyget_extra(yyscanner)->inter_word = true;
+		return TOKEN_WORD;
+	}
  /* anything that's not a metachar: return as a plain word */
 {WORD}	{
 		yylval->word = create_word_text(yyget_extra(yyscanner), yytext);
diff --git a/test/parser/test-grub2-menuentry-formats.c b/test/parser/test-grub2-menuentry-formats.c
index 132ce8d..3c6f4d7 100644
--- a/test/parser/test-grub2-menuentry-formats.c
+++ b/test/parser/test-grub2-menuentry-formats.c
@@ -20,6 +20,9 @@ menuentry "test.8" {
 menuentry "test.9" {
  linux /vmlinux
  }
+menuentry "" {
+ linux /vmlinux
+ }
 #endif
 
 void run_test(struct parser_test *test)
@@ -32,7 +35,7 @@ void run_test(struct parser_test *test)
 
 	test_run_parser(test, "grub2");
 
-	check_boot_option_count(test->ctx, 10);
+	check_boot_option_count(test->ctx, 11);
 	for (i = 0; i < 8; i++) {
 		opt = get_boot_option(test->ctx, i);
 		str[5] = i + '0';
-- 
2.7.1



More information about the Petitboot mailing list