diff options
Diffstat (limited to 'tests')
34 files changed, 594 insertions, 6 deletions
diff --git a/tests/SConstruct b/tests/SConstruct index d2dfeec..504f1b8 100644 --- a/tests/SConstruct +++ b/tests/SConstruct @@ -103,7 +103,7 @@ if not env.GetOption('clean'): # Check if we can use undefined behaviour sanitizer (only with clang) # TODO: Fuzz test triggers the bool sanitizer, figure out whether to # modify the fuzz test or to keep ignoring the check. - extra = '-fsanitize=undefined,integer -fno-sanitize-recover=undefined,integer -fsanitize-recover=bool ' + extra = '-fsanitize=undefined,integer -fno-sanitize-recover=undefined,integer ' if 'clang' in env['CC']: if conf.CheckCCFLAGS(extra, linkflags = extra): conf.env.Append(CORECFLAGS = extra) diff --git a/tests/alltypes/decode_alltypes.c b/tests/alltypes/decode_alltypes.c index b74121f..3b0f524 100644 --- a/tests/alltypes/decode_alltypes.c +++ b/tests/alltypes/decode_alltypes.c @@ -198,6 +198,7 @@ bool check_alltypes(pb_istream_t *stream, int mode) TEST(alltypes.which_oneof == AllTypes_oneof_msg1_tag); TEST(strcmp(alltypes.oneof.oneof_msg1.substuff1, "4059") == 0); TEST(alltypes.oneof.oneof_msg1.substuff2 == 4059); + TEST(alltypes.oneof.oneof_msg1.substuff3 == 3); } else if (mode == 2) { diff --git a/tests/encode_arrays_unpacked/SConscript b/tests/encode_arrays_unpacked/SConscript new file mode 100644 index 0000000..bd36d9d --- /dev/null +++ b/tests/encode_arrays_unpacked/SConscript @@ -0,0 +1,28 @@ +# Run the alltypes test case, but compile with PB_ENCODE_ARRAYS_UNPACKED=1 + +Import("env") + +# Take copy of the files for custom build. +c = Copy("$TARGET", "$SOURCE") +env.Command("alltypes.pb.h", "$BUILD/alltypes/alltypes.pb.h", c) +env.Command("alltypes.pb.c", "$BUILD/alltypes/alltypes.pb.c", c) +env.Command("encode_alltypes.c", "$BUILD/alltypes/encode_alltypes.c", c) +env.Command("decode_alltypes.c", "$BUILD/alltypes/decode_alltypes.c", c) + +# Define the compilation options +opts = env.Clone() +opts.Append(CPPDEFINES = {'PB_ENCODE_ARRAYS_UNPACKED': 1}) + +# Build new version of core +strict = opts.Clone() +strict.Append(CFLAGS = strict['CORECFLAGS']) +strict.Object("pb_decode_unpacked.o", "$NANOPB/pb_decode.c") +strict.Object("pb_encode_unpacked.o", "$NANOPB/pb_encode.c") +strict.Object("pb_common_unpacked.o", "$NANOPB/pb_common.c") + +# Now build and run the test normally. +enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_unpacked.o", "pb_common_unpacked.o"]) +dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_unpacked.o", "pb_common_unpacked.o"]) + +env.RunTest(enc) +env.RunTest([dec, "encode_alltypes.output"]) diff --git a/tests/enum_minmax/SConscript b/tests/enum_minmax/SConscript new file mode 100644 index 0000000..6a66cbd --- /dev/null +++ b/tests/enum_minmax/SConscript @@ -0,0 +1,8 @@ +# Test that different sizes of enum fields are properly encoded and decoded. + +Import('env') + +env.NanopbProto('enumminmax') + +p = env.Program(["enumminmax_unittests.c",]) +env.RunTest(p) diff --git a/tests/enum_minmax/enumminmax.proto b/tests/enum_minmax/enumminmax.proto new file mode 100644 index 0000000..482a8db --- /dev/null +++ b/tests/enum_minmax/enumminmax.proto @@ -0,0 +1,22 @@ +/* Test out-of-order enum values. + */ + +syntax = "proto3"; + +enum Language { + UNKNOWN = 0; + ENGLISH_EN_GB = 12; + ENGLISH_EN_US = 1; + FRENCH_FR_FR = 2; + ITALIAN_IT_IT = 3; + GERMAN_DE_DE = 4; + SPANISH_ES_AR = 13; + SPANISH_ES_ES = 5; + SPANISH_ES_MX = 14; + SWEDISH_SV_SE = 6; + DUTCH_NL_NL = 7; + KOREAN_KO_KR = 8; + JAPANESE_JA_JP = 9; + CHINESE_SIMPLIFIED_ZH_CN = 10; + CHINESE_TRADITIONAL_ZH_TW = 11; +} diff --git a/tests/enum_minmax/enumminmax_unittests.c b/tests/enum_minmax/enumminmax_unittests.c new file mode 100644 index 0000000..ccb10a4 --- /dev/null +++ b/tests/enum_minmax/enumminmax_unittests.c @@ -0,0 +1,16 @@ +#include "unittests.h" +#include "enumminmax.pb.h" + +int main() +{ + int status = 0; + + COMMENT("Verify min/max on unsorted enum"); + { + TEST(_Language_MIN == Language_UNKNOWN); + TEST(_Language_MAX == Language_SPANISH_ES_MX); + TEST(_Language_ARRAYSIZE == (Language_SPANISH_ES_MX+1)); + } + + return status; +} diff --git a/tests/fuzztest/fuzztest.c b/tests/fuzztest/fuzztest.c index ee851ec..0dc2382 100644 --- a/tests/fuzztest/fuzztest.c +++ b/tests/fuzztest/fuzztest.c @@ -171,6 +171,33 @@ static void rand_mess(uint8_t *buf, size_t count) /* Some default data to put in the message */ static const alltypes_static_AllTypes initval = alltypes_static_AllTypes_init_default; +/* Check the invariants defined in security model on decoded structure */ +static void sanity_check_static(alltypes_static_AllTypes *msg) +{ + bool truebool = true; + bool falsebool = false; + + /* TODO: Add more checks, or rather, generate them automatically */ + assert(strlen(msg->req_string) < sizeof(msg->req_string)); + assert(strlen(msg->opt_string) < sizeof(msg->opt_string)); + if (msg->rep_string_count > 0) + { + assert(strlen(msg->rep_string[0]) < sizeof(msg->rep_string[0])); + } + assert(memcmp(&msg->req_bool, &truebool, sizeof(bool)) == 0 || + memcmp(&msg->req_bool, &falsebool, sizeof(bool)) == 0); + assert(memcmp(&msg->has_opt_bool, &truebool, sizeof(bool)) == 0 || + memcmp(&msg->has_opt_bool, &falsebool, sizeof(bool)) == 0); + assert(memcmp(&msg->opt_bool, &truebool, sizeof(bool)) == 0 || + memcmp(&msg->opt_bool, &falsebool, sizeof(bool)) == 0); + assert(msg->rep_bool_count <= pb_arraysize(alltypes_static_AllTypes, rep_bool)); + if (msg->rep_bool_count > 0) + { + assert(memcmp(&msg->rep_bool[0], &truebool, sizeof(bool)) == 0 || + memcmp(&msg->rep_bool[0], &falsebool, sizeof(bool)) == 0); + } +} + #define BUFSIZE 4096 static bool do_static_encode(uint8_t *buffer, size_t *msglen) @@ -230,6 +257,11 @@ static bool do_static_decode(uint8_t *buffer, size_t msglen, bool assert_success rand_fill((uint8_t*)msg, sizeof(alltypes_static_AllTypes)); stream = pb_istream_from_buffer(buffer, msglen); status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg); + + if (status) + { + sanity_check_static(msg); + } if (!status && assert_success) { @@ -285,6 +317,7 @@ static void do_static_roundtrip(uint8_t *buffer, size_t msglen) pb_istream_t stream = pb_istream_from_buffer(buffer, msglen); status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg1); assert(status); + sanity_check_static(msg1); } { @@ -298,6 +331,7 @@ static void do_static_roundtrip(uint8_t *buffer, size_t msglen) pb_istream_t stream = pb_istream_from_buffer(buf2, msglen2); status = pb_decode(&stream, alltypes_static_AllTypes_fields, msg2); assert(status); + sanity_check_static(msg2); } { diff --git a/tests/mem_release/mem_release.c b/tests/mem_release/mem_release.c index 6e06da5..fae4516 100644 --- a/tests/mem_release/mem_release.c +++ b/tests/mem_release/mem_release.c @@ -133,13 +133,16 @@ static bool test_OneofMessage() } } - /* Encode second with SubMessage, invoking 'merge' behaviour */ + /* Encode second with SubMessage, replacing the oneof item */ { OneofMessage msg = OneofMessage_init_zero; + char *teststr = "1"; msg.which_msgs = OneofMessage_msg2_tag; msg.first = 999; msg.msgs.msg2.dynamic_str = "ABCD"; + msg.msgs.msg2.dynamic_str_arr_count = 1; + msg.msgs.msg2.dynamic_str_arr = &teststr; msg.last = 888; if (!pb_encode(&stream, OneofMessage_fields, &msg)) @@ -148,6 +151,25 @@ static bool test_OneofMessage() return false; } } + + /* Encode second SubMessage, invoking submessage merge behavior */ + { + OneofMessage msg = OneofMessage_init_zero; + char *teststr = "2"; + msg.which_msgs = OneofMessage_msg2_tag; + + msg.first = 99; + msg.msgs.msg2.dynamic_str = "EFGH"; + msg.msgs.msg2.dynamic_str_arr_count = 1; + msg.msgs.msg2.dynamic_str_arr = &teststr; + msg.last = 88; + + if (!pb_encode(&stream, OneofMessage_fields, &msg)) + { + fprintf(stderr, "Encode failed: %s\n", PB_GET_ERROR(&stream)); + return false; + } + } msgsize = stream.bytes_written; } @@ -160,13 +182,16 @@ static bool test_OneofMessage() return false; } - TEST(msg.first == 999); + TEST(msg.first == 99); TEST(msg.which_msgs == OneofMessage_msg2_tag); TEST(msg.msgs.msg2.dynamic_str); - TEST(strcmp(msg.msgs.msg2.dynamic_str, "ABCD") == 0); - TEST(msg.msgs.msg2.dynamic_str_arr == NULL); + TEST(strcmp(msg.msgs.msg2.dynamic_str, "EFGH") == 0); + TEST(msg.msgs.msg2.dynamic_str_arr != NULL); + TEST(msg.msgs.msg2.dynamic_str_arr_count == 2); + TEST(strcmp(msg.msgs.msg2.dynamic_str_arr[0], "1") == 0); + TEST(strcmp(msg.msgs.msg2.dynamic_str_arr[1], "2") == 0); TEST(msg.msgs.msg2.dynamic_submsg == NULL); - TEST(msg.last == 888); + TEST(msg.last == 88); pb_release(OneofMessage_fields, &msg); TEST(get_alloc_count() == 0); diff --git a/tests/regression/issue_363/SConscript b/tests/regression/issue_363/SConscript new file mode 100644 index 0000000..4ce3c6d --- /dev/null +++ b/tests/regression/issue_363/SConscript @@ -0,0 +1,14 @@ +# Regression test for #363: +# Incorrect PB_STATIC_ASSERT for bytes inside oneof + +Import("env") + +env.NanopbProto("oneofmsg.proto") +testprog = env.Program(["test_oneofmsg.c", + "oneofmsg.pb.c", + "$COMMON/pb_encode.o", + "$COMMON/pb_decode.o", + "$COMMON/pb_common.o"]) + +env.RunTest(testprog) + diff --git a/tests/regression/issue_363/oneofmsg.proto b/tests/regression/issue_363/oneofmsg.proto new file mode 100644 index 0000000..735bed8 --- /dev/null +++ b/tests/regression/issue_363/oneofmsg.proto @@ -0,0 +1,10 @@ +syntax = "proto2"; + +import "nanopb.proto"; + +message BodyMessage { + oneof body_type { + bytes device_data_crypted = 1 [(nanopb).max_size = 252]; + bytes device_config_crypted = 2 [(nanopb).max_size = 252]; + } +} diff --git a/tests/regression/issue_363/test_oneofmsg.c b/tests/regression/issue_363/test_oneofmsg.c new file mode 100644 index 0000000..c218192 --- /dev/null +++ b/tests/regression/issue_363/test_oneofmsg.c @@ -0,0 +1,42 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pb_encode.h> +#include <pb_decode.h> +#include "oneofmsg.pb.h" +#include "unittests.h" + +int main(int argc, char **argv) +{ + int status = 0; + uint8_t buffer[512]; + pb_size_t msglen = 0; + + { + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + BodyMessage msg = BodyMessage_init_zero; + + msg.which_body_type = BodyMessage_device_data_crypted_tag; + msg.body_type.device_data_crypted.size = 252; + memset(msg.body_type.device_data_crypted.bytes, 0xAA, 252); + + TEST(pb_encode(&stream, BodyMessage_fields, &msg)); + + msglen = stream.bytes_written; + TEST(msglen > 252); + } + + { + pb_istream_t stream = pb_istream_from_buffer(buffer, msglen); + BodyMessage msg = BodyMessage_init_zero; + + TEST(pb_decode(&stream, BodyMessage_fields, &msg)); + + TEST(msg.which_body_type == BodyMessage_device_data_crypted_tag); + TEST(msg.body_type.device_data_crypted.size == 252); + TEST(msg.body_type.device_data_crypted.bytes[251] == 0xAA); + } + + return status; +} + diff --git a/tests/regression/issue_376/SConscript b/tests/regression/issue_376/SConscript new file mode 100644 index 0000000..017a3ec --- /dev/null +++ b/tests/regression/issue_376/SConscript @@ -0,0 +1,14 @@ +# Regression test for #376: +# Problem with fixed array inside proto3 submessage + +Import("env") + +env.NanopbProto(["fixed_array.proto", "fixed_array.options"]) +testprog = env.Program(["test_fixarray.c", + "fixed_array.pb.c", + "$COMMON/pb_encode.o", + "$COMMON/pb_decode.o", + "$COMMON/pb_common.o"]) + +env.RunTest(testprog) + diff --git a/tests/regression/issue_376/fixed_array.options b/tests/regression/issue_376/fixed_array.options new file mode 100644 index 0000000..60fd687 --- /dev/null +++ b/tests/regression/issue_376/fixed_array.options @@ -0,0 +1 @@ +SubMessage.data fixed_count:true,max_count:8 diff --git a/tests/regression/issue_376/fixed_array.proto b/tests/regression/issue_376/fixed_array.proto new file mode 100644 index 0000000..6d86f80 --- /dev/null +++ b/tests/regression/issue_376/fixed_array.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +message MainMessage { + SubMessage submsg = 1; +} + +message SubMessage { + repeated int32 data = 1; +} + + diff --git a/tests/regression/issue_376/test_fixarray.c b/tests/regression/issue_376/test_fixarray.c new file mode 100644 index 0000000..f321b6d --- /dev/null +++ b/tests/regression/issue_376/test_fixarray.c @@ -0,0 +1,40 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pb_encode.h> +#include <pb_decode.h> +#include "fixed_array.pb.h" +#include "unittests.h" + +int main(int argc, char **argv) +{ + int status = 0; + uint8_t buffer[64]; + pb_size_t msglen = 0; + + { + pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + MainMessage msg = MainMessage_init_zero; + + msg.submsg.data[0] = 0; + msg.submsg.data[4] = 5; + + TEST(pb_encode(&stream, MainMessage_fields, &msg)); + + msglen = stream.bytes_written; + TEST(msglen > 5); + } + + { + pb_istream_t stream = pb_istream_from_buffer(buffer, msglen); + MainMessage msg = MainMessage_init_zero; + + TEST(pb_decode(&stream, MainMessage_fields, &msg)); + + TEST(msg.submsg.data[0] == 0); + TEST(msg.submsg.data[4] == 5); + } + + return status; +} + diff --git a/tests/regression/issue_380/SConscript b/tests/regression/issue_380/SConscript new file mode 100644 index 0000000..4606d9b --- /dev/null +++ b/tests/regression/issue_380/SConscript @@ -0,0 +1,9 @@ +# Regression test for #380: +# mangle_names:M_STRIP_PACKAGE is broken when message name (partially) +# matches package name + +Import("env") + +env.NanopbProto(["manglenames.proto", "manglenames.options"]) +env.Object("manglenames.pb.o", "manglenames.pb.c") + diff --git a/tests/regression/issue_380/manglenames.options b/tests/regression/issue_380/manglenames.options new file mode 100644 index 0000000..d9b4e41 --- /dev/null +++ b/tests/regression/issue_380/manglenames.options @@ -0,0 +1 @@ +* mangle_names:M_STRIP_PACKAGE diff --git a/tests/regression/issue_380/manglenames.proto b/tests/regression/issue_380/manglenames.proto new file mode 100644 index 0000000..186161d --- /dev/null +++ b/tests/regression/issue_380/manglenames.proto @@ -0,0 +1,16 @@ +syntax = "proto2"; +package A; + +message A { + message B { + optional uint32 val = 1; + } + optional B b = 1; +} + +message AP { + message B { + optional uint32 val = 1; + } + optional B m = 1; +} diff --git a/tests/regression/issue_395/SConscript b/tests/regression/issue_395/SConscript new file mode 100644 index 0000000..8bc1030 --- /dev/null +++ b/tests/regression/issue_395/SConscript @@ -0,0 +1,14 @@ +# Regression test for #395: +# Unexpected empty submessage in proto3 mode + +Import("env") + +env.NanopbProto(["test.proto", "test.options"]) +testprog = env.Program(["test.c", + "test.pb.c", + "$COMMON/pb_encode.o", + "$COMMON/pb_decode.o", + "$COMMON/pb_common.o"]) + +env.RunTest(testprog) + diff --git a/tests/regression/issue_395/test.c b/tests/regression/issue_395/test.c new file mode 100644 index 0000000..9578caf --- /dev/null +++ b/tests/regression/issue_395/test.c @@ -0,0 +1,38 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pb_encode.h> +#include <pb_decode.h> +#include "test.pb.h" +#include "unittests.h" + +int main(int argc, char **argv) +{ + int status = 0; + uint8_t buffer[512] = {0}; + int i; + pb_ostream_t ostream; + + Reply reply = Reply_init_zero; + Reply_Result request_result = Reply_Result_OK; + + ostream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + reply.result = request_result; + if (!pb_encode(&ostream, Reply_fields, &reply)) { + fprintf(stderr, "Encode failed: %s\n", PB_GET_ERROR(&ostream)); + return 1; + } + + printf("response payload (%d):", (int)ostream.bytes_written); + for (i = 0; i < ostream.bytes_written; i++) { + printf("%02X", buffer[i]); + } + printf("\n"); + + TEST(ostream.bytes_written == 2); + TEST(buffer[0] == 0x08); + TEST(buffer[1] == 0x01); + + return status; +} + diff --git a/tests/regression/issue_395/test.options b/tests/regression/issue_395/test.options new file mode 100644 index 0000000..5594796 --- /dev/null +++ b/tests/regression/issue_395/test.options @@ -0,0 +1,2 @@ +SubSubAMessage.somestring max_size:64 +SubSubBMessage.somestring max_size:64 diff --git a/tests/regression/issue_395/test.proto b/tests/regression/issue_395/test.proto new file mode 100644 index 0000000..91bf371 --- /dev/null +++ b/tests/regression/issue_395/test.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; + +message Error +{ + int32 code = 1; + string message = 2; +} + +message SubSubAMessage +{ + string somestring = 1; +} + +message SubSubBMessage +{ + string somestring = 1; +} + +message SubMessage +{ + SubSubAMessage subsubmessageA = 1; + repeated SubSubBMessage subsubmessageB = 2; +} + +message Reply +{ + enum Result + { + ERROR = 0; + OK = 1; + SOME_A = 2; + } + + Result result = 1; + Error error = 2; + SubMessage submessage = 3; +} diff --git a/tests/regression/issue_504/SConscript b/tests/regression/issue_504/SConscript new file mode 100644 index 0000000..c303171 --- /dev/null +++ b/tests/regression/issue_504/SConscript @@ -0,0 +1,12 @@ +# Regression test for #504: +# Non empty submessage considered empty on FT_POINTER fields with address aligned on 0x100 + +Import('env', 'malloc_env') + +env.NanopbProto(["test.proto"]) +test = malloc_env.Program(["test.c", + "test.pb.c", + "$COMMON/pb_encode.o", + "$COMMON/pb_common.o"]) + +env.RunTest(test) diff --git a/tests/regression/issue_504/test.c b/tests/regression/issue_504/test.c new file mode 100644 index 0000000..1ca86db --- /dev/null +++ b/tests/regression/issue_504/test.c @@ -0,0 +1,47 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pb_encode.h> +#include "test.pb.h" +#include "unittests.h" + +const char STR[] = "test str"; +#define ALIGN 0x100 + +int main(int argc, char **argv) +{ + int status = 0; + uint8_t buffer[512] = {0}; + int i; + pb_ostream_t ostream; + MyMessage msg = MyMessage_init_zero; + char *pStr, *pStrAligned; + ostream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + + /* copy STR to a malloced 0x100 aligned address */ + pStr = malloc(sizeof(STR) + ALIGN); + pStrAligned = (char*)((uintptr_t)(pStr + ALIGN) & ~(ALIGN - 1)); + memcpy(pStrAligned, STR, sizeof(STR)); + + msg.submessage.somestring = pStrAligned; + printf("%p: '%s'\n", msg.submessage.somestring, msg.submessage.somestring); + + if (!pb_encode(&ostream, MyMessage_fields, &msg)) { + fprintf(stderr, "Encode failed: %s\n", PB_GET_ERROR(&ostream)); + return 1; + } + + free(pStr); + msg.submessage.somestring = NULL; + + printf("response payload (%d):", (int)ostream.bytes_written); + for (i = 0; i < ostream.bytes_written; i++) { + printf("%02X", buffer[i]); + } + printf("\n"); + + TEST(ostream.bytes_written != 0); + + return status; +} + diff --git a/tests/regression/issue_504/test.proto b/tests/regression/issue_504/test.proto new file mode 100644 index 0000000..a5b0d9c --- /dev/null +++ b/tests/regression/issue_504/test.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +import "nanopb.proto"; + +message MyMessage +{ + SubMessage submessage = 1; +} + +message SubMessage +{ + string somestring = 1 [(nanopb).type = FT_POINTER]; +} diff --git a/tests/regression/issue_547/SConscript b/tests/regression/issue_547/SConscript new file mode 100644 index 0000000..c0a19fa --- /dev/null +++ b/tests/regression/issue_547/SConscript @@ -0,0 +1,21 @@ +# Regression test for issue #547: +# Buffer overflow when encoding bytes with size set to 65535 + +Import("env") + +env.NanopbProto("test.proto") + +# Define the compilation options +opts = env.Clone() +opts.Append(CPPDEFINES = {'PB_FIELD_32BIT': 1}) + +# Build new version of core +strict = opts.Clone() +strict.Append(CFLAGS = strict['CORECFLAGS']) +strict.Object("pb_encode_fields32.o", "$NANOPB/pb_encode.c") +strict.Object("pb_common_fields32.o", "$NANOPB/pb_common.c") + +# Build and run test +test = opts.Program(["test.c", "test.pb.c", "pb_encode_fields32.o", "pb_common_fields32.o"]) + +env.RunTest(test) diff --git a/tests/regression/issue_547/test.c b/tests/regression/issue_547/test.c new file mode 100644 index 0000000..9530302 --- /dev/null +++ b/tests/regression/issue_547/test.c @@ -0,0 +1,28 @@ +#include <string.h> +#include <pb_encode.h> +#include <unittests.h> +#include "test.pb.h" + +int main() +{ + pb_byte_t buf[512]; + MyMessage msg = MyMessage_init_zero; + pb_ostream_t stream = pb_ostream_from_buffer(buf, sizeof(buf)); + + msg.mybytes.size = 0xFFFFFFFF; + + if (pb_encode(&stream, MyMessage_fields, &msg)) + { + fprintf(stderr, "Failure: expected pb_encode() to fail.\n"); + return 1; + } + else if (strcmp(PB_GET_ERROR(&stream), "bytes size exceeded") != 0) + { + fprintf(stderr, "Unexpected encoding error: %s\n", PB_GET_ERROR(&stream)); + return 2; + } + else + { + return 0; + } +} diff --git a/tests/regression/issue_547/test.proto b/tests/regression/issue_547/test.proto new file mode 100644 index 0000000..56daa41 --- /dev/null +++ b/tests/regression/issue_547/test.proto @@ -0,0 +1,7 @@ +syntax = "proto2"; + +import "nanopb.proto"; + +message MyMessage { + required bytes mybytes = 1 [(nanopb).max_size = 512]; +} diff --git a/tests/regression/issue_611/SConscript b/tests/regression/issue_611/SConscript new file mode 100644 index 0000000..6295107 --- /dev/null +++ b/tests/regression/issue_611/SConscript @@ -0,0 +1,8 @@ +# Regression test for #611: +# Enum messages inside OneOf generated as ENUM instead of UENUM + +Import("env") + +env.NanopbProto("uenum.proto") +env.Match(["uenum.pb.c", "uenum.expected"]) +env.Object("uenum.pb.c") diff --git a/tests/regression/issue_611/uenum.expected b/tests/regression/issue_611/uenum.expected new file mode 100644 index 0000000..0806f24 --- /dev/null +++ b/tests/regression/issue_611/uenum.expected @@ -0,0 +1,3 @@ +[^U]ENUM.*ONEOF.*MyEnum +UENUM.*ONEOF.*MyUEnum + diff --git a/tests/regression/issue_611/uenum.proto b/tests/regression/issue_611/uenum.proto new file mode 100644 index 0000000..f6df218 --- /dev/null +++ b/tests/regression/issue_611/uenum.proto @@ -0,0 +1,28 @@ +syntax = "proto2"; + +enum my_enum { + E0 = 0; + E240 = 240; + E1 = -1; +} + +enum my_uenum { + U0 = 0; + U240 = 240; +} + +message my_message_regular { + required my_enum MyEnum = 1; + required my_uenum MyUEnum = 2; +} + +message my_message_oneof { + required uint32 Data1 = 1; + oneof Data { + bool null = 2; + my_enum MyEnum = 3; + my_uenum MyUEnum = 4; + } +} + + diff --git a/tests/regression/issue_647/SConscript b/tests/regression/issue_647/SConscript new file mode 100644 index 0000000..70eedf8 --- /dev/null +++ b/tests/regression/issue_647/SConscript @@ -0,0 +1,12 @@ +# Regression test for #647: +# Ill-formed oneof message leads to calling free on an arbitrary pointer + +Import("env") + +env.NanopbProto("repro.proto") + +test = env.Program(["repro.c", "repro.pb.c", + "$COMMON/pb_decode_with_malloc.o", + "$COMMON/pb_common_with_malloc.o", + "$COMMON/malloc_wrappers.o"]) +env.RunTest(test) diff --git a/tests/regression/issue_647/repro.c b/tests/regression/issue_647/repro.c new file mode 100644 index 0000000..48d9570 --- /dev/null +++ b/tests/regression/issue_647/repro.c @@ -0,0 +1,16 @@ +#include <pb_decode.h> +#include <unittests.h> +#include <malloc_wrappers.h> +#include "repro.pb.h" + +int main() { + const uint8_t data[] = {0x08, 0x08, 0x2d}; + int status = 0; + Repro repro = Repro_init_zero; + + pb_istream_t stream = pb_istream_from_buffer(data, sizeof(data)); + TEST(!pb_decode(&stream, Repro_fields, &repro)); + TEST(get_alloc_count() == 0); + + return status; +} diff --git a/tests/regression/issue_647/repro.proto b/tests/regression/issue_647/repro.proto new file mode 100644 index 0000000..1fe7777 --- /dev/null +++ b/tests/regression/issue_647/repro.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +import "nanopb.proto"; + +message Repro { + oneof value_type { + bool boolean_value = 1; + bytes bytes_value = 5 [(nanopb).type = FT_POINTER]; + } +} |