From 3ca0253c10cddad0a713fc7b62779776cb8616ae Mon Sep 17 00:00:00 2001 From: Arthur Chan Date: Tue, 29 Sep 2026 21:13:29 +0800 Subject: [PATCH] OSS-Fuzz: Add new fuzzer targets peg processing (#1890) Signed-off-by: Arthur Chan --- test/fuzzers/fuzz_peg.c | 51 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 test/fuzzers/fuzz_peg.c diff --git a/test/fuzzers/fuzz_peg.c b/test/fuzzers/fuzz_peg.c new file mode 100644 index 00000000..b55ccefb --- /dev/null +++ b/test/fuzzers/fuzz_peg.c @@ -0,0 +1,51 @@ +#include +#include +#include + +#define JANET_PEG_FUZZ_MAX_INPUT (1U << 20) + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (size < 2 || size > JANET_PEG_FUZZ_MAX_INPUT) + return 0; + + /* Byte 0 selects the split point for a Janet PEG pattern and subject. */ + size_t patlen = (size_t)data[0] % (size - 1); + const uint8_t *patsrc = data + 1; + const uint8_t *text = data + 1 + patlen; + size_t textlen = size - 1 - patlen; + + janet_init(); + + JanetParser parser; + janet_parser_init(&parser); + Janet matchfn = janet_resolve_core("peg/match"); + if (janet_checktype(matchfn, JANET_CFUNCTION)) { + JanetCFunction cfun = janet_unwrap_cfunction(matchfn); + + /* Stop after parser errors: consuming again would panic. */ + for (size_t i = 0; i < patlen; i++) { + janet_parser_consume(&parser, patsrc[i]); + if (janet_parser_status(&parser) == JANET_PARSE_ERROR) + break; + } + if (janet_parser_status(&parser) != JANET_PARSE_ERROR) + janet_parser_eof(&parser); + + if (janet_parser_status(&parser) != JANET_PARSE_ERROR && + janet_parser_has_more(&parser)) { + Janet pattern = janet_parser_produce(&parser); + JanetTryState tstate; + if (janet_try(&tstate) == JANET_SIGNAL_OK) { + Janet argv[2]; + argv[0] = pattern; + argv[1] = janet_stringv(text, (int32_t)textlen); + cfun(2, argv); + } + janet_restore(&tstate); + } + } + + janet_parser_deinit(&parser); + janet_deinit(); + return 0; +}