oss-fuzz: add fuzzer for parsing reftables

Add a new fuzzer that exercises our parsing of reftables. Fallout from this fuzzer will be fixed over subsequent commits. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jul 3, 2026 at 14:58 UTC adf45165e65beb4bc5c291b8debfcc3ed967aeb8
5 files changed +78
Makefile
+1
@@ -2603,6 +2603,7 @@ FUZZ_OBJS += oss-fuzz/fuzz-date.o
2603 FUZZ_OBJS += oss-fuzz/fuzz-pack-headers.o
2604 FUZZ_OBJS += oss-fuzz/fuzz-pack-idx.o
2605 FUZZ_OBJS += oss-fuzz/fuzz-parse-attr-line.o
2606 +FUZZ_OBJS += oss-fuzz/fuzz-reftable.o
2607 FUZZ_OBJS += oss-fuzz/fuzz-url-decode-mem.o
2608 .PHONY: fuzz-objs
2609 fuzz-objs: $(FUZZ_OBJS)
ci/run-build-and-minimal-fuzzers.sh
+1
@@ -21,6 +21,7 @@ date
21 pack-headers
22 pack-idx
23 parse-attr-line
24 +reftable
25 url-decode-mem
26 "
27
oss-fuzz/.gitignore
+1
@@ -5,4 +5,5 @@ fuzz-date
5 fuzz-pack-headers
6 fuzz-pack-idx
7 fuzz-parse-attr-line
8 +fuzz-reftable
9 fuzz-url-decode-mem
oss-fuzz/fuzz-reftable.c new
+74
@@ -0,0 +1,74 @@
1 +#include "git-compat-util.h"
2 +#include "reftable/basics.h"
3 +#include "reftable/blocksource.h"
4 +#include "reftable/reftable-blocksource.h"
5 +#include "reftable/reftable-error.h"
6 +#include "reftable/reftable-iterator.h"
7 +#include "reftable/reftable-record.h"
8 +#include "reftable/reftable-table.h"
9 +#include "reftable/reftable-writer.h"
10 +
11 +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
12 +
13 +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
14 +{
15 + struct reftable_block_source source = { 0 };
16 + struct reftable_buf buf = REFTABLE_BUF_INIT;
17 + struct reftable_table *table = NULL;
18 + int err;
19 +
20 + if (reftable_buf_add(&buf, (const char *)data, size) < 0)
21 + goto out;
22 + block_source_from_buf(&source, &buf);
23 +
24 + err = reftable_table_new(&table, &source, "fuzz-input");
25 + if (err < 0)
26 + goto out;
27 +
28 + /*
29 + * Exercise the ref, log and raw block iterators so that we cover as
30 + * much of the parsing code as possible.
31 + */
32 + {
33 + struct reftable_ref_record ref = { 0 };
34 + struct reftable_iterator it = { 0 };
35 +
36 + reftable_table_init_ref_iterator(table, &it);
37 + if (!reftable_iterator_seek_ref(&it, ""))
38 + while (!reftable_iterator_next_ref(&it, &ref))
39 + ;
40 +
41 + reftable_ref_record_release(&ref);
42 + reftable_iterator_destroy(&it);
43 + }
44 +
45 + {
46 + struct reftable_log_record log = { 0 };
47 + struct reftable_iterator it = { 0 };
48 +
49 + reftable_table_init_log_iterator(table, &it);
50 + if (!reftable_iterator_seek_log(&it, ""))
51 + while (!reftable_iterator_next_log(&it, &log))
52 + ;
53 +
54 + reftable_log_record_release(&log);
55 + reftable_iterator_destroy(&it);
56 + }
57 +
58 + {
59 + struct reftable_table_iterator it = { 0 };
60 + const struct reftable_block *block;
61 +
62 + if (!reftable_table_iterator_init(&it, table))
63 + while (!reftable_table_iterator_next(&it, &block))
64 + ;
65 +
66 + reftable_table_iterator_release(&it);
67 + }
68 +
69 +out:
70 + if (table)
71 + reftable_table_decref(table);
72 + reftable_buf_release(&buf);
73 + return 0;
74 +}
oss-fuzz/meson.build
+1
@@ -6,6 +6,7 @@ fuzz_programs = [
6 'fuzz-pack-headers.c',
7 'fuzz-pack-idx.c',
8 'fuzz-parse-attr-line.c',
9 + 'fuzz-reftable.c',
10 'fuzz-url-decode-mem.c',
11 ]
12