summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2025-09-01 17:05:23 +0200
committerSharlatan Hellseher <sharlatanus@gmail.com>2025-11-20 01:06:32 +0000
commitd111a6a60d3535933e4b6eba7007519b3e9d6835 (patch)
treed0b757e832007197bfc6eebf5814b133797cb07b
parent82918e4642c61170094720785950a23ecfe90e30 (diff)
guix: toml: Fix keys with embedded escape codes.
Quoted keys are treated by the specification like ordinary strings, so escape codes must be handled as well. * guix/build/toml.scm (eval-value): Move string escape handling… (eval-value): …here. (eval-toml-file): Un-escape quoted keys. * tests/toml.scm ("parse-toml: Quoted keys with escapes"): New testcase. Fixes: guix/guix#2414 Change-Id: I612e415cc93207bbdd18b6ec8279255fee16670a Signed-off-by: Sharlatan Hellseher <sharlatanus@gmail.com>
-rw-r--r--guix/build/toml.scm30
-rw-r--r--tests/toml.scm6
2 files changed, 24 insertions, 12 deletions
diff --git a/guix/build/toml.scm b/guix/build/toml.scm
index a9be0887e76..b43fe4bb8b0 100644
--- a/guix/build/toml.scm
+++ b/guix/build/toml.scm
@@ -361,6 +361,21 @@ the list KEY. For instance a KEY (a b) would retrieve alist[a][b]."
(string->number minute)) 60))
(#f #f)))))
+ (define (eval-string value)
+ "Turn a list of string tokens into an actual, flat string value by
+evaluating escape codes."
+ (apply string-append
+ (map (match-lambda
+ (('escaped "\"") "\"")
+ (('escaped "\\") "\\")
+ (('escaped "b") "\b")
+ (('escaped "t") "\t")
+ (('escaped "n") "\n")
+ (('escaped (? (lambda (x) (>= (string-length x) 4)) u))
+ (list->string (list (integer->char (string->number u 16)))))
+ ((? string? s) s))
+ (keyword-flatten '(escaped) value))))
+
(define (eval-value value)
"Evaluate right-hand-side of 'keyval token (i.e., a value)."
(match value
@@ -395,17 +410,7 @@ the list KEY. For instance a KEY (a b) would retrieve alist[a][b]."
(('local-time rest ...)
(eval-date rest))
(('string str ...)
- (apply string-append
- (map (match-lambda
- (('escaped "\"") "\"")
- (('escaped "\\") "\\")
- (('escaped "b") "\b")
- (('escaped "t") "\t")
- (('escaped "n") "\n")
- (('escaped (? (lambda (x) (>= (string-length x) 4)) u))
- (list->string (list (integer->char (string->number u 16)))))
- ((? string? s) s))
- (keyword-flatten '(escaped) str))))
+ (eval-string str))
('string "")
(('array tails ...)
(map eval-value (keyword-flatten '(boolean integer float string array
@@ -427,7 +432,8 @@ the list KEY. For instance a KEY (a b) would retrieve alist[a][b]."
(map
(match-lambda
(('simple-key 'quoted-key) "")
- (('simple-key ('quoted-key k)) k)
+ ;; Quoted keys are just ordinary strings and can contain escape codes.
+ (('simple-key ('quoted-key rest ...)) (eval-string rest))
(('simple-key (? string? k)) k)
(other (raise-exception `(invalid-simple-key ,other))))
(keyword-flatten '(simple-key) keys)))
diff --git a/tests/toml.scm b/tests/toml.scm
index 64bc667f0c9..955a9967b21 100644
--- a/tests/toml.scm
+++ b/tests/toml.scm
@@ -54,6 +54,12 @@ bare-key = \"value\"
'key2' = \"value\"
'quoted \"value\"' = \"value\""))
+(test-equal "parse-toml: Quoted keys with escapes"
+ '(("key \\ with \n escapes" . "value")
+ ("key" ("with \t escapes" ("and \n dots" . "value"))))
+ (parse-toml "\"key \\\\ with \\n escapes\" = \"value\"
+key.\"with \\t escapes\".\"and \\n dots\" = \"value\""))
+
(test-equal "parse-toml: No key"
#f
(parse-toml "= \"no key name\""))