/src/yyjson/fuzz/fuzzer.c
Line | Count | Source |
1 | | #include <stdlib.h> |
2 | | #include <string.h> |
3 | | #include <yyjson.h> |
4 | | |
5 | | /* Fuzzer-only allocator cap (not a library limit). |
6 | | OSS-Fuzz kills processes above ~2560MB RSS. Valid deep nesting with |
7 | | pretty-print can expand hugely; return NULL before the process is killed. */ |
8 | | #ifndef YYJSON_FUZZ_ALLOC_LIMIT |
9 | 200k | # define YYJSON_FUZZ_ALLOC_LIMIT (512u * 1024u * 1024u) |
10 | | #endif |
11 | | |
12 | 184k | static void *fuzz_malloc(void *ctx, size_t size) { |
13 | 184k | (void)ctx; |
14 | 184k | if (size > YYJSON_FUZZ_ALLOC_LIMIT) return NULL; |
15 | 184k | return malloc(size); |
16 | 184k | } |
17 | | |
18 | 16.6k | static void *fuzz_realloc(void *ctx, void *ptr, size_t old_size, size_t size) { |
19 | 16.6k | (void)ctx; |
20 | 16.6k | (void)old_size; |
21 | 16.6k | if (size > YYJSON_FUZZ_ALLOC_LIMIT) return NULL; |
22 | 16.5k | return realloc(ptr, size); |
23 | 16.6k | } |
24 | | |
25 | 184k | static void fuzz_free(void *ctx, void *ptr) { |
26 | 184k | (void)ctx; |
27 | 184k | free(ptr); |
28 | 184k | } |
29 | | |
30 | | static const yyjson_alc FUZZ_ALC = { |
31 | | fuzz_malloc, fuzz_realloc, fuzz_free, NULL |
32 | | }; |
33 | | |
34 | | /*----------------------------------------------------------------------------*/ |
35 | | |
36 | | static void test_with_flags(const uint8_t *data, size_t size, |
37 | 61.3k | yyjson_read_flag rflg, yyjson_write_flag wflg) { |
38 | 61.3k | yyjson_doc *idoc = yyjson_read_opts((char *)data, size, rflg, &FUZZ_ALC, NULL); |
39 | 61.3k | yyjson_mut_doc *mdoc = yyjson_doc_mut_copy(idoc, &FUZZ_ALC); |
40 | 61.3k | char *ijson = yyjson_write_opts(idoc, wflg, &FUZZ_ALC, NULL, NULL); |
41 | 61.3k | if (ijson) FUZZ_ALC.free(FUZZ_ALC.ctx, ijson); |
42 | 61.3k | char *mjson = yyjson_mut_write_opts(mdoc, wflg, &FUZZ_ALC, NULL, NULL); |
43 | 61.3k | if (mjson) FUZZ_ALC.free(FUZZ_ALC.ctx, mjson); |
44 | 61.3k | yyjson_doc_free(idoc); |
45 | 61.3k | yyjson_mut_doc_free(mdoc); |
46 | 61.3k | } |
47 | | |
48 | 30.6k | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
49 | 30.6k | test_with_flags(data, size, |
50 | 30.6k | YYJSON_READ_NOFLAG, |
51 | 30.6k | YYJSON_WRITE_NOFLAG); |
52 | 30.6k | test_with_flags(data, size, |
53 | 30.6k | YYJSON_READ_JSON5, |
54 | 30.6k | YYJSON_WRITE_PRETTY | |
55 | 30.6k | YYJSON_WRITE_ESCAPE_UNICODE | |
56 | 30.6k | YYJSON_WRITE_ESCAPE_SLASHES | |
57 | 30.6k | YYJSON_WRITE_ALLOW_INF_AND_NAN); |
58 | 30.6k | return 0; |
59 | 30.6k | } |