Skip to content

Commit

Permalink
Fix read of number followed by EOF can break subsequent read from see…
Browse files Browse the repository at this point in the history
…ing EOF
  • Loading branch information
puredanger committed Nov 26, 2024
1 parent dbff2f7 commit 45798a2
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ Change Log
----------------------------------------

* next
* In `read`, update docstring to specify minimum buffer size if PushbackReader supplied
* Fix: `read` of number followed by EOF can break subsequent read from seeing EOF
* In `read`, update docstring to specify minimum buffer size when PushbackReader supplied
* Release [2.5.0] on 2023-Dec-21
* Fix [DJSON-50]: `read` can take a PushbackReader for repeated read use case
* Fix `write` docstring to add `:indent` option added in [DJSON-18]
Expand Down
18 changes: 14 additions & 4 deletions src/main/clojure/clojure/data/json.clj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
(readChars [_ buffer start bufflen]
(.read rdr ^chars buffer start bufflen))
(unreadChar [_ c]
;; ASSERT: c should never be -1 (EOF)
(.unread rdr c))
(unreadChars [_ buffer start bufflen]
(.unread rdr buffer start bufflen))
Expand Down Expand Up @@ -63,6 +64,7 @@
(.getChars ^String s p end ^chars buffer start)))
(if (pos? n) n -1)))
(unreadChar [_ _c]
;; ASSERT: c should never be -1 (EOF)
(set! pos (unchecked-dec pos))
nil)
(unreadChars [_ _buffer _start bufflen]
Expand Down Expand Up @@ -234,9 +236,11 @@
:whitespace
(do (.unreadChar stream c)
false)
(\, \] \} -1)
(\, \] \})
(do (.unreadChar stream c)
false)
-1
false
(throw (Exception. "JSON error (invalid number literal)")))
;; previous character is a "0"
:frac-point
Expand All @@ -251,9 +255,11 @@
:whitespace
(do (.unreadChar stream c)
false)
(\, \] \} -1)
(\, \] \})
(do (.unreadChar stream c)
false)
-1
false
;; Disallow zero-padded numbers or invalid characters
(throw (Exception. "JSON error (invalid number literal)")))
;; previous character is a "."
Expand All @@ -276,9 +282,11 @@
:whitespace
(do (.unreadChar stream c)
true)
(\, \] \} -1)
(\, \] \})
(do (.unreadChar stream c)
true)
-1
true
(throw (Exception. "JSON error (invalid number literal)")))
;; previous character is a "e" or "E"
:exp-symbol
Expand Down Expand Up @@ -306,9 +314,11 @@
:whitespace
(do (.unreadChar stream c)
true)
(\, \] \} -1)
(\, \] \})
(do (.unreadChar stream c)
true)
-1
true
(throw (Exception. "JSON error (invalid number literal)"))))))]
(if decimal?
(read-decimal (str buffer) bigdec?)
Expand Down
18 changes: 18 additions & 0 deletions src/test/clojure/clojure/data/json_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,24 @@
(is (= {"foo" "some string"} (json/read pbr)))
(is (= {"foo" "another long ......................................................... string"} (json/read pbr)))))

(defn read-then-eof [s]
(let [r (pbr s)
val (json/read r :eof-error? false :eof-value :EOF)]
(is (= :EOF (json/read r :eof-error? false :eof-value :EOF)))
val))

(deftest read-multiple-eof
(are [expected s] (= expected (read-then-eof s))
1.2 "1.2"
0 "0"
1 "1"
1.0 "1.0"
"abc" "\"abc\""
"\u2202" "\"\u2202\""
[] "[]"
[1 2] "[1, 2]")
)

(deftest read-from-reader
(let [s (java.io.StringReader. "42")]
(is (= 42 (json/read s)))))
Expand Down

0 comments on commit 45798a2

Please sign in to comment.