Skip to content

Commit

Permalink
fix account_objects with invalid marker
Browse files Browse the repository at this point in the history
  • Loading branch information
yinyiqian1 committed Oct 4, 2024
1 parent a753099 commit 627655e
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 4 deletions.
99 changes: 99 additions & 0 deletions src/test/rpc/AccountObjects_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,104 @@ class AccountObjects_test : public beast::unit_test::suite
}
}

void
testAccountObjectMarker()
{
testcase("AccountObjectMarker");

using namespace jtx;
Env env(*this);

Account const alice{"alice"};
Account const bob{"bob"};
env.fund(XRP(10000), alice, bob);

unsigned const accountObjectSize = 30;
for (unsigned i = 0; i < accountObjectSize; i++)
env(check::create(alice, bob, XRP(10)));

env.close();

unsigned const limit = 11;
Json::Value marker;
// test account_objects with a limit and update marker
{
Json::Value params;
params[jss::account] = bob.human();
params[jss::limit] = limit;
params[jss::ledger_index] = "validated";
auto resp = env.rpc("json", "account_objects", to_string(params));
auto& accountObjects = resp[jss::result][jss::account_objects];
marker = resp[jss::result][jss::marker];
BEAST_EXPECT(!resp[jss::result].isMember(jss::error));
BEAST_EXPECT(accountObjects.size() == limit);
}

// test account_objects with valid marker and update marker
{
Json::Value params;
params[jss::account] = bob.human();
params[jss::limit] = limit;
params[jss::marker] = marker;
params[jss::ledger_index] = "validated";
auto resp = env.rpc("json", "account_objects", to_string(params));
auto& accountObjects = resp[jss::result][jss::account_objects];
marker = resp[jss::result][jss::marker];
BEAST_EXPECT(!resp[jss::result].isMember(jss::error));
BEAST_EXPECT(accountObjects.size() == limit);
}

// continue getting account_objects with valid marker
{
Json::Value params;
params[jss::account] = bob.human();
params[jss::limit] = limit;
params[jss::marker] = marker;
params[jss::ledger_index] = "validated";
auto resp = env.rpc("json", "account_objects", to_string(params));
auto& accountObjects = resp[jss::result][jss::account_objects];
BEAST_EXPECT(!resp[jss::result].isMember(jss::error));
BEAST_EXPECT(
accountObjects.size() == accountObjectSize - limit * 2);
}

// test account_objects with an invalid marker containing invalid
// dirIndex
{
std::string s = marker.asString();
s.replace(0, 7, "FFFFFFF");
Json::Value params;
params[jss::account] = bob.human();
params[jss::limit] = limit;
params[jss::marker] = s;
params[jss::ledger_index] = "validated";
auto resp = env.rpc("json", "account_objects", to_string(params));
BEAST_EXPECT(
resp[jss::result][jss::error_message] ==
"Invalid field \'marker\'.");
}

// test account_objects with an invalid marker containing invalid
// entryIndex
{
// construct an invalid entry
std::stringstream ss(marker.asString());
std::string s;
std::getline(ss, s, ',');
s = s + ",0";

Json::Value params;
params[jss::account] = bob.human();
params[jss::limit] = limit;
params[jss::marker] = s;
params[jss::ledger_index] = "validated";
auto resp = env.rpc("json", "account_objects", to_string(params));
BEAST_EXPECT(
resp[jss::result][jss::error_message] ==
"Invalid field \'marker\'.");
}
}

void
run() override
{
Expand All @@ -1229,6 +1327,7 @@ class AccountObjects_test : public beast::unit_test::suite
testObjectTypes();
testNFTsMarker();
testAccountNFTs();
testAccountObjectMarker();
}
};

Expand Down
5 changes: 4 additions & 1 deletion src/xrpld/rpc/detail/RPCHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,10 @@ getAccountObjects(
{
// it's possible the user had nftoken pages but no
// directory entries
return mlimit < limit;
if (mlimit >= limit)
jvResult[jss::account_objects] = Json::arrayValue;

return true;
}

std::uint32_t i = 0;
Expand Down
8 changes: 5 additions & 3 deletions src/xrpld/rpc/handlers/AccountObjects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ doAccountObjects(RPC::JsonContext& context)
return RPC::invalid_field_error(jss::marker);
}

// check if dirIndex is valid
if (!dirIndex.isZero() && !ledger->read({ltDIR_NODE, dirIndex}))
return RPC::invalid_field_error(jss::marker);

if (!RPC::getAccountObjects(
*ledger,
accountID,
Expand All @@ -291,9 +295,7 @@ doAccountObjects(RPC::JsonContext& context)
entryIndex,
limit,
result))
{
result[jss::account_objects] = Json::arrayValue;
}
return RPC::invalid_field_error(jss::marker);

result[jss::account] = toBase58(accountID);
context.loadType = Resource::feeMediumBurdenRPC;
Expand Down

0 comments on commit 627655e

Please sign in to comment.