20 #include <ripple/basics/StringUtilities.h>
21 #include <ripple/basics/contract.h>
22 #include <ripple/basics/safe_cast.h>
23 #include <ripple/beast/core/LexicalCast.h>
24 #include <ripple/protocol/ErrorCodes.h>
25 #include <ripple/protocol/LedgerFormats.h>
26 #include <ripple/protocol/STAccount.h>
27 #include <ripple/protocol/STAmount.h>
28 #include <ripple/protocol/STArray.h>
29 #include <ripple/protocol/STBitString.h>
30 #include <ripple/protocol/STBlob.h>
31 #include <ripple/protocol/STInteger.h>
32 #include <ripple/protocol/STParsedJSON.h>
33 #include <ripple/protocol/STPathSet.h>
34 #include <ripple/protocol/STVector256.h>
35 #include <ripple/protocol/TER.h>
36 #include <ripple/protocol/TxFormats.h>
37 #include <ripple/protocol/UintTypes.h>
38 #include <ripple/protocol/impl/STVar.h>
45 namespace STParsedJSONDetail {
46 template <
typename U,
typename S>
52 Throw<std::runtime_error>(
"Value out of range");
53 return static_cast<U
>(value);
56 template <
typename U1,
typename U2>
62 Throw<std::runtime_error>(
"Value out of range");
63 return static_cast<U1
>(value);
72 return object +
"." + field;
80 "Field '" +
make_name(
object, field) +
"' is not a JSON object.");
101 "Field '" +
make_name(
object, field) +
"' is unknown.");
109 "Field '" +
make_name(
object, field) +
"' is out of range.");
117 "Field '" +
make_name(
object, field) +
"' has bad type.");
125 "Field '" +
make_name(
object, field) +
"' has invalid data.");
139 "Field '" +
make_name(
object, field) +
"' must be a JSON array.");
147 "Field '" +
make_name(
object, field) +
"' must be a string.");
155 "Field '" +
object +
"' exceeds nesting depth limit.");
164 "]' must be an object with a single key/object value.");
172 "Object '" + sField.
getName() +
173 "' contents did not meet requirements for that type.");
182 " is not an object. Arrays may only contain objects.");
187 static boost::optional<detail::STVar>
195 boost::optional<detail::STVar> ret;
205 switch (field.fieldType)
210 constexpr
auto minValue =
212 constexpr
auto maxValue =
218 if (!strValue.
empty() &&
219 ((strValue[0] <
'0') || (strValue[0] >
'9')))
225 if (!ter ||
TERtoInt(*ter) < minValue ||
232 ret = detail::make_stvar<STUInt8>(
238 error =
bad_type(json_name, fieldName);
244 ret = detail::make_stvar<STUInt8>(
246 beast::lexicalCastThrow<std::uint8_t>(strValue));
249 else if (value.
isInt())
251 if (value.
asInt() < minValue || value.
asInt() > maxValue)
257 ret = detail::make_stvar<STUInt8>(
262 if (value.
asUInt() > maxValue)
268 ret = detail::make_stvar<STUInt8>(
273 error =
bad_type(json_name, fieldName);
291 if (!strValue.
empty() &&
292 ((strValue[0] <
'0') || (strValue[0] >
'9')))
301 Throw<std::runtime_error>(
302 "Invalid transaction format name");
303 ret = detail::make_stvar<STUInt16>(
323 Throw<std::runtime_error>(
324 "Invalid ledger entry type: out of range");
325 ret = detail::make_stvar<STUInt16>(
339 ret = detail::make_stvar<STUInt16>(
341 beast::lexicalCastThrow<std::uint16_t>(strValue));
344 else if (value.
isInt())
346 ret = detail::make_stvar<STUInt16>(
347 field, to_unsigned<std::uint16_t>(value.
asInt()));
351 ret = detail::make_stvar<STUInt16>(
352 field, to_unsigned<std::uint16_t>(value.
asUInt()));
356 error =
bad_type(json_name, fieldName);
373 ret = detail::make_stvar<STUInt32>(
375 beast::lexicalCastThrow<std::uint32_t>(
378 else if (value.
isInt())
380 ret = detail::make_stvar<STUInt32>(
381 field, to_unsigned<std::uint32_t>(value.
asInt()));
385 ret = detail::make_stvar<STUInt32>(
386 field, safe_cast<std::uint32_t>(value.
asUInt()));
390 error =
bad_type(json_name, fieldName);
412 str.data(), str.data() + str.size(), val, 16);
414 if (ec !=
std::errc() || (p != str.data() + str.size()))
415 Throw<std::invalid_argument>(
"invalid data");
417 ret = detail::make_stvar<STUInt64>(field, val);
419 else if (value.
isInt())
421 ret = detail::make_stvar<STUInt64>(
422 field, to_unsigned<std::uint64_t>(value.
asInt()));
426 ret = detail::make_stvar<STUInt64>(
427 field, safe_cast<std::uint64_t>(value.
asUInt()));
431 error =
bad_type(json_name, fieldName);
446 error =
bad_type(json_name, fieldName);
463 ret = detail::make_stvar<STHash128>(field, num);
470 error =
bad_type(json_name, fieldName);
487 ret = detail::make_stvar<STHash160>(field, num);
494 error =
bad_type(json_name, fieldName);
511 ret = detail::make_stvar<STHash256>(field, num);
518 error =
bad_type(json_name, fieldName);
526 ret = detail::make_stvar<STBlob>(
527 field, vBlob->data(), vBlob->size());
531 Throw<std::invalid_argument>(
"invalid data");
570 Throw<std::invalid_argument>(
"invalid data");
573 ret = detail::make_stvar<STVector256>(std::move(tail));
598 if (!value[i].isArrayOrNull())
601 ss << fieldName <<
"[" << i <<
"]";
609 ss << fieldName <<
"[" << i <<
"][" << j <<
"]";
611 json_name +
"." + ss.
str());
627 bool hasCurrency =
false;
634 if (!account.isString())
643 if (!uAccount.
parseHex(account.asString()))
646 parseBase58<AccountID>(account.asString());
693 parseBase58<AccountID>(issuer.
asString());
705 uAccount, uCurrency, uIssuer, hasCurrency);
710 ret = detail::make_stvar<STPathSet>(std::move(tail));
723 error =
bad_type(json_name, fieldName);
731 if (
AccountID account; account.parseHex(strValue))
732 return detail::make_stvar<STAccount>(field, account);
734 if (
auto result = parseBase58<AccountID>(strValue))
735 return detail::make_stvar<STAccount>(field, *result);
749 error =
bad_type(json_name, fieldName);
759 static boost::optional<detail::STVar>
767 static boost::optional<STObject>
803 switch (field.fieldType)
819 json_name +
"." + fieldName,
826 data.emplace_back(std::move(*ret));
841 json_name +
"." + fieldName,
846 if (array == boost::none)
848 data.emplace_back(std::move(*array));
861 parseLeaf(json_name, fieldName, &inName, value, error);
866 data.emplace_back(std::move(*leaf));
874 data.applyTemplateFromSField(inName);
889 static boost::optional<detail::STVar>
915 bool const isObjectOrNull(json[i].isObjectOrNull());
916 bool const singleKey(isObjectOrNull ? json[i].size() == 1 :
true);
918 if (!isObjectOrNull || !singleKey)
928 std::string const objectName(json[i].getMemberNames()[0]);
938 Json::Value const objectFields(json[i][objectName]);
941 ss << json_name <<
"."
942 <<
"[" << i <<
"]." << objectName;
945 ss.
str(), objectFields, nameField, depth + 1, error);
948 std::string errMsg = error[
"error_message"].asString();
949 error[
"error_message"] =
950 "Error at '" + ss.
str() +
"'. " + errMsg;
963 return detail::make_stvar<STArray>(std::move(tail));
980 using namespace STParsedJSONDetail;
990 using namespace STParsedJSONDetail;
996 auto p =
dynamic_cast<STArray*
>(&arr->get());
1000 array = std::move(*p);