Skip to content

Commit

Permalink
fix: proto3 optionals from base64 encoded proto descriptors
Browse files Browse the repository at this point in the history
This fixes  deserialization of optionals in proto3 descriptors as they are represented by synthetic oneofs.
  • Loading branch information
keejon committed Oct 30, 2024
1 parent 8e3d735 commit 51cbe5f
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/karapace/protobuf/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,20 @@ def _deserialize_msg(msgtype: Any) -> MessageElement:

for f in msgtype.field:
sf = _deserialize_field(f)
if f.HasField("oneof_index"):
is_oneof = f.HasField("oneof_index")
is_proto3_optional = f.HasField("oneof_index") and f.HasField("proto3_optional") and f.proto3_optional
if is_proto3_optional:
# Every proto3 optional field is placed into a one-field oneof, called a "synthetic" oneof,
# as it was not present in the source .proto file.
# This will make sure that we don't interpret those optionals as oneof.
one_ofs[f.oneof_index] = None
fields.append(sf)
elif is_oneof:
one_ofs[f.oneof_index].fields.append(sf)
else:
fields.append(sf)

one_ofs = [o for o in one_ofs if o is not None]
return MessageElement(
DEFAULT_LOCATION, msgtype.name, nested_types=nested_types, reserveds=reserveds, fields=fields, one_ofs=one_ofs
)
Expand Down
18 changes: 18 additions & 0 deletions tests/schemas/protobuf.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,21 @@
"lzdGVyLk1ldGFkYXRhEhYKDmNvbXBhbnlfbnVtYmVyGAIgASgJGhYKCE1ldGFkYXRhEgoK"
"AmlkGAEgASgJYgZwcm90bzM="
)

schema_protobuf_optionals_bin = (
"Cgp0ZXN0LnByb3RvIqYBCgpEaW1lbnNpb25zEhEKBHNpemUYASABKAFIAIgBARISCgV3aWR0aBgCIAEoAUgBiAEBEhMKBmhlaWdodBgDIAEo"
+ "AUgCiAEBEhMKBmxlbmd0aBgEIAEoAUgDiAEBEhMKBndlaWdodBgFIAEoAUgEiAEBQgcKBV9zaXplQggKBl93aWR0aEIJCgdfaGVpZ2h0Qg"
+ "kKB19sZW5ndGhCCQoHX3dlaWdodGIGcHJvdG8z"
)

schema_protobuf_optionals = """\
syntax = "proto3";
message Dimensions {
optional double size = 1;
optional double width = 2;
optional double height = 3;
optional double length = 4;
optional double weight = 5;
}
"""
4 changes: 4 additions & 0 deletions tests/unit/test_protobuf_binary_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
schema_protobuf_nested_message4_bin_protoc,
schema_protobuf_oneof,
schema_protobuf_oneof_bin,
schema_protobuf_optionals,
schema_protobuf_optionals_bin,
schema_protobuf_order_after,
schema_protobuf_order_after_bin,
schema_protobuf_plain,
Expand Down Expand Up @@ -89,6 +91,7 @@
(schema_protobuf_references, schema_protobuf_references_bin),
(schema_protobuf_references2, schema_protobuf_references2_bin),
(schema_protobuf_complex, schema_protobuf_complex_bin),
(schema_protobuf_optionals, schema_protobuf_optionals_bin),
],
)
def test_schema_deserialize(schema_plain, schema_serialized):
Expand Down Expand Up @@ -125,6 +128,7 @@ def test_protoc_serialized_schema_deserialize(schema_plain, schema_serialized):
schema_protobuf_references,
schema_protobuf_references2,
schema_protobuf_complex,
schema_protobuf_optionals,
],
)
def test_simple_schema_serialize(schema):
Expand Down

0 comments on commit 51cbe5f

Please sign in to comment.