diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/fuzz/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/test/fuzz/parse_iso8601.cpp | 27 | ||||
-rw-r--r-- | src/test/fuzz/util.cpp | 6 | ||||
-rw-r--r-- | src/test/util_tests.cpp | 51 |
4 files changed, 79 insertions, 6 deletions
diff --git a/src/test/fuzz/CMakeLists.txt b/src/test/fuzz/CMakeLists.txt index 1bf05ee4fb..f65ed62b2d 100644 --- a/src/test/fuzz/CMakeLists.txt +++ b/src/test/fuzz/CMakeLists.txt @@ -76,6 +76,7 @@ add_executable(fuzz p2p_transport_serialization.cpp package_eval.cpp parse_hd_keypath.cpp + parse_iso8601.cpp parse_numbers.cpp parse_script.cpp parse_univalue.cpp diff --git a/src/test/fuzz/parse_iso8601.cpp b/src/test/fuzz/parse_iso8601.cpp new file mode 100644 index 0000000000..7e51f57905 --- /dev/null +++ b/src/test/fuzz/parse_iso8601.cpp @@ -0,0 +1,27 @@ +// Copyright (c) 2019-present 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 <test/fuzz/FuzzedDataProvider.h> +#include <test/fuzz/fuzz.h> +#include <util/time.h> + +#include <cassert> +#include <cstdint> +#include <string> +#include <vector> + +FUZZ_TARGET(parse_iso8601) +{ + FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); + + const int64_t random_time = fuzzed_data_provider.ConsumeIntegral<int32_t>(); + const std::string random_string = fuzzed_data_provider.ConsumeRemainingBytesAsString(); + + const std::string iso8601_datetime = FormatISO8601DateTime(random_time); + (void)FormatISO8601Date(random_time); + const int64_t parsed_time_1{ParseISO8601DateTime(iso8601_datetime).value()}; + assert(parsed_time_1 == random_time); + + (void)ParseISO8601DateTime(random_string); +} diff --git a/src/test/fuzz/util.cpp b/src/test/fuzz/util.cpp index 425b9559a7..d700e5ac97 100644 --- a/src/test/fuzz/util.cpp +++ b/src/test/fuzz/util.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2022 The Bitcoin Core developers +// Copyright (c) 2021-present The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -34,8 +34,8 @@ CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider, const std::option int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optional<int64_t>& min, const std::optional<int64_t>& max) noexcept { // Avoid t=0 (1970-01-01T00:00:00Z) since SetMockTime(0) disables mocktime. - static const int64_t time_min{946684801}; // 2000-01-01T00:00:01Z - static const int64_t time_max{4133980799}; // 2100-12-31T23:59:59Z + static const int64_t time_min{ParseISO8601DateTime("2000-01-01T00:00:01Z").value()}; + static const int64_t time_max{ParseISO8601DateTime("2100-12-31T23:59:59Z").value()}; return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(min.value_or(time_min), max.value_or(time_max)); } diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 1624fb8b5b..3f6e5b1b66 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2022 The Bitcoin Core developers +// Copyright (c) 2011-present The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -323,20 +323,65 @@ BOOST_AUTO_TEST_CASE(util_TrimString) BOOST_CHECK_EQUAL(TrimStringView(std::string("\x05\x04\x03\x02\x01\x00", 6), std::string("\x05\x04\x03\x02\x01\x00", 6)), ""); } +BOOST_AUTO_TEST_CASE(util_ParseISO8601DateTime) +{ + BOOST_CHECK_EQUAL(ParseISO8601DateTime("1969-12-31T23:59:59Z").value(), -1); + BOOST_CHECK_EQUAL(ParseISO8601DateTime("1970-01-01T00:00:00Z").value(), 0); + BOOST_CHECK_EQUAL(ParseISO8601DateTime("1970-01-01T00:00:01Z").value(), 1); + BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T00:00:01Z").value(), 946684801); + BOOST_CHECK_EQUAL(ParseISO8601DateTime("2011-09-30T23:36:17Z").value(), 1317425777); + BOOST_CHECK_EQUAL(ParseISO8601DateTime("2100-12-31T23:59:59Z").value(), 4133980799); + BOOST_CHECK_EQUAL(ParseISO8601DateTime("9999-12-31T23:59:59Z").value(), 253402300799); + + // Accept edge-cases, where the time overflows. They are not produced by + // FormatISO8601DateTime, so this can be changed in the future, if needed. + // For now, keep compatibility with the previous implementation. + BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T99:00:00Z").value(), 947041200); + BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T00:99:00Z").value(), 946690740); + BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T00:00:99Z").value(), 946684899); + BOOST_CHECK_EQUAL(ParseISO8601DateTime("2000-01-01T99:99:99Z").value(), 947047239); + + // Reject date overflows. + BOOST_CHECK(!ParseISO8601DateTime("2000-99-01T00:00:00Z")); + BOOST_CHECK(!ParseISO8601DateTime("2000-01-99T00:00:00Z")); + + // Reject out-of-range years + BOOST_CHECK(!ParseISO8601DateTime("32768-12-31T23:59:59Z")); + BOOST_CHECK(!ParseISO8601DateTime("32767-12-31T23:59:59Z")); + BOOST_CHECK(!ParseISO8601DateTime("32767-12-31T00:00:00Z")); + BOOST_CHECK(!ParseISO8601DateTime("999-12-31T00:00:00Z")); + + // Reject invalid format + const std::string valid{"2000-01-01T00:00:01Z"}; + BOOST_CHECK(ParseISO8601DateTime(valid).has_value()); + for (auto mut{0U}; mut < valid.size(); ++mut) { + std::string invalid{valid}; + invalid[mut] = 'a'; + BOOST_CHECK(!ParseISO8601DateTime(invalid)); + } +} + BOOST_AUTO_TEST_CASE(util_FormatISO8601DateTime) { BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890963199), "32767-12-31T23:59:59Z"); BOOST_CHECK_EQUAL(FormatISO8601DateTime(971890876800), "32767-12-31T00:00:00Z"); - BOOST_CHECK_EQUAL(FormatISO8601DateTime(1317425777), "2011-09-30T23:36:17Z"); + + BOOST_CHECK_EQUAL(FormatISO8601DateTime(-1), "1969-12-31T23:59:59Z"); BOOST_CHECK_EQUAL(FormatISO8601DateTime(0), "1970-01-01T00:00:00Z"); + BOOST_CHECK_EQUAL(FormatISO8601DateTime(1), "1970-01-01T00:00:01Z"); + BOOST_CHECK_EQUAL(FormatISO8601DateTime(946684801), "2000-01-01T00:00:01Z"); + BOOST_CHECK_EQUAL(FormatISO8601DateTime(1317425777), "2011-09-30T23:36:17Z"); + BOOST_CHECK_EQUAL(FormatISO8601DateTime(4133980799), "2100-12-31T23:59:59Z"); + BOOST_CHECK_EQUAL(FormatISO8601DateTime(253402300799), "9999-12-31T23:59:59Z"); } BOOST_AUTO_TEST_CASE(util_FormatISO8601Date) { BOOST_CHECK_EQUAL(FormatISO8601Date(971890963199), "32767-12-31"); BOOST_CHECK_EQUAL(FormatISO8601Date(971890876800), "32767-12-31"); - BOOST_CHECK_EQUAL(FormatISO8601Date(1317425777), "2011-09-30"); + BOOST_CHECK_EQUAL(FormatISO8601Date(0), "1970-01-01"); + BOOST_CHECK_EQUAL(FormatISO8601Date(1317425777), "2011-09-30"); } BOOST_AUTO_TEST_CASE(util_FormatMoney) |