mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Clean up and secure subscribe books.
This commit is contained in:
@@ -2642,11 +2642,11 @@ Json::Value RPCHandler::doSubscribe(Json::Value jvRequest, int& cost)
|
||||
std::string strUsername = jvRequest.isMember("url_username") ? jvRequest["url_username"].asString() : "";
|
||||
std::string strPassword = jvRequest.isMember("url_password") ? jvRequest["url_password"].asString() : "";
|
||||
|
||||
// DEPRICATED
|
||||
// DEPRECATED
|
||||
if (jvRequest.isMember("username"))
|
||||
strUsername = jvRequest["username"].asString();
|
||||
|
||||
// DEPRICATED
|
||||
// DEPRECATED
|
||||
if (jvRequest.isMember("password"))
|
||||
strPassword = jvRequest["password"].asString();
|
||||
|
||||
@@ -2753,12 +2753,25 @@ Json::Value RPCHandler::doSubscribe(Json::Value jvRequest, int& cost)
|
||||
}
|
||||
|
||||
if (jvRequest.isMember("books"))
|
||||
{ // FIXME: This can crash the server if the parameters to things like getBookPage are invalid
|
||||
{
|
||||
for (Json::Value::iterator it = jvRequest["books"].begin(); it != jvRequest["books"].end(); it++)
|
||||
{
|
||||
uint160 uTakerPaysCurrencyID;
|
||||
uint160 uTakerPaysIssuerID;
|
||||
Json::Value jvTakerPays = (*it)["taker_pays"];
|
||||
Json::Value& jvSubRequest = *it;
|
||||
uint160 uTakerPaysCurrencyID;
|
||||
uint160 uTakerPaysIssuerID;
|
||||
uint160 uTakerGetsCurrencyID;
|
||||
uint160 uTakerGetsIssuerID;
|
||||
bool bBoth = (jvSubRequest.isMember("both") && jvSubRequest["both"].asBool())
|
||||
|| (jvSubRequest.isMember("both_sides") && jvSubRequest["both_sides"].asBool()); // DEPRECATED
|
||||
bool bSnapshot = (jvSubRequest.isMember("snapshot") && jvSubRequest["snapshot"].asBool())
|
||||
|| (jvSubRequest.isMember("start_now") && jvSubRequest["start_now"].asBool()); // DEPRECATED
|
||||
|
||||
|
||||
if (!jvSubRequest.isMember("taker_pays") || !jvSubRequest.isMember("taker_gets"))
|
||||
return rpcError(rpcINVALID_PARAMS);
|
||||
|
||||
Json::Value jvTakerPays = jvSubRequest["taker_pays"];
|
||||
Json::Value jvTakerGets = jvSubRequest["taker_gets"];
|
||||
|
||||
// Parse mandatory currency.
|
||||
if (!jvTakerPays.isMember("currency")
|
||||
@@ -2781,10 +2794,6 @@ Json::Value RPCHandler::doSubscribe(Json::Value jvRequest, int& cost)
|
||||
return rpcError(rpcSRC_ISR_MALFORMED);
|
||||
}
|
||||
|
||||
uint160 uTakerGetsCurrencyID;
|
||||
uint160 uTakerGetsIssuerID;
|
||||
Json::Value jvTakerGets = (*it)["taker_gets"];
|
||||
|
||||
// Parse mandatory currency.
|
||||
if (!jvTakerGets.isMember("currency")
|
||||
|| !STAmount::currencyFromString(uTakerGetsCurrencyID, jvTakerGets["currency"].asString()))
|
||||
@@ -2816,38 +2825,45 @@ Json::Value RPCHandler::doSubscribe(Json::Value jvRequest, int& cost)
|
||||
|
||||
RippleAddress raTakerID;
|
||||
|
||||
if (!(*it).isMember("taker"))
|
||||
if (!jvSubRequest.isMember("taker"))
|
||||
{
|
||||
raTakerID.setAccountID(ACCOUNT_ONE);
|
||||
}
|
||||
else if (!raTakerID.setAccountID((*it)["taker"].asString()))
|
||||
else if (!raTakerID.setAccountID(jvSubRequest["taker"].asString()))
|
||||
{
|
||||
return rpcError(rpcBAD_ISSUER);
|
||||
}
|
||||
|
||||
bool bothSides = (*it)["both_sides"].asBool();
|
||||
|
||||
if (!Ledger::isValidBook(uTakerPaysCurrencyID, uTakerPaysIssuerID, uTakerGetsCurrencyID, uTakerGetsIssuerID))
|
||||
{
|
||||
cLog(lsWARNING) << "Bad market: " <<
|
||||
uTakerPaysCurrencyID << ":" << uTakerPaysIssuerID << " -> " <<
|
||||
uTakerPaysCurrencyID << ":" << uTakerPaysIssuerID << " -> " <<
|
||||
uTakerGetsCurrencyID << ":" << uTakerGetsIssuerID;
|
||||
return rpcError(rpcBAD_MARKET);
|
||||
}
|
||||
|
||||
mNetOps->subBook(ispSub, uTakerPaysCurrencyID, uTakerGetsCurrencyID, uTakerPaysIssuerID, uTakerGetsIssuerID);
|
||||
if (bothSides) mNetOps->subBook(ispSub, uTakerGetsCurrencyID, uTakerPaysCurrencyID, uTakerGetsIssuerID, uTakerPaysIssuerID);
|
||||
if ((*it)["state_now"].asBool())
|
||||
if (bBoth) mNetOps->subBook(ispSub, uTakerGetsCurrencyID, uTakerPaysCurrencyID, uTakerGetsIssuerID, uTakerPaysIssuerID);
|
||||
|
||||
if (bSnapshot)
|
||||
{
|
||||
Ledger::pointer ledger= theApp->getLedgerMaster().getClosedLedger();
|
||||
Ledger::pointer lpLedger= theApp->getLedgerMaster().getClosedLedger();
|
||||
const Json::Value jvMarker = Json::Value(Json::nullValue);
|
||||
mNetOps->getBookPage(ledger, uTakerPaysCurrencyID, uTakerPaysIssuerID, uTakerGetsCurrencyID, uTakerGetsIssuerID, raTakerID.getAccountID(), false, 0, jvMarker, jvResult);
|
||||
if (bothSides)
|
||||
|
||||
if (bBoth)
|
||||
{
|
||||
Json::Value tempJson(Json::objectValue);
|
||||
if (jvResult.isMember("offers")) jvResult["bids"]=jvResult["offers"];
|
||||
mNetOps->getBookPage(ledger, uTakerGetsCurrencyID, uTakerGetsIssuerID, uTakerPaysCurrencyID, uTakerPaysIssuerID, raTakerID.getAccountID(), false, 0, jvMarker, tempJson);
|
||||
if (tempJson.isMember("offers")) jvResult["asks"]=tempJson["offers"];
|
||||
Json::Value jvBids(Json::objectValue);
|
||||
Json::Value jvAsks(Json::objectValue);
|
||||
|
||||
mNetOps->getBookPage(lpLedger, uTakerPaysCurrencyID, uTakerPaysIssuerID, uTakerGetsCurrencyID, uTakerGetsIssuerID, raTakerID.getAccountID(), false, 0, jvMarker, jvBids);
|
||||
if (jvBids.isMember("offers")) jvResult["bids"]=jvBids["offers"];
|
||||
|
||||
mNetOps->getBookPage(lpLedger, uTakerGetsCurrencyID, uTakerGetsIssuerID, uTakerPaysCurrencyID, uTakerPaysIssuerID, raTakerID.getAccountID(), false, 0, jvMarker, jvAsks);
|
||||
if (jvAsks.isMember("offers")) jvResult["asks"]=jvAsks["offers"];
|
||||
}
|
||||
else
|
||||
{
|
||||
mNetOps->getBookPage(lpLedger, uTakerPaysCurrencyID, uTakerPaysIssuerID, uTakerGetsCurrencyID, uTakerGetsIssuerID, raTakerID.getAccountID(), false, 0, jvMarker, jvResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user