Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/scripts/levelization/results/ordering.txt
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ test.peerfinder > xrpl.protocol
test.protocol > test.jtx
test.protocol > test.unit_test
test.protocol > xrpl.basics
test.protocol > xrpld.core
test.protocol > xrpl.json
test.protocol > xrpl.protocol
test.resource > test.unit_test
Expand Down
62 changes: 62 additions & 0 deletions src/test/app/LedgerReplay_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,46 @@ struct LedgerReplayer_test : public beast::unit_test::Suite
BEAST_EXPECT(!reply->has_error());
BEAST_EXPECT(server.msgHandler.processProofPathResponse(reply));

{
// bad reply: invalid hash/key sizes
{
// reply with undersized ledgerhash (31 bytes)
auto bad = std::make_shared<protocol::TMProofPathResponse>(*reply);
bad->set_ledgerhash(std::string(31, '\x01'));
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(bad));
}
{
// reply with oversized ledgerhash (33 bytes)
auto bad = std::make_shared<protocol::TMProofPathResponse>(*reply);
bad->set_ledgerhash(std::string(33, '\x01'));
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(bad));
}
{
// reply with empty ledgerhash
auto bad = std::make_shared<protocol::TMProofPathResponse>(*reply);
bad->set_ledgerhash(std::string());
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(bad));
}
{
// reply with undersized key (31 bytes)
auto bad = std::make_shared<protocol::TMProofPathResponse>(*reply);
bad->set_key(std::string(31, '\x01'));
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(bad));
}
{
// reply with oversized key (33 bytes)
auto bad = std::make_shared<protocol::TMProofPathResponse>(*reply);
bad->set_key(std::string(33, '\x01'));
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(bad));
}
{
// reply with empty key
auto bad = std::make_shared<protocol::TMProofPathResponse>(*reply);
bad->set_key(std::string());
BEAST_EXPECT(!server.msgHandler.processProofPathResponse(bad));
}
}

{
// bad reply
// bad header
Expand Down Expand Up @@ -988,6 +1028,28 @@ struct LedgerReplayer_test : public beast::unit_test::Suite
BEAST_EXPECT(!reply->has_error());
BEAST_EXPECT(server.msgHandler.processReplayDeltaResponse(reply));

{
// bad reply: invalid hash sizes
{
// reply with undersized ledgerhash (31 bytes)
auto bad = std::make_shared<protocol::TMReplayDeltaResponse>(*reply);
bad->set_ledgerhash(std::string(31, '\x01'));
BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(bad));
}
{
// reply with oversized ledgerhash (33 bytes)
auto bad = std::make_shared<protocol::TMReplayDeltaResponse>(*reply);
bad->set_ledgerhash(std::string(33, '\x01'));
BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(bad));
}
{
// reply with empty ledgerhash
auto bad = std::make_shared<protocol::TMReplayDeltaResponse>(*reply);
bad->set_ledgerhash(std::string());
BEAST_EXPECT(!server.msgHandler.processReplayDeltaResponse(bad));
}
}

{
// bad reply
// bad header
Expand Down
45 changes: 45 additions & 0 deletions src/test/basics/base_uint_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,34 @@ struct base_uint_test : beast::unit_test::Suite
}
}

