Tighten up some serialization checks

This commit is contained in:
David Schwartz
2014-06-20 09:53:19 -07:00
committed by Nik Bougalis
parent aec792f5b8
commit ed2c5078ad
7 changed files with 62 additions and 12 deletions

View File

@@ -27,7 +27,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

@@ -31,14 +31,15 @@ SField::StaticLockType& SField::getMutex ()
return mutex;
}
const SField sfInvalid (-1), sfGeneric (0);
const SField sfLedgerEntry (STI_LEDGERENTRY, 1, "LedgerEntry");
const SField sfTransaction (STI_TRANSACTION, 1, "Transaction");
const SField sfValidation (STI_VALIDATION, 1, "Validation");
const SField sfHash (STI_HASH256, 257, "hash");
const SField sfIndex (STI_HASH256, 258, "index");
SField const sfInvalid (-1), sfGeneric (0);
SField const sfLedgerEntry (STI_LEDGERENTRY, 257, "LedgerEntry");
SField const sfTransaction (STI_TRANSACTION, 257, "Transaction");
SField const sfValidation (STI_VALIDATION, 257, "Validation");
SField const sfMetadata (STI_METADATA, 257, "Metadata");
SField const sfHash (STI_HASH256, 257, "hash");
SField const sfIndex (STI_HASH256, 258, "index");
// TODO(tom): Remove this horrorr.
// TODO(tom): Remove this horror.
#define FIELD(name, type, index) \
SField sf##name(FIELD_CODE(STI_##type, index), STI_##type, index, #name);
#define TYPE(name, type, index)

View File

@@ -41,9 +41,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,8 +241,9 @@ protected:
SField (SerializedTypeID id, int val);
};
extern const SField sfInvalid, sfGeneric, sfLedgerEntry, sfTransaction,
sfValidation;
extern const 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

@@ -275,6 +275,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
@@ -359,6 +365,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);
@@ -1215,6 +1227,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 ())
@@ -1223,6 +1241,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

@@ -317,6 +317,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));
}
@@ -542,6 +544,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

@@ -123,13 +123,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);
}
@@ -224,6 +225,8 @@ public:
Json::Value getJson (int) const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_UINT8);
s.add8 (value);
}
@@ -283,6 +286,8 @@ public:
Json::Value getJson (int) const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_UINT16);
s.add16 (value);
}
@@ -342,6 +347,8 @@ public:
Json::Value getJson (int) const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_UINT32);
s.add32 (value);
}
@@ -400,6 +407,8 @@ public:
Json::Value getJson (int) const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_UINT64);
s.add64 (value);
}
@@ -873,6 +882,8 @@ public:
virtual std::string getText () const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_HASH128);
s.add128 (value);
}
@@ -946,6 +957,8 @@ public:
virtual std::string getText () const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_HASH160);
s.add160 (value);
}
@@ -1021,6 +1034,8 @@ public:
std::string getText () const;
void add (Serializer& s) const
{
assert (fName->isBinary ());
assert (fName->fieldType == STI_HASH256);
s.add256 (value);
}
@@ -1088,6 +1103,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);
}