]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/libs/json/fuzzing/fuzz_parser.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / json / fuzzing / fuzz_parser.cpp
diff --git a/ceph/src/boost/libs/json/fuzzing/fuzz_parser.cpp b/ceph/src/boost/libs/json/fuzzing/fuzz_parser.cpp
new file mode 100644 (file)
index 0000000..d6598db
--- /dev/null
@@ -0,0 +1,139 @@
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+// Copyright (c) 2020 Paul Dreik (github@pauldreik.se)
+//
+// 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
+//
+
+#include <boost/json/parse_options.hpp>
+#include <boost/json/serialize.hpp>
+#include <boost/json/stream_parser.hpp>
+#include <boost/json/monotonic_resource.hpp>
+#include <boost/json/null_resource.hpp>
+#include <boost/json/static_resource.hpp>
+#include <memory>
+
+using namespace boost::json;
+
+struct FuzzHelper {
+    parse_options opt;
+    string_view jsontext;
+    std::size_t memlimit1;
+    std::size_t memlimit2;
+    bool res;
+    void run(stream_parser& p) {
+        error_code ec;
+
+        // Write the first part of the buffer
+        p.write( jsontext, ec);
+
+        if(! ec)
+            p.finish( ec );
+
+        // Take ownership of the resulting value.
+        if(! ec)
+        {
+            value jv = p.release();
+            res=serialize(jv).size()==42;
+        } else
+            res=false;
+    }
+
+    // easy case - everything default
+    void useDefault() {
+        stream_parser p(storage_ptr{}, opt);
+        run(p);
+    }
+
+    void useMonotonic() {
+        monotonic_resource mr;
+        stream_parser p(storage_ptr{}, opt);
+        p.reset( &mr );
+
+        run(p);
+    }
+
+    void useLocalBuffer() {
+        std::unique_ptr<unsigned char[]> temp(new unsigned char[memlimit1]);
+        stream_parser p(
+                    storage_ptr(),
+                    opt,
+                    temp.get(),
+                    memlimit1);
+        run(p);
+    }
+
+    void useDynLess() {
+        // this is on the heap because the size is chosen dynamically
+        std::unique_ptr<unsigned char[]> temp(new unsigned char[memlimit1]);
+        stream_parser p(get_null_resource(),
+                 opt,
+                 temp.get(),
+                 memlimit1);
+
+        // this is on the heap because the size is chosen dynamically
+        std::unique_ptr<unsigned char[]> buf(new unsigned char[memlimit2]);
+        static_resource mr2( buf.get(), memlimit2 );
+        p.reset( &mr2 );
+
+        run(p);
+    }
+
+};
+
+
+extern "C"
+int
+LLVMFuzzerTestOneInput(
+        const uint8_t* data, size_t size)
+{
+    if(size<=5)
+        return 0;
+
+    FuzzHelper fh;
+
+    // set parse options
+    fh.opt.allow_comments=!!(data[0]&0x1);
+    fh.opt.allow_trailing_commas=!!(data[0]&0x2);
+    fh.opt.allow_invalid_utf8=!!(data[0]&0x4);
+    fh.opt.max_depth= (data[0]>>3);
+
+    // select memory strategy to use
+    const int strategy=data[1] & 0x3;
+
+    // memory limits
+    fh.memlimit1=data[2]*256+data[3];
+    fh.memlimit2=data[4]*256+data[5];
+
+    data+=6;
+    size-=6;
+
+    //set the json string to parse
+    fh.jsontext=string_view{
+            reinterpret_cast<const char*>(
+                data), size};
+    try
+    {
+        switch(strategy) {
+        case 0:
+            fh.useDefault();
+            break;
+        case 1:
+            fh.useDefault();
+            break;
+        case 2:
+            fh.useLocalBuffer();
+            break;
+        case 3:
+            fh.useDynLess();
+            break;
+        }
+    }
+    catch(...)
+    {
+    }
+    return 0;
+}
+