Skip to content

Commit 8661733

Browse files
committed
DJSON-57 Throw better exception on EOF in object or array reading
1 parent d694575 commit 8661733

3 files changed

Lines changed: 37 additions & 2 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ Change Log
153153
* Next
154154
* Fix [DJSON-50]: `read` can take a PushbackReader for repeated read use case
155155
* Fix `write` docstring to add `:indent` option added in [DJSON-18]
156+
* Fix [DJSON-57]: Throw better exception when EOF encountered while reading array or object
156157
* Add [DJSON-46]: In `read`, add `:extra-data-fn` that can be provided to cause an eof check after value is read
157158
* Add [DJSON-54]: In `write`, add custom fallback fn for writing unknown types
158159
* Perf [DJSON-61]: Faster string writing when string is "simple"
@@ -246,6 +247,7 @@ Change Log
246247
* Source-compatible with clojure.contrib.json, except for the name change.
247248

248249
[DJSON-61]: https://clojure.atlassian.net/browse/DJSON-61
250+
[DJSON-57]: https://clojure.atlassian.net/browse/DJSON-57
249251
[DJSON-54]: https://clojure.atlassian.net/browse/DJSON-54
250252
[DJSON-53]: https://clojure.atlassian.net/browse/DJSON-53
251253
[DJSON-52]: https://clojure.atlassian.net/browse/DJSON-52

src/main/clojure/clojure/data/json.clj

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,13 +325,17 @@
325325
(defn invalid-array-exception []
326326
(Exception. "JSON error (invalid array)"))
327327

328+
(defn- eof-array-exception []
329+
(EOFException. "JSON error (EOF in array)"))
330+
328331
(defn- read-array* [^InternalPBR stream options]
329332
;; Handles all array values after the first.
330333
(loop [result (transient [])]
331334
(let [r (conj! result (-read stream true nil options))]
332335
(codepoint-case (int (next-token stream))
333336
\] (persistent! r)
334337
\, (recur r)
338+
-1 (throw (eof-array-exception))
335339
(throw (invalid-array-exception))))))
336340

337341
(defn- read-array [^InternalPBR stream options]
@@ -342,19 +346,35 @@
342346
(codepoint-case c
343347
\] []
344348
\, (throw (invalid-array-exception))
349+
-1 (throw (eof-array-exception))
345350
(do (.unreadChar stream c)
346351
(read-array* stream options)))))
347352

353+
(defn- object-colon-exception []
354+
(Exception. "JSON error (missing `:` in object)"))
355+
356+
(defn- eof-object-exception []
357+
(EOFException. "JSON error (EOF in object)"))
358+
359+
(defn- invalid-key-exception [c]
360+
(if (= c -1)
361+
(throw (eof-object-exception))
362+
(throw (Exception. (str "JSON error (non-string key in object), found `" (char c) "`, expected `\"`")))))
363+
364+
(comment
365+
(compile 'clojure.data.json)
366+
)
367+
348368
(defn- read-key [^InternalPBR stream]
349369
(let [c (int (next-token stream))]
350370
(if (= c (codepoint \"))
351371
(let [key (read-quoted-string stream)]
352372
(if (= (codepoint \:) (int (next-token stream)))
353373
key
354-
(throw (Exception. "JSON error (missing `:` in object)"))))
374+
(throw (object-colon-exception))))
355375
(if (= c (codepoint \}))
356376
nil
357-
(throw (Exception. (str "JSON error (non-string key in object), found `" (char c) "`, expected `\"`")))))))
377+
(invalid-key-exception c)))))
358378

359379
(defn- read-object [^InternalPBR stream options]
360380
;; Expects to be called with the head of the stream AFTER the
@@ -374,6 +394,7 @@
374394
(codepoint-case (int (next-token stream))
375395
\, (recur r)
376396
\} (persistent! r)
397+
-1 (throw (eof-object-exception))
377398
(throw (Exception. "JSON error (missing entry in object)"))))
378399
(let [r (persistent! result)]
379400
(if (empty? r)

src/test/clojure/clojure/data/json_test.clj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,18 @@
407407
(is (thrown? java.io.EOFException
408408
(json/read-str "\"\\"))))
409409

410+
(deftest throws-eof-in-arrays
411+
(is (thrown? java.io.EOFException
412+
(json/read-str "[1,")))
413+
(is (thrown? java.io.EOFException
414+
(json/read-str "[1,2,"))))
415+
416+
(deftest throws-eof-in-objects
417+
(is (thrown? java.io.EOFException
418+
(json/read-str "{")))
419+
(is (thrown? java.io.EOFException
420+
(json/read-str "{\"\":1,"))))
421+
410422
(deftest accept-eof
411423
(is (= ::eof (json/read-str "" :eof-error? false :eof-value ::eof))))
412424

0 commit comments

Comments
 (0)