Skip to content

Commit e840129

Browse files
committed
fix more tagging issues
1 parent 9b3f0e5 commit e840129

File tree

5 files changed

+169
-11
lines changed

5 files changed

+169
-11
lines changed

formats/cbor/commonMain/src/kotlinx/serialization/cbor/CborElement.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public class CborString(
154154
@Serializable(with = CborBooleanSerializer::class)
155155
public class CborBoolean(
156156
value: Boolean,
157-
tags: ULongArray = ulongArrayOf()
157+
vararg tags: ULong
158158
) : CborPrimitive<Boolean>(value, tags)
159159

160160
/**

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,12 @@ internal class CborTreeReader(
5656
when (parser.curByte) {
5757
0xF4 -> {
5858
parser.readByte() // Advance parser position
59-
CborBoolean(false, tags)
59+
CborBoolean(false, tags = tags)
6060
}
6161

6262
0xF5 -> {
6363
parser.readByte() // Advance parser position
64-
CborBoolean(true, tags)
64+
CborBoolean(true, tags = tags)
6565
}
6666

6767
0xF6, 0xF7 -> {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,11 +313,11 @@ internal class StructuredCborWriter(cbor: Cbor) : CborWriter(cbor) {
313313

314314

315315
override fun encodeTags(tags: ULongArray) {
316-
nextValueTags = tags
316+
nextValueTags += tags
317317
}
318318

319319
override fun encodeBoolean(value: Boolean) {
320-
currentElement += CborBoolean(value, nextValueTags)
320+
currentElement += CborBoolean(value, tags = nextValueTags)
321321
}
322322

323323
override fun encodeByte(value: Byte) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class CborElementEqualityTest {
8686
val bool1 = CborBoolean(true)
8787
val bool2 = CborBoolean(true)
8888
val bool3 = CborBoolean(false)
89-
val bool4 = CborBoolean(true, ulongArrayOf(1u))
89+
val bool4 = CborBoolean(true, 1u)
9090

9191
assertEquals(bool1, bool2)
9292
assertEquals(bool1.hashCode(), bool2.hashCode())

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

Lines changed: 163 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package kotlinx.serialization.cbor
66

77
import kotlinx.serialization.*
8+
import kotlinx.serialization.cbor.internal.*
89
import kotlin.test.*
910

1011
class CborElementTest {
@@ -330,6 +331,7 @@ class CborElementTest {
330331
encodeKeyTags = true
331332
verifyKeyTags = true
332333
verifyObjectTags = true
334+
verifyValueTags = true
333335
},
334336
MixedBag(
335337
str = "A string, is a string, is a string",
@@ -356,10 +358,11 @@ class CborElementTest {
356358
encodeKeyTags = true
357359
verifyKeyTags = true
358360
verifyObjectTags = true
361+
verifyValueTags = true
359362
},
360363
MixedBag(
361364
str = "A string, is a string, is a string",
362-
bStr = null,
365+
bStr = null,
363366
cborElement = CborBoolean(false),
364367
cborPositiveInt = CborPositiveInt(1u),
365368
cborInt = CborInt(-1),
@@ -383,11 +386,12 @@ class CborElementTest {
383386
encodeKeyTags = true
384387
verifyKeyTags = true
385388
verifyObjectTags = true
389+
verifyValueTags = true
386390
},
387391
MixedBag(
388392
str = "A string, is a string, is a string",
389-
bStr = null,
390-
cborElement = CborMap(mapOf(CborByteString(byteArrayOf(1,3,3,7)) to CborNull())),
393+
bStr = null,
394+
cborElement = CborMap(mapOf(CborByteString(byteArrayOf(1, 3, 3, 7)) to CborNull())),
391395
cborPositiveInt = CborPositiveInt(1u),
392396
cborInt = CborInt(-1),
393397
tagged = 26
@@ -411,10 +415,11 @@ class CborElementTest {
411415
encodeKeyTags = true
412416
verifyKeyTags = true
413417
verifyObjectTags = true
418+
verifyValueTags = true
414419
},
415420
MixedBag(
416421
str = "A string, is a string, is a string",
417-
bStr = null,
422+
bStr = null,
418423
cborElement = CborNull(),
419424
cborPositiveInt = CborPositiveInt(1u),
420425
cborInt = CborInt(-1),
@@ -438,10 +443,11 @@ class CborElementTest {
438443
encodeKeyTags = true
439444
verifyKeyTags = true
440445
verifyObjectTags = true
446+
verifyValueTags = true
441447
},
442448
MixedBag(
443449
str = "A string, is a string, is a string",
444-
bStr = CborByteString(byteArrayOf(), 1u,3u ),
450+
bStr = CborByteString(byteArrayOf(), 1u, 3u),
445451
cborElement = CborBoolean(false),
446452
cborPositiveInt = CborPositiveInt(1u),
447453
cborInt = CborInt(-1),
@@ -457,6 +463,150 @@ class CborElementTest {
457463
assertEquals(obj, cbor.decodeFromCbor(struct))
458464
assertEquals(obj, cbor.decodeFromHexString(hex))
459465
}
466+
467+
Triple(
468+
Cbor {
469+
encodeValueTags = false
470+
encodeKeyTags = true
471+
verifyKeyTags = true
472+
verifyObjectTags = true
473+
verifyValueTags = false
474+
},
475+
MixedBag(
476+
str = "A string, is a string, is a string",
477+
bStr = CborByteString(byteArrayOf(), 1u, 3u),
478+
cborElement = CborBoolean(false),
479+
cborPositiveInt = CborPositiveInt(1u),
480+
cborInt = CborInt(-1),
481+
tagged = 26
482+
),
483+
"bf6373747278224120737472696e672c206973206120737472696e672c206973206120737472696e676462537472c1c3406b63626f72456c656d656e74f46f63626f72506f736974697665496e74016763626f72496e7420d82a66746167676564181aff"
484+
)
485+
.let { (cbor, obj, hex) ->
486+
val struct = cbor.encodeToCbor(obj)
487+
assertEquals(hex, cbor.encodeToHexString(obj))
488+
assertEquals(hex, cbor.encodeToHexString(struct))
489+
assertEquals(struct, cbor.decodeFromHexString<CborElement>(hex))
490+
assertEquals(obj, cbor.decodeFromCbor(struct))
491+
assertEquals(obj, cbor.decodeFromHexString(hex))
492+
}
493+
494+
Triple(
495+
Cbor {
496+
encodeValueTags = true
497+
encodeKeyTags = true
498+
verifyKeyTags = true
499+
verifyObjectTags = true
500+
verifyValueTags = true
501+
},
502+
MixedTag(
503+
cborElement = CborBoolean(false),
504+
),
505+
"bfd82a6b63626f72456c656d656e74d90921f4ff"
506+
)
507+
.let { (cbor, obj, hex) ->
508+
val struct = cbor.encodeToCbor(obj)
509+
assertEquals(hex, cbor.encodeToHexString(obj))
510+
assertEquals(hex, cbor.encodeToHexString(struct))
511+
assertEquals(struct, cbor.decodeFromHexString<CborElement>(hex))
512+
// this is ambiguous. the cborBoolean has a tag attached in the struct, coming from the valueTag (as intended),
513+
// so now the resulting object won't have a tag but the cborElement property will have a tag attached
514+
// hence, the following two will have:
515+
// Expected :MixedTag(cborElement=CborPrimitive(kind=Boolean, tags=, value=false))
516+
// Actual :MixedTag(cborElement=CborPrimitive(kind=Boolean, tags=2337, value=false))
517+
assertNotEquals(obj, cbor.decodeFromCbor(struct))
518+
assertNotEquals(obj, cbor.decodeFromHexString(hex))
519+
}
520+
Triple(
521+
Cbor {
522+
encodeValueTags = true
523+
encodeKeyTags = true
524+
verifyKeyTags = true
525+
verifyObjectTags = true
526+
verifyValueTags = true
527+
},
528+
MixedTag(
529+
cborElement = CborBoolean(false, 90u),
530+
),
531+
//valueTags first, then CborElement tags
532+
"bfd82a6b63626f72456c656d656e74d90921d85af4ff"
533+
)
534+
.let { (cbor, obj, hex) ->
535+
val struct = cbor.encodeToCbor(obj)
536+
assertEquals(hex, cbor.encodeToHexString(obj))
537+
assertEquals(hex, cbor.encodeToHexString(struct))
538+
assertEquals(struct, cbor.decodeFromHexString<CborElement>(hex))
539+
// this is ambiguous. the cborBoolean has a tag attached in the struct, coming from the valueTag (as intended),
540+
// so now the resulting object won't have a tag but the cborElement property will have a tag attached
541+
// hence, the following two will have:
542+
// Expected :MixedTag(cborElement=CborPrimitive(kind=Boolean, tags=90, value=false))
543+
// Actual :MixedTag(cborElement=CborPrimitive(kind=Boolean, tags=2337, 90, value=false))
544+
//of course, the value tag verification will also fail hard
545+
assertFailsWith(
546+
CborDecodingException::class,
547+
"CBOR tags [2337, 90] do not match expected tags [2337]"
548+
) {
549+
assertNotEquals(obj, cbor.decodeFromCbor(struct))
550+
}
551+
assertFailsWith(
552+
CborDecodingException::class,
553+
"CBOR tags [2337, 90] do not match expected tags [2337]"
554+
) {
555+
assertNotEquals(obj, cbor.decodeFromHexString(hex))
556+
}
557+
}
558+
559+
Triple(
560+
Cbor {
561+
encodeValueTags = true
562+
encodeKeyTags = true
563+
verifyKeyTags = true
564+
verifyObjectTags = true
565+
verifyValueTags = false
566+
},
567+
MixedTag(
568+
cborElement = CborBoolean(false, 90u),
569+
),
570+
//valueTags first, then CborElement tags
571+
"bfd82a6b63626f72456c656d656e74d90921d85af4ff"
572+
)
573+
.let { (cbor, obj, hex) ->
574+
val struct = cbor.encodeToCbor(obj)
575+
assertEquals(hex, cbor.encodeToHexString(obj))
576+
assertEquals(hex, cbor.encodeToHexString(struct))
577+
assertEquals(struct, cbor.decodeFromHexString<CborElement>(hex))
578+
// this is ambiguous. the cborBoolean has a tag attached in the struct, coming from the valueTag (as intended),
579+
// so now the resulting object won't have a tag but the cborElement property will have a tag attached
580+
// hence, the following two will have:
581+
// Expected :MixedTag(cborElement=CborPrimitive(kind=Boolean, tags=90, value=false))
582+
// Actual :MixedTag(cborElement=CborPrimitive(kind=Boolean, tags=2337, 90, value=false))
583+
assertNotEquals(obj, cbor.decodeFromCbor(struct))
584+
assertNotEquals(obj, cbor.decodeFromHexString(hex))
585+
}
586+
587+
588+
Triple(
589+
Cbor {
590+
encodeValueTags = false
591+
encodeKeyTags = true
592+
verifyKeyTags = true
593+
verifyObjectTags = true
594+
verifyValueTags = false
595+
},
596+
MixedTag(
597+
cborElement = CborBoolean(false, 90u),
598+
),
599+
"bfd82a6b63626f72456c656d656e74d85af4ff"
600+
)
601+
.let { (cbor, obj, hex) ->
602+
val struct = cbor.encodeToCbor(obj)
603+
assertEquals(hex, cbor.encodeToHexString(obj))
604+
assertEquals(hex, cbor.encodeToHexString(struct))
605+
assertEquals(struct, cbor.decodeFromHexString<CborElement>(hex))
606+
//no value tags means everything's fine again
607+
assertEquals(obj, cbor.decodeFromCbor(struct))
608+
assertEquals(obj, cbor.decodeFromHexString(hex))
609+
}
460610
}
461611

462612
}
@@ -472,3 +622,11 @@ data class MixedBag(
472622
@ValueTags(2337u)
473623
val tagged: Int
474624
)
625+
626+
627+
@Serializable
628+
data class MixedTag(
629+
@KeyTags(42u)
630+
@ValueTags(2337u)
631+
val cborElement: CborElement?,
632+
)

0 commit comments

Comments
 (0)