/src/spicy/ci/fuzz/fuzz.cc
Line | Count | Source |
1 | | // Copyright (c) 2020-now by the Zeek Project. See LICENSE for details. |
2 | | |
3 | | #include <cassert> |
4 | | #include <cstddef> |
5 | | #include <cstdint> |
6 | | #include <cstdlib> |
7 | | #include <iostream> |
8 | | |
9 | | #include <hilti/rt/exception.h> |
10 | | #include <hilti/rt/init.h> |
11 | | #include <hilti/rt/types/reference.h> |
12 | | #include <hilti/rt/types/stream.h> |
13 | | #include <hilti/rt/util.h> |
14 | | |
15 | | #include <spicy/rt/init.h> |
16 | | #include <spicy/rt/parsed-unit.h> |
17 | | #include <spicy/rt/parser.h> |
18 | | |
19 | | #ifndef SPICY_FUZZ_PARSER |
20 | | #error "SPICY_FUZZ_PARSER needs to be defined" |
21 | | #endif |
22 | | |
23 | 33.3k | extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { |
24 | 33.3k | static const spicy::rt::Parser* parser = nullptr; |
25 | | |
26 | 33.3k | if ( ! parser ) { |
27 | 9 | hilti::rt::init(); |
28 | 9 | spicy::rt::init(); |
29 | | |
30 | 13 | for ( auto* p : spicy::rt::parsers() ) { |
31 | 13 | parser = p; |
32 | 13 | if ( p->name == SPICY_FUZZ_PARSER ) |
33 | 0 | break; |
34 | 13 | } |
35 | 9 | } |
36 | | |
37 | 33.3k | assert(parser); |
38 | | |
39 | 33.3k | hilti::rt::ValueReference<hilti::rt::Stream> stream; |
40 | 33.3k | stream->append(reinterpret_cast<const char*>(Data), Size); |
41 | | |
42 | 33.3k | hilti::rt::ValueReference<spicy::rt::ParsedUnit> pu; |
43 | | |
44 | 33.3k | try { |
45 | 33.3k | if ( parser->parse1 ) |
46 | 33.3k | parser->parse1(stream, {}, {}); |
47 | 0 | else if ( parser->parse3 ) |
48 | 0 | parser->parse3(pu, stream, {}, {}); |
49 | 33.3k | } catch ( ... ) { |
50 | 5.45k | } |
51 | | |
52 | 33.3k | return 0; // Non-zero return values are reserved for future use. |
53 | 33.3k | } |
54 | | |
55 | | extern "C" int LLVMFuzzerRunDriver(int* argc, char*** argv, int (*UserCb)(const uint8_t* Data, size_t Size)); |
56 | | |
57 | | // We provide our own `main` to avoid linking to hilti-rt's weak `main` symbol. |
58 | 18 | int main(int argc, char** argv) { LLVMFuzzerRunDriver(&argc, &argv, LLVMFuzzerTestOneInput); } |