From ed23c8568e10d15196bb4ff2b79fc14191d28109 Mon Sep 17 00:00:00 2001 From: Fabian Schmitthenner Date: Tue, 19 Jan 2016 20:07:53 +0000 Subject: [PATCH] next try for "don't abort when given unmatched '}' with 'start-condition stack underflow'. This fixes #751" This reverts commit 8120b6fb8a4924f8ae717bba9bbda4a2f89e2141 and fixes the regression introduced in 8d22b26448a091c76ab972c0b0603daac5e255e4. --- src/libexpr/lexer.l | 24 +++++++++++++++++------- tests/lexer.nix | 2 ++ tests/lexer.sh | 3 +++ tests/local.mk | 2 +- 4 files changed, 23 insertions(+), 8 deletions(-) create mode 100644 tests/lexer.nix create mode 100644 tests/lexer.sh diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l index 1f2957ec7..478f41641 100644 --- a/src/libexpr/lexer.l +++ b/src/libexpr/lexer.l @@ -8,6 +8,7 @@ %x STRING %x IND_STRING +%x INSIDE_DOLLAR_CURLY %{ @@ -93,6 +94,8 @@ URI [a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9\%\/\?\:\@\&\=\+\$\,\-\_\.\!\~ %% +{ + if { return IF; } then { return THEN; } @@ -124,11 +127,15 @@ or { return OR_KW; } return INT; } -\$\{ { PUSH_STATE(INITIAL); return DOLLAR_CURLY; } -\{ { PUSH_STATE(INITIAL); return '{'; } -\} { POP_STATE(); return '}'; } +\$\{ { PUSH_STATE(INSIDE_DOLLAR_CURLY); return DOLLAR_CURLY; } +} -\" { PUSH_STATE(STRING); return '"'; } +\} { return '}'; } +\} { POP_STATE(); return '}'; } +\{ { return '{'; } +\{ { PUSH_STATE(INSIDE_DOLLAR_CURLY); return '{'; } + +\" { PUSH_STATE(STRING); return '"'; } ([^\$\"\\]|\$[^\{\"\\]|\\.|\$\\.)*\$/\" | ([^\$\"\\]|\$[^\{\"\\]|\\.|\$\\.)+ { /* It is impossible to match strings ending with '$' with one @@ -137,11 +144,11 @@ or { return OR_KW; } yylval->e = unescapeStr(data->symbols, yytext); return STR; } -\$\{ { PUSH_STATE(INITIAL); return DOLLAR_CURLY; } +\$\{ { PUSH_STATE(INSIDE_DOLLAR_CURLY); return DOLLAR_CURLY; } \" { POP_STATE(); return '"'; } . return yytext[0]; /* just in case: shouldn't be reached */ -\'\'(\ *\n)? { PUSH_STATE(IND_STRING); return IND_STRING_OPEN; } +\'\'(\ *\n)? { PUSH_STATE(IND_STRING); return IND_STRING_OPEN; } ([^\$\']|\$[^\{\']|\'[^\'\$])+ { yylval->e = new ExprIndStr(yytext); return IND_STR; @@ -158,7 +165,7 @@ or { return OR_KW; } yylval->e = unescapeStr(data->symbols, yytext + 2); return IND_STR; } -\$\{ { PUSH_STATE(INITIAL); return DOLLAR_CURLY; } +\$\{ { PUSH_STATE(INSIDE_DOLLAR_CURLY); return DOLLAR_CURLY; } \'\' { POP_STATE(); return IND_STRING_CLOSE; } \' { yylval->e = new ExprIndStr("'"); @@ -166,6 +173,8 @@ or { return OR_KW; } } . return yytext[0]; /* just in case: shouldn't be reached */ +{ + {PATH} { yylval->path = strdup(yytext); return PATH; } {HPATH} { yylval->path = strdup(yytext); return HPATH; } {SPATH} { yylval->path = strdup(yytext); return SPATH; } @@ -177,6 +186,7 @@ or { return OR_KW; } . return yytext[0]; +} %% diff --git a/tests/lexer.nix b/tests/lexer.nix new file mode 100644 index 000000000..05c78b301 --- /dev/null +++ b/tests/lexer.nix @@ -0,0 +1,2 @@ +let const = a: "const"; in +''${ const { x = "q"; }}'' diff --git a/tests/lexer.sh b/tests/lexer.sh new file mode 100644 index 000000000..e45a6b00a --- /dev/null +++ b/tests/lexer.sh @@ -0,0 +1,3 @@ +source common.sh + +nix-instantiate --eval ./lexer.nix diff --git a/tests/local.mk b/tests/local.mk index 03f53b44c..05c6e04ee 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -11,7 +11,7 @@ nix_tests = \ binary-patching.sh timeout.sh secure-drv-outputs.sh nix-channel.sh \ multiple-outputs.sh import-derivation.sh fetchurl.sh optimise-store.sh \ binary-cache.sh nix-profile.sh repair.sh dump-db.sh case-hack.sh \ - check-reqs.sh pass-as-file.sh tarball.sh + check-reqs.sh pass-as-file.sh tarball.sh lexer.sh # parallel.sh install-tests += $(foreach x, $(nix_tests), tests/$(x))