]> git.eshelyaron.com Git - emacs.git/commitdiff
Treat control characters in JSON strings as invalid
authorMark Oteiza <mvoteiza@udel.edu>
Fri, 18 Aug 2017 00:00:52 +0000 (20:00 -0400)
committerMark Oteiza <mvoteiza@udel.edu>
Fri, 18 Aug 2017 00:00:52 +0000 (20:00 -0400)
* 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.

lisp/json.el
test/lisp/json-tests.el

index 627e65efa45e67e9e1f2dcf64e4dc1bceb2f607a..64486258ccf58b4469f0928afd82fc69382dcbd3 100644 (file)
@@ -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
 
index c6bd295d667ecf1a65fcfcda55b036f8ac55c804..1d13ccf074f5abb3cd6c588c0c0c292182400fbc 100644 (file)
@@ -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αβγ\""