stream: fix regression in JsonFraming (#44)

* stream: fix regression in JsonFraming

Was introduced in 6b30134c5c where
an invariant was changed what `pos` can be when the loop is run.

* fix when maximumObjectLength is near Int.MaxValue
This commit is contained in:
Johannes Rudolph 2023-05-29 17:27:37 +02:00 committed by GitHub
parent 0bb2e8668b
commit 6b90b20334
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 10 additions and 4 deletions

View file

@ -41,7 +41,7 @@ class JsonFramingSpec extends PekkoSpec {
|""".stripMargin // also should complete once notices end of array
val result =
Source.single(ByteString(input)).via(JsonFraming.objectScanner(Int.MaxValue)).runFold(Seq.empty[String]) {
Source.single(ByteString(input)).via(JsonFraming.objectScanner(64)).runFold(Seq.empty[String]) {
case (acc, entry) => acc ++ Seq(entry.utf8String)
}
// #using-json-framing
@ -494,6 +494,11 @@ class JsonFramingSpec extends PekkoSpec {
a[FramingException] shouldBe thrownBy { buffer.poll() }
}
}
"maximumObjectLength is near Int.MaxValue" in {
val buffer = new JsonObjectParser(Int.MaxValue - 1)
buffer.offer(ByteString(""" {}"""))
buffer.poll().get.utf8String shouldBe """{}"""
}
}
"fail on too large initial object" in {

View file

@ -117,21 +117,22 @@ import pekko.util.ByteString
val bufSize = buffer.length
skipToNextObject(bufSize)
val maxObjectLengthIndex = if (pos + maximumObjectLength < 0) Int.MaxValue else pos + maximumObjectLength
while (pos < bufSize && pos < maximumObjectLength && !completedObject) {
while (pos < bufSize && pos < maxObjectLengthIndex && !completedObject) {
val input = buffer(pos)
proceed(input)
pos += 1
}
if (pos >= maximumObjectLength)
if (pos >= maxObjectLengthIndex)
throw new FramingException(s"""JSON element exceeded maximumObjectLength ($maximumObjectLength bytes)!""")
completedObject
}
private def skipToNextObject(bufSize: Int): Unit =
while (pos != -1 && pos < bufSize && pos < maximumObjectLength && depth == 0) {
while (pos != -1 && pos < bufSize && depth == 0) {
val outer = outerChars(buffer(pos) & 0xFF)
start += outer & 1
depth = (outer & 2) >> 1