diff --git a/API-CHANGELOG.md b/API-CHANGELOG.md index 79fb8ff522..bc3672588e 100644 --- a/API-CHANGELOG.md +++ b/API-CHANGELOG.md @@ -54,6 +54,7 @@ This section contains changes targeting a future version. - `submit`: The `fail_hard` field now returns an error if the value is not a boolean. [#6529](https://github.com/XRPLF/rippled/pull/6529) - `subscribe`: The `taker` field in the `books` array now returns `actMalformed` instead of `badIssuer` if the value is not a valid account. [#6529](https://github.com/XRPLF/rippled/pull/6529) - Fixed a bug in `Forwarded` HTTP header parsing where the extracted IP address could be incorrect when no comma or semicolon delimiter follows the address. This could cause the server to misidentify a client's IP address when operating behind a reverse proxy. [#6529](https://github.com/XRPLF/rippled/pull/6529) +- `account_lines`: The `peer` field now returns an error if the value is not a string. [#7728](https://github.com/XRPLF/rippled/pull/7728) ## XRP Ledger server version 3.1.0 diff --git a/src/test/rpc/AccountLines_test.cpp b/src/test/rpc/AccountLines_test.cpp index cb20de9bf5..3de2bdefa3 100644 --- a/src/test/rpc/AccountLines_test.cpp +++ b/src/test/rpc/AccountLines_test.cpp @@ -94,6 +94,24 @@ public: LedgerHeader const ledger3Info = env.closed()->header(); BEAST_EXPECT(ledger3Info.seq == 3); + { + // test peer non-string + auto testInvalidPeerParam = [&](auto const& param) { + json::Value params; + params[jss::account] = alice.human(); + params[jss::peer] = param; + auto jrr = env.rpc("json", "account_lines", to_string(params))[jss::result]; + BEAST_EXPECT(jrr[jss::error] == "invalidParams"); + BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'peer'."); + }; + + testInvalidPeerParam(1); + testInvalidPeerParam(1.1); + testInvalidPeerParam(true); + testInvalidPeerParam(json::Value(json::ValueType::Null)); + testInvalidPeerParam(json::Value(json::ValueType::Object)); + testInvalidPeerParam(json::Value(json::ValueType::Array)); + } { // alice is funded but has no lines. An empty array is returned. json::Value params; @@ -775,6 +793,35 @@ public: LedgerHeader const ledger3Info = env.closed()->header(); BEAST_EXPECT(ledger3Info.seq == 3); + { + // test peer non-string + auto testInvalidPeerParam = [&](auto const& param) { + json::Value params; + params[jss::account] = alice.human(); + params[jss::peer] = param; + + json::Value request; + request[jss::method] = "account_lines"; + request[jss::jsonrpc] = "2.0"; + request[jss::ripplerpc] = "2.0"; + request[jss::id] = 5; + request[jss::params] = params; + + auto const lines = env.rpc("json2", to_string(request)); + BEAST_EXPECT(lines[jss::error][jss::error] == "invalidParams"); + BEAST_EXPECT(lines[jss::error][jss::message] == "Invalid field 'peer'."); + BEAST_EXPECT(lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0"); + BEAST_EXPECT(lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] == "2.0"); + BEAST_EXPECT(lines.isMember(jss::id) && lines[jss::id] == 5); + }; + + testInvalidPeerParam(1); + testInvalidPeerParam(1.1); + testInvalidPeerParam(true); + testInvalidPeerParam(json::Value(json::ValueType::Null)); + testInvalidPeerParam(json::Value(json::ValueType::Object)); + testInvalidPeerParam(json::Value(json::ValueType::Array)); + } { // alice is funded but has no lines. An empty array is returned. json::Value params; diff --git a/src/xrpld/rpc/handlers/account/AccountLines.cpp b/src/xrpld/rpc/handlers/account/AccountLines.cpp index 4a6d22d5d8..ac98e271b6 100644 --- a/src/xrpld/rpc/handlers/account/AccountLines.cpp +++ b/src/xrpld/rpc/handlers/account/AccountLines.cpp @@ -107,7 +107,12 @@ doAccountLines(rpc::JsonContext& context) std::string strPeer; if (params.isMember(jss::peer)) + { + if (!params[jss::peer].isString()) + return rpc::invalidFieldError(jss::peer); + strPeer = params[jss::peer].asString(); + } auto const raPeerAccount = [&]() -> std::optional { return strPeer.empty() ? std::nullopt : parseBase58(strPeer);