diff --git a/arcanist/linter/LocaleDependenceLinter.php b/arcanist/linter/LocaleDependenceLinter.php index 432313e8a..9ad1265a3 100644 --- a/arcanist/linter/LocaleDependenceLinter.php +++ b/arcanist/linter/LocaleDependenceLinter.php @@ -1,290 +1,291 @@ [ "stoul", "trim_right", ], "src/dbwrapper.cpp" => [ "stoul", "vsnprintf" ], "src/httprpc.cpp" => ["trim"], "src/init.cpp" => ["atoi"], "src/netbase.cpp" => ["to_lower"], "src/qt/rpcconsole.cpp" => [ "atoi", ], "src/rest.cpp" => ["strtol"], "src/rpc/server.cpp" => ["to_upper"], "src/test/dbwrapper_tests.cpp" => ["snprintf"], "src/test/getarg_tests.cpp" => [ "split", "is_space", ], "src/seeder/main.cpp" => [ "strtoull", "strcasecmp", "strftime", ], "src/seeder/dns.cpp" => ["strcasecmp"], "src/torcontrol.cpp" => [ "atoi", "strtol", ], + "src/test/fuzz/parse_numbers.cpp" => ["atoi"], "src/util/system.cpp" => ["atoi"], "src/util/strencodings.cpp" => [ "atoi", "strtol", "strtoll", "strtoul", "strtoull", ], "src/util/strencodings.h" => ["atoi"], ); const LOCALE_DEPENDENT_FUNCTIONS = array( "alphasort", // LC_COLLATE (via strcoll) "asctime", // LC_TIME (directly) "asprintf", // (via vasprintf) "atof", // LC_NUMERIC (via strtod) "atoi", // LC_NUMERIC (via strtol) "atol", // LC_NUMERIC (via strtol) "atoll", // (via strtoll) "atoq", "btowc", // LC_CTYPE (directly) "ctime", // (via asctime or localtime) "dprintf", // (via vdprintf) "fgetwc", "fgetws", "fold_case", // boost::locale::fold_case "fprintf", // (via vfprintf) "fputwc", "fputws", "fscanf", // (via __vfscanf) "fwprintf", // (via __vfwprintf) "getdate", // via __getdate_r => isspace // __localtime_r "getwc", "getwchar", "is_digit", // boost::algorithm::is_digit "is_space", // boost::algorithm::is_space "isalnum", // LC_CTYPE "isalpha", // LC_CTYPE "isblank", // LC_CTYPE "iscntrl", // LC_CTYPE "isctype", // LC_CTYPE "isdigit", // LC_CTYPE "isgraph", // LC_CTYPE "islower", // LC_CTYPE "isprint", // LC_CTYPE "ispunct", // LC_CTYPE "isspace", // LC_CTYPE "isupper", // LC_CTYPE "iswalnum", // LC_CTYPE "iswalpha", // LC_CTYPE "iswblank", // LC_CTYPE "iswcntrl", // LC_CTYPE "iswctype", // LC_CTYPE "iswdigit", // LC_CTYPE "iswgraph", // LC_CTYPE "iswlower", // LC_CTYPE "iswprint", // LC_CTYPE "iswpunct", // LC_CTYPE "iswspace", // LC_CTYPE "iswupper", // LC_CTYPE "iswxdigit", // LC_CTYPE "isxdigit", // LC_CTYPE "localeconv", // LC_NUMERIC + LC_MONETARY "mblen", // LC_CTYPE "mbrlen", "mbrtowc", "mbsinit", "mbsnrtowcs", "mbsrtowcs", "mbstowcs", // LC_CTYPE "mbtowc", // LC_CTYPE "mktime", "normalize", // boost::locale::normalize "printf", // LC_NUMERIC "putwc", "putwchar", "scanf", // LC_NUMERIC "setlocale", "snprintf", "sprintf", "sscanf", "stod", "stof", "stoi", "stol", "stold", "stoll", "stoul", "stoull", "strcasecmp", "strcasestr", "strcoll", // LC_COLLATE //"strerror" "strfmon", "strftime", // LC_TIME "strncasecmp", "strptime", "strtod", // LC_NUMERIC "strtof", "strtoimax", "strtol", // LC_NUMERIC "strtold", "strtoll", "strtoq", "strtoul", // LC_NUMERIC "strtoull", "strtoumax", "strtouq", "strxfrm", // LC_COLLATE "swprintf", "to_lower", // boost::locale::to_lower "to_title", // boost::locale::to_title "to_upper", // boost::locale::to_upper "tolower", // LC_CTYPE "toupper", // LC_CTYPE "towctrans", "towlower", // LC_CTYPE "towupper", // LC_CTYPE "trim", // boost::algorithm::trim "trim_left", // boost::algorithm::trim_left "trim_right", // boost::algorithm::trim_right "ungetwc", "vasprintf", "vdprintf", "versionsort", "vfprintf", "vfscanf", "vfwprintf", "vprintf", "vscanf", "vsnprintf", "vsprintf", "vsscanf", "vswprintf", "vwprintf", "wcrtomb", "wcscasecmp", "wcscoll", // LC_COLLATE "wcsftime", // LC_TIME "wcsncasecmp", "wcsnrtombs", "wcsrtombs", "wcstod", // LC_NUMERIC "wcstof", "wcstoimax", "wcstol", // LC_NUMERIC "wcstold", "wcstoll", "wcstombs", // LC_CTYPE "wcstoul", // LC_NUMERIC "wcstoull", "wcstoumax", "wcswidth", "wcsxfrm", // LC_COLLATE "wctob", "wctomb", // LC_CTYPE "wctrans", "wctype", "wcwidth", "wprintf", ); const LOCALE_DEPENDENCE_ERROR = 1; const ADVICE_MESSAGE = << ArcanistLintSeverity::SEVERITY_ERROR, ); } public function getLintNameMap() { return array( self::LOCALE_DEPENDENCE_ERROR => pht('Locale dependent function'), ); } public function lintPath($path) { $absolutePath = Filesystem::resolvePath($path, $this->getProjectRoot()); $fileContent = file($absolutePath, FILE_SKIP_EMPTY_LINES); // Flag if the path is part of the known exceptions $exceptions = array(); if (array_key_exists($path, self::KNOWN_VIOLATIONS)) { $exceptions = self::KNOWN_VIOLATIONS[$path]; } $anyFunction = implode("|", self::LOCALE_DEPENDENT_FUNCTIONS); $pattern = "/[^\w`'\"<>](?P".$anyFunction."(_r|_s)?)[^\w`'\"<>]/"; foreach ($fileContent as $lineNumber => $lineContent) { // Filter comments and string constants if (preg_match("#^\s*(//|\*|/\*|\")#", $lineContent)) { continue; } /* * Find the locale dependent functions occurrences. * There can be multiple occurrences for a single line. */ if (preg_match_all($pattern, $lineContent, $matches, PREG_OFFSET_CAPTURE)) { foreach($matches["function"] as $function) { list($functionName, $offset) = $function; // Filter known exceptions if (!in_array($functionName, $exceptions)) { $this->raiseLintAtLine( $lineNumber + 1, $offset + 1, self::LOCALE_DEPENDENCE_ERROR, self::ADVICE_MESSAGE, $functionName); } } } } } } diff --git a/src/test/fuzz/CMakeLists.txt b/src/test/fuzz/CMakeLists.txt index 481035576..632a2bca8 100644 --- a/src/test/fuzz/CMakeLists.txt +++ b/src/test/fuzz/CMakeLists.txt @@ -1,159 +1,163 @@ # Fuzzer test harness add_custom_target(bitcoin-fuzzers) define_property(GLOBAL PROPERTY FUZZ_TARGETS BRIEF_DOCS "List of fuzz targets" FULL_DOCS "A list of the fuzz targets" ) set_property(GLOBAL APPEND PROPERTY FUZZ_TARGETS bitcoin-fuzzers) macro(add_fuzz_target TARGET EXE_NAME) add_executable(${TARGET} EXCLUDE_FROM_ALL fuzz.cpp ${ARGN} ) set_target_properties(${TARGET} PROPERTIES OUTPUT_NAME ${EXE_NAME}) - target_link_libraries(${TARGET} server testutil) + target_link_libraries(${TARGET} server testutil rpcclient) add_dependencies(bitcoin-fuzzers ${TARGET}) set_property(GLOBAL APPEND PROPERTY FUZZ_TARGETS ${TARGET}) endmacro() function(add_regular_fuzz_targets) foreach(_fuzz_test_name ${ARGN}) sanitize_target_name("fuzz-" ${_fuzz_test_name} _fuzz_target_name) add_fuzz_target( ${_fuzz_target_name} ${_fuzz_test_name} # Sources "${_fuzz_test_name}.cpp" ) endforeach() endfunction() include(SanitizeHelper) function(add_deserialize_fuzz_targets) foreach(_fuzz_test_name ${ARGN}) sanitize_target_name("fuzz-" ${_fuzz_test_name} _fuzz_target_name) add_fuzz_target( ${_fuzz_target_name} ${_fuzz_test_name} # Sources deserialize.cpp ) sanitize_c_cxx_definition("" ${_fuzz_test_name} _target_definition) string(TOUPPER ${_target_definition} _target_definition) target_compile_definitions(${_fuzz_target_name} PRIVATE ${_target_definition}) endforeach() endfunction() function(add_process_message_fuzz_targets) foreach(_fuzz_test_name ${ARGN}) sanitize_target_name("fuzz-process_message_" ${_fuzz_test_name} _fuzz_target_name) add_fuzz_target( ${_fuzz_target_name} process_message_${_fuzz_test_name} # Sources process_message.cpp ) target_compile_definitions(${_fuzz_target_name} PRIVATE MESSAGE_TYPE=${_fuzz_test_name}) endforeach() endfunction() add_regular_fuzz_targets( addrdb block bloom_filter rolling_bloom_filter cashaddr descriptor_parse eval_script integer net_permissions + parse_hd_keypath parse_iso8601 + parse_numbers + parse_script + parse_univalue process_message psbt script script_flags spanparsing strprintf timedata transaction tx_in tx_out ) add_deserialize_fuzz_targets( addr_info_deserialize address_deserialize addrman_deserialize banentry_deserialize block_deserialize block_file_info_deserialize block_filter_deserialize block_header_and_short_txids_deserialize blockheader_deserialize blocklocator_deserialize blockmerkleroot blocktransactions_deserialize blocktransactionsrequest_deserialize blockundo_deserialize bloomfilter_deserialize coins_deserialize diskblockindex_deserialize fee_rate_deserialize flat_file_pos_deserialize inv_deserialize key_origin_info_deserialize merkle_block_deserialize messageheader_deserialize netaddr_deserialize out_point_deserialize partial_merkle_tree_deserialize partially_signed_transaction_deserialize prefilled_transaction_deserialize psbt_input_deserialize psbt_output_deserialize pub_key_deserialize script_deserialize service_deserialize sub_net_deserialize tx_in_deserialize txoutcompressor_deserialize txundo_deserialize ) add_process_message_fuzz_targets( addr block blocktxn cmpctblock feefilter filteradd filterclear filterload getaddr getblocks getblocktxn getdata getheaders headers inv mempool notfound ping pong sendcmpct sendheaders tx verack version ) diff --git a/src/test/fuzz/parse_hd_keypath.cpp b/src/test/fuzz/parse_hd_keypath.cpp new file mode 100644 index 000000000..8456d53b0 --- /dev/null +++ b/src/test/fuzz/parse_hd_keypath.cpp @@ -0,0 +1,13 @@ +// Copyright (c) 2009-2019 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include + +void test_one_input(const std::vector &buffer) { + const std::string keypath_str(buffer.begin(), buffer.end()); + std::vector keypath; + (void)ParseHDKeypath(keypath_str, keypath); +} diff --git a/src/test/fuzz/parse_numbers.cpp b/src/test/fuzz/parse_numbers.cpp new file mode 100644 index 000000000..dd193b74d --- /dev/null +++ b/src/test/fuzz/parse_numbers.cpp @@ -0,0 +1,35 @@ +// Copyright (c) 2009-2019 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include + +#include + +#include + +void test_one_input(const std::vector &buffer) { + const std::string random_string(buffer.begin(), buffer.end()); + + Amount amount; + (void)ParseMoney(random_string, amount); + + double d; + (void)ParseDouble(random_string, &d); + + int32_t i32; + (void)ParseInt32(random_string, &i32); + (void)atoi(random_string); + + uint32_t u32; + (void)ParseUInt32(random_string, &u32); + + int64_t i64; + (void)atoi64(random_string); + (void)ParseFixedPoint(random_string, 3, &i64); + (void)ParseInt64(random_string, &i64); + + uint64_t u64; + (void)ParseUInt64(random_string, &u64); +} diff --git a/src/test/fuzz/parse_script.cpp b/src/test/fuzz/parse_script.cpp new file mode 100644 index 000000000..e30ccfa81 --- /dev/null +++ b/src/test/fuzz/parse_script.cpp @@ -0,0 +1,16 @@ +// Copyright (c) 2009-2019 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include