mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-28 22:45:49 +00:00
cherry-ff (#52)
Co-authored-by: Richard Holland <richard.holland@starstone.co.nz>
This commit is contained in:
@@ -58,51 +58,62 @@ URIToken::preflight(PreflightContext const& ctx)
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
if (!([](std::vector<uint8_t> const& u) -> bool
|
||||
{
|
||||
// this code is from https://www.cl.cam.ac.uk/~mgk25/ucs/utf8_check.c
|
||||
if (!([](std::vector<uint8_t> const& u) -> bool {
|
||||
// this code is from
|
||||
// https://www.cl.cam.ac.uk/~mgk25/ucs/utf8_check.c
|
||||
uint8_t const* s = (uint8_t const*)u.data();
|
||||
uint8_t const* end = s + u.size();
|
||||
while (s < end) {
|
||||
while (s < end)
|
||||
{
|
||||
if (*s < 0x80)
|
||||
/* 0xxxxxxx */
|
||||
s++;
|
||||
else if ((s[0] & 0xe0) == 0xc0) {
|
||||
else if ((s[0] & 0xe0) == 0xc0)
|
||||
{
|
||||
/* 110XXXXx 10xxxxxx */
|
||||
if ((s[1] & 0xc0) != 0x80 ||
|
||||
(s[0] & 0xfe) == 0xc0) /* overlong? */
|
||||
(s[0] & 0xfe) == 0xc0) /* overlong? */
|
||||
return false;
|
||||
else
|
||||
s += 2;
|
||||
} else if ((s[0] & 0xf0) == 0xe0) {
|
||||
}
|
||||
else if ((s[0] & 0xf0) == 0xe0)
|
||||
{
|
||||
/* 1110XXXX 10Xxxxxx 10xxxxxx */
|
||||
if ((s[1] & 0xc0) != 0x80 ||
|
||||
(s[2] & 0xc0) != 0x80 ||
|
||||
(s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || /* overlong? */
|
||||
(s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || /* surrogate? */
|
||||
(s[0] == 0xef && s[1] == 0xbf &&
|
||||
(s[2] & 0xfe) == 0xbe)) /* U+FFFE or U+FFFF? */
|
||||
(s[2] & 0xc0) != 0x80 ||
|
||||
(s[0] == 0xe0 &&
|
||||
(s[1] & 0xe0) == 0x80) || /* overlong? */
|
||||
(s[0] == 0xed &&
|
||||
(s[1] & 0xe0) == 0xa0) || /* surrogate? */
|
||||
(s[0] == 0xef && s[1] == 0xbf &&
|
||||
(s[2] & 0xfe) == 0xbe)) /* U+FFFE or U+FFFF? */
|
||||
return false;
|
||||
else
|
||||
s += 3;
|
||||
} else if ((s[0] & 0xf8) == 0xf0) {
|
||||
}
|
||||
else if ((s[0] & 0xf8) == 0xf0)
|
||||
{
|
||||
/* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */
|
||||
if ((s[1] & 0xc0) != 0x80 ||
|
||||
(s[2] & 0xc0) != 0x80 ||
|
||||
(s[3] & 0xc0) != 0x80 ||
|
||||
(s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || /* overlong? */
|
||||
(s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) /* > U+10FFFF? */
|
||||
(s[2] & 0xc0) != 0x80 ||
|
||||
(s[3] & 0xc0) != 0x80 ||
|
||||
(s[0] == 0xf0 &&
|
||||
(s[1] & 0xf0) == 0x80) || /* overlong? */
|
||||
(s[0] == 0xf4 && s[1] > 0x8f) ||
|
||||
s[0] > 0xf4) /* > U+10FFFF? */
|
||||
return false;
|
||||
else
|
||||
s += 4;
|
||||
} else
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})(uri))
|
||||
{
|
||||
JLOG(ctx.j.warn())
|
||||
<< "Malformed transaction. URI must be a valid utf-8 string.";
|
||||
JLOG(ctx.j.warn()) << "Malformed transaction. URI must be a "
|
||||
"valid utf-8 string.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
@@ -221,8 +232,7 @@ URIToken::preclaim(PreclaimContext const& ctx)
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
case ttURITOKEN_BUY:
|
||||
{
|
||||
case ttURITOKEN_BUY: {
|
||||
if (acc == *owner)
|
||||
return tecCANT_ACCEPT_OWN_NFTOKEN_OFFER;
|
||||
|
||||
@@ -512,7 +522,6 @@ URIToken::doApply()
|
||||
return tecNO_LINE_INSUF_RESERVE;
|
||||
}
|
||||
}
|
||||
|
||||
if (buyerIssuer)
|
||||
{
|
||||
// pass: issuer does not adjust own trustline
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace ripple {
|
||||
class URIToken : public Transactor
|
||||
{
|
||||
public:
|
||||
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit URIToken(ApplyContext& ctx) : Transactor(ctx)
|
||||
|
||||
@@ -633,7 +633,7 @@ trustTransferAllowed(
|
||||
std::shared_ptr<SLE>,
|
||||
std::shared_ptr<SLE const>>::type SLEPtr;
|
||||
|
||||
if (isFakeXRP(issue.currency))
|
||||
if (issue.currency == badCurrency())
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
auto const sleIssuerAcc = view.read(keylet::account(issue.account));
|
||||
@@ -680,6 +680,7 @@ trustTransferAllowed(
|
||||
}
|
||||
|
||||
// sanity check the line, insane lines are a bar to xfer
|
||||
if (lockedBalanceAllowed)
|
||||
{
|
||||
// these "strange" old lines, if they even exist anymore are
|
||||
// always a bar to xfer
|
||||
|
||||
@@ -418,7 +418,9 @@ Keylet
|
||||
uritoken(AccountID const& issuer, Blob const& uri)
|
||||
{
|
||||
return {
|
||||
ltURI_TOKEN, indexHash(LedgerNameSpace::URI_TOKEN, issuer, Slice{uri.data(), uri.size()})};
|
||||
ltURI_TOKEN,
|
||||
indexHash(
|
||||
LedgerNameSpace::URI_TOKEN, issuer, Slice{uri.data(), uri.size()})};
|
||||
}
|
||||
|
||||
} // namespace keylet
|
||||
|
||||
@@ -135,6 +135,12 @@ JSS(TxnSignature); // field.
|
||||
JSS(TransactionType); // in: TransactionSign.
|
||||
JSS(TransferRate); // in: TransferRate.
|
||||
JSS(TrustSet); // transaction type.
|
||||
JSS(URIToken); // LedgerEntry
|
||||
JSS(URITokenMint); // tx type
|
||||
JSS(URITokenBurn); // tx type
|
||||
JSS(URITokenBuy); // tx type
|
||||
JSS(URITokenCreateSellOffer); // tx type
|
||||
JSS(URITokenCancelSellOffer); // tx type
|
||||
JSS(aborted); // out: InboundLedger
|
||||
JSS(accepted); // out: LedgerToJson, OwnerInfo, SubmitTransaction
|
||||
JSS(account); // in/out: many
|
||||
@@ -666,12 +672,6 @@ JSS(unl); // out: UnlList
|
||||
JSS(unlimited); // out: Connection.h
|
||||
JSS(uptime); // out: GetCounts
|
||||
JSS(uri); // out: ValidatorSites
|
||||
JSS(URIToken); // LedgerEntry
|
||||
JSS(URITokenMint); // tx type
|
||||
JSS(URITokenBurn); // tx type
|
||||
JSS(URITokenBuy); // tx type
|
||||
JSS(URITokenCreateSellOffer); // tx type
|
||||
JSS(URITokenCancelSellOffer); // tx type
|
||||
JSS(url); // in/out: Subscribe, Unsubscribe
|
||||
JSS(url_password); // in: Subscribe
|
||||
JSS(url_username); // in: Subscribe
|
||||
|
||||
@@ -206,6 +206,7 @@ doAccountObjects(RPC::JsonContext& context)
|
||||
{jss::escrow, ltESCROW},
|
||||
{jss::nft_page, ltNFTOKEN_PAGE},
|
||||
{jss::payment_channel, ltPAYCHAN},
|
||||
{jss::uri_token, ltURI_TOKEN},
|
||||
{jss::state, ltRIPPLE_STATE}};
|
||||
|
||||
typeFilter.emplace();
|
||||
|
||||
@@ -259,6 +259,16 @@ doLedgerEntry(RPC::JsonContext& context)
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
}
|
||||
}
|
||||
else if (context.params.isMember(jss::uri_token))
|
||||
{
|
||||
expectedType = ltURI_TOKEN;
|
||||
|
||||
if (!uNodeIndex.parseHex(context.params[jss::uri_token].asString()))
|
||||
{
|
||||
uNodeIndex = beast::zero;
|
||||
jvResult[jss::error] = "malformedRequest";
|
||||
}
|
||||
}
|
||||
else if (context.params.isMember(jss::ripple_state))
|
||||
{
|
||||
expectedType = ltRIPPLE_STATE;
|
||||
|
||||
@@ -1076,6 +1076,7 @@ chooseLedgerEntryType(Json::Value const& params)
|
||||
{jss::hashes, ltLEDGER_HASHES},
|
||||
{jss::offer, ltOFFER},
|
||||
{jss::payment_channel, ltPAYCHAN},
|
||||
{jss::uri_token, ltURI_TOKEN},
|
||||
{jss::signer_list, ltSIGNER_LIST},
|
||||
{jss::state, ltRIPPLE_STATE},
|
||||
{jss::ticket, ltTICKET},
|
||||
|
||||
@@ -46,7 +46,8 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
{
|
||||
auto const uritSle = view.read({ltURI_TOKEN, tid});
|
||||
ripple::Dir const ownerDir(view, keylet::ownerDir(acct.id()));
|
||||
return std::find(ownerDir.begin(), ownerDir.end(), uritSle) != ownerDir.end();
|
||||
return std::find(ownerDir.begin(), ownerDir.end(), uritSle) !=
|
||||
ownerDir.end();
|
||||
}
|
||||
|
||||
static std::size_t
|
||||
@@ -116,8 +117,7 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
jtx::Account const& gw,
|
||||
jtx::IOU const& iou)
|
||||
{
|
||||
auto const sle =
|
||||
env.le(keylet::line(account, gw, iou.currency));
|
||||
auto const sle = env.le(keylet::line(account, gw, iou.currency));
|
||||
if (sle && sle->isFieldPresent(sfBalance))
|
||||
return (*sle)[sfBalance];
|
||||
return STAmount(iou, 0);
|
||||
@@ -200,7 +200,8 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
{
|
||||
// If the URIToken amendment is not enabled, you should not be able
|
||||
// to mint, burn, buy, sell or clear uri tokens.
|
||||
auto const amend = withURIToken ? features : features - featureURIToken;
|
||||
auto const amend =
|
||||
withURIToken ? features : features - featureURIToken;
|
||||
Env env{*this, amend};
|
||||
|
||||
env.fund(XRP(1000), alice, bob);
|
||||
@@ -558,7 +559,6 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
// tecINSUFFICIENT_FUNDS - insuficient amount sent
|
||||
env(buy(bob, hexid, USD(10000)), ter(tecINSUFFICIENT_FUNDS));
|
||||
env.close();
|
||||
|
||||
// tecNO_LINE_INSUF_RESERVE - insuficient xrp to create line
|
||||
{
|
||||
// fund dave 251 xrp (not enough for line reserve)
|
||||
@@ -656,7 +656,8 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
auto const tid = tokenid(alice, uri);
|
||||
std::string const hexid{strHex(tid)};
|
||||
|
||||
std::string const digestval = "C16E7263F07AA41261DCC955660AF4646ADBA414E37B6F5A5BA50F75153F5CCC";
|
||||
std::string const digestval =
|
||||
"C16E7263F07AA41261DCC955660AF4646ADBA414E37B6F5A5BA50F75153F5CCC";
|
||||
|
||||
// has digest - has uri - no flags
|
||||
{
|
||||
@@ -664,7 +665,8 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
env(mint(alice, uri), json(sfDigest.fieldName, digestval));
|
||||
env.close();
|
||||
BEAST_EXPECT(inOwnerDir(*env.current(), alice, tid));
|
||||
BEAST_EXPECT(to_string(tokenDigest(*env.current(), tid)) == digestval);
|
||||
BEAST_EXPECT(
|
||||
to_string(tokenDigest(*env.current(), tid)) == digestval);
|
||||
// cleanup
|
||||
env(burn(alice, hexid));
|
||||
env.close();
|
||||
@@ -678,7 +680,8 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
json(sfDigest.fieldName, digestval));
|
||||
env.close();
|
||||
BEAST_EXPECT(inOwnerDir(*env.current(), alice, tid));
|
||||
BEAST_EXPECT(to_string(tokenDigest(*env.current(), tid)) == digestval);
|
||||
BEAST_EXPECT(
|
||||
to_string(tokenDigest(*env.current(), tid)) == digestval);
|
||||
// cleanup
|
||||
env(burn(alice, hexid));
|
||||
env.close();
|
||||
@@ -1404,7 +1407,6 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
auto const USD = t.gw["USD"];
|
||||
env.fund(XRP(5000), t.src, t.dst, t.gw);
|
||||
env.close();
|
||||
|
||||
if (t.hasTrustline)
|
||||
env.trust(USD(100000), t.src, t.dst);
|
||||
else
|
||||
@@ -1457,21 +1459,19 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
bool negative;
|
||||
};
|
||||
|
||||
std::array<TestAccountData, 4> tests = {
|
||||
{
|
||||
// acct no trustline
|
||||
// acct > issuer
|
||||
{Account("alice2"), Account{"gw0"}, false, true},
|
||||
// acct < issuer
|
||||
{Account("carol0"), Account{"gw1"}, false, false},
|
||||
std::array<TestAccountData, 4> tests = {{
|
||||
// acct no trustline
|
||||
// acct > issuer
|
||||
{Account("alice2"), Account{"gw0"}, false, true},
|
||||
// acct < issuer
|
||||
{Account("carol0"), Account{"gw1"}, false, false},
|
||||
|
||||
// acct has trustline
|
||||
// acct > issuer
|
||||
{Account("alice2"), Account{"gw0"}, true, true},
|
||||
// acct < issuer
|
||||
{Account("carol0"), Account{"gw1"}, true, false},
|
||||
}
|
||||
};
|
||||
// acct has trustline
|
||||
// acct > issuer
|
||||
{Account("alice2"), Account{"gw0"}, true, true},
|
||||
// acct < issuer
|
||||
{Account("carol0"), Account{"gw1"}, true, false},
|
||||
}};
|
||||
|
||||
// test gateway is buyer
|
||||
for (auto const& t : tests)
|
||||
@@ -1488,7 +1488,6 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
|
||||
if (t.hasTrustline)
|
||||
env(pay(t.gw, t.acct, USD(10000)));
|
||||
|
||||
env.close();
|
||||
|
||||
// acct can create uritoken
|
||||
@@ -1504,7 +1503,8 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
env(sell(t.acct, id, delta));
|
||||
env.close();
|
||||
auto const preAmount = t.hasTrustline ? 10000 : 0;
|
||||
BEAST_EXPECT(preAcct == (t.negative ? -USD(preAmount) : USD(preAmount)));
|
||||
BEAST_EXPECT(
|
||||
preAcct == (t.negative ? -USD(preAmount) : USD(preAmount)));
|
||||
|
||||
// gw can create buy
|
||||
env(buy(t.gw, id, delta));
|
||||
@@ -1544,7 +1544,8 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
env(sell(t.gw, id, delta));
|
||||
env.close();
|
||||
auto const preAmount = 10000;
|
||||
BEAST_EXPECT(preAcct == (t.negative ? -USD(preAmount) : USD(preAmount)));
|
||||
BEAST_EXPECT(
|
||||
preAcct == (t.negative ? -USD(preAmount) : USD(preAmount)));
|
||||
|
||||
// acct can create buy
|
||||
env(buy(t.acct, id, delta));
|
||||
@@ -1623,7 +1624,6 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
auto const carol = Account("carol");
|
||||
auto const gw = Account{"gateway"};
|
||||
auto const USD = gw["USD"];
|
||||
|
||||
// test Global Freeze
|
||||
{
|
||||
// setup env
|
||||
@@ -1752,7 +1752,6 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
std::string const id{strHex(tokenid(alice, uri))};
|
||||
auto const delta = USD(100);
|
||||
auto preBob = env.balance(bob, USD.issue());
|
||||
|
||||
// alice mints and sells
|
||||
env(mint(alice, uri));
|
||||
env(sell(alice, id, delta));
|
||||
@@ -1803,7 +1802,6 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
// alice mints
|
||||
env(mint(alice, uri));
|
||||
env.close();
|
||||
|
||||
// alice sells
|
||||
env(sell(alice, hexid, delta));
|
||||
env.close();
|
||||
@@ -1912,7 +1910,6 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
|
||||
// test utf-8 success
|
||||
{
|
||||
|
||||
// case: kosme
|
||||
uri = "κόσμε";
|
||||
env(mint(alice, uri));
|
||||
@@ -1950,7 +1947,8 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
|
||||
// case: 1 byte (U-00000000)
|
||||
uri = "\x00";
|
||||
env(mint(alice, uri), ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
env(mint(alice, uri),
|
||||
ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
// case: 2 bytes (U-00000080)
|
||||
uri = "\xC2\x80";
|
||||
env(mint(alice, uri));
|
||||
@@ -1962,10 +1960,12 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
env(mint(alice, uri));
|
||||
// case: 5 bytes (U-00200000)
|
||||
uri = "\xF8\x88\x80\x80\x80";
|
||||
env(mint(alice, uri), ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
env(mint(alice, uri),
|
||||
ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
// case: 6 bytes (U-04000000)
|
||||
uri = "\xFC\x84\x80\x80\x80\x80";
|
||||
env(mint(alice, uri), ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
env(mint(alice, uri),
|
||||
ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
|
||||
// BOUNDRY - END
|
||||
// ----------------------------------------------------------------
|
||||
@@ -1978,22 +1978,27 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
env(mint(alice, uri));
|
||||
// case: 3 bytes (U-0000FFFF)
|
||||
uri = "\xEF\xBF\xBF";
|
||||
env(mint(alice, uri), ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
env(mint(alice, uri),
|
||||
ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
// case: 4 bytes (U-001FFFFF)
|
||||
uri = "\xF7\xBF\xBF\xBF";
|
||||
env(mint(alice, uri), ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
env(mint(alice, uri),
|
||||
ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
// case: 5 bytes (U-03FFFFFF)
|
||||
uri = "\xFB\xBF\xBF\xBF\xBF";
|
||||
env(mint(alice, uri), ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
env(mint(alice, uri),
|
||||
ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
// case: 6 bytes (U-7FFFFFFF)
|
||||
uri = "\xFD\xBF\xBF\xBF\xBF\xBF";
|
||||
env(mint(alice, uri), ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
env(mint(alice, uri),
|
||||
ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
|
||||
// // BOUNDRY - OTHER
|
||||
// ----------------------------------------------------------------
|
||||
// case: 1 bytes (U-0000D7FF)
|
||||
uri = "\xD7\xFF";
|
||||
env(mint(alice, uri), ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
env(mint(alice, uri),
|
||||
ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
// case: 2 bytes (U-0000E000)
|
||||
uri = "\xEE\x80\x80";
|
||||
env(mint(alice, uri));
|
||||
@@ -2005,7 +2010,8 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
env(mint(alice, uri));
|
||||
// // case: 4 bytes (U-00110000)
|
||||
uri = "\xF4\x90\x80\x80";
|
||||
env(mint(alice, uri), ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
env(mint(alice, uri),
|
||||
ter(temMALFORMED)); // TODO: REVIEW - SHOULD NOT FAIL
|
||||
}
|
||||
// test utf8 malformed
|
||||
{
|
||||
@@ -2014,59 +2020,77 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
// First continuation byte 0x80:
|
||||
uri = "\x80";
|
||||
env(mint(alice, uri), ter(temMALFORMED));
|
||||
|
||||
// Last continuation byte 0xbf
|
||||
uri = "\xBF";
|
||||
env(mint(alice, uri), ter(temMALFORMED));
|
||||
|
||||
// 2 continuation bytes
|
||||
uri = "<EFBFBD><EFBFBD>";
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
|
||||
// 3 continuation bytes
|
||||
uri = "<EFBFBD><EFBFBD><EFBFBD>";
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
|
||||
// 4 continuation bytes
|
||||
uri = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
|
||||
// 5 continuation bytes
|
||||
uri = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
|
||||
// 6 continuation bytes
|
||||
uri = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
|
||||
// 7 continuation bytes
|
||||
uri = "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
|
||||
// Sequence of all 64 possible continuation bytes (0x80-0xbf)
|
||||
uri = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF";
|
||||
uri =
|
||||
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E"
|
||||
"\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D"
|
||||
"\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC"
|
||||
"\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB"
|
||||
"\xBC\xBD\xBE\xBF";
|
||||
env(mint(alice, uri), ter(temMALFORMED));
|
||||
|
||||
// TODO: REVIEW - THIS IS NOT THE CORRECT 32 byte sequence.
|
||||
// All 32 first bytes of 2-byte sequences (0xc0-0xdf), each followed
|
||||
// by a space character
|
||||
// uri = "\xE0\x80\x80 \xE0\x80\x81 \xE0\x80\x82 \xE0\x80\x83 \xE0\x80\x84 \xE0\x80\x85 \xE0\x80\x86 \xE0\x80\x87 \xE0\x80\x88 \xE0\x80\x89 \xE0\x80\x8A \xE0\x80\x8B \xE0\x80\x8C \xE0\x80\x8D \xE0\x80\x8E \xE0\x80\x8F \xE0\x80\x90";
|
||||
// env(mint(alice, uri), ter(temMALFORMED));
|
||||
// uri = "\xE0\x80\x80 \xE0\x80\x81 \xE0\x80\x82 \xE0\x80\x83
|
||||
// \xE0\x80\x84 \xE0\x80\x85 \xE0\x80\x86 \xE0\x80\x87 \xE0\x80\x88
|
||||
// \xE0\x80\x89 \xE0\x80\x8A \xE0\x80\x8B \xE0\x80\x8C \xE0\x80\x8D
|
||||
// \xE0\x80\x8E \xE0\x80\x8F \xE0\x80\x90"; env(mint(alice, uri),
|
||||
// ter(temMALFORMED));
|
||||
|
||||
// All 16 first bytes of 3-byte sequences (0xe0-0xef), each followed
|
||||
// by a space character
|
||||
uri = "\xE0\x80\x80 \xE0\x80\x81 \xE0\x80\x82 \xE0\x80\x83 \xE0\x80\x84 \xE0\x80\x85 \xE0\x80\x86 \xE0\x80\x87 \xE0\x80\x88 \xE0\x80\x89 \xE0\x80\x8A \xE0\x80\x8B \xE0\x80\x8C \xE0\x80\x8D \xE0\x80\x8E \xE0\x80\x8F \xE0\x80\x90";
|
||||
uri =
|
||||
"\xE0\x80\x80 \xE0\x80\x81 \xE0\x80\x82 \xE0\x80\x83 "
|
||||
"\xE0\x80\x84 \xE0\x80\x85 \xE0\x80\x86 \xE0\x80\x87 "
|
||||
"\xE0\x80\x88 \xE0\x80\x89 \xE0\x80\x8A \xE0\x80\x8B "
|
||||
"\xE0\x80\x8C \xE0\x80\x8D \xE0\x80\x8E \xE0\x80\x8F "
|
||||
"\xE0\x80\x90";
|
||||
env(mint(alice, uri), ter(temMALFORMED));
|
||||
|
||||
// All 8 first bytes of 4-byte sequences (0xf0-0xf7), each followed
|
||||
// by a space character
|
||||
uri = "\xF0\x90\x80\x80 \xF0\x90\x80\x81 \xF0\x90\x80\x82 \xF0\x90\x80\x83 \xF0\x90\x80\x84 \xF0\x90\x80\x85 \xF0\x90\x80\x86 \xF0\x90\x80\x87";
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
uri =
|
||||
"\xF0\x90\x80\x80 \xF0\x90\x80\x81 \xF0\x90\x80\x82 "
|
||||
"\xF0\x90\x80\x83 \xF0\x90\x80\x84 \xF0\x90\x80\x85 "
|
||||
"\xF0\x90\x80\x86 \xF0\x90\x80\x87";
|
||||
env(mint(alice, uri)); // TODO: REVIEW - SHOULD FAIL
|
||||
|
||||
// All 4 first bytes of 5-byte sequences (0xf8-0xfb), each followed
|
||||
// by a space character
|
||||
uri = "\xF8\x88\x80\x80\x80 \xF8\x88\x80\x80\x81 \xF8\x88\x80\x80\x82 \xF8\x88\x80\x80\x83";
|
||||
env(mint(alice, uri), ter(temMALFORMED)); // TODO: REVIEW - SHOULD FAIL
|
||||
uri =
|
||||
"\xF8\x88\x80\x80\x80 \xF8\x88\x80\x80\x81 "
|
||||
"\xF8\x88\x80\x80\x82 \xF8\x88\x80\x80\x83";
|
||||
env(mint(alice, uri),
|
||||
ter(temMALFORMED)); // TODO: REVIEW - SHOULD FAIL
|
||||
|
||||
// All 2 first bytes of 6-byte sequences (0xfc-0xfd), each followed
|
||||
// by a space character
|
||||
@@ -2194,7 +2218,6 @@ struct URIToken_test : public beast::unit_test::suite
|
||||
env(mint(alice, uri), ter(temMALFORMED));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testWithFeats(FeatureBitset features)
|
||||
{
|
||||
|
||||
@@ -585,6 +585,7 @@ public:
|
||||
BEAST_EXPECT(acct_objs_is_size(acct_objs(gw, jss::signer_list), 0));
|
||||
BEAST_EXPECT(acct_objs_is_size(acct_objs(gw, jss::state), 0));
|
||||
BEAST_EXPECT(acct_objs_is_size(acct_objs(gw, jss::ticket), 0));
|
||||
BEAST_EXPECT(acct_objs_is_size(acct_objs(gw, jss::uri_token), 0));
|
||||
|
||||
// gw mints an NFT so we can find it.
|
||||
uint256 const nftID{token::getNextID(env, gw, 0u, tfTransferable)};
|
||||
@@ -746,7 +747,7 @@ public:
|
||||
{
|
||||
// Find the uri token.
|
||||
std::string const uri(maxTokenURILength, '?');
|
||||
Json::Value const resp = acct_objs(gw, jss::URIToken);
|
||||
Json::Value const resp = acct_objs(gw, jss::uri_token);
|
||||
BEAST_EXPECT(acct_objs_is_size(resp, 1));
|
||||
|
||||
auto const& uritoken = resp[jss::result][jss::account_objects][0u];
|
||||
@@ -767,7 +768,8 @@ public:
|
||||
jss::Check.c_str(),
|
||||
jss::NFTokenPage.c_str(),
|
||||
jss::RippleState.c_str(),
|
||||
jss::PayChannel.c_str()};
|
||||
jss::PayChannel.c_str(),
|
||||
jss::URIToken.c_str()};
|
||||
std::sort(v.begin(), v.end());
|
||||
return v;
|
||||
}();
|
||||
|
||||
@@ -1230,7 +1230,8 @@ class LedgerRPC_test : public beast::unit_test::suite
|
||||
env.close();
|
||||
|
||||
// Lambda to create an uritoken.
|
||||
auto mint = [](test::jtx::Account const& account, std::string const& uri) {
|
||||
auto mint = [](test::jtx::Account const& account,
|
||||
std::string const& uri) {
|
||||
Json::Value jv;
|
||||
jv[jss::TransactionType] = jss::URITokenMint;
|
||||
jv[jss::Flags] = tfBurnable;
|
||||
@@ -1246,13 +1247,15 @@ class LedgerRPC_test : public beast::unit_test::suite
|
||||
|
||||
std::string const ledgerHash{to_string(env.closed()->info().hash)};
|
||||
|
||||
uint256 const uritokenIndex{keylet::uritoken(alice, Blob(uri.begin(), uri.end())).key};
|
||||
uint256 const uritokenIndex{
|
||||
keylet::uritoken(alice, Blob(uri.begin(), uri.end())).key};
|
||||
{
|
||||
// Request the uritoken using its index.
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::URIToken] = to_string(uritokenIndex);
|
||||
jvParams[jss::uri_token] = to_string(uritokenIndex);
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
Json::Value const jrr = env.rpc("json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::node][sfOwner.jsonName] == alice.human());
|
||||
BEAST_EXPECT(jrr[jss::node][sfURI.jsonName] == strHex(uri));
|
||||
BEAST_EXPECT(jrr[jss::node][sfFlags.jsonName] == 1);
|
||||
@@ -1260,7 +1263,7 @@ class LedgerRPC_test : public beast::unit_test::suite
|
||||
{
|
||||
// Request an index that is not a uritoken.
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::URIToken] = ledgerHash;
|
||||
jvParams[jss::uri_token] = ledgerHash;
|
||||
jvParams[jss::ledger_hash] = ledgerHash;
|
||||
Json::Value const jrr = env.rpc(
|
||||
"json", "ledger_entry", to_string(jvParams))[jss::result];
|
||||
|
||||
Reference in New Issue
Block a user