Make fuzz test also check under low memory conditions.
diff --git a/tests/common/malloc_wrappers.c b/tests/common/malloc_wrappers.c
index a5b7fe6..2cfde9d 100644
--- a/tests/common/malloc_wrappers.c
+++ b/tests/common/malloc_wrappers.c
@@ -14,8 +14,8 @@
#define CHECK1 ((size_t)0xDEADBEEF)
#define CHECK2 ((size_t)0x600DCAFE)
-#ifndef MAX_REALLOC_SIZE
-#define MAX_REALLOC_SIZE 1024*1024
+#ifndef MAX_ALLOC_BYTES
+#define MAX_ALLOC_BYTES 16*1024*1024
#endif
#ifndef DEBUG_MALLOC
@@ -23,18 +23,26 @@
#endif
static size_t g_alloc_count = 0;
-static size_t g_max_realloc_size = MAX_REALLOC_SIZE;
+static size_t g_alloc_bytes = 0;
+static size_t g_max_alloc_bytes = MAX_ALLOC_BYTES;
/* Allocate memory and place check values before and after. */
void* malloc_with_check(size_t size)
{
- char *buf = malloc(size + GUARD_SIZE);
+ char *buf = NULL;
+
+ if (g_alloc_bytes + size <= g_max_alloc_bytes)
+ {
+ buf = malloc(size + GUARD_SIZE);
+ }
+
if (buf)
{
((size_t*)buf)[0] = size;
((size_t*)buf)[1] = CHECK1;
((size_t*)(buf + size))[2] = CHECK2;
g_alloc_count++;
+ g_alloc_bytes += size;
if (DEBUG_MALLOC) fprintf(stderr, "Alloc 0x%04x/%u\n", (unsigned)(uintptr_t)(buf + PREFIX_SIZE), (unsigned)size);
return buf + PREFIX_SIZE;
}
@@ -56,7 +64,9 @@
assert(((size_t*)buf)[1] == CHECK1);
assert(((size_t*)(buf + size))[2] == CHECK2);
assert(g_alloc_count > 0);
+ assert(g_alloc_bytes >= size);
g_alloc_count--;
+ g_alloc_bytes -= size;
free(buf);
}
}
@@ -64,10 +74,6 @@
/* Reallocate block and check / write guard values */
void* realloc_with_check(void *ptr, size_t size)
{
- /* Don't allocate crazy amounts of RAM when fuzzing */
- if (size > g_max_realloc_size)
- return NULL;
-
if (!ptr && size)
{
/* Allocate new block and write guard values */
@@ -81,8 +87,17 @@
assert(((size_t*)buf)[1] == CHECK1);
assert(((size_t*)(buf + oldsize))[2] == CHECK2);
assert(g_alloc_count > 0);
+ assert(g_alloc_bytes >= oldsize);
- buf = realloc(buf, size + GUARD_SIZE);
+ if (g_alloc_bytes - oldsize + size <= g_max_alloc_bytes)
+ {
+ buf = realloc(buf, size + GUARD_SIZE);
+ }
+ else
+ {
+ buf = NULL;
+ }
+
if (!buf)
{
if (DEBUG_MALLOC) fprintf(stderr, "Realloc 0x%04x/%u to %u failed\n", (unsigned)(uintptr_t)ptr, (unsigned)oldsize, (unsigned)size);
@@ -92,6 +107,8 @@
((size_t*)buf)[0] = size;
((size_t*)buf)[1] = CHECK1;
((size_t*)(buf + size))[2] = CHECK2;
+ g_alloc_bytes -= oldsize;
+ g_alloc_bytes += size;
if (DEBUG_MALLOC) fprintf(stderr, "Realloc 0x%04x/%u to 0x%04x/%u\n", (unsigned)(uintptr_t)ptr, (unsigned)oldsize, (unsigned)(uintptr_t)(buf + PREFIX_SIZE), (unsigned)size);
return buf + PREFIX_SIZE;
@@ -122,9 +139,19 @@
return ((size_t*)buf)[0];
}
-/* Set limit for allocation size */
-void set_max_realloc_size(size_t max_size)
+/* Get total number of allocated bytes */
+size_t get_alloc_bytes()
{
- g_max_realloc_size = max_size;
+ return g_alloc_bytes;
}
+/* Set limit for allocation size */
+void set_max_alloc_bytes(size_t max_bytes)
+{
+ g_max_alloc_bytes = max_bytes;
+}
+
+size_t get_max_alloc_bytes()
+{
+ return g_max_alloc_bytes;
+}
diff --git a/tests/common/malloc_wrappers.h b/tests/common/malloc_wrappers.h
index b8c27ec..d6bc6c1 100644
--- a/tests/common/malloc_wrappers.h
+++ b/tests/common/malloc_wrappers.h
@@ -5,4 +5,6 @@
void* realloc_with_check(void *ptr, size_t size);
size_t get_alloc_count();
size_t get_allocation_size(const void *mem);
-void set_max_realloc_size(size_t max_size);
+size_t get_alloc_bytes();
+void set_max_alloc_bytes(size_t max_bytes);
+size_t get_max_alloc_bytes();
diff --git a/tests/fuzztest/fuzztest.c b/tests/fuzztest/fuzztest.c
index 4de793d..b65464b 100644
--- a/tests/fuzztest/fuzztest.c
+++ b/tests/fuzztest/fuzztest.c
@@ -255,6 +255,7 @@
void do_roundtrips(const uint8_t *data, size_t size, bool expect_valid)
{
size_t initial_alloc_count = get_alloc_count();
+ size_t orig_max_alloc_bytes = get_max_alloc_bytes();
/* Check decoding as static fields */
if (do_decode(data, size, sizeof(alltypes_static_AllTypes), alltypes_static_AllTypes_fields, 0, expect_valid))
@@ -290,6 +291,12 @@
do_roundtrip(data, size, sizeof(alltypes_proto3_pointer_AllTypes), alltypes_proto3_pointer_AllTypes_fields);
}
+ /* Test decoding when memory size is limited */
+ set_max_alloc_bytes(get_alloc_bytes() + 1024);
+ do_decode(data, size, sizeof(alltypes_pointer_AllTypes), alltypes_pointer_AllTypes_fields, 0, false);
+ do_decode(data, size, sizeof(alltypes_proto3_pointer_AllTypes), alltypes_proto3_pointer_AllTypes_fields, 0, false);
+ set_max_alloc_bytes(orig_max_alloc_bytes);
+
/* Test decoding on a failing stream */
do_stream_decode(data, size, size - 16, sizeof(alltypes_static_AllTypes), alltypes_static_AllTypes_fields, false);
do_stream_decode(data, size, size - 16, sizeof(alltypes_proto3_static_AllTypes), alltypes_proto3_static_AllTypes_fields, false);
diff --git a/tests/site_scons/platforms/avr/avr.py b/tests/site_scons/platforms/avr/avr.py
index dbf7627..6272983 100644
--- a/tests/site_scons/platforms/avr/avr.py
+++ b/tests/site_scons/platforms/avr/avr.py
@@ -12,8 +12,7 @@
env.Append(CFLAGS = "-mmcu=atmega1284 -Dmain=app_main -Os")
env.Append(CXXFLAGS = "-mmcu=atmega1284 -Dmain=app_main -Os -Wno-type-limits")
env.Append(CPPDEFINES = {'PB_CONVERT_DOUBLE_FLOAT': 1, 'UNITTESTS_SHORT_MSGS': 1,
- '__ASSERT_USE_STDERR': 1, 'MAX_REALLOC_SIZE': '4096',
- 'FUZZTEST_BUFSIZE': 2048})
+ '__ASSERT_USE_STDERR': 1, 'FUZZTEST_BUFSIZE': 2048})
env.Append(LINKFLAGS = "-mmcu=atmega1284")
env.Append(LINKFLAGS = "-Wl,-Map,build/avr.map")