Commit 5238d655 authored by Oleg Efimov's avatar Oleg Efimov

protobuf-c.c: Better input checks in protobuf_c_message_free_unpacked

Check for NULL pointer for repeated fields passed to protobuf_c_message_free_unpacked

Closes #177
parent 24182d85
...@@ -3186,24 +3186,25 @@ protobuf_c_message_free_unpacked(ProtobufCMessage *message, ...@@ -3186,24 +3186,25 @@ protobuf_c_message_free_unpacked(ProtobufCMessage *message,
message, message,
desc->fields[f].offset); desc->fields[f].offset);
if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) { if (arr != NULL) {
unsigned i; if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) {
for (i = 0; i < n; i++) unsigned i;
do_free(allocator, ((char **) arr)[i]); for (i = 0; i < n; i++)
} else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) { do_free(allocator, ((char **) arr)[i]);
unsigned i; } else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) {
for (i = 0; i < n; i++) unsigned i;
do_free(allocator, ((ProtobufCBinaryData *) arr)[i].data); for (i = 0; i < n; i++)
} else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) { do_free(allocator, ((ProtobufCBinaryData *) arr)[i].data);
unsigned i; } else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) {
for (i = 0; i < n; i++) unsigned i;
protobuf_c_message_free_unpacked( for (i = 0; i < n; i++)
((ProtobufCMessage **) arr)[i], protobuf_c_message_free_unpacked(
allocator ((ProtobufCMessage **) arr)[i],
); allocator
} );
if (arr != NULL) }
do_free(allocator, arr); do_free(allocator, arr);
}
} else if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) { } else if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) {
char *str = STRUCT_MEMBER(char *, message, char *str = STRUCT_MEMBER(char *, message,
desc->fields[f].offset); desc->fields[f].offset);
......
...@@ -1931,6 +1931,24 @@ test_free_unpacked_input_check_for_null_message (void) ...@@ -1931,6 +1931,24 @@ test_free_unpacked_input_check_for_null_message (void)
protobuf_c_message_free_unpacked (NULL, NULL); protobuf_c_message_free_unpacked (NULL, NULL);
} }
static void
test_free_unpacked_input_check_for_null_repeated_field (void)
{
Foo__TestMess *tm = calloc(1, foo__test_mess__descriptor.sizeof_message);
foo__test_mess__init(tm);
tm->n_test_string = 1;
tm->test_string = NULL;
tm->n_test_bytes = 1;
tm->test_bytes = NULL;
tm->n_test_message = 1;
tm->test_message = NULL;
foo__test_mess__free_unpacked (tm, NULL);
}
/* This test checks that protobuf decoder is capable of detecting special /* This test checks that protobuf decoder is capable of detecting special
cases of incomplete messages. The message should have at least two required cases of incomplete messages. The message should have at least two required
fields field1 and field129 with positions pos1 and pos2 (no matter what the fields field1 and field129 with positions pos1 and pos2 (no matter what the
...@@ -2232,6 +2250,7 @@ static Test tests[] = ...@@ -2232,6 +2250,7 @@ static Test tests[] =
{ "test alloc failure", test_alloc_fail }, { "test alloc failure", test_alloc_fail },
{ "test free unpacked input check for null message", test_free_unpacked_input_check_for_null_message }, { "test free unpacked input check for null message", test_free_unpacked_input_check_for_null_message },
{ "test free unpacked input check for null repeated field", test_free_unpacked_input_check_for_null_repeated_field },
{ "test required_fields_bitmap", test_required_fields_bitmap }, { "test required_fields_bitmap", test_required_fields_bitmap },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment