Fix output of keys.

They need to be encoded in the same way that strings are
encoded.  (Report and fixed by Phil Roberts.)

Also added a FIXME about leftover occurrences of \U in the output.

Closes PR 13966.
This commit is contained in:
Eli Barzilay 2013-08-14 16:27:50 -04:00
parent 431a520ed8
commit c069b8e51c
2 changed files with 15 additions and 2 deletions

View File

@ -72,7 +72,14 @@
(jsexpr->string "\37\40\177") => "\"\\u001f \\u007f\""
(jsexpr->string "λ∀𝄞") => "\"λ∀𝄞\""
(jsexpr->string "λ∀𝄞" #:encode 'all)
=> "\"\\u03bb\\u2200\\ud834\\udd1e\""))
=> "\"\\u03bb\\u2200\\ud834\\udd1e\""
;; and that the same holds for keys
(jsexpr->string (string->jsexpr "{\"\U0010FFFF\":\"\U0010FFFF\"}"))
=> "{\"\U0010FFFF\":\"\U0010FFFF\"}"
(jsexpr->string (string->jsexpr "{\"\U0010FFFF\":\"\U0010FFFF\"}")
#:encode 'all)
=> "{\"\\udbff\\udfff\":\"\\udbff\\udfff\"}"
))
(define (parse-tests)
(test (string->jsexpr @T{ 1 }) => 1

View File

@ -52,6 +52,10 @@
(u-esc (+ #xDC00 (bitwise-and n #x3FF)))))))))
(define rx-to-encode
(case enc
;; FIXME: This should also encode (always) anything that is represented
;; with a \U in Racket (since the json thing should be two \u sequences,
;; so there should never be a \U in the output of this function); but I
;; don't know if there's a known specification to what gets a \U
[(control) #rx"[\0-\37\\\"\177]"]
[(all) #rx"[\0-\37\\\"\177-\U10FFFF]"]
[else (raise-type-error who "encoding symbol" enc)]))
@ -78,7 +82,9 @@
(unless (symbol? k)
(raise-type-error who "legal JSON key value" k))
(if first? (set! first? #f) (write-bytes #"," o))
(write (symbol->string k) o) ; no `printf' => proper escapes
;; use a string encoding so we get the same deal with
;; `rx-to-encode'
(write-json-string (symbol->string k))
(write-bytes #":" o)
(loop v))
(write-bytes #"}" o)]