mirror of
https://github.com/tristanpenman/valijson.git
synced 2024-12-12 10:13:51 +01:00
Merge pull request #201 from tyler92/improve-fuzzing
Fuzzing improvements
This commit is contained in:
commit
bd1f707f8c
@ -1,43 +1,78 @@
|
|||||||
#include <stdexcept>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <document.h>
|
|
||||||
#include <valijson/adapters/rapidjson_adapter.hpp>
|
#include <valijson/adapters/rapidjson_adapter.hpp>
|
||||||
#include <valijson/utils/rapidjson_utils.hpp>
|
|
||||||
#include <valijson/schema.hpp>
|
|
||||||
#include <valijson/schema_parser.hpp>
|
#include <valijson/schema_parser.hpp>
|
||||||
|
#include <valijson/validator.hpp>
|
||||||
|
|
||||||
using valijson::Schema;
|
using valijson::Schema;
|
||||||
using valijson::SchemaParser;
|
using valijson::SchemaParser;
|
||||||
|
using valijson::ValidationResults;
|
||||||
|
using valijson::Validator;
|
||||||
|
using valijson::adapters::AdapterTraits;
|
||||||
using valijson::adapters::RapidJsonAdapter;
|
using valijson::adapters::RapidJsonAdapter;
|
||||||
|
using AdapterType = RapidJsonAdapter;
|
||||||
|
|
||||||
extern "C" int
|
void runOneTest(const AdapterType &test, const Schema &schema,
|
||||||
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
Validator::TypeCheckingMode mode)
|
||||||
{
|
{
|
||||||
if(size<3) return 0;
|
|
||||||
char input_file[256];
|
|
||||||
sprintf(input_file, "/tmp/libfuzzer.json");
|
|
||||||
FILE *fp = fopen(input_file, "wb");
|
|
||||||
if (!fp)
|
|
||||||
return 0;
|
|
||||||
fwrite(data, size, 1, fp);
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
rapidjson::Document schemaDocument;
|
|
||||||
if (!valijson::utils::loadDocument(input_file, schemaDocument)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Schema schema;
|
|
||||||
SchemaParser parser;
|
|
||||||
RapidJsonAdapter schemaDocumentAdapter(schemaDocument);
|
|
||||||
try {
|
try {
|
||||||
parser.populateSchema(schemaDocumentAdapter, schema);
|
if (!test.isObject()) {
|
||||||
} catch (std::exception &e) {
|
return;
|
||||||
unlink(input_file);
|
}
|
||||||
return 1;
|
|
||||||
|
const AdapterType::Object testObject = test.getObject();
|
||||||
|
const auto dataItr = testObject.find("data");
|
||||||
|
|
||||||
|
if (dataItr == testObject.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Validator validator(mode);
|
||||||
|
ValidationResults results;
|
||||||
|
validator.validate(schema, dataItr->second, &results);
|
||||||
|
} catch (const std::exception &) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||||
|
{
|
||||||
|
AdapterTraits<AdapterType>::DocumentType document;
|
||||||
|
document.template Parse<rapidjson::kParseIterativeFlag>(reinterpret_cast<const char *>(data), size);
|
||||||
|
|
||||||
|
if (document.HasParseError() || !document.IsArray()) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink(input_file);
|
for (const auto &testCase : AdapterType(document).getArray()) {
|
||||||
return 1;
|
if (!testCase.isObject()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AdapterType::Object object = testCase.getObject();
|
||||||
|
const auto schemaItr = object.find("schema");
|
||||||
|
const auto testsItr = object.find("tests");
|
||||||
|
|
||||||
|
if (schemaItr == object.end() || testsItr == object.end() ||
|
||||||
|
!testsItr->second.isArray()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Schema schema;
|
||||||
|
SchemaParser parser(size % 2 ? SchemaParser::kDraft4
|
||||||
|
: SchemaParser::kDraft7);
|
||||||
|
|
||||||
|
try {
|
||||||
|
parser.populateSchema(schemaItr->second, schema);
|
||||||
|
} catch (const std::exception &) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto mode = testsItr->second.hasStrictTypes()
|
||||||
|
? Validator::kStrongTypes
|
||||||
|
: Validator::kWeakTypes;
|
||||||
|
|
||||||
|
for (const AdapterType test : testsItr->second.getArray()) {
|
||||||
|
runOneTest(test, schema, mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2,38 +2,31 @@
|
|||||||
|
|
||||||
git submodule update --init --depth 1 thirdparty
|
git submodule update --init --depth 1 thirdparty
|
||||||
|
|
||||||
# This line causes an abort which breaks fuzzing:
|
|
||||||
sed -i '27d' include/valijson/utils/rapidjson_utils.hpp
|
|
||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake \
|
cmake \
|
||||||
-Dvalijson_BUILD_TESTS=TRUE \
|
-Dvalijson_BUILD_TESTS=FALSE \
|
||||||
-Dvalijson_BUILD_EXAMPLES=FALSE \
|
-Dvalijson_BUILD_EXAMPLES=FALSE \
|
||||||
-Dvalijson_EXCLUDE_BOOST=TRUE \
|
-Dvalijson_EXCLUDE_BOOST=TRUE \
|
||||||
..
|
..
|
||||||
|
|
||||||
make -j"$(nproc)"
|
make -j"$(nproc)"
|
||||||
|
|
||||||
cd ../tests/fuzzing
|
cd ../tests/fuzzing
|
||||||
|
|
||||||
find ../.. -name "*.o" -exec ar rcs fuzz_lib.a {} \;
|
|
||||||
|
|
||||||
# CXXFLAGS may contain spaces
|
# CXXFLAGS may contain spaces
|
||||||
# shellcheck disable=SC2086
|
|
||||||
"$CXX" $CXXFLAGS -DVALIJSON_USE_EXCEPTIONS=1 \
|
|
||||||
-I/src/valijson/thirdparty/rapidjson/include \
|
|
||||||
-I/src/valijson/thirdparty/rapidjson/include/rapidjson \
|
|
||||||
-I/src/valijson/include \
|
|
||||||
-I/src/valijson/include/valijson \
|
|
||||||
-I/src/valijson/include/valijson/adapters \
|
|
||||||
-c fuzzer.cpp -o fuzzer.o
|
|
||||||
|
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
"$CXX" $CXXFLAGS "$LIB_FUZZING_ENGINE" \
|
"$CXX" $CXXFLAGS "$LIB_FUZZING_ENGINE" \
|
||||||
-DVALIJSON_USE_EXCEPTIONS=1 \
|
-DVALIJSON_USE_EXCEPTIONS=1 \
|
||||||
-rdynamic fuzzer.o \
|
-I/src/valijson/thirdparty/rapidjson/include \
|
||||||
-o "${OUT}/fuzzer" fuzz_lib.a
|
-I/src/valijson/include \
|
||||||
|
fuzzer.cpp -o "${OUT}/fuzzer"
|
||||||
|
|
||||||
zip "${OUT}/fuzzer_seed_corpus.zip" \
|
mkdir seed_corpus
|
||||||
"${SRC}/valijson/doc/schema/draft-03.json"
|
|
||||||
|
find "${SRC}/valijson/thirdparty/JSON-Schema-Test-Suite/tests" -name "*.json" | while read file; do
|
||||||
|
sha1=$(sha1sum "$file" | awk '{print $1}')
|
||||||
|
cp "$file" seed_corpus/"${sha1}"
|
||||||
|
done
|
||||||
|
|
||||||
|
zip -j -r "${OUT}/fuzzer_seed_corpus.zip" seed_corpus
|
||||||
|
Loading…
Reference in New Issue
Block a user