From 1c8805a780aee4c35c962059980ea06176055260 Mon Sep 17 00:00:00 2001 From: Paolo Borelli Date: Sun, 9 Apr 2017 10:51:35 +0200 Subject: [PATCH] Fix "is zeroish" evaluation for proto3 In proto3 the default value is zero (NULL for pointers and 0 for scalars). However when checking we still need to test by type because poinetr types have an extra indirection. --- protobuf-c/protobuf-c.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/protobuf-c/protobuf-c.c b/protobuf-c/protobuf-c.c index 39819b4..c092d34 100644 --- a/protobuf-c/protobuf-c.c +++ b/protobuf-c/protobuf-c.c @@ -523,6 +523,20 @@ optional_field_get_packed_size(const ProtobufCFieldDescriptor *field, return required_field_get_packed_size(field, member); } +static protobuf_c_boolean +field_is_zeroish(const ProtobufCFieldDescriptor *field, + const void *member) +{ + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) + { + const void *ptr = *(const void * const *) member; + if (ptr == NULL) + return TRUE; + } + return member == NULL; +} + /** * Calculate the serialized size of a single unlabeled message field, including * the space needed by the preceding tag. Returns 0 if the field isn't set or @@ -540,10 +554,8 @@ static size_t unlabeled_field_get_packed_size(const ProtobufCFieldDescriptor *field, const void *member) { - const void *ptr = *(const void * const *) member; - if (ptr == NULL) { + if (field_is_zeroish(field, member)) return 0; - } return required_field_get_packed_size(field, member); } @@ -1168,10 +1180,8 @@ static size_t unlabeled_field_pack(const ProtobufCFieldDescriptor *field, const void *member, uint8_t *out) { - const void *ptr = *(const void * const *) member; - if (ptr == NULL) { + if (field_is_zeroish(field, member)) return 0; - } return required_field_pack(field, member, out); } @@ -1673,10 +1683,8 @@ static size_t unlabeled_field_pack_to_buffer(const ProtobufCFieldDescriptor *field, const void *member, ProtobufCBuffer *buffer) { - const void *ptr = *(const void *const *) member; - if (ptr == NULL) { + if (field_is_zeroish(field, member)) return 0; - } return required_field_pack_to_buffer(field, member, buffer); }