diff options
author | Doğaç Eldenk <dogacel@gmail.com> | 2023-08-14 18:15:50 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-14 17:15:50 +0200 |
commit | a7109d8d0dae37f4b2907b8f3329c79288556d6b (patch) | |
tree | 633709506a2eb6450f8b15618f65cc60bf069dbc | |
parent | 1e88d42f9200da48ec27d0fd066e6bd1923b8b42 (diff) | |
download | kotlinx.serialization-a7109d8d0dae37f4b2907b8f3329c79288556d6b.tar.gz |
Fix negative enums in protobuf not serializing & de-serializing (#2400)
From language guide:
Enumerator constants must be in the range of a 32-bit integer. Since enum values use varint encoding on the wire, negative values are inefficient and thus not recommended (but still possible).
3 files changed, 4 insertions, 3 deletions
diff --git a/formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/ProtobufDecoding.kt b/formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/ProtobufDecoding.kt index 09773919..d2a28b5c 100644 --- a/formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/ProtobufDecoding.kt +++ b/formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/ProtobufDecoding.kt @@ -80,7 +80,7 @@ internal open class ProtobufDecoder( private fun findIndexByTag(descriptor: SerialDescriptor, protoTag: Int): Int { // Fast-path: tags are incremental, 1-based - if (protoTag < descriptor.elementsCount) { + if (protoTag < descriptor.elementsCount && protoTag >= 0) { val protoId = extractProtoId(descriptor, protoTag, true) if (protoId == protoTag) return protoTag } diff --git a/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/RandomTests.kt b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/RandomTests.kt index 0c94c6e3..2a12424d 100644 --- a/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/RandomTests.kt +++ b/formats/protobuf/jvmTest/src/kotlinx/serialization/protobuf/RandomTests.kt @@ -162,11 +162,11 @@ class RandomTest : ShouldSpec() { } } - enum class KCoffee { AMERICANO, LATTE, CAPPUCCINO } + enum class KCoffee(val value: Int) { AMERICANO(0), LATTE(1), CAPPUCCINO(2), @ProtoNumber(-1) NO_COFFEE(-1) } @Serializable data class KTestEnum(@ProtoNumber(1) val a: KCoffee): IMessage { - override fun toProtobufMessage() = TestEnum.newBuilder().setA(TestEnum.Coffee.forNumber(a.ordinal)).build() + override fun toProtobufMessage() = TestEnum.newBuilder().setA(TestEnum.Coffee.forNumber(a.value)).build() companion object : Gen<KTestEnum> { override fun generate(): KTestEnum = KTestEnum(Gen.oneOf<KCoffee>().generate()) diff --git a/formats/protobuf/testProto/test_data.proto b/formats/protobuf/testProto/test_data.proto index f4b1f5f0..2b50c600 100644 --- a/formats/protobuf/testProto/test_data.proto +++ b/formats/protobuf/testProto/test_data.proto @@ -59,6 +59,7 @@ message TestEnum { Americano = 0; Latte = 1; Capuccino = 2; + NoCoffee = -1; } required Coffee a = 1; } |