]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/libs/json/fuzzing/Jamfile
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / json / fuzzing / Jamfile
index bbc43ef1e55f54aa0d47f3e074c7bbc89d7bff17..983612d3f0c2c8fec88dee0a78413ede15a58d34 100644 (file)
@@ -1,5 +1,7 @@
 #
 # Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+# Copyright (c) 2019 Paul Dreik
+# Copyright (c) 2021 Dmitry Arkhipov (grisumbras@gmail.com)
 #
 # 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)
 # Official repository: https://github.com/boostorg/json
 #
 
+
+import common ;
+import link ;
 import os ;
+import path ;
+import property ;
+import sequence ;
+
+
+# set the maximum size of the input, to avoid
+# big inputs which blow up the corpus size
+.MAXLEN = [ os.environ MAXLEN ] ;
+.MAXLEN ?= -max_len=4000 ;
+
+# set a timelimit (you may want to adjust this if you run locally)
+.MAXTIME = [ os.environ MAXTIME  ] ;
+.MAXTIME ?= -max_total_time=30 ;
+
+# If doing fuzzing locally (not in CI), adjust this to utilize more
+# of your cpu.
+#JOBS="-jobs=32"
+.JOBS = [ os.environ JOBS ] ;
 
-STANDALONE = [ os.environ STANDALONE ] ;
-if $(STANDALONE)
+# make sure ubsan stops in case anything is found
+.UBSAN_OPTIONS = [
+    common.variable-setting-command UBSAN_OPTIONS : halt_on_error=1
+] ;
+
+local corpus.tar = [ glob-ex . : corpus.tar ] ;
+if $(corpus.tar)
 {
-    LIB =
-        <define>BOOST_JSON_STANDALONE=1
-        <source>../src/src.cpp
+    # if an old corpus exists, use it
+    # get it with curl -O --location -J https://bintray.com/pauldreik/boost.json/download_file?file_path=corpus%2Fcorpus.tar
+    make old-corpus
+        : $(corpus.tar)
+        : @untar-corpus
+        : <location>oldcorpus
         ;
 }
 else
 {
-    LIB = <library>/boost/json//boost_json ;
+    alias old-corpus ;
 }
+explicit old-corpus ;
+
+
+local initial-corpus = [ glob-tree-ex ../test : *.json ] ;
 
-# See the comments in CMakeLists.txt for why
-# these are libraries and not exe targets.
-lib fuzzerlib_basic_parser :
-    fuzz_basic_parser.cpp
-    : :
-    $(LIB)
-    ;
 
+local variants = basic_parser parse parser ;
+for local variant in basic_parser parse parser
+{
+    local $(variant)-runs ;
+    local fuzzer = fuzzer_$(variant) ;
+    lib $(fuzzer) : fuzz_$(variant).cpp /boost/json//boost_json ;
+    exe $(fuzzer)
+        : fuzz_$(variant).cpp /boost/json//json_sources
+        : requirements
+          <toolset>clang
+          <conditional>@fuzzer-props
+        ;
+
+    # make sure the old crashes pass without problems
+    local old-runs = [ glob-tree-ex old_crashes/$(variant) : * ] ;
+    if $(old-runs)
+    {
+        run $(fuzzer)
+            : target-name $(variant)-run-crashes
+            : input-files [ SORT $(old-runs) ]
+            ;
+        $(variant)-runs += $(variant)-run-crashes ;
+    }
+
+    make oldcorpus/$(variant)
+        : old-corpus
+        : common.MkDir
+        : <location>.
+        ;
+    explicit oldcorpus/$(variant) ;
+
+    # make an initial corpus from the test data already in the repo
+    local seed-corpus ;
+    for file in $(initial-corpus)
+    {
+        local copied = $(variant)/$(file:D=) ;
+        make $(copied) : $(file) : common.copy : <location>seedcorpus ;
+        explicit $(copied) ;
+        seed-corpus += $(copied) ;
+    }
+    make seedcorpus/$(variant)
+        : $(seed-corpus)
+        : common.MkDir
+        : <location>.
+        ;
+    explicit seedcorpus/$(variant) ;
+
+    # run the fuzzer for a short while
+    make out/$(variant)
+        : $(fuzzer)
+          oldcorpus/$(variant)
+          seedcorpus/$(variant)
+        : @run-fuzzer
+        : <location>.
+          <flags>$(.MAXTIME)
+          <flags>$(.MAXLEN)
+          <flags>$(.JOBS)
+        ;
+    $(variant)-runs += out/$(variant) ;
+
+    # minimize the corpus
+    make cmin/$(variant)
+        : $(fuzzer)
+          oldcorpus/$(variant)
+          out/$(variant)
+        : @run-fuzzer
+        : <location>.
+          <flags>-merge=1
+          <flags>$(.MAXLEN)
+        ;
+    $(variant)-runs += cmin/$(variant) ;
+
+    alias $(variant)-run : $($(variant)-runs) ;
+    explicit $($(variant)-runs) ;
+}
+
+alias run : $(variants)-run ;
+explicit run $(variants)-run ;
+
+
+rule fuzzer-props ( props * )
+{
+    local toolset = [ property.select toolset : $(props) ] ;
+    if clang = $(toolset:G=)
+    {
+        return
+          <debug-symbols>on
+          <optimization>speed
+          <address-sanitizer>on
+          <undefined-sanitizer>norecover
+          <cxxflags>-fsanitize=fuzzer
+          <linkflags>-fsanitize=fuzzer
+          # explicitly set BOOST_JSON_STACK_BUFFER_SIZE small so interesting
+          # code paths are taken also for small inputs
+          # (see https://github.com/CPPAlliance/json/issues/333)
+          <define>BOOST_JSON_STACK_BUFFER_SIZE=64
+          ;
+    }
+    else
+    {
+        return <build>no ;
+    }
+}
+
+
+rule run-fuzzer ( target : sources * : props * )
+{
+    local flags = [ property.select flags : $(props) ] ;
+    FLAGS on $(target) = $(flags:G=) ;
+
+    local dir = [ path.make [ on $(target) return $(LOCATE) ] ] ;
+    dir = $(dir)/$(target:G=) ;
+    common.MkDir $(dir) ;
+    DEPENDS $(target) : $(dir) ;
+}
+
+actions run-fuzzer
+{
+    $(.UBSAN_OPTIONS)
+    $(>[1]) $(<) $(>[2]) $(>[3]) $(FLAGS)
+}
+
+.TOUCH_FILE = [ common.file-touch-command ] ;
+actions untar-corpus
+{
+    tar xf $(>) -C $(<:D)
+    $(.TOUCH_FILE) $(<)
+}