fuzz_programs =
if USE_FUZZER
-fuzz_programs += fuzz-message-parser
+fuzz_programs += fuzz-message-parser \
+ fuzz-qp-decoder \
+ fuzz-message-date \
+ fuzz-message-decoder
nodist_EXTRA_fuzz_message_parser_SOURCES = force-cxx-linking.cxx
fuzz_message_parser_LDADD = $(test_libs)
fuzz_message_parser_DEPENDENCIES = $(test_deps)
+nodist_EXTRA_fuzz_qp_decoder_SOURCES = force-cxx-linking.cxx
+
+fuzz_qp_decoder_CPPFLAGS = $(FUZZER_CPPFLAGS)
+fuzz_qp_decoder_LDFLAGS = $(FUZZER_LDFLAGS)
+fuzz_qp_decoder_SOURCES = fuzz-qp-decoder.c
+fuzz_qp_decoder_LDADD = $(test_libs)
+fuzz_qp_decoder_DEPENDENCIES = $(test_deps)
+
+nodist_EXTRA_fuzz_message_date_SOURCES = force-cxx-linking.cxx
+
+fuzz_message_date_CPPFLAGS = $(FUZZER_CPPFLAGS)
+fuzz_message_date_LDFLAGS = $(FUZZER_LDFLAGS)
+fuzz_message_date_SOURCES = fuzz-message-date.c
+fuzz_message_date_LDADD = $(test_libs)
+fuzz_message_date_DEPENDENCIES = $(test_deps)
+
+nodist_EXTRA_fuzz_message_decoder_SOURCES = force-cxx-linking.cxx
+
+fuzz_message_decoder_CPPFLAGS = $(FUZZER_CPPFLAGS)
+fuzz_message_decoder_LDFLAGS = $(FUZZER_LDFLAGS)
+fuzz_message_decoder_SOURCES = fuzz-message-decoder.c
+fuzz_message_decoder_LDADD = $(test_libs)
+fuzz_message_decoder_DEPENDENCIES = $(test_deps)
+
endif
noinst_PROGRAMS += $(fuzz_programs)
--- /dev/null
+/* Copyright (c) 2025 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "fuzzer.h"
+#include "message-date.h"
+
+FUZZ_BEGIN_DATA(const unsigned char *data, size_t size)
+{
+ time_t t ATTR_UNUSED;
+ int tz ATTR_UNUSED;
+ (void)message_date_parse(data, size, &t, &tz);
+}
+FUZZ_END
--- /dev/null
+/* Copyright (c) 2025 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "istream.h"
+#include "test-common.h"
+#include "fuzzer.h"
+#include "message-parser.h"
+#include "message-decoder.h"
+
+FUZZ_BEGIN_DATA(const unsigned char *data, size_t size)
+{
+ struct istream *input = test_istream_create_data(data, size);
+ const struct message_parser_settings set = {
+ .hdr_flags = 0,
+ .flags = MESSAGE_PARSER_FLAG_INCLUDE_MULTIPART_BLOCKS,
+ .max_nested_mime_parts = 0,
+ .max_total_mime_parts = 0,
+ };
+ struct message_parser_ctx *ctx =
+ message_parser_init(pool_datastack_create(), input, &set);
+ struct message_block block, block_normalized;
+ struct message_decoder_context *dctx =
+ message_decoder_init(uni_utf8_write_nfc, 0);
+
+ while (message_parser_parse_next_block(ctx, &block) > -1)
+ message_decoder_decode_next_block(dctx, &block, &block_normalized);
+
+ struct message_part *part ATTR_UNUSED;
+ message_decoder_deinit(&dctx);
+ message_parser_deinit(&ctx, &part);
+ i_stream_unref(&input);
+}
+FUZZ_END
--- /dev/null
+/* Copyright (c) 2025 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "fuzzer.h"
+#include "buffer.h"
+#include "qp-decoder.h"
+
+FUZZ_BEGIN_DATA(const unsigned char *data, size_t size)
+{
+ const char *error ATTR_UNUSED;
+ size_t invalid_src_pos ATTR_UNUSED;
+
+ buffer_t *buf = buffer_create_dynamic(default_pool, size);
+ struct qp_decoder *decoder = qp_decoder_init(buf);
+
+ (void)qp_decoder_more(decoder, data, size, &invalid_src_pos, &error);
+
+ qp_decoder_finish(decoder, &error);
+ qp_decoder_deinit(&decoder);
+ buffer_free(&buf);
+}
+FUZZ_END