Fix handling of escape sequences in JsonObjectParser #21961 (#21962)

* Fix handling of escape sequences in JsonObjectParser #21961

* Add test coverage to verify issue #21961
This commit is contained in:
Andrew Rapp 2016-12-08 06:35:53 -07:00 committed by Konrad `ktoso` Malawski
parent 76017adc30
commit 591eafe04c
2 changed files with 37 additions and 2 deletions

View file

@ -267,6 +267,36 @@ class JsonFramingSpec extends AkkaSpec {
| }
|}""".stripMargin
}
"successfully parse an escaped backslash followed by a double quote" in {
val buffer = new JsonObjectParser()
buffer.offer(ByteString(
"""
|{
| "key": "\\"
| }
| """.stripMargin
))
buffer.poll().get.utf8String shouldBe """{
| "key": "\\"
| }""".stripMargin
}
"successfully parse a string that contains an escaped quote" in {
val buffer = new JsonObjectParser()
buffer.offer(ByteString(
"""
|{
| "key": "\""
| }
| """.stripMargin
))
buffer.poll().get.utf8String shouldBe """{
| "key": "\""
| }""".stripMargin
}
}
"has nested array" should {

View file

@ -55,6 +55,7 @@ private[akka] class JsonObjectParser(maximumObjectLength: Int = Int.MaxValue) {
private var completedObject = false
private var inStringExpression = false
private var isStartOfEscapeSequence = false
private var lastInput = 0.toByte
/**
* Appends input ByteString to internal byte string buffer.
@ -105,7 +106,7 @@ private[akka] class JsonObjectParser(maximumObjectLength: Int = Int.MaxValue) {
completedObject
}
private def proceed(input: Byte): Unit =
private def proceed(input: Byte): Unit = {
if (input == SquareBraceStart && outsideObject) {
// outer object is an array
pos += 1
@ -118,7 +119,8 @@ private[akka] class JsonObjectParser(maximumObjectLength: Int = Int.MaxValue) {
pos += 1
trimFront += 1
} else if (input == Backslash) {
isStartOfEscapeSequence = true
if (lastInput == Backslash) isStartOfEscapeSequence = false
else isStartOfEscapeSequence = true
pos += 1
} else if (input == DoubleQuote) {
if (!isStartOfEscapeSequence) inStringExpression = !inStringExpression
@ -146,6 +148,9 @@ private[akka] class JsonObjectParser(maximumObjectLength: Int = Int.MaxValue) {
throw new FramingException(s"Invalid JSON encountered at position [$pos] of [$buffer]")
}
lastInput = input
}
@inline private final def insideObject: Boolean =
!outsideObject