Describe the bug
When using negative values for @CborLabel when combined with preferCborLabelsOverNames decoding fails
To Reproduce
Quick Test file
package kotlinx.serialization.cbor
import kotlinx.serialization.*
import kotlin.test.*
class NegativeLabelsOverNamesTest {
private val withLabel = Cbor {
preferCborLabelsOverNames = true
useDefiniteLengthEncoding = true
}
@Test
fun withNegativeTwoLabel() {
val target = WithNegativeTwo(
3,
true
)
// a2010321f5
/**
* A2 # map(2)
* 01 # unsigned(1)
* 03 # unsigned(3)
* 21 # negative(1)
* F5 # primitive(21)
*/
val bytes = withLabel.encodeToByteArray(target)
// failure - kotlinx.serialization.cbor.internal.CborDecodingException: Expected an unsigned or negative integer, but found F5
val decodeBack: WithNegativeTwo = withLabel.decodeFromByteArray(bytes)
assertEquals(target, decodeBack)
}
@Test
fun withNegativeOneLabel() {
val target = WithNegativeOne(
3,
true
)
//a2010320f5
/**
* A2 # map(2)
* 01 # unsigned(1)
* 03 # unsigned(3)
* 20 # negative(0)
* F5 # primitive(21)
*/
val bytes = withLabel.encodeToByteArray(target)
// failure - kotlinx.serialization.cbor.internal.CborDecodingException: CborLabel unknown: 0 for kotlinx.serialization.cbor.NegativeLabelsOverNamesTest.WithNegativeOne(id: kotlin.Int, cool: kotlin.Boolean?)
val decodeBack: WithNegativeOne = withLabel.decodeFromByteArray(bytes)
assertEquals(target, decodeBack)
}
@OptIn(ExperimentalSerializationApi::class)
@Serializable
data class WithNegativeTwo(
@CborLabel(1)
val id: Int,
// critical bit: negative label causes failure to decode
@CborLabel(-2)
val cool: Boolean? = null,
)
@OptIn(ExperimentalSerializationApi::class)
@Serializable
data class WithNegativeOne(
@CborLabel(1)
val id: Int,
// critical bit: negative label causes failure to decode
@CborLabel(-1)
val cool: Boolean? = null,
)
}
Expected behavior
Tests should pass.
Fix
The fix I applied locally to 1.11.0 is attached as a patch (one liner):
kotlinx.serialization-3-41-26 PM.patch
This does change that line from:
e334d1c
Which was intended to make reading strictly follow the RFC - but since it only allowed positive numbers I just changed it to the generic 'readNumber' to handle both positive and negative.
Environment
- Kotlin version: 2.3.20
- Library version: 1.11.0
- Kotlin platforms: All
- Gradle version: 8.7
Describe the bug
When using negative values for
@CborLabelwhen combined withpreferCborLabelsOverNamesdecoding failsTo Reproduce
Quick Test file
Expected behavior
Tests should pass.
Fix
The fix I applied locally to 1.11.0 is attached as a patch (one liner):
kotlinx.serialization-3-41-26 PM.patch
This does change that line from:
e334d1c
Which was intended to make reading strictly follow the RFC - but since it only allowed positive numbers I just changed it to the generic 'readNumber' to handle both positive and negative.
Environment