diff options
Diffstat (limited to 'src/lib-imap/fuzz-imap-bodystructure.c')
-rw-r--r-- | src/lib-imap/fuzz-imap-bodystructure.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/lib-imap/fuzz-imap-bodystructure.c b/src/lib-imap/fuzz-imap-bodystructure.c new file mode 100644 index 0000000..a9d4499 --- /dev/null +++ b/src/lib-imap/fuzz-imap-bodystructure.c @@ -0,0 +1,52 @@ +/* Copyright (c) 2020 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "str.h" +#include "fuzzer.h" +#include "imap-bodystructure.c" +#include <ctype.h> + +static const char *str_sanitize_binary(const char *input) +{ + string_t *dest = t_str_new(strlen(input)); + for (;*input != '\0';input++) { + if (i_isprint(*input) == 0) + str_printfa(dest, "<%02x>", (unsigned char)*input); + else + str_append_c(dest, *input); + } + return str_c(dest); +} + +FUZZ_BEGIN_STR(const char *str) +{ + pool_t pool = + pool_alloconly_create(MEMPOOL_GROWING"fuzz bodystructure", 1024); + struct message_part parts; + string_t *dest = str_new(pool, 32); + const char *error ATTR_UNUSED; + i_zero(&parts); + + if (imap_bodystructure_parse(str, pool, &parts, &error) == 0) { + if (imap_bodystructure_write(&parts, dest, TRUE, &error) < 0) + i_panic("Failed to write bodystructure: %s", error); + /* The written bodystructure must be parseable *and* + it must come out exactly the same again */ + if (imap_bodystructure_parse(str_c(dest), pool, &parts, &error) != 0) { + i_panic("Failed to reparse bodystructure '%s'", + str_sanitize_binary(str_c(dest))); + } else { + const char *new_str = t_strdup(str_c(dest)); + str_truncate(dest, 0); + if (imap_bodystructure_write(&parts, dest, TRUE, &error) < 0) + i_panic("Failed to write reparsed bodystructure: %s", error); + if (strcmp(str_c(dest), new_str) != 0) { + i_panic("Parsed bodystructure '%s' does not match '%s'", + str_sanitize_binary(new_str), + str_sanitize_binary(str_c(dest))); + } + } + } + pool_unref(&pool); +} +FUZZ_END |