Skip to content

Commit

Permalink
Fix incorrect handling of object end when JsonTreeReader (JsonElement…
Browse files Browse the repository at this point in the history
…) is used with decodeToSequence (#1782)

Fixes #1779
  • Loading branch information
sandwwraith committed Nov 30, 2021
1 parent 9755adc commit 1b2344f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
* Copyright 2017-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
* Copyright 2017-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package kotlinx.serialization.json.internal

import kotlinx.serialization.*
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.*

@OptIn(ExperimentalSerializationApi::class)
Expand Down Expand Up @@ -34,8 +34,10 @@ internal class JsonTreeReader(
result[key] = element
// Verify the next token
lastToken = lexer.consumeNextToken()
if (lastToken != TC_COMMA && lastToken != TC_END_OBJ) {
lexer.fail("Expected end of the object or comma")
when (lastToken) {
TC_COMMA -> Unit // no-op, can continue with `canConsumeValue` that verifies the token after comma
TC_END_OBJ -> break // `canConsumeValue` can return incorrect result, since it checks token _after_ TC_END_OBJ
else -> lexer.fail("Expected end of the object or comma")
}
}
// Check for the correct ending
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.features.sealed.SealedChild
import kotlinx.serialization.features.sealed.SealedParent
import kotlinx.serialization.json.*
import kotlinx.serialization.json.internal.JsonDecodingException
import kotlinx.serialization.test.assertFailsWithMessage
Expand Down Expand Up @@ -108,6 +110,32 @@ class JsonStreamFlowTest {
assertEquals(inputList, json.decodeToSequence(ins, StringData.serializer()).toList())
}

@Test
fun testJsonElement() {
val list = listOf<JsonElement>(
buildJsonObject { put("foo", "bar") },
buildJsonObject { put("foo", "baz") },
JsonPrimitive(10),
JsonPrimitive("abacaba"),
buildJsonObject { put("foo", "qux") }
)
val inputWs = """${list[0]} ${list[1]} ${list[2]} ${list[3]} ${list[4]}"""
val decodedWs = json.decodeToSequence<JsonElement>(inputWs.asInputStream()).toList()
assertEquals(list, decodedWs, "Failed whitespace-separated test")
val inputArray = """[${list[0]}, ${list[1]},${list[2]} , ${list[3]} ,${list[4]}]"""
val decodedArrayWrap = json.decodeToSequence<JsonElement>(inputArray.asInputStream()).toList()
assertEquals(list, decodedArrayWrap, "Failed array-wrapped test")
}


@Test
fun testSealedClasses() {
val input = """{"type":"first child","i":1,"j":10} {"type":"first child","i":1,"j":11}"""
val iter = json.iterateOverStream(input.asInputStream(), SealedParent.serializer())
iter.assertNext(SealedChild(10))
iter.assertNext(SealedChild(11))
}

@Test
fun testMalformedArray() {
val input1 = """[1, 2, 3"""
Expand Down

0 comments on commit 1b2344f

Please sign in to comment.