use super::{build, MutationOperator, OperatorSet};
pub struct BitcoinCore;
impl OperatorSet for BitcoinCore {
fn regex_operators(&self) -> Result<Vec<MutationOperator>, regex::Error> {
let operators = vec![
(r"--(\b\w+\b)", r"++$1"),
(r"(\b\w+\b)--", r"$1++"),
("Misbehaving", "//Misbehaving"),
("continue", "break"),
("break", "continue"),
("std::all_of", "std::any_of"),
("std::any_of", "std::all_of"),
("std::min", "std::max"),
("std::max", "std::min"),
("std::begin", "std::end"),
("std::end", "std::begin"),
("true", "false"),
("false", "true"),
(r" / ", " * "),
(r" >= ", " > "),
(r" <= ", " < "),
(r" > ", " >= "),
(r" < ", " <= "),
(r" >= ", " <= "),
(r" <= ", " >= "),
(r" > ", " < "),
(r" < ", " > "),
(r" > ", " <= "),
(r" < ", " >= "),
(r"&&", "||"),
(r"\|\|", "&&"),
(r" == ", " != "),
(r" != ", " == "),
(" - ", " + "),
(r" \+ ", " - "),
(r" \+ ", " * "),
(r" \+ ", " / "),
(r"\((-?\d+)\)", r"($1 - 1)"),
(r"\((-?\d+)\)", r"($1 + 1)"),
(r"\b(if|else\s+if|while)\s*\(([^()]*)\)", r"$1 (1==1)"),
(r"\b(if|else\s+if|while)\s*\(([^()]*)\)", r"$1 (1==0)"),
(r".*\berase\(.+", ""),
(
r"^\s*[a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*(?:(?:->|\.)[a-zA-Z_]\w*)*\s*\([^;]*\)\s*;$",
"",
),
(r"^.*if\s*\(.*\)\s*continue;.*$", ""),
(r"^.*if\s*\(.*\)\s*return;.*$", ""),
(r"^.*if\s*\(.*\)\s*return.*;.*$", ""),
(r"^(.*for\s*\(.*;.*;.*\)\s*\{.*)$", r"$1break;"),
(r"^(.*while\s*\(.*\)\s*\{.*)$", r"$1break;"),
];
build(operators)
}
fn security_operators(&self) -> Result<Vec<MutationOperator>, regex::Error> {
let operators = vec![
("==", "="),
(r" - ", " + "),
(r"\s\+\s", "-"),
(
r"std::array<\s*([\w:]+)\s*,\s*(\d+)\s*>",
r"std::array<$1, $2 - 2>",
),
(
r"\b((?:int16_t|uint16_t|int32_t|uint32_t|int64_t|uint64_t|int)\s*[\(\{])([^\)\}]*)[\)\}]",
"$2",
),
(r"ignore\((\s*(\d+)\s*)\)", r"ignore($2 + 100)"),
(r"(\w+)\[(\w+)\]", r"$1[$2 + 5]"),
(
r"^\s*(?:\(void\)\s*)?[a-zA-Z_][\w:]*\s*\([\w\s,]*\)\s*;\s*$",
"",
),
(r"if\s*\(\s*(.*?)\s*\|\|\s*(.*?)\s*\)", r"if($2||$1)"),
(
r"GetSelectionAmount\(\)",
r"GetSelectionAmount() + std::numeric_limits<CAmount>::max() - 1",
),
(r"resetBlock\(\);", ""),
(
r"\w+(\.|->)GetMedianTimePast\(\)",
"std::numeric_limits<int64_t>::max()",
),
("break", ""),
];
build(operators)
}
fn test_operators(&self) -> Result<Vec<MutationOperator>, regex::Error> {
let operators = vec![
(r"^\s*(?:\w+(?:\.|->|::))*(\w+)\s*\([^)]*\)\s*;?\s*$", ""), ];
build(operators)
}
fn do_not_mutate_patterns(&self) -> Vec<&'static str> {
vec![
"/",
"//",
"#",
"*",
"assert",
"self.log",
"Assume",
"CHECK_NONFATAL",
"/*",
"LogPrintf",
"LogPrint",
"LogDebug",
"strprintf",
"G_FUZZING",
"if (nFound > 0)",
]
}
fn do_not_mutate_py_patterns(&self) -> Vec<&'static str> {
vec![
"wait_for",
"wait_until",
"check_",
"for",
"expected_error",
"def",
"send_and_ping",
"test_",
"rehash",
"start_",
"solve()",
"restart_",
"stop_",
"connect_",
"sync_",
"class",
"return",
"generate(",
"continue",
"sleep",
"break",
"getcontext().prec",
"if",
"else",
"assert",
]
}
fn do_not_mutate_unit_patterns(&self) -> Vec<&'static str> {
vec![
"while",
"for",
"if",
"test_",
"_test",
"reset",
"class",
"return",
"continue",
"break",
"else",
"reserve",
"resize",
"static",
"void",
"BOOST_",
"LOCK(",
"LOCK2(",
"Test",
"Assert",
"EXCLUSIVE_LOCKS_REQUIRED",
"catch",
]
}
fn skip_if_contain_patterns(&self) -> Vec<&'static str> {
vec!["EnableFuzzDeterminism", "nLostUnk", "RPCArg::Type::"]
}
fn test_line_skip_prefixes(&self) -> Vec<&'static str> {
vec![
"assert",
"BOOST_",
"EXPECT_",
"ASSERT_",
"CHECK_",
"REQUIRE_",
"wait_for",
"wait_until",
"send_and_ping",
]
}
}