diff --git a/test/tools/ossfuzz/CMakeLists.txt b/test/tools/ossfuzz/CMakeLists.txt
index a799bd736..622146209 100644
--- a/test/tools/ossfuzz/CMakeLists.txt
+++ b/test/tools/ossfuzz/CMakeLists.txt
@@ -27,7 +27,12 @@ if (OSSFUZZ)
target_link_libraries(solc_opt_ossfuzz PRIVATE libsolc evmasm)
set_target_properties(solc_opt_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
- add_executable(solc_noopt_ossfuzz solc_noopt_ossfuzz.cpp ../fuzzer_common.cpp ../../TestCaseReader.cpp)
+ add_executable(solc_noopt_ossfuzz
+ solc_noopt_ossfuzz.cpp
+ ../fuzzer_common.cpp
+ ../../TestCaseReader.cpp
+ SolRegexpMutator.cpp
+ )
target_link_libraries(solc_noopt_ossfuzz PRIVATE libsolc evmasm)
set_target_properties(solc_noopt_ossfuzz PROPERTIES LINK_FLAGS ${LIB_FUZZING_ENGINE})
diff --git a/test/tools/ossfuzz/SolRegexpMutator.cpp b/test/tools/ossfuzz/SolRegexpMutator.cpp
new file mode 100644
index 000000000..23059cc38
--- /dev/null
+++ b/test/tools/ossfuzz/SolRegexpMutator.cpp
@@ -0,0 +1,43 @@
+/*
+ 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 .
+*/
+
+#include
+
+#include
+
+using namespace solidity::test::fuzzer;
+using namespace std;
+
+size_t SRM::mutateInPlace(uint8_t* _data, size_t _size, size_t _maxSize, unsigned _ruleIdx)
+{
+ unsigned Idx = _ruleIdx % RegexpRules.size();
+ string mutant = regex_replace(
+ string(_data, _data + _size),
+ RegexpRules[Idx].first,
+ RegexpRules[Idx].second,
+ regex_constants::format_first_only
+ );
+
+ if (mutant.size() < _maxSize)
+ {
+ mempcpy(_data, mutant.data(), mutant.size());
+ return mutant.size();
+ }
+ else
+ return 0;
+}
+
diff --git a/test/tools/ossfuzz/SolRegexpMutator.h b/test/tools/ossfuzz/SolRegexpMutator.h
new file mode 100644
index 000000000..9765867f9
--- /dev/null
+++ b/test/tools/ossfuzz/SolRegexpMutator.h
@@ -0,0 +1,54 @@
+/*
+ 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 .
+*/
+
+#pragma once
+
+#include
+#include
+#include
+
+namespace solidity::test::fuzzer
+{
+ static std::vector> Mutations = {
+ {"==", "!="},
+ {"!=", "=="},
+ {">", "<="},
+ {"<", ">="},
+ {"<=", ">"},
+ {">=", "<"},
+ {"\n", "\nbreak;\n"},
+ {"break;\n", ""},
+ {"\n", "\ncontinue;\n"},
+ {"continue;\n", ""}
+ };
+
+ struct SRM {
+ SRM() {
+ for (auto const& item: Mutations)
+ addRule(item.first, item.second);
+ }
+
+ void addRule(std::string const& _pattern, std::string const& _replaceString)
+ {
+ RegexpRules.emplace_back(std::pair(std::regex(_pattern), _replaceString));
+ }
+
+ size_t mutateInPlace(uint8_t* _data, size_t size, size_t _maxSize, unsigned _ruleIdx);
+
+ std::vector> RegexpRules = {};
+ };
+}
\ No newline at end of file
diff --git a/test/tools/ossfuzz/solc_noopt_ossfuzz.cpp b/test/tools/ossfuzz/solc_noopt_ossfuzz.cpp
index 8a7b83561..65c031c41 100644
--- a/test/tools/ossfuzz/solc_noopt_ossfuzz.cpp
+++ b/test/tools/ossfuzz/solc_noopt_ossfuzz.cpp
@@ -19,6 +19,8 @@
#include
+#include
+
#include
#include
@@ -28,6 +30,7 @@
#include
#include
+using namespace solidity::test::fuzzer;
using namespace solidity::frontend::test;
using namespace std;
@@ -39,8 +42,8 @@ struct CustomMutator {
explicit CustomMutator(unsigned _seed = 1337): Rand(_seed) {}
enum class Mutation {
- DEFAULT,
ADDSTMT,
+ MUTATE,
NUMMUTATIONS
};
@@ -61,15 +64,24 @@ struct CustomMutator {
switch (_mut)
{
- case Mutation::DEFAULT:
- return LLVMFuzzerMutate(_data, _size, _maxSize);
case Mutation::ADDSTMT:
return addStmt(_data, _size, _maxSize);
+ case Mutation::MUTATE:
+ return mutate(_data, _size, _maxSize);
case Mutation::NUMMUTATIONS:
solAssert(false, "Solc fuzzer: Invalid mutation selected");
}
}
+ size_t mutate(uint8_t* _data, size_t _size, size_t _maxSize)
+ {
+ unsigned newSize = SRM{}.mutateInPlace(_data, _size, _maxSize, Rand());
+ if (newSize == 0)
+ return LLVMFuzzerMutate(_data, _size, _maxSize);
+ else
+ return newSize;
+ }
+
size_t addStmt(uint8_t* _data, size_t _size, size_t _maxSize)
{
// Pseudo randomly choose statement