Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposed version 2.2.1 #5078

Merged
merged 3 commits into from
Jul 29, 2024
Merged
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
2 changes: 1 addition & 1 deletion Builds/CMake/RippledCore.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,7 @@ if (tests)
#]===============================]
src/test/rpc/AccountCurrencies_test.cpp
src/test/rpc/AccountInfo_test.cpp
src/test/rpc/AccountLinesRPC_test.cpp
src/test/rpc/AccountLines_test.cpp
src/test/rpc/AccountObjects_test.cpp
src/test/rpc/AccountOffers_test.cpp
src/test/rpc/AccountSet_test.cpp
Expand Down
2 changes: 1 addition & 1 deletion src/ripple/protocol/impl/BuildInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace BuildInfo {
// and follow the format described at http://semver.org/
//------------------------------------------------------------------------------
// clang-format off
char const* const versionString = "2.2.0"
char const* const versionString = "2.2.1"
// clang-format on

#if defined(DEBUG) || defined(SANITIZER)
Expand Down
24 changes: 12 additions & 12 deletions src/ripple/protocol/impl/b58_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define RIPPLE_PROTOCOL_B58_UTILS_H_INCLUDED

#include <ripple/basics/contract.h>
#include <ripple/protocol/impl/token_errors.h>

#include <boost/outcome.hpp>
#include <boost/outcome/result.hpp>
Expand Down Expand Up @@ -71,12 +72,12 @@ carrying_add(std::uint64_t a, std::uint64_t b)
// (i.e a[0] is the 2^0 coefficient, a[n] is the 2^(64*n) coefficient)
// panics if overflows (this is a specialized adder for b58 decoding.
// it should never overflow).
inline void
[[nodiscard]] inline TokenCodecErrc
inplace_bigint_add(std::span<std::uint64_t> a, std::uint64_t b)
{
if (a.size() <= 1)
{
ripple::LogicError("Input span too small for inplace_bigint_add");
return TokenCodecErrc::inputTooSmall;
}

std::uint64_t carry;
Expand All @@ -86,28 +87,29 @@ inplace_bigint_add(std::span<std::uint64_t> a, std::uint64_t b)
{
if (!carry)
{
return;
return TokenCodecErrc::success;
}
std::tie(v, carry) = carrying_add(v, 1);
}
if (carry)
{
LogicError("Overflow in inplace_bigint_add");
return TokenCodecErrc::overflowAdd;
}
return TokenCodecErrc::success;
}

inline void
[[nodiscard]] inline TokenCodecErrc
inplace_bigint_mul(std::span<std::uint64_t> a, std::uint64_t b)
{
if (a.empty())
{
LogicError("Empty span passed to inplace_bigint_mul");
return TokenCodecErrc::inputTooSmall;
}

auto const last_index = a.size() - 1;
if (a[last_index] != 0)
{
LogicError("Non-zero element in inplace_bigint_mul last index");
return TokenCodecErrc::inputTooLarge;
}

std::uint64_t carry = 0;
Expand All @@ -116,7 +118,9 @@ inplace_bigint_mul(std::span<std::uint64_t> a, std::uint64_t b)
std::tie(coeff, carry) = carrying_mul(coeff, b, carry);
}
a[last_index] = carry;
return TokenCodecErrc::success;
}

