Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed decoding of huge JSON data for okio streams #2007

Merged
merged 7 commits into from Aug 15, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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,39 @@
/*
* 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 kotlinx.serialization.test.noLegacyJs
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() = noLegacyJs {
shanshin marked this conversation as resolved.
Show resolved Hide resolved
// 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
shanshin marked this conversation as resolved.
Show resolved Hide resolved
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
sandwwraith marked this conversation as resolved.
Show resolved Hide resolved
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