Parse pathsets when accounts are specified in hex

This commit is contained in:
Nik Bougalis
2015-05-27 11:22:29 -07:00
parent e980e69eca
commit 24ea1ab035
2 changed files with 44 additions and 49 deletions

View File

@@ -306,31 +306,45 @@ public:
h(a.pn, sizeof(a.pn));
}
/** Parse a hex string into a base_uint
The string must contain exactly bytes * 2 hex characters and must not
have any leading or trailing whitespace.
*/
bool SetHexExact (const char* psz)
{
// must be precisely the correct number of hex digits
unsigned char* pOut = begin ();
for (int i = 0; i < sizeof (pn); ++i)
{
auto cHigh = charUnHex(*psz++);
auto cLow = charUnHex(*psz++);
if (cHigh == -1 || cLow == -1)
auto hi = charUnHex(*psz++);
if (hi == -1)
return false;
*pOut++ = (cHigh << 4) | cLow;
auto lo = charUnHex (*psz++);
if (lo == -1)
return false;
*pOut++ = (hi << 4) | lo;
}
assert (*psz == 0);
assert (pOut == end ());
return true;
// We've consumed exactly as many bytes as we needed at this point
// so we should be at the end of the string.
return (*psz == 0);
}
// Allow leading whitespace.
// Allow leading "0x".
// To be valid must be '\0' terminated.
/** Parse a hex string into a base_uint
The input can be:
- shorter than the full hex representation by not including leading
zeroes.
- longer than the full hex representation in which case leading
bytes are discarded.
When finished parsing, the string must be fully consumed with only a
null terminator remaining.
When bStrict is false, the parsing is done in non-strict mode, and, if
present, leading whitespace and the 0x prefix will be skipped.
*/
bool SetHex (const char* psz, bool bStrict = false)
{
// skip leading spaces
@@ -381,9 +395,9 @@ public:
return SetHex (str.c_str (), bStrict);
}
void SetHexExact (std::string const& str)
bool SetHexExact (std::string const& str)
{
SetHexExact (str.c_str ());
return SetHexExact (str.c_str ());
}
unsigned int size () const

View File

@@ -540,20 +540,16 @@ static boost::optional<detail::STVar> parseLeaf (
return ret;
}
std::string const strValue (account.asString ());
if (value.size () == 40) // 160-bit hex account value
uAccount.SetHex (strValue);
// If we have what looks like a 160-bit hex value, we
// set it, otherwise, we assume it's an AccountID
if (!uAccount.SetHexExact (account.asString ()))
{
RippleAddress a;
if (! a.setAccountID (strValue))
if (!a.setAccountID (account.asString ()))
{
error = invalid_data (element_name, "account");
return ret;
}
uAccount = a.getAccountID ();
}
}
@@ -569,14 +565,13 @@ static boost::optional<detail::STVar> parseLeaf (
hasCurrency = true;
if (currency.asString ().size () == 40)
if (!uCurrency.SetHexExact (currency.asString ()))
{
uCurrency.SetHex (currency.asString ());
}
else if (!to_currency (uCurrency, currency.asString ()))
{
error = invalid_data (element_name, "currency");
return ret;
if (!to_currency (uCurrency, currency.asString ()))
{
error = invalid_data (element_name, "currency");
return ret;
}
}
}
@@ -589,20 +584,14 @@ static boost::optional<detail::STVar> parseLeaf (
return ret;
}
if (issuer.asString ().size () == 40)
{
uIssuer.SetHex (issuer.asString ());
}
else
if (!uIssuer.SetHexExact (issuer.asString ()))
{
RippleAddress a;
if (!a.setAccountID (issuer.asString ()))
{
error = invalid_data (element_name, "issuer");
return ret;
}
uIssuer = a.getAccountID ();
}
}
@@ -634,26 +623,18 @@ static boost::optional<detail::STVar> parseLeaf (
try
{
if (value.size () == 40) // 160-bit hex account value
Account account;
if (!account.SetHexExact (strValue))
{
Account account;
account.SetHex (strValue);
ret = detail::make_stvar <STAccount> (field, account);
}
else
{
// ripple address
RippleAddress a;
if (!a.setAccountID (strValue))
{
error = invalid_data (json_name, fieldName);
return ret;
}
ret =
detail::make_stvar <STAccount> (field, a.getAccountID ());
account.copyFrom (a.getAccountID ());
}
ret = detail::make_stvar <STAccount> (field, account);
}
catch (...)
{