// divide a "big uint" value inplace and return the mod
// numerator is stored so smallest coefficients come first
[[nodiscard]] inline std::uint64_t
Expand Down Expand Up @@ -166,11 +170,7 @@ inplace_bigint_div_rem(std::span<uint64_t> numerator, std::uint64_t divisor)
b58_10_to_b58_be(std::uint64_t input)
{
constexpr std::uint64_t B_58_10 = 430804206899405824; // 58^10;
if (input >= B_58_10)
{
LogicError("Input to b58_10_to_b58_be equals or exceeds 58^10.");
}

assert(input < B_58_10);
constexpr std::size_t resultSize = 10;
std::array<std::uint8_t, resultSize> result{};
int i = 0;
Expand Down
1 change: 1 addition & 0 deletions src/ripple/protocol/impl/token_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ enum class TokenCodecErrc {
mismatchedTokenType,
mismatchedChecksum,
invalidEncodingChar,
overflowAdd,
unknown,
};
}
Expand Down
26 changes: 22 additions & 4 deletions src/ripple/protocol/impl/tokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,11 @@ b256_to_b58_be(std::span<std::uint8_t const> input, std::span<std::uint8_t> out)
{
continue;
}
static constexpr std::uint64_t B_58_10 = 430804206899405824; // 58^10;
if (base_58_10_coeff[i] >= B_58_10)
{
return Unexpected(TokenCodecErrc::inputTooLarge);
}
std::array<std::uint8_t, 10> const b58_be =
ripple::b58_fast::detail::b58_10_to_b58_be(base_58_10_coeff[i]);
std::size_t to_skip = 0;
Expand Down Expand Up @@ -565,10 +570,23 @@ b58_to_b256_be(std::string_view input, std::span<std::uint8_t> out)
for (int i = 1; i < num_b_58_10_coeffs; ++i)
{
std::uint64_t const c = b_58_10_coeff[i];
ripple::b58_fast::detail::inplace_bigint_mul(
std::span(&result[0], cur_result_size + 1), B_58_10);
ripple::b58_fast::detail::inplace_bigint_add(
std::span(&result[0], cur_result_size + 1), c);

{
auto code = ripple::b58_fast::detail::inplace_bigint_mul(
std::span(&result[0], cur_result_size + 1), B_58_10);
if (code != TokenCodecErrc::success)
{
return Unexpected(code);
}
}
{
auto code = ripple::b58_fast::detail::inplace_bigint_add(
std::span(&result[0], cur_result_size + 1), c);
if (code != TokenCodecErrc::success)
{
return Unexpected(code);
}
}
if (result[cur_result_size] != 0)
{
cur_result_size += 1;
Expand Down
3 changes: 3 additions & 0 deletions src/ripple/rpc/handlers/AccountChannels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ doAccountChannels(RPC::JsonContext& context)
if (!params.isMember(jss::account))
return RPC::missing_field_error(jss::account);

if (!params[jss::account].isString())
return RPC::invalid_field_error(jss::account);

std::shared_ptr<ReadView const> ledger;
auto result = RPC::lookupLedger(ledger, context);
if (!ledger)
Expand Down
24 changes: 17 additions & 7 deletions src/ripple/rpc/handlers/AccountCurrenciesHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,29 @@ doAccountCurrencies(RPC::JsonContext& context)
{
auto& params = context.params;

if (!(params.isMember(jss::account) || params.isMember(jss::ident)))
return RPC::missing_field_error(jss::account);

std::string strIdent;
if (params.isMember(jss::account))
{
if (!params[jss::account].isString())
return RPC::invalid_field_error(jss::account);
strIdent = params[jss::account].asString();
}
else if (params.isMember(jss::ident))
{
if (!params[jss::ident].isString())
return RPC::invalid_field_error(jss::ident);
strIdent = params[jss::ident].asString();
}

// Get the current ledger
std::shared_ptr<ReadView const> ledger;
auto result = RPC::lookupLedger(ledger, context);
if (!ledger)
return result;

if (!(params.isMember(jss::account) || params.isMember(jss::ident)))
return RPC::missing_field_error(jss::account);

std::string const strIdent(
params.isMember(jss::account) ? params[jss::account].asString()
: params[jss::ident].asString());

// Get info on account.
auto id = parseBase58<AccountID>(strIdent);
if (!id)
Expand Down
9 changes: 9 additions & 0 deletions src/ripple/rpc/handlers/AccountInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <ripple/ledger/ReadView.h>
#include <ripple/protocol/ErrorCodes.h>
#include <ripple/protocol/Indexes.h>
#include <ripple/protocol/RPCErr.h>
#include <ripple/protocol/UintTypes.h>
#include <ripple/protocol/jss.h>
#include <ripple/rpc/Context.h>
Expand Down Expand Up @@ -53,9 +54,17 @@ doAccountInfo(RPC::JsonContext& context)

std::string strIdent;
if (params.isMember(jss::account))
{
if (!params[jss::account].isString())
return RPC::invalid_field_error(jss::account);
strIdent = params[jss::account].asString();
}
else if (params.isMember(jss::ident))
{
if (!params[jss::ident].isString())
return RPC::invalid_field_error(jss::ident);
strIdent = params[jss::ident].asString();
}
else
return RPC::missing_field_error(jss::account);

Expand Down
3 changes: 3 additions & 0 deletions src/ripple/rpc/handlers/AccountLines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ doAccountLines(RPC::JsonContext& context)
if (!params.isMember(jss::account))
return RPC::missing_field_error(jss::account);

if (!params[jss::account].isString())
return RPC::invalid_field_error(jss::account);

std::shared_ptr<ReadView const> ledger;
auto result = RPC::lookupLedger(ledger, context);
if (!ledger)
Expand Down
17 changes: 11 additions & 6 deletions src/ripple/rpc/handlers/AccountObjects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,19 @@ doAccountNFTs(RPC::JsonContext& context)
if (!params.isMember(jss::account))
return RPC::missing_field_error(jss::account);

std::shared_ptr<ReadView const> ledger;
auto result = RPC::lookupLedger(ledger, context);
if (ledger == nullptr)
return result;
if (!params[jss::account].isString())
return RPC::invalid_field_error(jss::account);

auto id = parseBase58<AccountID>(params[jss::account].asString());
if (!id)
{
RPC::inject_error(rpcACT_MALFORMED, result);
return result;
return rpcError(rpcACT_MALFORMED);
}

std::shared_ptr<ReadView const> ledger;
auto result = RPC::lookupLedger(ledger, context);
if (ledger == nullptr)
return result;
auto const accountID{id.value()};

if (!ledger->exists(keylet::account(accountID)))
Expand Down Expand Up @@ -167,6 +169,9 @@ doAccountObjects(RPC::JsonContext& context)
if (!params.isMember(jss::account))
return RPC::missing_field_error(jss::account);

if (!params[jss::account].isString())
return RPC::invalid_field_error(jss::account);

std::shared_ptr<ReadView const> ledger;
auto result = RPC::lookupLedger(ledger, context);
if (ledger == nullptr)
Expand Down
13 changes: 8 additions & 5 deletions src/ripple/rpc/handlers/AccountOffers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ doAccountOffers(RPC::JsonContext& context)
if (!params.isMember(jss::account))
return RPC::missing_field_error(jss::account);

if (!params[jss::account].isString())
return RPC::invalid_field_error(jss::account);

std::shared_ptr<ReadView const> ledger;
auto result = RPC::lookupLedger(ledger, context);
if (!ledger)
Expand All @@ -84,7 +87,7 @@ doAccountOffers(RPC::JsonContext& context)
return *err;

if (limit == 0)
return rpcError(rpcINVALID_PARAMS);
return RPC::invalid_field_error(jss::limit);

Json::Value& jsonOffers(result[jss::offers] = Json::arrayValue);
std::vector<std::shared_ptr<SLE const>> offers;
Expand All @@ -101,21 +104,21 @@ doAccountOffers(RPC::JsonContext& context)
std::stringstream marker(params[jss::marker].asString());
std::string value;
if (!std::getline(marker, value, ','))
return rpcError(rpcINVALID_PARAMS);
return RPC::invalid_field_error(jss::marker);

if (!startAfter.parseHex(value))
return rpcError(rpcINVALID_PARAMS);
return RPC::invalid_field_error(jss::marker);

if (!std::getline(marker, value, ','))
return rpcError(rpcINVALID_PARAMS);
return RPC::invalid_field_error(jss::marker);

try
{
startHint = boost::lexical_cast<std::uint64_t>(value);
}
catch (boost::bad_lexical_cast&)
{
return rpcError(rpcINVALID_PARAMS);
return RPC::invalid_field_error(jss::marker);
}

// We then must check if the object pointed to by the marker is actually
Expand Down
9 changes: 6 additions & 3 deletions src/ripple/rpc/handlers/AccountTx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,12 +426,12 @@ doAccountTxJson(RPC::JsonContext& context)
if (context.apiVersion > 1u && params.isMember(jss::binary) &&
!params[jss::binary].isBool())
{
return rpcError(rpcINVALID_PARAMS);
return RPC::invalid_field_error(jss::binary);
}
if (context.apiVersion > 1u && params.isMember(jss::forward) &&
!params[jss::forward].isBool())
{
return rpcError(rpcINVALID_PARAMS);
return RPC::invalid_field_error(jss::forward);
}

args.limit = params.isMember(jss::limit) ? params[jss::limit].asUInt() : 0;
Expand All @@ -440,7 +440,10 @@ doAccountTxJson(RPC::JsonContext& context)
params.isMember(jss::forward) && params[jss::forward].asBool();

if (!params.isMember(jss::account))
return rpcError(rpcINVALID_PARAMS);
return RPC::missing_field_error(jss::account);

if (!params[jss::account].isString())
return RPC::invalid_field_error(jss::account);

auto const account =
parseBase58<AccountID>(params[jss::account].asString());
Expand Down
6 changes: 5 additions & 1 deletion src/ripple/rpc/handlers/NoRippleCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ doNoRippleCheck(RPC::JsonContext& context)

if (!params.isMember("role"))
return RPC::missing_field_error("role");

if (!params[jss::account].isString())
return RPC::invalid_field_error(jss::account);

bool roleGateway = false;
{
std::string const role = params["role"].asString();
Expand All @@ -90,7 +94,7 @@ doNoRippleCheck(RPC::JsonContext& context)
if (context.apiVersion > 1u && params.isMember(jss::transactions) &&
!params[jss::transactions].isBool())
{
return rpcError(rpcINVALID_PARAMS);
return RPC::invalid_field_error(jss::transactions);
}

std::shared_ptr<ReadView const> ledger;
Expand Down
19 changes: 19 additions & 0 deletions src/test/app/PayChan_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,25 @@ struct PayChan_test : public beast::unit_test::suite
auto const chan1Str = to_string(channel(alice, bob, env.seq(alice)));
env(create(alice, bob, channelFunds, settleDelay, pk));
env.close();
{
// test account non-string
auto testInvalidAccountParam = [&](auto const& param) {
Json::Value params;
params[jss::account] = param;
auto jrr = env.rpc(
"json", "account_channels", to_string(params))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(
jrr[jss::error_message] == "Invalid field 'account'.");
};

testInvalidAccountParam(1);
testInvalidAccountParam(1.1);
testInvalidAccountParam(true);
testInvalidAccountParam(Json::Value(Json::nullValue));
testInvalidAccountParam(Json::Value(Json::objectValue));
testInvalidAccountParam(Json::Value(Json::arrayValue));
}
{
auto const r =
env.rpc("account_channels", alice.human(), bob.human());
Expand Down
Loading
Loading