in scripts/src/main/scala/com/gu/mediaservice/lib/JsonValueCodecJsValue.scala [17:72]
def decodeValue(in: JsonReader, default: JsValue): JsValue = {
val b = in.nextToken()
if (b == 'n') in.readNullOrError(default, "expected `null` value")
else if (b == '"') {
in.rollbackToken()
JsString(in.readString(null))
} else if (b == 'f' || b == 't') {
in.rollbackToken()
if (in.readBoolean()) JsTrue else JsFalse
} else if ((b >= '0' && b <= '9') || b == '-') {
in.rollbackToken()
val bigDecimal = in.readBigDecimal(null)
JsNumber(bigDecimal)
} else if (b == '[') {
val array: IndexedSeq[JsValue] =
if (in.isNextToken(']')) new Array[JsValue](0)
else {
in.rollbackToken()
var i = 0
var arr = new Array[JsValue](4)
do {
if (i == arr.length) arr = java.util.Arrays.copyOf(arr, i << 1)
arr(i) = decodeValue(in, default)
i += 1
} while (in.isNextToken(','))
if (in.isCurrentToken(']'))
if (i == arr.length) arr else java.util.Arrays.copyOf(arr, i)
else in.arrayEndOrCommaError()
}
JsArray(array)
} else if (b == '{') {
/*
* Because of DoS vulnerability in Scala 2.12 HashMap https://github.com/scala/bug/issues/11203
* we use a Java LinkedHashMap because it better handles hash code collisions for Comparable keys.
*/
val kvs =
if (in.isNextToken('}')) new java.util.LinkedHashMap[String, JsValue]()
else {
val underlying = new java.util.LinkedHashMap[String, JsValue]()
in.rollbackToken()
do {
underlying.put(in.readKeyAsString(), decodeValue(in, default))
} while (in.isNextToken(','))
if (!in.isCurrentToken('}'))
in.objectEndOrCommaError()
underlying
}
import scala.jdk.CollectionConverters._
JsObject(kvs.asScala)
} else {
in.decodeError("expected JSON value")
}
}