mirror of
https://github.com/protobuf-c/protobuf-c.git
synced 2024-12-28 14:48:18 +08:00
protobuf_c_unpack_message():
Insist that required fields be represented in the packed message. git-svn-id: https://protobuf-c.googlecode.com/svn/trunk@242 00440858-1255-0410-a3e6-75ea37f81c3a
This commit is contained in:
parent
45d9ee4679
commit
e30ec5f71e
@ -5,7 +5,9 @@
|
|||||||
- bug in dsk_dispatch_close_fd(), which usually only
|
- bug in dsk_dispatch_close_fd(), which usually only
|
||||||
showed up in later function calls.
|
showed up in later function calls.
|
||||||
- support for deprecated fields -- enable a GCC warning
|
- support for deprecated fields -- enable a GCC warning
|
||||||
if a field has the "deprecated" option enabled. (Andrey Nigmatulin)
|
if a field has the "deprecated" option enabled. (Andrei Nigmatulin)
|
||||||
|
- fix for protobuf_c_message_unpack() to issue error if any "required" field
|
||||||
|
is missing in input stream. (Andrei Nigmatulin)
|
||||||
|
|
||||||
0.13:
|
0.13:
|
||||||
- Fix for when the number of connections gets too great in RPC.
|
- Fix for when the number of connections gets too great in RPC.
|
||||||
|
@ -2103,11 +2103,20 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
|
|||||||
size_t n_unknown = 0;
|
size_t n_unknown = 0;
|
||||||
unsigned f;
|
unsigned f;
|
||||||
unsigned i_slab;
|
unsigned i_slab;
|
||||||
|
unsigned last_field_index = 0;
|
||||||
|
unsigned long *required_fields_bitmap;
|
||||||
|
unsigned required_fields_bitmap_len;
|
||||||
|
static const unsigned word_bits = sizeof(long) * 8;
|
||||||
|
|
||||||
ASSERT_IS_MESSAGE_DESCRIPTOR (desc);
|
ASSERT_IS_MESSAGE_DESCRIPTOR (desc);
|
||||||
|
|
||||||
if (allocator == NULL)
|
if (allocator == NULL)
|
||||||
allocator = &protobuf_c_default_allocator;
|
allocator = &protobuf_c_default_allocator;
|
||||||
|
|
||||||
|
required_fields_bitmap_len = (desc->n_fields + word_bits - 1) / word_bits;
|
||||||
|
required_fields_bitmap = alloca(required_fields_bitmap_len * sizeof(long));
|
||||||
|
memset(required_fields_bitmap, 0, required_fields_bitmap_len * sizeof(long));
|
||||||
|
|
||||||
DO_ALLOC (rv, allocator, desc->sizeof_message, return NULL);
|
DO_ALLOC (rv, allocator, desc->sizeof_message, return NULL);
|
||||||
scanned_member_slabs[0] = first_member_slab;
|
scanned_member_slabs[0] = first_member_slab;
|
||||||
|
|
||||||
@ -2150,11 +2159,15 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
|
|||||||
{
|
{
|
||||||
field = desc->fields + field_index;
|
field = desc->fields + field_index;
|
||||||
last_field = field;
|
last_field = field;
|
||||||
|
last_field_index = field_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
field = last_field;
|
field = last_field;
|
||||||
|
|
||||||
|
if (field != NULL && field->label == PROTOBUF_C_LABEL_REQUIRED)
|
||||||
|
required_fields_bitmap[last_field_index / word_bits] |= (1UL << (last_field_index % word_bits));
|
||||||
|
|
||||||
at += used;
|
at += used;
|
||||||
rem -= used;
|
rem -= used;
|
||||||
tmp.tag = tag;
|
tmp.tag = tag;
|
||||||
@ -2258,11 +2271,12 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
|
|||||||
rem -= tmp.len;
|
rem -= tmp.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate space for repeated fields */
|
/* allocate space for repeated fields, also check that all required fields have been set */
|
||||||
for (f = 0; f < desc->n_fields; f++)
|
for (f = 0; f < desc->n_fields; f++)
|
||||||
if (desc->fields[f].label == PROTOBUF_C_LABEL_REPEATED)
|
{
|
||||||
{
|
const ProtobufCFieldDescriptor *field = desc->fields + f;
|
||||||
const ProtobufCFieldDescriptor *field = desc->fields + f;
|
if (field->label == PROTOBUF_C_LABEL_REPEATED)
|
||||||
|
{
|
||||||
size_t siz = sizeof_elt_in_repeated_array (field->type);
|
size_t siz = sizeof_elt_in_repeated_array (field->type);
|
||||||
size_t *n_ptr = STRUCT_MEMBER_PTR (size_t, rv, field->quantifier_offset);
|
size_t *n_ptr = STRUCT_MEMBER_PTR (size_t, rv, field->quantifier_offset);
|
||||||
if (*n_ptr != 0)
|
if (*n_ptr != 0)
|
||||||
@ -2282,7 +2296,16 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
|
|||||||
CLEAR_REMAINING_N_PTRS (); goto error_cleanup);
|
CLEAR_REMAINING_N_PTRS (); goto error_cleanup);
|
||||||
#undef CLEAR_REMAINING_N_PTRS
|
#undef CLEAR_REMAINING_N_PTRS
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (field->label == PROTOBUF_C_LABEL_REQUIRED)
|
||||||
|
{
|
||||||
|
if (field->default_value == NULL && 0 == (required_fields_bitmap[f / word_bits] & (1UL << (f % word_bits))))
|
||||||
|
{
|
||||||
|
UNPACK_ERROR (("message '%s': missing required field '%s'", desc->name, field->name));
|
||||||
|
goto error_cleanup;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* allocate space for unknown fields */
|
/* allocate space for unknown fields */
|
||||||
if (n_unknown)
|
if (n_unknown)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user