about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Maudoux <layus.on@gmail.com>2015-07-02T21·53+0200
committerGuillaume Maudoux <layus.on@gmail.com>2015-07-03T12·09+0200
commit467977f20326f704b259157652ee9b7ba2efaa78 (patch)
tree2aef3ca8cad3613e09a71cd3811164ffcab46ecf
parent65e4dcd69bb618ef2bf07ec128b207df3d9e868a (diff)
Fix the parsing of "$"'s in strings.
-rw-r--r--src/libexpr/lexer.l11
-rw-r--r--tests/lang/eval-okay-string.exp2
-rw-r--r--tests/lang/eval-okay-string.nix2
3 files changed, 8 insertions, 7 deletions
diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l
index 7483e5cc4acb..1f2957ec71ad 100644
--- a/src/libexpr/lexer.l
+++ b/src/libexpr/lexer.l
@@ -129,12 +129,11 @@ or          { return OR_KW; }
 \}          { POP_STATE(); return '}'; }
 
 \"          { PUSH_STATE(STRING); return '"'; }
-<STRING>([^\$\"\\]|\$[^\{\"]|\\.)+ {
-              /* !!! Not quite right: we want a follow restriction on
-                 "$", it shouldn't be followed by a "{".  Right now
-                 "$\"" will be consumed as part of a string, rather
-                 than a "$" followed by the string terminator.
-                 Disallow "$\"" for now. */
+<STRING>([^\$\"\\]|\$[^\{\"\\]|\\.|\$\\.)*\$/\" |
+<STRING>([^\$\"\\]|\$[^\{\"\\]|\\.|\$\\.)+ {
+              /* It is impossible to match strings ending with '$' with one
+                 regex because trailing contexts are only valid at the end
+                 of a rule. (A sane but undocumented limitation.) */
               yylval->e = unescapeStr(data->symbols, yytext);
               return STR;
             }
diff --git a/tests/lang/eval-okay-string.exp b/tests/lang/eval-okay-string.exp
index 6079202470e3..63f650f73a3a 100644
--- a/tests/lang/eval-okay-string.exp
+++ b/tests/lang/eval-okay-string.exp
@@ -1 +1 @@
-"foobar/a/b/c/d/foo/xyzzy/foo.txt/../foo/x/yescape: \"quote\" \n \\end\nof\nlinefoobarblaatfoo$bar"
+"foobar/a/b/c/d/foo/xyzzy/foo.txt/../foo/x/yescape: \"quote\" \n \\end\nof\nlinefoobarblaatfoo$bar$\"$\"$"
diff --git a/tests/lang/eval-okay-string.nix b/tests/lang/eval-okay-string.nix
index 839539e6c171..47cc989ad46a 100644
--- a/tests/lang/eval-okay-string.nix
+++ b/tests/lang/eval-okay-string.nix
@@ -8,3 +8,5 @@ of
 line"
   + "foo${if true then "b${"a" + "r"}" else "xyzzy"}blaat"
   + "foo$bar"
+  + "$\"$\""
+  + "$"