#ifdef NDEBUG
void
testFromRawSizeMismatch()
{
testcase("base_uint: fromRaw size mismatch");

// Container smaller than the base_uint (8 bytes vs 12 bytes for
// test96). Only the first 8 bytes are copied; the remaining 4 bytes
// stay zero.
{
Blob const tooSmall{1, 2, 3, 4, 5, 6, 7, 8};
test96 const result = test96::fromRaw(tooSmall);
auto const resultText = to_string(result);
BEAST_EXPECTS(resultText.substr(0, 16) == "0102030405060708", resultText);
}

// Container larger than the base_uint (16 bytes vs 12 bytes for
// test96). Only the first 12 bytes are copied; the extra bytes are
// ignored.
{
Blob const tooBig{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
test96 const result = test96::fromRaw(tooBig);
auto const resultText = to_string(result);
BEAST_EXPECTS(resultText == "0102030405060708090A0B0C", resultText);
}
}
#endif

void
run() override
{
Expand All @@ -125,6 +153,10 @@ struct base_uint_test : beast::unit_test::Suite
static_assert(!std::is_constructible_v<test96, std::complex<double>>);
static_assert(!std::is_assignable_v<test96&, std::complex<double>>);

#ifdef NDEBUG
testFromRawSizeMismatch();
#endif

testComparisons();

// used to verify set insertion (hashing required)
Expand Down Expand Up @@ -194,6 +226,19 @@ struct base_uint_test : beast::unit_test::Suite
BEAST_EXPECT(d == 0);
}

{
// There are several ways to create a zero. beast::kZero is tested above. Test some
// others.
test96 z1;
BEAST_EXPECTS(z1 == z, to_string(z1));

test96 z2{};
BEAST_EXPECTS(z2 == z, to_string(z2));

test96 z3{0u};
BEAST_EXPECTS(z3 == z, to_string(z2));
}

test96 n{z};
n++;
BEAST_EXPECT(n == test96(1));
Expand Down
100 changes: 100 additions & 0 deletions src/test/protocol/Issue_test.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#include <xrpl/basics/UnorderedContainers.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/unit_test/suite.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Book.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/jss.h>

#include <functional>
#include <map>
Expand Down Expand Up @@ -863,6 +865,101 @@ class Issue_test : public beast::unit_test::Suite

//--------------------------------------------------------------------------

void
testIssueFromJson()
{
testcase("issueFromJson");

// Valid XRP — no issuer field
{
json::Value jv;
jv[jss::currency] = "XRP";
auto const issue = issueFromJson(jv);
BEAST_EXPECT(isXRP(issue));
}

// Valid IOU — legitimate issuer
{
json::Value jv;
jv[jss::currency] = "USD";
jv[jss::issuer] = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
auto const issue = issueFromJson(jv);
BEAST_EXPECT(!isXRP(issue));
BEAST_EXPECT(issue.account != noAccount());
}

// noAccount() is the MPT sentinel in binary serialization - must be
// rejected
try
{
json::Value jv;
jv[jss::currency] = "USD";
jv[jss::issuer] = to_string(noAccount());
issueFromJson(jv);
fail("noAccount() accepted as IOU issuer");
}
catch (...)
{
pass();
}

// xrpAccount() is the XRP sentinel (all zeros) - must be rejected
// as IOU issuer
try
{
json::Value jv;
jv[jss::currency] = "USD";
jv[jss::issuer] = to_string(xrpAccount());
issueFromJson(jv);
fail("xrpAccount() accepted as IOU issuer");
}
catch (...)
{
pass();
}

// Invalid base58 — must be rejected
try
{
json::Value jv;
jv[jss::currency] = "USD";
jv[jss::issuer] = "not_a_valid_address";
issueFromJson(jv);
fail("invalid base58 accepted as IOU issuer");
}
catch (...)
{
pass();
}

// Non-XRP currency with no issuer field — must be rejected
try
{
json::Value jv;
jv[jss::currency] = "USD";
issueFromJson(jv);
fail("missing issuer accepted");
}
catch (...)
{
pass();
}

// XRP with an issuer field — must be rejected
try
{
json::Value jv;
jv[jss::currency] = "XRP";
jv[jss::issuer] = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
issueFromJson(jv);
fail("XRP with issuer accepted");
}
catch (...)
{
pass();
}
}

void
run() override
{
Expand Down Expand Up @@ -897,6 +994,9 @@ class Issue_test : public beast::unit_test::Suite
// ---
testIssueDomainSets();
testIssueDomainMaps();

// ---
testIssueFromJson();
}
};

Expand Down
Loading
Loading