diff --git a/src/ripple_app/tx/TransactionMeta.cpp b/src/ripple_app/tx/TransactionMeta.cpp index ceab83338..f5cf4e60b 100644 --- a/src/ripple_app/tx/TransactionMeta.cpp +++ b/src/ripple_app/tx/TransactionMeta.cpp @@ -29,7 +29,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_data/protocol/FieldNames.cpp b/src/ripple_data/protocol/FieldNames.cpp index 864aab9a1..88d083b7d 100644 --- a/src/ripple_data/protocol/FieldNames.cpp +++ b/src/ripple_data/protocol/FieldNames.cpp @@ -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"); diff --git a/src/ripple_data/protocol/FieldNames.h b/src/ripple_data/protocol/FieldNames.h index 858cb01e1..550c21afc 100644 --- a/src/ripple_data/protocol/FieldNames.h +++ b/src/ripple_data/protocol/FieldNames.h @@ -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) diff --git a/src/ripple_data/protocol/STParsedJSON.cpp b/src/ripple_data/protocol/STParsedJSON.cpp index b014354b6..78fde9b60 100644 --- a/src/ripple_data/protocol/STParsedJSON.cpp +++ b/src/ripple_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_data/protocol/SerializedObject.cpp b/src/ripple_data/protocol/SerializedObject.cpp index 7ae1fdd5c..ab3ac609f 100644 --- a/src/ripple_data/protocol/SerializedObject.cpp +++ b/src/ripple_data/protocol/SerializedObject.cpp @@ -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); } diff --git a/src/ripple_data/protocol/SerializedTypes.cpp b/src/ripple_data/protocol/SerializedTypes.cpp index e44f227f0..eda4dacb9 100644 --- a/src/ripple_data/protocol/SerializedTypes.cpp +++ b/src/ripple_data/protocol/SerializedTypes.cpp @@ -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) diff --git a/src/ripple_data/protocol/SerializedTypes.h b/src/ripple_data/protocol/SerializedTypes.h index 6ebf7349f..57e8a522f 100644 --- a/src/ripple_data/protocol/SerializedTypes.h +++ b/src/ripple_data/protocol/SerializedTypes.h @@ -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); }