summaryrefslogtreecommitdiff
path: root/src/test/scala/spray/json/JsonParserSpec.scala
diff options
context:
space:
mode:
authorJohannes Rudolph <johannes.rudolph@gmail.com>2018-11-06 16:19:13 +0100
committerJohannes Rudolph <johannes.rudolph@gmail.com>2018-11-07 15:04:41 +0100
commita55875309b804f10c22dffb1a37358518d8ac48d (patch)
tree1e863a869986974b82b87a590df2ee30a21e2de8 /src/test/scala/spray/json/JsonParserSpec.scala
parent3ccb0768cb5ccb0c4b577742ee7f1ec7d3b9c83f (diff)
downloadspray-json-a55875309b804f10c22dffb1a37358518d8ac48d.tar.gz
spray-json-a55875309b804f10c22dffb1a37358518d8ac48d.tar.bz2
spray-json-a55875309b804f10c22dffb1a37358518d8ac48d.zip
CVE-2018-18855 Fix uncontrolled recursion in the JsonParser by imposing a configurable limit on the depth, fixes #286
Diffstat (limited to 'src/test/scala/spray/json/JsonParserSpec.scala')
-rw-r--r--src/test/scala/spray/json/JsonParserSpec.scala26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/test/scala/spray/json/JsonParserSpec.scala b/src/test/scala/spray/json/JsonParserSpec.scala
index e5645a4..4c64989 100644
--- a/src/test/scala/spray/json/JsonParserSpec.scala
+++ b/src/test/scala/spray/json/JsonParserSpec.scala
@@ -18,6 +18,8 @@ package spray.json
import org.specs2.mutable._
+import scala.util.control.NonFatal
+
class JsonParserSpec extends Specification {
"The JsonParser" should {
@@ -114,6 +116,30 @@ class JsonParserSpec extends Specification {
|""".stripMargin
}
+ "fail gracefully for deeply nested structures" in {
+ val queue = new java.util.ArrayDeque[String]()
+
+ // testing revealed that each recursion will need approx. 280 bytes of stack space
+ val depth = 1500
+ val runnable = new Runnable {
+ override def run(): Unit =
+ try {
+ val nested = "[{\"key\":" * (depth / 2)
+ JsonParser(nested)
+ queue.push("didn't fail")
+ } catch {
+ case s: StackOverflowError => queue.push("stackoverflow")
+ case NonFatal(e) =>
+ queue.push(s"nonfatal: ${e.getMessage}")
+ }
+ }
+
+ val thread = new Thread(null, runnable, "parser-test", 655360)
+ thread.start()
+ thread.join()
+ queue.peek() === "nonfatal: JSON input nested too deeply:JSON input was nested more deeply than the configured limit of maxNesting = 1000"
+ }
+
"parse multiple values when allowTrailingInput" in {
val parser = new JsonParser("""{"key":1}{"key":2}""")
parser.parseJsValue(true) === JsObject("key" -> JsNumber(1))