diff --git a/src/ripple/module/app/tx/TransactionMeta.cpp b/src/ripple/module/app/tx/TransactionMeta.cpp index b07cb12b6d..c5b2331eca 100644 --- a/src/ripple/module/app/tx/TransactionMeta.cpp +++ b/src/ripple/module/app/tx/TransactionMeta.cpp @@ -27,7 +27,7 @@ TransactionMetaSet::TransactionMetaSet (uint256 const& txid, std::uint32_t ledge Serializer s (vec); SerializerIterator sit (s); - std::unique_ptr pobj = STObject::deserialize (sit, sfAffectedNodes); + std::unique_ptr pobj = STObject::deserialize (sit, sfMetadata); STObject* obj = static_cast (pobj.get ()); if (!obj) diff --git a/src/ripple/module/data/protocol/FieldNames.cpp b/src/ripple/module/data/protocol/FieldNames.cpp index 2a3abe2873..eef059f89d 100644 --- a/src/ripple/module/data/protocol/FieldNames.cpp +++ b/src/ripple/module/data/protocol/FieldNames.cpp @@ -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) diff --git a/src/ripple/module/data/protocol/FieldNames.h b/src/ripple/module/data/protocol/FieldNames.h index e0e782edca..07731dd4ad 100644 --- a/src/ripple/module/data/protocol/FieldNames.h +++ b/src/ripple/module/data/protocol/FieldNames.h @@ -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) diff --git a/src/ripple/module/data/protocol/STParsedJSON.cpp b/src/ripple/module/data/protocol/STParsedJSON.cpp index 7c68c78acb..ff8ecb8dc1 100644 --- a/src/ripple/module/data/protocol/STParsedJSON.cpp +++ b/src/ripple/module/data/protocol/STParsedJSON.cpp @@ -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_); diff --git a/src/ripple/module/data/protocol/SerializedObject.cpp b/src/ripple/module/data/protocol/SerializedObject.cpp index ea0d1fb123..598c63daba 100644 --- a/src/ripple/module/data/protocol/SerializedObject.cpp +++ b/src/ripple/module/data/protocol/SerializedObject.cpp @@ -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); } diff --git a/src/ripple/module/data/protocol/SerializedTypes.cpp b/src/ripple/module/data/protocol/SerializedTypes.cpp index cec276c39f..4f1965f94f 100644 --- a/src/ripple/module/data/protocol/SerializedTypes.cpp +++ b/src/ripple/module/data/protocol/SerializedTypes.cpp @@ -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) diff --git a/src/ripple/module/data/protocol/SerializedTypes.h b/src/ripple/module/data/protocol/SerializedTypes.h index 18dea8df15..1372efee2f 100644 --- a/src/ripple/module/data/protocol/SerializedTypes.h +++ b/src/ripple/module/data/protocol/SerializedTypes.h @@ -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); }