From 848f95261707e085fa88a8226b00cc0eb372362e Mon Sep 17 00:00:00 2001 From: Shabinder Singh Date: Sat, 10 Aug 2024 17:34:01 +0530 Subject: [PATCH 1/3] Patch for StackOverflow on Recursive Class Definitions. --- .../internal/bridge/ZiplineServiceAdapter.kt | 12 ++++++++-- .../zipline/internal/bridge/SerialNameTest.kt | 23 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/ZiplineServiceAdapter.kt b/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/ZiplineServiceAdapter.kt index 611129cee9..8cb630cf14 100644 --- a/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/ZiplineServiceAdapter.kt +++ b/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/ZiplineServiceAdapter.kt @@ -93,7 +93,15 @@ internal fun serialName(typeName: String, serializers: List>): St } } -private fun descriptorName(typeName: SerialDescriptor): String { +private fun descriptorName(typeName: SerialDescriptor, visited: MutableSet = mutableSetOf()): String { + // Check if we've already visited this descriptor to avoid infinite recursion + if (visited.contains(typeName)) { + return typeName.serialName + } + + // Mark this descriptor as visited + visited.add(typeName) + return buildString { append(typeName.serialName) @@ -102,7 +110,7 @@ private fun descriptorName(typeName: SerialDescriptor): String { val elementIndices = 0 until typeName.elementsCount for (i in elementIndices) { - append(descriptorName(typeName.getElementDescriptor(i))) + append(descriptorName(typeName.getElementDescriptor(i), visited)) if (i < elementIndices.last) { append(',') } diff --git a/zipline/src/hostTest/kotlin/app/cash/zipline/internal/bridge/SerialNameTest.kt b/zipline/src/hostTest/kotlin/app/cash/zipline/internal/bridge/SerialNameTest.kt index 09ca77c9cc..360d322efb 100644 --- a/zipline/src/hostTest/kotlin/app/cash/zipline/internal/bridge/SerialNameTest.kt +++ b/zipline/src/hostTest/kotlin/app/cash/zipline/internal/bridge/SerialNameTest.kt @@ -17,6 +17,7 @@ package app.cash.zipline.internal.bridge import kotlin.test.Test import kotlin.test.assertEquals +import kotlinx.serialization.Serializable import kotlinx.serialization.serializer class SerialNameTest { @@ -79,4 +80,26 @@ class SerialNameTest { serialName, ) } + + @Test + fun recursiveSerializer() { + val serialName = serialName( + "SomeType", + serializers = listOf( + serializer(), + ), + ) + assertEquals( + expected = "SomeType<" + + "app.cash.zipline.internal.bridge.SomeRecursiveType<" + + "app.cash.zipline.internal.bridge.SomeRecursiveType?" + + ">>", + actual = serialName + ) + } } + +@Serializable +private data class SomeRecursiveType( + val someData: SomeRecursiveType? +) From 80e3248f0dad4e9e8e7a12fb85c38d36b8b03703 Mon Sep 17 00:00:00 2001 From: Shabinder Singh Date: Sat, 10 Aug 2024 18:19:57 +0530 Subject: [PATCH 2/3] Spotless Applied --- .../kotlin/app/cash/zipline/internal/bridge/SerialNameTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zipline/src/hostTest/kotlin/app/cash/zipline/internal/bridge/SerialNameTest.kt b/zipline/src/hostTest/kotlin/app/cash/zipline/internal/bridge/SerialNameTest.kt index 360d322efb..cc3a327ea5 100644 --- a/zipline/src/hostTest/kotlin/app/cash/zipline/internal/bridge/SerialNameTest.kt +++ b/zipline/src/hostTest/kotlin/app/cash/zipline/internal/bridge/SerialNameTest.kt @@ -94,12 +94,12 @@ class SerialNameTest { "app.cash.zipline.internal.bridge.SomeRecursiveType<" + "app.cash.zipline.internal.bridge.SomeRecursiveType?" + ">>", - actual = serialName + actual = serialName, ) } } @Serializable private data class SomeRecursiveType( - val someData: SomeRecursiveType? + val someData: SomeRecursiveType?, ) From cee1378ae9e3a57b3fcce5142dcb125415aef067 Mon Sep 17 00:00:00 2001 From: Shabinder Singh Date: Tue, 13 Aug 2024 10:01:51 +0530 Subject: [PATCH 3/3] concise check over descriptor recursion. Co-authored-by: Jake Wharton --- .../cash/zipline/internal/bridge/ZiplineServiceAdapter.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/ZiplineServiceAdapter.kt b/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/ZiplineServiceAdapter.kt index 8cb630cf14..e14cb2df63 100644 --- a/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/ZiplineServiceAdapter.kt +++ b/zipline/src/commonMain/kotlin/app/cash/zipline/internal/bridge/ZiplineServiceAdapter.kt @@ -95,13 +95,10 @@ internal fun serialName(typeName: String, serializers: List>): St private fun descriptorName(typeName: SerialDescriptor, visited: MutableSet = mutableSetOf()): String { // Check if we've already visited this descriptor to avoid infinite recursion - if (visited.contains(typeName)) { + if (!visited.add(typeName)) { return typeName.serialName } - // Mark this descriptor as visited - visited.add(typeName) - return buildString { append(typeName.serialName)