Skip to content

Commit 81b5390

Browse files
committed
more tests + tagging fixes
1 parent 949b293 commit 81b5390

File tree

5 files changed

+102
-14
lines changed

5 files changed

+102
-14
lines changed

formats/cbor/commonMain/src/kotlinx/serialization/cbor/internal/CborElementSerializers.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ internal object CborNullSerializer : KSerializer<CborNull> {
8989
buildSerialDescriptor("kotlinx.serialization.cbor.CborNull", SerialKind.ENUM)
9090

9191
override fun serialize(encoder: Encoder, value: CborNull) {
92-
encoder.asCborEncoder().encodeTags(value)
92+
encoder.asCborEncoder()
9393
encoder.encodeNull()
9494
}
9595

@@ -107,7 +107,7 @@ internal object CborIntSerializer : KSerializer<CborNegativeInt> {
107107
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("kotlinx.serialization.cbor.CborInt", PrimitiveKind.LONG)
108108

109109
override fun serialize(encoder: Encoder, value: CborNegativeInt) {
110-
encoder.asCborEncoder().encodeTags(value)
110+
encoder.asCborEncoder()
111111
encoder.encodeLong(value.value)
112112
}
113113

@@ -121,7 +121,7 @@ internal object CborUIntSerializer : KSerializer<CborPositiveInt> {
121121
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("CborUInt", PrimitiveKind.LONG)
122122

123123
override fun serialize(encoder: Encoder, value: CborPositiveInt) {
124-
encoder.asCborEncoder().encodeTags(value)
124+
encoder.asCborEncoder()
125125
encoder.encodeInline(descriptor).encodeSerializableValue(ULong.serializer(), value.value)
126126
}
127127

@@ -135,7 +135,7 @@ internal object CborDoubleSerializer : KSerializer<CborDouble> {
135135
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("kotlinx.serialization.cbor.CborDouble", PrimitiveKind.DOUBLE)
136136

137137
override fun serialize(encoder: Encoder, value: CborDouble) {
138-
encoder.asCborEncoder().encodeTags(value)
138+
encoder.asCborEncoder()
139139
encoder.encodeDouble(value.value)
140140
}
141141

@@ -154,7 +154,7 @@ internal object CborStringSerializer : KSerializer<CborString> {
154154
PrimitiveSerialDescriptor("kotlinx.serialization.cbor.CborString", PrimitiveKind.STRING)
155155

156156
override fun serialize(encoder: Encoder, value: CborString) {
157-
encoder.asCborEncoder().encodeTags(value)
157+
encoder.asCborEncoder()
158158
encoder.encodeString(value.value)
159159
}
160160

@@ -175,7 +175,7 @@ internal object CborBooleanSerializer : KSerializer<CborBoolean> {
175175
PrimitiveSerialDescriptor("kotlinx.serialization.cbor.CborBoolean", PrimitiveKind.BOOLEAN)
176176

177177
override fun serialize(encoder: Encoder, value: CborBoolean) {
178-
encoder.asCborEncoder().encodeTags(value)
178+
encoder.asCborEncoder()
179179
encoder.encodeBoolean(value.value)
180180
}
181181

@@ -197,7 +197,6 @@ internal object CborByteStringSerializer : KSerializer<CborByteString> {
197197

198198
override fun serialize(encoder: Encoder, value: CborByteString) {
199199
val cborEncoder = encoder.asCborEncoder()
200-
cborEncoder.encodeTags(value)
201200
cborEncoder.encodeByteString(value.value)
202201
}
203202

formats/cbor/commonMain/src/kotlinx/serialization/cbor/internal/CborTreeReader.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,16 @@ internal class CborTreeReader(
7171
// Half/Float32/Float64
7272
NEXT_HALF, NEXT_FLOAT, NEXT_DOUBLE -> CborDouble(parser.nextDouble(), tags)
7373
else -> throw CborDecodingException(
74-
"Invalid simple value or float type: ${parser.curByte.toString(16)}"
74+
"Invalid simple value or float type: ${parser.curByte.toString(16).uppercase()}"
7575
)
7676
}
7777
}
7878

79-
else -> throw CborDecodingException("Invalid CBOR major type: ${parser.curByte shr 5}")
79+
else -> {
80+
val errByte = parser.curByte shr 5
81+
throw if (errByte == -1) CborDecodingException("Unexpected EOF")
82+
else CborDecodingException("Invalid CBOR major type: $errByte")
83+
}
8084
}
8185
return result
8286
}

formats/cbor/commonTest/src/kotlinx/serialization/cbor/CborDecoderTest.kt

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,39 @@ class CborDecoderTest {
130130
@Test
131131
fun testIgnoreUnknownKeysFailsWhenCborDataIsMissingKeysThatArePresentInKotlinClass() {
132132
// with maps & lists of indefinite length
133+
val hex =
134+
"bf637374726d48656c6c6f2c20776f726c64216169182a686e756c6c61626c65f6646c6973749f61616162ff636d6170bf01f502f4ff65696e6e6572bf6161636c6f6cff6a696e6e6572734c6973749fbf6161636b656bffffff"
135+
133136
assertFailsWithMessage<SerializationException>("Field 'a' is required") {
134137
ignoreUnknownKeys.decodeFromHexString(
135138
Simple.serializer(),
136-
"bf637374726d48656c6c6f2c20776f726c64216169182a686e756c6c61626c65f6646c6973749f61616162ff636d6170bf01f502f4ff65696e6e6572bf6161636c6f6cff6a696e6e6572734c6973749fbf6161636b656bffffff"
139+
hex
140+
)
141+
}
142+
143+
val struct = Cbor.decodeFromHexString<CborElement>(hex)
144+
assertFailsWithMessage<SerializationException>("Field 'a' is required") {
145+
ignoreUnknownKeys.decodeFromCbor(
146+
Simple.serializer(),
147+
struct
137148
)
138149
}
139150

140151
// with maps & lists of definite length
152+
val hexDef =
153+
"a7646c6973748261616162686e756c6c61626c65f6636d6170a202f401f56169182a6a696e6e6572734c69737481a16161636b656b637374726d48656c6c6f2c20776f726c642165696e6e6572a16161636c6f6c"
141154
assertFailsWithMessage<SerializationException>("Field 'a' is required") {
142155
ignoreUnknownKeys.decodeFromHexString(
143156
Simple.serializer(),
144-
"a7646c6973748261616162686e756c6c61626c65f6636d6170a202f401f56169182a6a696e6e6572734c69737481a16161636b656b637374726d48656c6c6f2c20776f726c642165696e6e6572a16161636c6f6c"
157+
hexDef
158+
)
159+
}
160+
161+
val structDef = Cbor.decodeFromHexString<CborElement>(hexDef)
162+
assertFailsWithMessage<SerializationException>("Field 'a' is required") {
163+
ignoreUnknownKeys.decodeFromCbor(
164+
Simple.serializer(),
165+
structDef
145166
)
146167
}
147168
}
@@ -160,13 +181,19 @@ class CborDecoderTest {
160181
* 69676E6F7265 # "ignore"
161182
* (missing value associated with "ignore" key)
162183
*/
184+
val hex = "a36373747266737472696e676169006669676e6f7265"
163185
assertFailsWithMessage<CborDecodingException>("Unexpected EOF while skipping element") {
164186
ignoreUnknownKeys.decodeFromHexString(
165187
TypesUmbrella.serializer(),
166-
"a36373747266737472696e676169006669676e6f7265"
188+
hex
167189
)
168190
}
169191

192+
193+
assertFailsWithMessage<CborDecodingException>("Unexpected EOF") {
194+
Cbor.decodeFromHexString<CborElement>(hex)
195+
}
196+
170197
/* A3 # map(3)
171198
* 63 # text(3)
172199
* 737472 # "str"
@@ -180,12 +207,17 @@ class CborDecoderTest {
180207
* A2 # map(2)
181208
* (missing map contents associated with "ignore" key)
182209
*/
210+
val hex2 = "a36373747266737472696e676169006669676e6f7265a2"
183211
assertFailsWithMessage<CborDecodingException>("Unexpected EOF while skipping element") {
184212
ignoreUnknownKeys.decodeFromHexString(
185213
TypesUmbrella.serializer(),
186-
"a36373747266737472696e676169006669676e6f7265a2"
214+
hex2
187215
)
188216
}
217+
218+
assertFailsWithMessage<CborDecodingException>("Unexpected EOF") {
219+
Cbor.decodeFromHexString<CborElement>(hex2)
220+
}
189221
}
190222

191223
@Test
@@ -199,12 +231,17 @@ class CborDecoderTest {
199231
* 69676E6F7265 # "ignore"
200232
* FF # primitive(*)
201233
*/
234+
val hex = "a36373747266737472696e676669676e6f7265ff"
202235
assertFailsWithMessage<CborDecodingException>("Expected next data item, but found FF") {
203236
ignoreUnknownKeys.decodeFromHexString(
204237
TypesUmbrella.serializer(),
205-
"a36373747266737472696e676669676e6f7265ff"
238+
hex
206239
)
207240
}
241+
242+
assertFailsWithMessage<CborDecodingException>("Invalid simple value or float type: FF") {
243+
Cbor.decodeFromHexString<CborElement>(hex)
244+
}
208245
}
209246

210247

formats/cbor/commonTest/src/kotlinx/serialization/cbor/CborDefiniteLengthTest.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ class CborDefiniteLengthTest {
2626
"a9637374726d48656c6c6f2c20776f726c64216169182a686e756c6c61626c65f6646c6973748261616162636d6170a201f502f465696e6e6572a16161636c6f6c6a696e6e6572734c69737481a16161636b656b6a62797465537472696e6742cafe6962797465417272617982383521",
2727
Cbor { useDefiniteLengthEncoding = true }.encodeToHexString(TypesUmbrella.serializer(), test)
2828
)
29+
assertEquals(
30+
"a9637374726d48656c6c6f2c20776f726c64216169182a686e756c6c61626c65f6646c6973748261616162636d6170a201f502f465696e6e6572a16161636c6f6c6a696e6e6572734c69737481a16161636b656b6a62797465537472696e6742cafe6962797465417272617982383521",
31+
Cbor { useDefiniteLengthEncoding = true }.run {
32+
encodeToHexString(
33+
CborElement.serializer(),
34+
encodeToCbor(TypesUmbrella.serializer(), test)
35+
)
36+
}
37+
)
2938
}
3039

3140
}

formats/cbor/commonTest/src/kotlinx/serialization/cbor/CborLabelTest.kt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ class CborLabelTest {
3535
}
3636
assertEquals(referenceHexLabelString, cbor.encodeToHexString(ClassWithCborLabel.serializer(), reference))
3737
assertEquals(reference, cbor.decodeFromHexString(ClassWithCborLabel.serializer(), referenceHexLabelString))
38+
39+
val struct = cbor.encodeToCbor(ClassWithCborLabel.serializer(), reference)
40+
assertEquals(reference, cbor.decodeFromCbor(ClassWithCborLabel.serializer(), struct))
41+
assertEquals(referenceHexLabelString, cbor.encodeToHexString(CborElement.serializer(), struct))
3842
}
3943

4044
@Test
@@ -44,6 +48,11 @@ class CborLabelTest {
4448
}
4549
assertEquals(referenceHexNameString, cbor.encodeToHexString(ClassWithCborLabel.serializer(), reference))
4650
assertEquals(reference, cbor.decodeFromHexString(ClassWithCborLabel.serializer(), referenceHexNameString))
51+
52+
53+
val struct = cbor.encodeToCbor(ClassWithCborLabel.serializer(), reference)
54+
assertEquals(reference, cbor.decodeFromCbor(ClassWithCborLabel.serializer(), struct))
55+
assertEquals(referenceHexLabelString, cbor.encodeToHexString(CborElement.serializer(), struct))
4756
}
4857

4958
@Test
@@ -64,6 +73,10 @@ class CborLabelTest {
6473
}
6574
assertEquals(referenceHexLabelWithTagString, cbor.encodeToHexString(ClassWithCborLabelAndTag.serializer(), referenceWithTag))
6675
assertEquals(referenceWithTag, cbor.decodeFromHexString(ClassWithCborLabelAndTag.serializer(), referenceHexLabelWithTagString))
76+
77+
val struct = cbor.encodeToCbor(ClassWithCborLabelAndTag.serializer(), referenceWithTag)
78+
assertEquals(referenceWithTag, cbor.decodeFromCbor(ClassWithCborLabelAndTag.serializer(), struct))
79+
assertEquals(referenceHexLabelWithTagString, cbor.encodeToHexString(CborElement.serializer(), struct))
6780
}
6881

