Treat control characters in JSON strings as invalid
* lisp/json.el (json-peek): Reduce to following-char. (json-pop, json-read): Zero (null char) means end of file. (json-read-escaped-char): Delimit URL properly. (json-read-string): Signal error for ASCII control characters. * test/lisp/json-tests.el (test-json-peek): Check for zero instead of :json-eof symbol. (test-json-read-string): New test for control characters in JSON strings.
This commit is contained in:
parent
61631476d7
commit
87645443b5
2 changed files with 14 additions and 10 deletions
20
lisp/json.el
20
lisp/json.el
|
@ -193,12 +193,12 @@ Unlike `reverse', this keeps the property-value pairs intact."
|
|||
|
||||
(defsubst json-peek ()
|
||||
"Return the character at point."
|
||||
(or (char-after (point)) :json-eof))
|
||||
(following-char))
|
||||
|
||||
(defsubst json-pop ()
|
||||
"Advance past the character at point, returning it."
|
||||
(let ((char (json-peek)))
|
||||
(if (eq char :json-eof)
|
||||
(if (zerop char)
|
||||
(signal 'json-end-of-file nil)
|
||||
(json-advance)
|
||||
char)))
|
||||
|
@ -380,7 +380,7 @@ representation will be parsed correctly."
|
|||
(special (cdr special))
|
||||
((not (eq char ?u)) char)
|
||||
;; Special-case UTF-16 surrogate pairs,
|
||||
;; cf. https://tools.ietf.org/html/rfc7159#section-7. Note that
|
||||
;; cf. <https://tools.ietf.org/html/rfc7159#section-7>. Note that
|
||||
;; this clause overlaps with the next one and therefore has to
|
||||
;; come first.
|
||||
((looking-at
|
||||
|
@ -406,6 +406,8 @@ representation will be parsed correctly."
|
|||
(let ((characters '())
|
||||
(char (json-peek)))
|
||||
(while (not (= char ?\"))
|
||||
(when (< char 32)
|
||||
(signal 'json-string-format (list (prin1-char char))))
|
||||
(push (if (= char ?\\)
|
||||
(json-read-escaped-char)
|
||||
(json-pop))
|
||||
|
@ -686,12 +688,12 @@ become JSON objects."
|
|||
Advances point just past JSON object."
|
||||
(json-skip-whitespace)
|
||||
(let ((char (json-peek)))
|
||||
(if (not (eq char :json-eof))
|
||||
(let ((record (cdr (assq char json-readtable))))
|
||||
(if (functionp (car record))
|
||||
(apply (car record) (cdr record))
|
||||
(signal 'json-readtable-error record)))
|
||||
(signal 'json-end-of-file nil))))
|
||||
(if (zerop char)
|
||||
(signal 'json-end-of-file nil)
|
||||
(let ((record (cdr (assq char json-readtable))))
|
||||
(if (functionp (car record))
|
||||
(apply (car record) (cdr record))
|
||||
(signal 'json-readtable-error record))))))
|
||||
|
||||
;; Syntactic sugar for the reader
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ Point is moved to beginning of the buffer."
|
|||
|
||||
(ert-deftest test-json-peek ()
|
||||
(json-tests--with-temp-buffer ""
|
||||
(should (eq (json-peek) :json-eof)))
|
||||
(should (zerop (json-peek))))
|
||||
(json-tests--with-temp-buffer "{ \"a\": 1 }"
|
||||
(should (equal (json-peek) ?{))))
|
||||
|
||||
|
@ -164,6 +164,8 @@ Point is moved to beginning of the buffer."
|
|||
(should (equal (json-read-escaped-char) ?\"))))
|
||||
|
||||
(ert-deftest test-json-read-string ()
|
||||
(json-tests--with-temp-buffer "\"formfeed\f\""
|
||||
(should-error (json-read-string) :type 'json-string-format))
|
||||
(json-tests--with-temp-buffer "\"foo \\\"bar\\\"\""
|
||||
(should (equal (json-read-string) "foo \"bar\"")))
|
||||
(json-tests--with-temp-buffer "\"abcαβγ\""
|
||||
|
|
Loading…
Add table
Reference in a new issue