mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Correctly check validity for type during setType.
This commit is contained in:
@@ -14,7 +14,8 @@ SerializedLedgerEntry::SerializedLedgerEntry(SerializerIterator& sit, const uint
|
|||||||
if (mFormat == NULL)
|
if (mFormat == NULL)
|
||||||
throw std::runtime_error("invalid ledger entry type");
|
throw std::runtime_error("invalid ledger entry type");
|
||||||
mType = mFormat->t_type;
|
mType = mFormat->t_type;
|
||||||
setType(mFormat->elements);
|
if (!setType(mFormat->elements))
|
||||||
|
throw std::runtime_error("ledger entry not valid for type");
|
||||||
}
|
}
|
||||||
|
|
||||||
SerializedLedgerEntry::SerializedLedgerEntry(const Serializer& s, const uint256& index)
|
SerializedLedgerEntry::SerializedLedgerEntry(const Serializer& s, const uint256& index)
|
||||||
@@ -28,7 +29,8 @@ SerializedLedgerEntry::SerializedLedgerEntry(const Serializer& s, const uint256&
|
|||||||
if (mFormat == NULL)
|
if (mFormat == NULL)
|
||||||
throw std::runtime_error("invalid ledger entry type");
|
throw std::runtime_error("invalid ledger entry type");
|
||||||
mType = mFormat->t_type;
|
mType = mFormat->t_type;
|
||||||
setType(mFormat->elements);
|
if (!setType(mFormat->elements))
|
||||||
|
throw std::runtime_error("ledger entry not valid for type");
|
||||||
}
|
}
|
||||||
|
|
||||||
SerializedLedgerEntry::SerializedLedgerEntry(LedgerEntryType type) : STObject(sfLedgerEntry), mType(type)
|
SerializedLedgerEntry::SerializedLedgerEntry(LedgerEntryType type) : STObject(sfLedgerEntry), mType(type)
|
||||||
|
|||||||
@@ -130,46 +130,54 @@ void STObject::set(SOElement::ptr elem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool STObject::compare(const SerializedType& f1, const SerializedType& f2)
|
bool STObject::setType(SOElement::ptrList t)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(SOElement::ptr elem, mType)
|
boost::ptr_vector<SerializedType> newData;
|
||||||
{
|
bool valid = true;
|
||||||
if (elem->e_field == f1.getFName()) // element one comes first
|
|
||||||
return true;
|
|
||||||
if (elem->e_field == f2.getFName()) // element two comes first
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
assert(false);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void STObject::setType(SOElement::ptrList t)
|
|
||||||
{
|
|
||||||
mType.empty();
|
mType.empty();
|
||||||
while (t->flags != SOE_END)
|
while (t->flags != SOE_END)
|
||||||
mType.push_back(t++);
|
{
|
||||||
|
bool match = false;
|
||||||
|
for (boost::ptr_vector<SerializedType>::iterator it = mData.begin(); it != mData.end(); ++it)
|
||||||
|
if (it->getFName() == t->e_field)
|
||||||
|
{
|
||||||
|
match = true;
|
||||||
|
newData.push_back(mData.release(it).release());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
std::sort(mData.begin(), mData.end(), boost::bind(&STObject::compare, this, _1, _2));
|
if (!match)
|
||||||
|
{
|
||||||
|
if (t->flags != SOE_OPTIONAL)
|
||||||
|
{
|
||||||
|
Log(lsTRACE) << "setType !valid missing";
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
newData.push_back(makeNonPresentObject(t->e_field));
|
||||||
|
}
|
||||||
|
|
||||||
|
mType.push_back(t++);
|
||||||
|
}
|
||||||
|
if (mData.size() != 0)
|
||||||
|
{
|
||||||
|
Log(lsTRACE) << "setType !valid leftover";
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
mData.swap(newData);
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool STObject::isValidForType()
|
bool STObject::isValidForType()
|
||||||
{
|
{
|
||||||
|
boost::ptr_vector<SerializedType>::iterator it = mData.begin();
|
||||||
BOOST_FOREACH(SOElement::ptr elem, mType)
|
BOOST_FOREACH(SOElement::ptr elem, mType)
|
||||||
{ // are any required elemnents missing
|
{
|
||||||
if ((elem->flags == SOE_REQUIRED) && (getPField(elem->e_field) == NULL))
|
if (it == mData.end())
|
||||||
{
|
|
||||||
Log(lsWARNING) << getName() << " missing required element " << elem->e_field.fieldName;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
if (elem->e_field != it->getFName())
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FOREACH(const SerializedType& elem, mData)
|
|
||||||
{ // are any non-permitted elements present
|
|
||||||
if (!isFieldAllowed(elem.getFName()))
|
|
||||||
{
|
|
||||||
Log(lsWARNING) << getName() << " has non-permitted element " << elem.getName();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -282,7 +290,8 @@ std::string STObject::getText() const
|
|||||||
bool STObject::isEquivalent(const SerializedType& t) const
|
bool STObject::isEquivalent(const SerializedType& t) const
|
||||||
{
|
{
|
||||||
const STObject* v = dynamic_cast<const STObject*>(&t);
|
const STObject* v = dynamic_cast<const STObject*>(&t);
|
||||||
if (!v) return false;
|
if (!v)
|
||||||
|
return false;
|
||||||
boost::ptr_vector<SerializedType>::const_iterator it1 = mData.begin(), end1 = mData.end();
|
boost::ptr_vector<SerializedType>::const_iterator it1 = mData.begin(), end1 = mData.end();
|
||||||
boost::ptr_vector<SerializedType>::const_iterator it2 = v->mData.begin(), end2 = v->mData.end();
|
boost::ptr_vector<SerializedType>::const_iterator it2 = v->mData.begin(), end2 = v->mData.end();
|
||||||
while ((it1 != end1) && (it2 != end2))
|
while ((it1 != end1) && (it2 != end2))
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ protected:
|
|||||||
std::vector<SOElement::ptr> mType;
|
std::vector<SOElement::ptr> mType;
|
||||||
|
|
||||||
STObject* duplicate() const { return new STObject(*this); }
|
STObject* duplicate() const { return new STObject(*this); }
|
||||||
bool compare(const SerializedType& f1, const SerializedType& f2);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STObject() { ; }
|
STObject() { ; }
|
||||||
@@ -45,7 +44,7 @@ public:
|
|||||||
|
|
||||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name);
|
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, SField::ref name);
|
||||||
|
|
||||||
void setType(SOElement::ptrList);
|
bool setType(SOElement::ptrList);
|
||||||
bool isValidForType();
|
bool isValidForType();
|
||||||
bool isFieldAllowed(SField::ref);
|
bool isFieldAllowed(SField::ref);
|
||||||
|
|
||||||
|
|||||||
@@ -30,11 +30,10 @@ SerializedTransaction::SerializedTransaction(SerializerIterator& sit) : STObject
|
|||||||
|
|
||||||
mFormat = getTxnFormat(mType);
|
mFormat = getTxnFormat(mType);
|
||||||
if (!mFormat)
|
if (!mFormat)
|
||||||
throw std::runtime_error("invalid transction type");
|
throw std::runtime_error("invalid transaction type");
|
||||||
setType(mFormat->elements);
|
if (!setType(mFormat->elements))
|
||||||
if (!isValidForType())
|
|
||||||
{
|
{
|
||||||
Log(lsDEBUG) << "Transaction not valid for type " << getJson(0);
|
assert(false);
|
||||||
throw std::runtime_error("transaction not valid");
|
throw std::runtime_error("transaction not valid");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user