Constrain valid inputs for memo fields (RIPD-712)

This commit is contained in:
Nik Bougalis
2015-01-21 05:44:39 -08:00
committed by Tom Ritchford
parent fde6303ae6
commit e3a7aa0033

View File

@@ -31,6 +31,7 @@
#include <ripple/json/to_string.h>
#include <beast/unit_test/suite.h>
#include <boost/format.hpp>
#include <array>
namespace ripple {
@@ -308,13 +309,59 @@ isMemoOkay (STObject const& st, std::string& reason)
for (auto const& memoElement : *memoObj)
{
if ((memoElement.getFName() != sfMemoType) &&
(memoElement.getFName() != sfMemoData) &&
(memoElement.getFName() != sfMemoFormat))
auto const& name = memoElement.getFName();
if (name != sfMemoType &&
name != sfMemoData &&
name != sfMemoFormat)
{
reason = "A memo may contain only MemoType, MemoData or MemoFormat fields.";
reason = "A memo may contain only MemoType, MemoData or "
"MemoFormat fields.";
return false;
}
// The raw data is stored as hex-octets, which we want to decode.
auto data = strUnHex (memoElement.getText ());
if (!data.second)
{
reason = "The MemoType, MemoData and MemoFormat fields may "
"only contain hex-encoded data.";
return false;
}
if (name == sfMemoData)
continue;
// The only allowed characters for MemoType and MemoFormat are the
// characters allowed in URLs per RFC 3986: alphanumerics and the
// following symbols: -._~:/?#[]@!$&'()*+,;=%
static std::array<char, 256> const allowedSymbols = []
{
std::array<char, 256> a;
a.fill(0);
std::string symbols (
"0123456789"
"-._~:/?#[]@!$&'()*+,;=%"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz");
for(char c : symbols)
a[c] = 1;
return a;
}();
for (auto c : data.first)
{
if (!allowedSymbols[c])
{
reason = "The MemoType and MemoFormat fields may only "
"contain characters that are allowed in URLs "
"under RFC 3986.";
return false;
}
}
}
}