diff options
author | eater <hello@eaterofco.de> | 2023-10-20 17:50:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-20 17:50:34 +0200 |
commit | bfbe6a9127952473ef79a79e11ec754086cb0be3 (patch) | |
tree | 15575ca4406a76c54e5878acaa30f7523d25272f | |
parent | 7d4bb2a80b5ad7f053c8bd5596f7acb33e262114 (diff) | |
download | kotlinx.serialization-bfbe6a9127952473ef79a79e11ec754086cb0be3.tar.gz |
Cbor: check if inline value classes is marked as @ByteString (#2466)
Fixes #2187
4 files changed, 78 insertions, 1 deletions
diff --git a/formats/cbor/commonMain/src/kotlinx/serialization/cbor/internal/Encoding.kt b/formats/cbor/commonMain/src/kotlinx/serialization/cbor/internal/Encoding.kt index 0b7a0e0c..b77a18c5 100644 --- a/formats/cbor/commonMain/src/kotlinx/serialization/cbor/internal/Encoding.kt +++ b/formats/cbor/commonMain/src/kotlinx/serialization/cbor/internal/Encoding.kt @@ -70,6 +70,8 @@ internal open class CborWriter(private val cbor: Cbor, protected val encoder: Cb if (encodeByteArrayAsByteString && serializer.descriptor == ByteArraySerializer().descriptor) { encoder.encodeByteString(value as ByteArray) } else { + encodeByteArrayAsByteString = encodeByteArrayAsByteString || serializer.descriptor.isInlineByteString() + super.encodeSerializableValue(serializer, value) } } @@ -278,6 +280,7 @@ internal open class CborReader(private val cbor: Cbor, protected val decoder: Cb @Suppress("UNCHECKED_CAST") decoder.nextByteString() as T } else { + decodeByteArrayAsByteString = decodeByteArrayAsByteString || deserializer.descriptor.isInlineByteString() super.decodeSerializableValue(deserializer) } } @@ -636,6 +639,11 @@ private fun SerialDescriptor.isByteString(index: Int): Boolean { return getElementAnnotations(index).find { it is ByteString } != null } +private fun SerialDescriptor.isInlineByteString(): Boolean { + // inline item classes should only have 1 item + return isInline && isByteString(0) +} + private val normalizeBaseBits = SINGLE_PRECISION_NORMALIZE_BASE.toBits() diff --git a/formats/cbor/commonTest/src/kotlinx/serialization/cbor/CborReaderTest.kt b/formats/cbor/commonTest/src/kotlinx/serialization/cbor/CborReaderTest.kt index edbe5e62..f615d5ed 100644 --- a/formats/cbor/commonTest/src/kotlinx/serialization/cbor/CborReaderTest.kt +++ b/formats/cbor/commonTest/src/kotlinx/serialization/cbor/CborReaderTest.kt @@ -634,6 +634,34 @@ class CborReaderTest { } @Test + fun testReadValueClassWithByteString() { + assertContentEquals( + expected = byteArrayOf(0x11, 0x22, 0x33), + actual = Cbor.decodeFromHexString<ValueClassWithByteString>("43112233").x + ) + } + + @Test + fun testReadValueClassCustomByteString() { + assertEquals( + expected = ValueClassWithCustomByteString(CustomByteString(0x11, 0x22, 0x33)), + actual = Cbor.decodeFromHexString("43112233") + ) + } + + @Test + fun testReadValueClassWithUnlabeledByteString() { + assertContentEquals( + expected = byteArrayOf( + 0x11, + 0x22, + 0x33 + ), + actual = Cbor.decodeFromHexString<ValueClassWithUnlabeledByteString>("43112233").x.x + ) + } + + @Test fun testIgnoresTagsOnStrings() { /* * 84 # array(4) diff --git a/formats/cbor/commonTest/src/kotlinx/serialization/cbor/CborWriterTest.kt b/formats/cbor/commonTest/src/kotlinx/serialization/cbor/CborWriterTest.kt index c546bdf6..da7b1287 100644 --- a/formats/cbor/commonTest/src/kotlinx/serialization/cbor/CborWriterTest.kt +++ b/formats/cbor/commonTest/src/kotlinx/serialization/cbor/CborWriterTest.kt @@ -122,4 +122,28 @@ class CbrWriterTest { actual = Cbor.encodeToHexString(TypeWithNullableCustomByteString(null)) ) } + + @Test + fun testWriteValueClassWithByteString() { + assertEquals( + expected = "43112233", + actual = Cbor.encodeToHexString(ValueClassWithByteString(byteArrayOf(0x11, 0x22, 0x33))) + ) + } + + @Test + fun testWriteValueClassCustomByteString() { + assertEquals( + expected = "43112233", + actual = Cbor.encodeToHexString(ValueClassWithCustomByteString(CustomByteString(0x11, 0x22, 0x33))) + ) + } + + @Test + fun testWriteValueClassWithUnlabeledByteString() { + assertEquals( + expected = "43112233", + actual = Cbor.encodeToHexString(ValueClassWithUnlabeledByteString(ValueClassWithUnlabeledByteString.Inner(byteArrayOf(0x11, 0x22, 0x33)))) + ) + } } diff --git a/formats/cbor/commonTest/src/kotlinx/serialization/cbor/SampleClasses.kt b/formats/cbor/commonTest/src/kotlinx/serialization/cbor/SampleClasses.kt index ad55d042..e4418f47 100644 --- a/formats/cbor/commonTest/src/kotlinx/serialization/cbor/SampleClasses.kt +++ b/formats/cbor/commonTest/src/kotlinx/serialization/cbor/SampleClasses.kt @@ -8,6 +8,7 @@ import kotlinx.serialization.* import kotlinx.serialization.builtins.* import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* +import kotlin.jvm.* @Serializable data class Simple(val a: String) @@ -110,4 +111,20 @@ class CustomByteStringSerializer : KSerializer<CustomByteString> { data class TypeWithCustomByteString(@ByteString val x: CustomByteString) @Serializable -data class TypeWithNullableCustomByteString(@ByteString val x: CustomByteString?)
\ No newline at end of file +data class TypeWithNullableCustomByteString(@ByteString val x: CustomByteString?) + +@JvmInline +@Serializable +value class ValueClassWithByteString(@ByteString val x: ByteArray) + +@JvmInline +@Serializable +value class ValueClassWithCustomByteString(@ByteString val x: CustomByteString) + +@JvmInline +@Serializable +value class ValueClassWithUnlabeledByteString(@ByteString val x: Inner) { + @JvmInline + @Serializable + value class Inner(val x: ByteArray) +}
\ No newline at end of file |