diff --git a/src/test/rpc/Transaction_test.cpp b/src/test/rpc/Transaction_test.cpp index 72a7681ce97..2bd20eb3707 100644 --- a/src/test/rpc/Transaction_test.cpp +++ b/src/test/rpc/Transaction_test.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -671,6 +672,47 @@ class Transaction_test : public beast::unit_test::suite BEAST_EXPECT(jrr[jss::hash]); } + // test querying with mixed case ctid + { + Env env{*this, makeNetworkConfig(11111)}; + std::uint32_t const netID = env.app().config().NETWORK_ID; + + Account const alice = Account("alice"); + Account const bob = Account("bob"); + + std::uint32_t const startLegSeq = env.current()->info().seq; + env.fund(XRP(10000), alice, bob); + env(pay(alice, bob, XRP(10))); + env.close(); + + std::string const ctid = *RPC::encodeCTID(startLegSeq, 0, netID); + auto isUpper = [](char c) { return std::isupper(c) != 0; }; + + // Verify that there are at least two upper case letters in ctid and + // test a mixed case + if (BEAST_EXPECT( + std::count_if(ctid.begin(), ctid.end(), isUpper) > 1)) + { + // Change the first upper case letter to lower case. + std::string mixedCase = ctid; + { + auto const iter = std::find_if( + mixedCase.begin(), mixedCase.end(), isUpper); + *iter = std::tolower(*iter); + } + BEAST_EXPECT(ctid != mixedCase); + + Json::Value jsonTx; + jsonTx[jss::binary] = false; + jsonTx[jss::ctid] = mixedCase; + jsonTx[jss::id] = 1; + Json::Value const jrr = + env.rpc("json", "tx", to_string(jsonTx))[jss::result]; + BEAST_EXPECT(jrr[jss::ctid] == ctid); + BEAST_EXPECT(jrr[jss::hash]); + } + } + // test that if the network is 65535 the ctid is not in the response { Env env{*this, makeNetworkConfig(65535)}; diff --git a/src/xrpld/rpc/CTID.h b/src/xrpld/rpc/CTID.h index 8f6c64bc028..8cac8d63171 100644 --- a/src/xrpld/rpc/CTID.h +++ b/src/xrpld/rpc/CTID.h @@ -63,7 +63,7 @@ decodeCTID(const T ctid) noexcept if (ctidString.length() != 16) return {}; - if (!boost::regex_match(ctidString, boost::regex("^[0-9A-F]+$"))) + if (!boost::regex_match(ctidString, boost::regex("^[0-9A-Fa-f]+$"))) return {}; ctidValue = std::stoull(ctidString, nullptr, 16);