Coverage Report

Created: 2026-10-17 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}