Fuzztest: include callback fields in test
diff --git a/tests/fuzztest/SConscript b/tests/fuzztest/SConscript
index 3280f75..91ecee0 100644
--- a/tests/fuzztest/SConscript
+++ b/tests/fuzztest/SConscript
@@ -18,8 +18,8 @@
env.Command("alltypes_pointer.proto", "#alltypes/alltypes.proto",
lambda target, source, env: set_pkgname(source[0], target[0], 'alltypes_pointer'))
-p1 = env.NanopbProto(["alltypes_pointer", "alltypes_pointer.options"])
-p2 = env.NanopbProto(["alltypes_static", "alltypes_static.options"])
+env.NanopbProto(["alltypes_pointer", "alltypes_pointer.options"])
+env.NanopbProto(["alltypes_static", "alltypes_static.options"])
# Do the same for proto3 versions
env.Command("alltypes_proto3_static.proto", "#alltypes_proto3/alltypes.proto",
@@ -27,8 +27,13 @@
env.Command("alltypes_proto3_pointer.proto", "#alltypes_proto3/alltypes.proto",
lambda target, source, env: set_pkgname(source[0], target[0], 'alltypes_proto3_pointer'))
-p1 = env.NanopbProto(["alltypes_proto3_pointer", "alltypes_proto3_pointer.options"])
-p2 = env.NanopbProto(["alltypes_proto3_static", "alltypes_proto3_static.options"])
+env.NanopbProto(["alltypes_proto3_pointer", "alltypes_proto3_pointer.options"])
+env.NanopbProto(["alltypes_proto3_static", "alltypes_proto3_static.options"])
+
+# And also a callback version
+env.Command("alltypes_callback.proto", "#alltypes/alltypes.proto",
+ lambda target, source, env: set_pkgname(source[0], target[0], 'alltypes_callback'))
+env.NanopbProto(["alltypes_callback", "alltypes_callback.options"])
fuzz = malloc_env.Program(["fuzztest.c",
"random_data.c",
@@ -36,6 +41,7 @@
"flakystream.c",
"alltypes_pointer.pb.c",
"alltypes_static.pb.c",
+ "alltypes_callback.pb.c",
"alltypes_proto3_pointer.pb.c",
"alltypes_proto3_static.pb.c",
"$COMMON/pb_encode_with_malloc.o",
diff --git a/tests/fuzztest/alltypes_proto3_pointer.options b/tests/fuzztest/alltypes_proto3_pointer.options
index ddd7934..e495787 100644
--- a/tests/fuzztest/alltypes_proto3_pointer.options
+++ b/tests/fuzztest/alltypes_proto3_pointer.options
@@ -1,5 +1,3 @@
* type:FT_POINTER
*.*fbytes fixed_length:true max_size:4
*.req_limits proto3_singular_msgs:true
-*.*farray fixed_count:true max_count:5
-*.DescriptorSize8 descriptorsize:DS_8
diff --git a/tests/fuzztest/alltypes_proto3_static.options b/tests/fuzztest/alltypes_proto3_static.options
index 305837b..b90eb38 100644
--- a/tests/fuzztest/alltypes_proto3_static.options
+++ b/tests/fuzztest/alltypes_proto3_static.options
@@ -2,5 +2,3 @@
* max_count:8
*.*fbytes fixed_length:true max_size:4
*.req_limits proto3_singular_msgs:true
-*.*farray fixed_count:true max_count:5
-*.DescriptorSize8 descriptorsize:DS_8
diff --git a/tests/fuzztest/fuzztest.c b/tests/fuzztest/fuzztest.c
index 1a4a7d2..2cbe05a 100644
--- a/tests/fuzztest/fuzztest.c
+++ b/tests/fuzztest/fuzztest.c
@@ -20,6 +20,7 @@
#include "test_helpers.h"
#include "alltypes_static.pb.h"
#include "alltypes_pointer.pb.h"
+#include "alltypes_callback.pb.h"
#include "alltypes_proto3_static.pb.h"
#include "alltypes_proto3_pointer.pb.h"
@@ -90,6 +91,50 @@
return status;
}
+static int g_sentinel;
+
+static bool field_callback(pb_istream_t *stream, const pb_field_t *field, void **arg)
+{
+ assert(*arg == &g_sentinel);
+ return pb_read(stream, NULL, stream->bytes_left);
+}
+
+static bool do_callback_decode(const uint8_t *buffer, size_t msglen, bool assert_success)
+{
+ bool status;
+ pb_istream_t stream;
+ size_t initial_alloc_count = get_alloc_count();
+ alltypes_callback_AllTypes *msg = malloc_with_check(sizeof(alltypes_callback_AllTypes));
+
+ memset(msg, 0, sizeof(alltypes_callback_AllTypes));
+ stream = pb_istream_from_buffer(buffer, msglen);
+
+ msg->rep_int32.funcs.decode = &field_callback;
+ msg->rep_int32.arg = &g_sentinel;
+ msg->rep_string.funcs.decode = &field_callback;
+ msg->rep_string.arg = &g_sentinel;
+ msg->rep_farray.funcs.decode = &field_callback;
+ msg->rep_farray.arg = &g_sentinel;
+ msg->req_limits.int64_min.funcs.decode = &field_callback;
+ msg->req_limits.int64_min.arg = &g_sentinel;
+ msg->cb_oneof.funcs.decode = &field_callback;
+ msg->cb_oneof.arg = &g_sentinel;
+
+ status = pb_decode(&stream, alltypes_callback_AllTypes_fields, msg);
+
+ if (assert_success)
+ {
+ if (!status) fprintf(stderr, "pb_decode: %s\n", PB_GET_ERROR(&stream));
+ assert(status);
+ }
+
+ pb_release(alltypes_callback_AllTypes_fields, msg);
+ free_with_check(msg);
+ assert(get_alloc_count() == initial_alloc_count);
+
+ return status;
+}
+
/* Do a decode -> encode -> decode -> encode roundtrip */
static void do_roundtrip(const uint8_t *buffer, size_t msglen, size_t structsize, const pb_msgdesc_t *msgtype)
{
@@ -183,6 +228,9 @@
/* Test successful decoding also when using a stream */
do_stream_decode(data, size, SIZE_MAX, sizeof(alltypes_static_AllTypes), alltypes_static_AllTypes_fields, true);
do_stream_decode(data, size, SIZE_MAX, sizeof(alltypes_proto3_static_AllTypes), alltypes_proto3_static_AllTypes_fields, true);
+
+ /* Test callbacks */
+ do_callback_decode(data, size, true);
}
else if (do_decode(data, size, sizeof(alltypes_proto3_static_AllTypes), alltypes_proto3_static_AllTypes_fields, 0, expect_valid))
{
@@ -215,6 +263,9 @@
do_decode(data, size, sizeof(alltypes_static_AllTypes), alltypes_static_AllTypes_fields, PB_DECODE_DELIMITED, false);
do_decode(data, size, sizeof(alltypes_static_AllTypes), alltypes_static_AllTypes_fields, PB_DECODE_NULLTERMINATED, false);
+ /* Test callbacks also when message is not valid */
+ do_callback_decode(data, size, false);
+
assert(get_alloc_count() == initial_alloc_count);
}