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); Serializer s (vec);
SerializerIterator sit (s); 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 ()); STObject* obj = static_cast<STObject*> (pobj.get ());
if (!obj) if (!obj)

View File

@@ -31,14 +31,15 @@ SField::StaticLockType& SField::getMutex ()
return mutex; return mutex;
} }
const SField sfInvalid (-1), sfGeneric (0); SField const sfInvalid (-1), sfGeneric (0);
const SField sfLedgerEntry (STI_LEDGERENTRY, 1, "LedgerEntry"); SField const sfLedgerEntry (STI_LEDGERENTRY, 257, "LedgerEntry");
const SField sfTransaction (STI_TRANSACTION, 1, "Transaction"); SField const sfTransaction (STI_TRANSACTION, 257, "Transaction");
const SField sfValidation (STI_VALIDATION, 1, "Validation"); SField const sfValidation (STI_VALIDATION, 257, "Validation");
const SField sfHash (STI_HASH256, 257, "hash"); SField const sfMetadata (STI_METADATA, 257, "Metadata");
const SField sfIndex (STI_HASH256, 258, "index"); 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) \ #define FIELD(name, type, index) \
SField sf##name(FIELD_CODE(STI_##type, index), STI_##type, index, #name); SField sf##name(FIELD_CODE(STI_##type, index), STI_##type, index, #name);
#define TYPE(name, type, index) #define TYPE(name, type, index)

View File

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

View File

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

View File

@@ -275,6 +275,12 @@ bool STObject::set (SerializerIterator& sit, int depth)
reachedEndOfObject = (type == STI_OBJECT) && (field == 1); 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) if (!reachedEndOfObject)
{ {
// Figure out the field // Figure out the field
@@ -359,6 +365,12 @@ void STObject::add (Serializer& s, bool withSigningFields) const
// insert them in sorted order // insert them in sorted order
const SerializedType* field = it.second; 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->addFieldID (s);
field->add (s); field->add (s);
@@ -1215,6 +1227,12 @@ STArray* STArray::construct (SerializerIterator& sit, SField::ref field)
if ((type == STI_ARRAY) && (field == 1)) if ((type == STI_ARRAY) && (field == 1))
break; 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); SField::ref fn = SField::getField (type, field);
if (fn.isInvalid ()) if (fn.isInvalid ())
@@ -1223,6 +1241,12 @@ STArray* STArray::construct (SerializerIterator& sit, SField::ref field)
throw std::runtime_error ("Unknown 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.push_back (new STObject (fn));
value.rbegin ()->set (sit, 1); 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 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)); 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 void STPathSet::add (Serializer& s) const
{ {
assert (fName->isBinary ());
assert (fName->fieldType == STI_PATHSET);
bool bFirst = true; bool bFirst = true;
BOOST_FOREACH (const STPath & spPath, value) BOOST_FOREACH (const STPath & spPath, value)

View File

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