summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreater <hello@eaterofco.de>2023-10-20 17:50:34 +0200
committerGitHub <noreply@github.com>2023-10-20 17:50:34 +0200
commitbfbe6a9127952473ef79a79e11ec754086cb0be3 (patch)
tree15575ca4406a76c54e5878acaa30f7523d25272f
parent7d4bb2a80b5ad7f053c8bd5596f7acb33e262114 (diff)
downloadkotlinx.serialization-bfbe6a9127952473ef79a79e11ec754086cb0be3.tar.gz
Cbor: check if inline value classes is marked as @ByteString (#2466)
Fixes #2187
-rw-r--r--formats/cbor/commonMain/src/kotlinx/serialization/cbor/internal/Encoding.kt8
-rw-r--r--formats/cbor/commonTest/src/kotlinx/serialization/cbor/CborReaderTest.kt28
-rw-r--r--formats/cbor/commonTest/src/kotlinx/serialization/cbor/CborWriterTest.kt24
-rw-r--r--formats/cbor/commonTest/src/kotlinx/serialization/cbor/SampleClasses.kt19
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