From 0188d3243031cdf4d14e4c8c82c79692ec4b4b4b Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com> Date: Thu, 7 Oct 2021 11:45:53 +0200 Subject: [PATCH] merge bitcoin#23213: Return error when header count is not integral --- src/rest.cpp | 12 +++++++----- test/functional/interface_rest.py | 7 +++++++ test/lint/lint-locale-dependence.sh | 1 - 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/rest.cpp b/src/rest.cpp index fc268870d5..1b07cde554 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -188,9 +188,10 @@ static bool rest_headers(const CoreContext& context, if (path.size() != 2) return RESTERR(req, HTTP_BAD_REQUEST, "No header count specified. Use /rest/headers//.."); - long count = strtol(path[0].c_str(), nullptr, 10); - if (count < 1 || count > 2000) + const auto parsed_count{ToIntegral(path[0])}; + if (!parsed_count.has_value() || *parsed_count < 1 || *parsed_count > 2000) { return RESTERR(req, HTTP_BAD_REQUEST, "Header count out of range: " + path[0]); + } std::string hashStr = path[1]; uint256 hash; @@ -198,8 +199,8 @@ static bool rest_headers(const CoreContext& context, return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); const CBlockIndex* tip = nullptr; - std::vector headers; - headers.reserve(count); + std::vector headers; + headers.reserve(*parsed_count); { ChainstateManager* maybe_chainman = GetChainman(context, req); if (!maybe_chainman) return false; @@ -210,8 +211,9 @@ static bool rest_headers(const CoreContext& context, const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash); while (pindex != nullptr && active_chain.Contains(pindex)) { headers.push_back(pindex); - if (headers.size() == (unsigned long)count) + if (headers.size() == *parsed_count) { break; + } pindex = active_chain.Next(pindex); } } diff --git a/test/functional/interface_rest.py b/test/functional/interface_rest.py index 2ece391bf7..63ffb9b30a 100755 --- a/test/functional/interface_rest.py +++ b/test/functional/interface_rest.py @@ -283,6 +283,13 @@ class RESTTest (BitcoinTestFramework): json_obj = self.test_rest_request("/headers/5/{}".format(bb_hash)) assert_equal(len(json_obj), 5) # now we should have 5 header objects + # Test number parsing + for num in ['5a', '-5', '0', '2001', '99999999999999999999999999999999999']: + assert_equal( + bytes(f'Header count out of range: {num}\r\n', 'ascii'), + self.test_rest_request(f"/headers/{num}/{bb_hash}", ret_type=RetType.BYTES, status=400), + ) + self.log.info("Test tx inclusion in the /mempool and /block URIs") # Make 3 tx and mine them on node 1 diff --git a/test/lint/lint-locale-dependence.sh b/test/lint/lint-locale-dependence.sh index 076753e720..2531d0b501 100755 --- a/test/lint/lint-locale-dependence.sh +++ b/test/lint/lint-locale-dependence.sh @@ -44,7 +44,6 @@ export LC_ALL=C KNOWN_VIOLATIONS=( "src/bitcoin-tx.cpp.*stoul" "src/dbwrapper.cpp:.*vsnprintf" - "src/rest.cpp:.*strtol" "src/test/dbwrapper_tests.cpp:.*snprintf" "src/test/fuzz/locale.cpp" "src/test/fuzz/string.cpp"