Tighten up some serialization checks

This commit is contained in:
David Schwartz
2014-06-20 09:53:19 -07:00
parent e70d618aff
commit d06092212f
7 changed files with 58 additions and 7 deletions

View File

@@ -29,7 +29,7 @@ TransactionMetaSet::TransactionMetaSet (uint256 const& txid, std::uint32_t ledge
Serializer s (vec);
SerializerIterator sit (s);
std::unique_ptr<SerializedType> pobj = STObject::deserialize (sit, sfAffectedNodes);
std::unique_ptr<SerializedType> pobj = STObject::deserialize (sit, sfMetadata);
STObject* obj = static_cast<STObject*> (pobj.get ());
if (!obj)

View File

@@ -32,9 +32,10 @@ SField::StaticLockType& SField::getMutex ()
}
SField sfInvalid (-1), sfGeneric (0);
SField sfLedgerEntry (STI_LEDGERENTRY, 1, "LedgerEntry");
SField sfTransaction (STI_TRANSACTION, 1, "Transaction");
SField sfValidation (STI_VALIDATION, 1, "Validation");
SField sfLedgerEntry (STI_LEDGERENTRY, 257, "LedgerEntry");
SField sfTransaction (STI_TRANSACTION, 257, "Transaction");
SField sfValidation (STI_VALIDATION, 257, "Validation");
SField sfMetadata (STI_METADATA, 257, "Metadata");
SField sfHash (STI_HASH256, 257, "hash");
SField sfIndex (STI_HASH256, 258, "index");

View File

@@ -39,9 +39,11 @@ enum SerializedTypeID
#undef FIELD
// high level types
// cannot be serialized inside other types
STI_TRANSACTION = 10001,
STI_LEDGERENTRY = 10002,
STI_VALIDATION = 10003,
STI_METADATA = 10004,
};
/** Identifies fields.
@@ -239,7 +241,9 @@ protected:
SField (SerializedTypeID id, int val);
};
extern SField sfInvalid, sfGeneric, sfLedgerEntry, sfTransaction, sfValidation;
extern SField
sfInvalid, sfGeneric,
sfLedgerEntry, sfTransaction, sfValidation, sfMetadata;
#define FIELD(name, type, index) extern SField sf##name;
#define TYPE(name, type, index)

View File

@@ -705,7 +705,7 @@ bool STParsedJSON::parse (std::string const& json_name,
"[" << i << "]." << objectName;
bool const success (parse (ss.str (), objectFields,
nameField, depth + 1, sub_object_));
if (! success)
if (! success || (sub_object_->getFName().fieldType != STI_OBJECT))
return false;
}
tail->push_back (*sub_object_);

View File

@@ -277,6 +277,12 @@ bool STObject::set (SerializerIterator& sit, int depth)
reachedEndOfObject = (type == STI_OBJECT) && (field == 1);
if ((type == STI_ARRAY) && (field == 1))
{
WriteLog (lsWARNING, STObject) << "Encountered object with end of array marker";
throw std::runtime_error ("Illegal terminator in object");
}
if (!reachedEndOfObject)
{
// Figure out the field
@@ -361,6 +367,12 @@ void STObject::add (Serializer& s, bool withSigningFields) const
// insert them in sorted order
const SerializedType* field = it.second;
// When we serialize an object inside another object,
// the type associated by rule with this field name
// must be OBJECT, or the object cannot be deserialized
assert ((field->getSType() != STI_OBJECT) ||
(field->getFName().fieldType == STI_OBJECT));
field->addFieldID (s);
field->add (s);
@@ -1233,6 +1245,12 @@ STArray* STArray::construct (SerializerIterator& sit, SField::ref field)
if ((type == STI_ARRAY) && (field == 1))
break;
if ((type == STI_OBJECT) && (field == 1))
{
WriteLog (lsWARNING, STObject) << "Encountered array with end of object marker";
throw std::runtime_error ("Illegal terminator in array");
}
SField::ref fn = SField::getField (type, field);
if (fn.isInvalid ())
@@ -1241,6 +1259,12 @@ STArray* STArray::construct (SerializerIterator& sit, SField::ref field)
throw std::runtime_error ("Unknown field");
}
if (fn.fieldType != STI_OBJECT)
{
WriteLog (lsTRACE, STObject) << "Array contains non-object";
throw std::runtime_error ("Non-object in array");
}
value.push_back (new STObject (fn));
value.rbegin ()->set (sit, 1);
}

View File

@@ -353,6 +353,8 @@ STVector256* STVector256::construct (SerializerIterator& u, SField::ref name)
void STVector256::add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_VECTOR256);
s.addVL (mValue.empty () ? nullptr : mValue[0].begin (), mValue.size () * (256 / 8));
}
@@ -592,6 +594,8 @@ std::string STPathSet::getText () const
void STPathSet::add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_PATHSET);
bool bFirst = true;
BOOST_FOREACH (const STPath & spPath, value)

View File

@@ -146,13 +146,14 @@ public:
virtual void add (Serializer& s) const
{
;
assert (false);
}
virtual bool isEquivalent (const SerializedType& t) const;
void addFieldID (Serializer& s) const
{
assert (fName->isBinary ());
s.addFieldID (fName->fieldType, fName->fieldValue);
}
@@ -247,6 +248,8 @@ public:
Json::Value getJson (int) const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_UINT8);
s.add8 (value);
}
@@ -306,6 +309,8 @@ public:
Json::Value getJson (int) const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_UINT16);
s.add16 (value);
}
@@ -365,6 +370,8 @@ public:
Json::Value getJson (int) const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_UINT32);
s.add32 (value);
}
@@ -423,6 +430,8 @@ public:
Json::Value getJson (int) const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_UINT64);
s.add64 (value);
}
@@ -881,6 +890,8 @@ public:
virtual std::string getText () const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_HASH128);
s.add128 (value);
}
@@ -954,6 +965,8 @@ public:
virtual std::string getText () const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_HASH160);
s.add160 (value);
}
@@ -1027,6 +1040,8 @@ public:
std::string getText () const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_HASH256);
s.add256 (value);
}
@@ -1094,6 +1109,9 @@ public:
virtual std::string getText () const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert ((fName->fieldType == STI_VL) ||
(fName->fieldType == STI_ACCOUNT));
s.addVL (value);
}