Browse Source

Merge pull request #2457 from ethereum/stricterrlp

Stricter checks on RLP.
cl-refactor
Gav Wood 9 years ago
parent
commit
1373083b74
  1. 12
      libdevcore/RLP.cpp
  2. 21
      libdevcore/RLP.h

12
libdevcore/RLP.cpp

@ -173,8 +173,14 @@ size_t RLP::length() const
if (lengthSize > sizeof(ret))
// We did not check, but would most probably not fit in our memory.
BOOST_THROW_EXCEPTION(UndersizeRLP());
// No leading zeroes.
if (!m_data[1])
BOOST_THROW_EXCEPTION(BadRLP());
for (unsigned i = 0; i < lengthSize; ++i)
ret = (ret << 8) | m_data[i + 1];
// Must be greater than the limit.
if (ret < c_rlpListStart - c_rlpDataImmLenStart - c_rlpMaxLengthBytes)
BOOST_THROW_EXCEPTION(BadRLP());
}
else if (n <= c_rlpListIndLenZero)
return n - c_rlpListStart;
@ -189,8 +195,12 @@ size_t RLP::length() const
if (lengthSize > sizeof(ret))
// We did not check, but would most probably not fit in our memory.
BOOST_THROW_EXCEPTION(UndersizeRLP());
if (!m_data[1])
BOOST_THROW_EXCEPTION(BadRLP());
for (unsigned i = 0; i < lengthSize; ++i)
ret = (ret << 8) | m_data[i + 1];
if (ret < 0x100 - c_rlpListStart - c_rlpMaxLengthBytes)
BOOST_THROW_EXCEPTION(BadRLP());
}
// We have to be able to add payloadOffset to length without overflow.
// This rejects roughly 4GB-sized RLPs on some platforms.
@ -203,7 +213,7 @@ size_t RLP::items() const
{
if (isList())
{
bytesConstRef d = payload().cropped(0, length());
bytesConstRef d = payload();
size_t i = 0;
for (; d.size(); ++i)
d = d.cropped(sizeAsEncoded(d));

21
libdevcore/RLP.h

@ -232,25 +232,22 @@ public:
template <class T, class U>
std::pair<T, U> toPair() const
{
if (itemCountStrict() != 2)
BOOST_THROW_EXCEPTION(BadCast());
std::pair<T, U> ret;
if (isList())
{
ret.first = (T)(*this)[0];
ret.second = (U)(*this)[1];
}
ret.first = (T)(*this)[0];
ret.second = (U)(*this)[1];
return ret;
}
template <class T, size_t N>
std::array<T, N> toArray() const
{
if (itemCount() != N || !isList())
if (itemCountStrict() != N)
BOOST_THROW_EXCEPTION(BadCast());
std::array<T, N> ret;
for (size_t i = 0; i < N; ++i)
{
ret[i] = (T)operator[](i);
}
return ret;
}
@ -281,7 +278,9 @@ public:
template <class _N> _N toHash(int _flags = Strict) const
{
requireGood();
if (!isData() || (length() > _N::size && (_flags & FailIfTooBig)) || (length() < _N::size && (_flags & FailIfTooSmall)))
auto p = payload();
auto l = p.size();
if (!isData() || (l > _N::size && (_flags & FailIfTooBig)) || (l < _N::size && (_flags & FailIfTooSmall)))
{
if (_flags & ThrowOnFail)
BOOST_THROW_EXCEPTION(BadCast());
@ -290,8 +289,8 @@ public:
}
_N ret;
size_t s = std::min<size_t>(_N::size, length());
memcpy(ret.data() + _N::size - s, payload().data(), s);
size_t s = std::min<size_t>(_N::size, l);
memcpy(ret.data() + _N::size - s, p.data(), s);
return ret;
}

Loading…
Cancel
Save