Skip to content

Commit

Permalink
Fixed decoding of huge JSON data for okio streams
Browse files Browse the repository at this point in the history
Fixes #2006
  • Loading branch information
shanshin committed Aug 8, 2022
1 parent 83b6e33 commit 025d288
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 3 deletions.
Expand Up @@ -50,7 +50,7 @@ internal class OkioSerialReader(private val source: BufferedSource): SerialReade
override fun read(buffer: CharArray, bufferOffset: Int, count: Int): Int {
var i = 0
while (i < count && !source.exhausted()) {
buffer[i] = source.readUtf8CodePoint().toChar()
buffer[bufferOffset + i] = source.readUtf8CodePoint().toChar()
i++
}
return if (i > 0) i else -1
Expand Down
@@ -0,0 +1,38 @@
/*
* Copyright 2017-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package kotlinx.serialization.json

import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlin.test.Test


class JsonHugeDataSerializationTest : JsonTestBase() {

@Serializable
private data class Node(
val children: List<Node>?
)

private fun createNodes(count: Int, depth: Int): List<Node> {
val ret = mutableListOf<Node>()
if (depth == 0) return ret
for (i in 0 until count) {
ret.add(Node(createNodes(1, depth - 1)))
}
return ret
}

@Test
fun test() {
// create some huge instance
val rootNode = Node(createNodes(1000, 10))

// Encoding will always be true for a standard `encodeToString` - we leave this assumption so as not to insert a huge string into the sources
val expectedJson = Json.encodeToString(rootNode)

assertJsonFormAndRestored(Node.serializer(), rootNode, expectedJson)
}
}
Expand Up @@ -184,7 +184,6 @@ internal abstract class AbstractJsonLexer {

open fun consumeNextToken(expected: Char) {
ensureHaveChars()
val source = source
var cpos = currentPosition
while (true) {
cpos = prefetchOrEof(cpos)
Expand Down
Expand Up @@ -67,7 +67,9 @@ internal class ReaderJsonLexer(

private fun preload(spaceLeft: Int) {
val buffer = _source
buffer.copyInto(buffer, 0, currentPosition, currentPosition + spaceLeft)
if (spaceLeft != 0) {
buffer.copyInto(buffer, 0, currentPosition, currentPosition + spaceLeft)
}
var read = spaceLeft
val sizeTotal = _source.size
while (read != sizeTotal) {
Expand Down

0 comments on commit 025d288

Please sign in to comment.