mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9722 from ethereum/fix-9676
Add Solidity test case generator framework
This commit is contained in:
commit
1944d5ce44
@ -91,7 +91,9 @@ defaults:
|
|||||||
paths:
|
paths:
|
||||||
- test/tools/ossfuzz/abiv2_proto_ossfuzz
|
- test/tools/ossfuzz/abiv2_proto_ossfuzz
|
||||||
- test/tools/ossfuzz/const_opt_ossfuzz
|
- test/tools/ossfuzz/const_opt_ossfuzz
|
||||||
|
- test/tools/ossfuzz/solc_noopt_mutator_ossfuzz
|
||||||
- test/tools/ossfuzz/solc_noopt_ossfuzz
|
- test/tools/ossfuzz/solc_noopt_ossfuzz
|
||||||
|
- test/tools/ossfuzz/solc_opt_mutator_ossfuzz
|
||||||
- test/tools/ossfuzz/solc_opt_ossfuzz
|
- test/tools/ossfuzz/solc_opt_ossfuzz
|
||||||
- test/tools/ossfuzz/strictasm_assembly_ossfuzz
|
- test/tools/ossfuzz/strictasm_assembly_ossfuzz
|
||||||
- test/tools/ossfuzz/strictasm_diff_ossfuzz
|
- test/tools/ossfuzz/strictasm_diff_ossfuzz
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
add_custom_target(ossfuzz)
|
add_custom_target(ossfuzz)
|
||||||
add_dependencies(ossfuzz
|
add_dependencies(ossfuzz
|
||||||
solc_opt_ossfuzz
|
solc_opt_ossfuzz
|
||||||
|
solc_opt_mutator_ossfuzz
|
||||||
solc_noopt_ossfuzz
|
solc_noopt_ossfuzz
|
||||||
|
solc_noopt_mutator_ossfuzz
|
||||||
const_opt_ossfuzz
|
const_opt_ossfuzz
|
||||||
strictasm_diff_ossfuzz
|
strictasm_diff_ossfuzz
|
||||||
strictasm_opt_ossfuzz
|
strictasm_opt_ossfuzz
|
||||||
strictasm_assembly_ossfuzz
|
strictasm_assembly_ossfuzz
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if (OSSFUZZ)
|
if (OSSFUZZ)
|
||||||
@ -31,6 +33,16 @@ if (OSSFUZZ)
|
|||||||
target_link_libraries(solc_opt_ossfuzz PRIVATE libsolc evmasm)
|
target_link_libraries(solc_opt_ossfuzz PRIVATE libsolc evmasm)
|
||||||
set_target_properties(solc_opt_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
set_target_properties(solc_opt_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||||
|
|
||||||
|
add_executable(solc_opt_mutator_ossfuzz
|
||||||
|
solc_opt_ossfuzz.cpp
|
||||||
|
../fuzzer_common.cpp
|
||||||
|
../../TestCaseReader.cpp
|
||||||
|
SolidityGenerator.cpp
|
||||||
|
SolidityCustomMutatorInterface.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(solc_opt_mutator_ossfuzz PRIVATE libsolc evmasm)
|
||||||
|
set_target_properties(solc_opt_mutator_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||||
|
|
||||||
add_executable(solc_noopt_ossfuzz
|
add_executable(solc_noopt_ossfuzz
|
||||||
solc_noopt_ossfuzz.cpp
|
solc_noopt_ossfuzz.cpp
|
||||||
../fuzzer_common.cpp
|
../fuzzer_common.cpp
|
||||||
@ -39,6 +51,16 @@ if (OSSFUZZ)
|
|||||||
target_link_libraries(solc_noopt_ossfuzz PRIVATE libsolc evmasm)
|
target_link_libraries(solc_noopt_ossfuzz PRIVATE libsolc evmasm)
|
||||||
set_target_properties(solc_noopt_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
set_target_properties(solc_noopt_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||||
|
|
||||||
|
add_executable(solc_noopt_mutator_ossfuzz
|
||||||
|
solc_noopt_ossfuzz.cpp
|
||||||
|
../fuzzer_common.cpp
|
||||||
|
../../TestCaseReader.cpp
|
||||||
|
SolidityGenerator.cpp
|
||||||
|
SolidityCustomMutatorInterface.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(solc_noopt_mutator_ossfuzz PRIVATE libsolc evmasm)
|
||||||
|
set_target_properties(solc_noopt_mutator_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||||
|
|
||||||
add_executable(const_opt_ossfuzz const_opt_ossfuzz.cpp ../fuzzer_common.cpp)
|
add_executable(const_opt_ossfuzz const_opt_ossfuzz.cpp ../fuzzer_common.cpp)
|
||||||
target_link_libraries(const_opt_ossfuzz PRIVATE libsolc evmasm)
|
target_link_libraries(const_opt_ossfuzz PRIVATE libsolc evmasm)
|
||||||
set_target_properties(const_opt_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
set_target_properties(const_opt_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||||
@ -82,14 +104,14 @@ if (OSSFUZZ)
|
|||||||
protoToYul.cpp
|
protoToYul.cpp
|
||||||
yulProto.pb.cc
|
yulProto.pb.cc
|
||||||
protomutators/YulProtoMutator.cpp
|
protomutators/YulProtoMutator.cpp
|
||||||
)
|
)
|
||||||
target_include_directories(yul_proto_diff_custom_mutate_ossfuzz PRIVATE /usr/include/libprotobuf-mutator)
|
target_include_directories(yul_proto_diff_custom_mutate_ossfuzz PRIVATE /usr/include/libprotobuf-mutator)
|
||||||
target_link_libraries(yul_proto_diff_custom_mutate_ossfuzz PRIVATE yul
|
target_link_libraries(yul_proto_diff_custom_mutate_ossfuzz PRIVATE yul
|
||||||
yulInterpreter
|
yulInterpreter
|
||||||
protobuf-mutator-libfuzzer.a
|
protobuf-mutator-libfuzzer.a
|
||||||
protobuf-mutator.a
|
protobuf-mutator.a
|
||||||
protobuf.a
|
protobuf.a
|
||||||
)
|
)
|
||||||
set_target_properties(yul_proto_diff_custom_mutate_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
set_target_properties(yul_proto_diff_custom_mutate_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
|
||||||
target_compile_options(yul_proto_diff_custom_mutate_ossfuzz PUBLIC ${COMPILE_OPTIONS} -Wno-sign-conversion)
|
target_compile_options(yul_proto_diff_custom_mutate_ossfuzz PUBLIC ${COMPILE_OPTIONS} -Wno-sign-conversion)
|
||||||
|
|
||||||
@ -139,12 +161,24 @@ else()
|
|||||||
)
|
)
|
||||||
target_link_libraries(solc_opt_ossfuzz PRIVATE libsolc evmasm)
|
target_link_libraries(solc_opt_ossfuzz PRIVATE libsolc evmasm)
|
||||||
|
|
||||||
|
add_library(solc_opt_mutator_ossfuzz
|
||||||
|
solc_opt_ossfuzz.cpp
|
||||||
|
../fuzzer_common.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(solc_opt_mutator_ossfuzz PRIVATE libsolc evmasm)
|
||||||
|
|
||||||
add_library(solc_noopt_ossfuzz
|
add_library(solc_noopt_ossfuzz
|
||||||
solc_noopt_ossfuzz.cpp
|
solc_noopt_ossfuzz.cpp
|
||||||
../fuzzer_common.cpp
|
../fuzzer_common.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(solc_noopt_ossfuzz PRIVATE libsolc evmasm)
|
target_link_libraries(solc_noopt_ossfuzz PRIVATE libsolc evmasm)
|
||||||
|
|
||||||
|
add_library(solc_noopt_mutator_ossfuzz
|
||||||
|
solc_noopt_ossfuzz.cpp
|
||||||
|
../fuzzer_common.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(solc_noopt_mutator_ossfuzz PRIVATE libsolc evmasm)
|
||||||
|
|
||||||
add_library(const_opt_ossfuzz
|
add_library(const_opt_ossfuzz
|
||||||
const_opt_ossfuzz.cpp
|
const_opt_ossfuzz.cpp
|
||||||
../fuzzer_common.cpp)
|
../fuzzer_common.cpp)
|
||||||
|
69
test/tools/ossfuzz/SolidityCustomMutatorInterface.cpp
Normal file
69
test/tools/ossfuzz/SolidityCustomMutatorInterface.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
|
||||||
|
#include <test/tools/ossfuzz/SolidityCustomMutatorInterface.h>
|
||||||
|
#include <test/tools/ossfuzz/SolidityGenerator.h>
|
||||||
|
|
||||||
|
#include <liblangutil/Exceptions.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace solidity::test::fuzzer;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
/// Forward declare libFuzzer's default mutator definition
|
||||||
|
extern "C" size_t LLVMFuzzerMutate(uint8_t* _data, size_t _size, size_t _maxSize);
|
||||||
|
|
||||||
|
/// Define Solidity's custom mutator by implementing libFuzzer's
|
||||||
|
/// custom mutator external interface.
|
||||||
|
extern "C" size_t LLVMFuzzerCustomMutator(
|
||||||
|
uint8_t* _data,
|
||||||
|
size_t _size,
|
||||||
|
size_t _maxSize,
|
||||||
|
unsigned int _seed
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (_maxSize <= _size || _size == 0)
|
||||||
|
return LLVMFuzzerMutate(_data, _size, _maxSize);
|
||||||
|
return SolidityCustomMutatorInterface{_data, _size, _maxSize, _seed}.generate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SolidityCustomMutatorInterface::SolidityCustomMutatorInterface(
|
||||||
|
uint8_t* _data,
|
||||||
|
size_t _size,
|
||||||
|
size_t _maxSize,
|
||||||
|
unsigned int _seed
|
||||||
|
):
|
||||||
|
data(_data),
|
||||||
|
size(_size),
|
||||||
|
maxMutantSize(_maxSize),
|
||||||
|
generator(make_shared<SolidityGenerator>(_seed))
|
||||||
|
{}
|
||||||
|
|
||||||
|
size_t SolidityCustomMutatorInterface::generate()
|
||||||
|
{
|
||||||
|
string testCase = generator->generateTestProgram();
|
||||||
|
solAssert(
|
||||||
|
!testCase.empty() && data,
|
||||||
|
"Solc custom mutator: Invalid mutant or memory pointer"
|
||||||
|
);
|
||||||
|
size_t mutantSize = min(testCase.size(), maxMutantSize - 1);
|
||||||
|
mempcpy(data, testCase.data(), mutantSize);
|
||||||
|
return mutantSize;
|
||||||
|
}
|
46
test/tools/ossfuzz/SolidityCustomMutatorInterface.h
Normal file
46
test/tools/ossfuzz/SolidityCustomMutatorInterface.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
/**
|
||||||
|
* Implements libFuzzer's custom mutator interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <test/tools/ossfuzz/SolidityGenerator.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace solidity::test::fuzzer
|
||||||
|
{
|
||||||
|
struct SolidityCustomMutatorInterface
|
||||||
|
{
|
||||||
|
SolidityCustomMutatorInterface(uint8_t* _data, size_t _size, size_t _maxSize, unsigned _seed);
|
||||||
|
/// Generates Solidity test program, copies it into buffer
|
||||||
|
/// provided by libFuzzer and @returns size of the test program.
|
||||||
|
size_t generate();
|
||||||
|
|
||||||
|
/// Raw pointer to libFuzzer provided input
|
||||||
|
uint8_t* data;
|
||||||
|
/// Size of libFuzzer provided input
|
||||||
|
size_t size;
|
||||||
|
/// Maximum length of mutant specified by libFuzzer
|
||||||
|
size_t maxMutantSize;
|
||||||
|
/// Solidity generator handle
|
||||||
|
std::shared_ptr<SolidityGenerator> generator;
|
||||||
|
};
|
||||||
|
}
|
35
test/tools/ossfuzz/SolidityGenerator.cpp
Normal file
35
test/tools/ossfuzz/SolidityGenerator.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
|
||||||
|
#include <test/tools/ossfuzz/SolidityGenerator.h>
|
||||||
|
|
||||||
|
#include <libsolutil/Whiskers.h>
|
||||||
|
|
||||||
|
using namespace solidity::test::fuzzer;
|
||||||
|
using namespace solidity::util;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
string SolidityGenerator::generateTestProgram()
|
||||||
|
{
|
||||||
|
// TODO: Add generators for grammar elements of
|
||||||
|
// Solidity antlr4 grammar. Currently, the generated
|
||||||
|
// test program consists of a version pragma only.
|
||||||
|
return Whiskers(R"(pragma <directive>;)")
|
||||||
|
("directive", "solidity >= 0.0.0")
|
||||||
|
.render();
|
||||||
|
}
|
42
test/tools/ossfuzz/SolidityGenerator.h
Normal file
42
test/tools/ossfuzz/SolidityGenerator.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
/**
|
||||||
|
* Implements generators for synthesizing mostly syntactically valid
|
||||||
|
* Solidity test programs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
namespace solidity::test::fuzzer
|
||||||
|
{
|
||||||
|
using RandomEngine = std::mt19937_64;
|
||||||
|
|
||||||
|
class SolidityGenerator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SolidityGenerator(uint64_t _seed): m_rand(_seed)
|
||||||
|
{}
|
||||||
|
/// @returns a pseudo randomly generated test program
|
||||||
|
std::string generateTestProgram();
|
||||||
|
private:
|
||||||
|
/// Random number generator
|
||||||
|
RandomEngine const m_rand;
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user