6982
@Test
@@ -84,6 +97,15 @@ class CborLabelTest {
8497
assertFailsWith(CborDecodingException::class) {
8598
cbor.decodeFromHexString(ClassWithCborLabelAndTag.serializer(), referenceHexLabelWithTagString)
8699
}
100+
101+
//we can encode and decode since it is a valid structure
102+
val struct = cbor.decodeFromHexString(CborElement.serializer(), referenceHexLabelWithTagString)
103+
assertEquals(referenceHexLabelWithTagString, cbor.encodeToHexString(CborElement.serializer(), struct))
104+
105+
//we cannot deserialize from the struct since it does not match the class structure
106+
assertFailsWith(CborDecodingException::class) {
107+
cbor.decodeFromCbor(ClassWithCborLabelAndTag.serializer(), struct)
108+
}
87109
}
88110

89111
@Test
@@ -107,6 +129,18 @@ class CborLabelTest {
107129
useDefiniteLengthEncoding = true
108130
}
109131
assertEquals(referenceWithTag, cbor.decodeFromHexString(ClassWithCborLabelAndTag.serializer(), referenceHexLabelWithTagString))
132+
133+
//no unknown props
134+
val struct = cbor.encodeToCbor(ClassWithCborLabelAndTag.serializer(), referenceWithTag)
135+
136+
//with unknown props
137+
val structFromString = cbor.decodeFromHexString(CborElement.serializer(), referenceHexLabelWithTagString)
138+
//must obv mismatch
139+
assertNotEquals(struct, structFromString)
140+
assertNotEquals(referenceHexLabelWithTagString, cbor.encodeToHexString(CborElement.serializer(), struct))
141+
142+
assertEquals(referenceWithTag, cbor.decodeFromCbor(ClassWithCborLabelAndTag.serializer(), struct))
143+
assertEquals(referenceHexLabelWithTagString, cbor.encodeToHexString(CborElement.serializer(), structFromString))
110144
}
111145

112146
@Test
@@ -128,6 +162,11 @@ class CborLabelTest {
128162
}
129163

130164
assertEquals(referenceWithoutLabel, cbor.decodeFromHexString(ClassWithoutCborLabel.serializer(), referenceHexStringWithoutLabel))
165+
166+
val struct = cbor.encodeToCbor(ClassWithoutCborLabel.serializer(), referenceWithoutLabel)
167+
assertEquals(referenceWithoutLabel, cbor.decodeFromCbor(ClassWithoutCborLabel.serializer(), struct))
168+
assertEquals(referenceHexStringWithoutLabel, cbor.encodeToHexString(CborElement.serializer(), struct))
169+
131170
}
132171

133172
@Serializable

0 commit comments

Comments
 (0)