Skip to content

Commit

Permalink
Merge pull request #789 from cppalliance/fuzzing
Browse files Browse the repository at this point in the history
Improved Fuzzing
  • Loading branch information
mborland authored Jan 15, 2025
2 parents 113de3d + b978857 commit 5fdab9f
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 25 deletions.
63 changes: 38 additions & 25 deletions fuzzing/Jamfile
Original file line number Diff line number Diff line change
@@ -1,27 +1,50 @@
#
# Copyright (c) 2019-2023 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
# Copyright (c) 2024 Matt Borland
# Copyright (c) 2025 Alexander Grund
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt.


import common ;
import path ;
import python ;
import regex ;
import toolset ;

path-constant HERE : . ;

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

if ! [ python.configured ]
{
using python ;
}

.make-corpus-script = $(HERE)/make-corpus.py ;

rule make-corpus ( target : sources + : properties * )
{
RUNNER on $(target) = [ path.native $(.make-corpus-script) ] ;
}
actions make-corpus
{
"$(PYTHON:E=python)" "$(RUNNER)" $(<) $(>)
}
toolset.flags $(__name__).make-corpus PYTHON <python.interpreter> ;

for local fuzzer in $(all_fuzzers)
{
# These two fuzzers are the most complex ones. The rest are really
# simple, so less time is enough
local fuzz_time = 30 ;
local fuzz_time = 60 ;
local corpus = /tmp/corpus/$(fuzzer) ;
local min_corpus = /tmp/mincorpus/$(fuzzer) ;
local seed_corpus = $(HERE)/seedcorpus/$(fuzzer) ;
local seed_files = [ glob "$(seed_corpus)/*" ] ;

# Create the output corpus directories
make /tmp/corpus/$(fuzzer) : : common.MkDir ;
make /tmp/mincorpus/$(fuzzer) : : common.MkDir ;
make $(corpus) : $(seed_files) : make-corpus ;
make $(min_corpus) : : common.MkDir ;

# Build the fuzzer
exe $(fuzzer)
Expand All @@ -36,31 +59,21 @@ for local fuzzer in $(all_fuzzers)
<linkflags>-fsanitize=fuzzer
;

# Make sure that any old crashes are run without problems
local old_crashes = [ glob-tree-ex old_crashes/$(fuzzer) : * ] ;
if $(old_crashes)
{
run $(fuzzer)
: target-name $(fuzzer)-old-crashes
: input-files [ SORT $(old_crashes) ]
;
}

# Run the fuzzer for a short while
run $(fuzzer)
: <testing.arg>"seedcorpus/$(fuzzer) -max_total_time=$(fuzz_time)"
: <testing.arg>"$(corpus) -max_total_time=$(fuzz_time)"
: target-name $(fuzzer)-fuzzing
: requirements
<dependency>/tmp/corpus/$(fuzzer)
<dependency>$(corpus)
;

# Minimize the corpus
run $(fuzzer)
: <testing.arg>"/tmp/mincorpus/$(fuzzer) /tmp/corpus/$(fuzzer) -merge=1"
: <testing.arg>"$(min_corpus) $(corpus) -merge=1"
: target-name $(fuzzer)-minimize-corpus
: requirements
<dependency>$(fuzzer)-fuzzing
<dependency>/tmp/corpus/$(fuzzer)
<dependency>/tmp/mincorpus/$(fuzzer)
<dependency>$(corpus)
<dependency>$(min_corpus)
;
}
32 changes: 32 additions & 0 deletions fuzzing/make-corpus.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/env python

# Copyright (c) 2025 Alexander Grund
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt.

import os
import sys

def get_samples(input_files):
for file_name in input_files:
if not os.path.isfile(file_name):
raise RuntimeError("Not a file: " + file_name)
with open(file_name, 'r') as input_file:
yield from input_file


def process_files(output_folder, input_files):
if not os.path.exists(output_folder):
os.makedirs(output_folder)

for i, sample in enumerate(get_samples(input_files)):
with open(os.path.join(output_folder, str(i) + ".txt"), 'w') as output_file:
output_file.write(sample)


if __name__ == "__main__":
if len(sys.argv) < 3:
print("Usage: python script.py <output_folder> <input_file1> [<input_file2> ...]")
sys.exit(1)

process_files(output_folder=sys.argv[1], input_files=sys.argv[2:])

0 comments on commit 5fdab9f

Please sign in to comment.