Skip to content

Commit a971e00

Browse files
authored
Merge pull request #208 from cppalliance/better_fuzzing
Better fuzzing
2 parents bb585c5 + 3601cac commit a971e00

File tree

2 files changed

+69
-20
lines changed

2 files changed

+69
-20
lines changed

fuzzing/Jamfile

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,52 @@
11
#
22
# Copyright (c) 2019-2023 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
33
# Copyright (c) 2024 Matt Borland
4+
# Copyright (c) 2025 Alexander Grund
45
#
5-
# Distributed under the Boost Software License, Version 1.0. (See accompanying
6-
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
# Distributed under the Boost Software License, Version 1.0.
7+
# https://www.boost.org/LICENSE_1_0.txt.
78
#
89

910
import common ;
11+
import path ;
12+
import python ;
1013
import regex ;
14+
import toolset ;
15+
16+
path-constant HERE : . ;
1117

1218
local all_fuzzers = [ regex.replace-list
1319
[ glob "fuzz_*.cpp" ] : ".cpp" : ""
1420
] ;
1521

22+
if ! [ python.configured ]
23+
{
24+
using python ;
25+
}
26+
27+
.make-corpus-script = $(HERE)/make-corpus.py ;
28+
29+
rule make-corpus ( target : sources + : properties * )
30+
{
31+
RUNNER on $(target) = [ path.native $(.make-corpus-script) ] ;
32+
}
33+
actions make-corpus
34+
{
35+
"$(PYTHON:E=python)" "$(RUNNER)" $(<) $(>)
36+
}
37+
toolset.flags $(__name__).make-corpus PYTHON <python.interpreter> ;
38+
1639
for local fuzzer in $(all_fuzzers)
1740
{
18-
local fuzz_time = 30 ;
41+
local fuzz_time = 60 ;
42+
local corpus = /tmp/corpus/$(fuzzer) ;
43+
local min_corpus = /tmp/mincorpus/$(fuzzer) ;
44+
local seed_corpus = $(HERE)/seedcorpus/$(fuzzer) ;
45+
local seed_files = [ glob "$(seed_corpus)/*" ] ;
1946

2047
# Create the output corpus directories
21-
make /tmp/corpus/$(fuzzer) : : common.MkDir ;
22-
make /tmp/mincorpus/$(fuzzer) : : common.MkDir ;
48+
make $(corpus) : $(seed_files) : make-corpus ;
49+
make $(min_corpus) : : common.MkDir ;
2350

2451
# Build the fuzzer
2552
exe $(fuzzer)
@@ -34,31 +61,21 @@ for local fuzzer in $(all_fuzzers)
3461
<linkflags>-fsanitize=fuzzer
3562
;
3663

37-
# Make sure that any old crashes are run without problems
38-
local old_crashes = [ glob-tree-ex old_crashes/$(fuzzer) : * ] ;
39-
if $(old_crashes)
40-
{
41-
run $(fuzzer)
42-
: target-name $(fuzzer)-old-crashes
43-
: input-files [ SORT $(old_crashes) ]
44-
;
45-
}
46-
4764
# Run the fuzzer for a short while
4865
run $(fuzzer)
49-
: <testing.arg>"seedcorpus/$(fuzzer) -max_total_time=$(fuzz_time)"
66+
: <testing.arg>"$(corpus) -max_total_time=$(fuzz_time)"
5067
: target-name $(fuzzer)-fuzzing
5168
: requirements
52-
<dependency>/tmp/corpus/$(fuzzer)
69+
<dependency>$(corpus)
5370
;
5471

5572
# Minimize the corpus
5673
run $(fuzzer)
57-
: <testing.arg>"/tmp/mincorpus/$(fuzzer) /tmp/corpus/$(fuzzer) -merge=1"
74+
: <testing.arg>"$(min_corpus) $(corpus) -merge=1"
5875
: target-name $(fuzzer)-minimize-corpus
5976
: requirements
6077
<dependency>$(fuzzer)-fuzzing
61-
<dependency>/tmp/corpus/$(fuzzer)
62-
<dependency>/tmp/mincorpus/$(fuzzer)
78+
<dependency>$(corpus)
79+
<dependency>$(min_corpus)
6380
;
6481
}

fuzzing/make-corpus.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/bin/env python
2+
3+
# Copyright (c) 2025 Alexander Grund
4+
# Distributed under the Boost Software License, Version 1.0.
5+
# https://www.boost.org/LICENSE_1_0.txt.
6+
7+
import os
8+
import sys
9+
10+
def get_samples(input_files):
11+
for file_name in input_files:
12+
if not os.path.isfile(file_name):
13+
raise RuntimeError("Not a file: " + file_name)
14+
with open(file_name, 'r') as input_file:
15+
yield from input_file
16+
17+
18+
def process_files(output_folder, input_files):
19+
if not os.path.exists(output_folder):
20+
os.makedirs(output_folder)
21+
22+
for i, sample in enumerate(get_samples(input_files)):
23+
with open(os.path.join(output_folder, str(i) + ".txt"), 'w') as output_file:
24+
output_file.write(sample)
25+
26+
27+
if __name__ == "__main__":
28+
if len(sys.argv) < 3:
29+
print("Usage: python script.py <output_folder> <input_file1> [<input_file2> ...]")
30+
sys.exit(1)
31+
32+
process_files(output_folder=sys.argv[1], input_files=sys.argv[2:])

0 commit comments

Comments
 (0)