diff --git a/docs/index.rst b/docs/index.rst index fa7469f..6b90173 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -15,7 +15,7 @@ Overall structure For the runtime program, you always need *pb.h* for type declarations. Depending on whether you want to encode, decode, or both, you also need *pb_encode.h/c* or *pb_decode.h/c*. -If your *.proto* file encodes submessages or other fields using pointers, you must compile *pb_decode.c* with a preprocessor macro named *MALLOC_HEADER* that is the name of a header with definitions (either as functions or macros) for *malloc()*, *realloc()* and *free()*. For a typical hosted configuration, this should be **. +If your *.proto* file encodes submessages or other fields using pointers, you must compile *pb_decode.c* with a preprocessor macro named *MALLOC_HEADER* that is the name of a header with definitions (either as functions or macros) for *calloc()*, *realloc()* and *free()*. For a typical hosted configuration, this should be **. The high-level encoding and decoding functions take an array of *pb_field_t* structures, which describes the fields of a message structure. Usually you want these autogenerated from a *.proto* file. The tool script *nanopb_generator.py* accomplishes this. diff --git a/pb_decode.c b/pb_decode.c index 8931887..e4d0b3e 100644 --- a/pb_decode.c +++ b/pb_decode.c @@ -661,10 +661,11 @@ bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_t *field #ifdef MALLOC_HEADER if (*(void**)dest == NULL) { - void *object = malloc(msg->size); + void *object = calloc(1, msg->size); if (!object) return false; *(void**)dest = object; + pb_message_set_to_defaults(msg, object); dest = object; } else { dest = *(void**)dest; diff --git a/tests/decode_unittests.c b/tests/decode_unittests.c index 352146c..6ac03ed 100644 --- a/tests/decode_unittests.c +++ b/tests/decode_unittests.c @@ -287,12 +287,12 @@ int main() memset(&dest, 0, sizeof(dest)); #ifdef MALLOC_HEADER - TEST((s = S("\x0A\x01\x61\x12\x01\x62\x2A\x01\x65\x32\x01\x66\x3A\x00" - "\x42\x01\x63\x4A\x01\x64"), + TEST((s = S("\x0A\x01\x61\x12\x01\x62\x1A\x00\x2A\x01\x65\x32\x01\x66" + "\x3A\x00\x42\x01\x63\x4A\x01\x64"), pb_decode(&s, PointerContainer_msg, &dest))) TEST(0 == strcmp(dest.text, "a")) TEST(dest.blob.size == 1 && dest.blob.bytes[0] == 'b') - TEST(dest.submsg == NULL) + TEST(dest.submsg != NULL && dest.submsg->data == 10) TEST(dest.rtext_count == 1 && (0 == strcmp(dest.rtext[0], "e"))) TEST(dest.rblob_count == 1 && dest.rblob[0].size == 1 && dest.rblob[0].bytes[0] == 'f') @@ -301,8 +301,8 @@ int main() TEST(dest.oblob.size == 1 && dest.oblob.bytes[0] == 'd') TEST(pb_clean(PointerContainer_msg, &dest)); #else - TEST((s = S("\x0A\x01\x61\x12\x01\x62\x2A\x01\x65\x32\x01\x66\x3A\x00" - "\x42\x01\x63\x4A\x01\x64"), + TEST((s = S("\x0A\x01\x61\x12\x01\x62\x2A\x01\x65\x32\x01\x66\x01\x66" + "\x3A\x00\x42\x01\x63\x4A\x01\x64"), !pb_decode(&s, PointerContainer_msg, &dest))) #endif } diff --git a/tests/encode_unittests.c b/tests/encode_unittests.c index d3b3151..bf332e4 100644 --- a/tests/encode_unittests.c +++ b/tests/encode_unittests.c @@ -273,7 +273,7 @@ int main() uint8_t buffer[128]; pb_ostream_t s; PointerContainer msg; - PointerContainer msg2; + DefaultContainer msg2; IntegerArray msg3; COMMENT("Test pb_encode with pointer fields.") @@ -285,7 +285,7 @@ int main() msg.blob.bytes = (uint8_t*)"b"; msg.submsg = &msg2; TEST(WRITES(pb_encode(&s, PointerContainer_msg, &msg), - "\x0A\x01\x61\x12\x01\x62")) + "\x0A\x01\x61\x12\x01\x62\x1A\x00")) memset(&msg3, 0, sizeof(msg3)); msg.rtext_count = 1; @@ -296,7 +296,7 @@ int main() msg.rsubmsg_count = 1; msg.rsubmsg[0] = &msg3; TEST(WRITES(pb_encode(&s, PointerContainer_msg, &msg), - "\x0A\x01\x61\x12\x01\x62" + "\x0A\x01\x61\x12\x01\x62\x1A\x00" "\x2A\x01\x65\x32\x01\x66\x3A\x00")); PointerContainer_set(msg, otext); @@ -305,7 +305,7 @@ int main() msg.oblob.size = 1; msg.oblob.bytes = (uint8_t*)"d"; TEST(WRITES(pb_encode(&s, PointerContainer_msg, &msg), - "\x0A\x01\x61\x12\x01\x62" + "\x0A\x01\x61\x12\x01\x62\x1A\x00" "\x2A\x01\x65\x32\x01\x66\x3A\x00" "\x42\x01\x63\x4A\x01\x64")); } diff --git a/tests/unittestproto.proto b/tests/unittestproto.proto index 89d571e..84ec970 100644 --- a/tests/unittestproto.proto +++ b/tests/unittestproto.proto @@ -27,10 +27,14 @@ message CallbackContainerContainer { required CallbackContainer submsg = 1; } +message DefaultContainer { + optional int32 data = 1 [default = 10]; +} + message PointerContainer { required string text = 1 [(nanopb).pointer = true]; required bytes blob = 2 [(nanopb).pointer = true]; - optional PointerContainer submsg = 3 [(nanopb).pointer = true]; + required DefaultContainer submsg = 3 [(nanopb).pointer = true]; // This should be rejected: // required int32 data = 4 [(nanopb).pointer = true]; repeated string rtext = 5 [(nanopb).pointer = true, (nanopb).max_count = 10];