From a5297d13c4f6a2ffb643e697d9ff1fcda385b932 Mon Sep 17 00:00:00 2001 From: David Schwartz Date: Mon, 23 Jun 2014 10:43:41 -0700 Subject: [PATCH] Add new memo restrictions --- .../module/app/misc/SerializedTransaction.cpp | 29 ++++++++++++++++++- .../data/protocol/SerializeDeclarations.h | 1 + 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/ripple/module/app/misc/SerializedTransaction.cpp b/src/ripple/module/app/misc/SerializedTransaction.cpp index 47c71b07c..b268b7738 100644 --- a/src/ripple/module/app/misc/SerializedTransaction.cpp +++ b/src/ripple/module/app/misc/SerializedTransaction.cpp @@ -318,13 +318,40 @@ bool isMemoOkay (STObject const& st) { if (!st.isFieldPresent (sfMemos)) return true; + + const STArray& memos = st.getFieldArray (sfMemos); // The number 2048 is a preallocation hint, not a hard limit // to avoid allocate/copy/free's Serializer s (2048); - st.getFieldArray (sfMemos).add (s); + memos.add (s); // FIXME move the memo limit into a config tunable if (s.getDataLength () > 1024) return false; + + for (auto const& memo : memos) + { + auto memoObj = dynamic_cast (&memo); + + // Memos array must consist solely of Memo objects + if (!memoObj || (memoObj->getFName() != sfMemo)) + { + return false; + } + + // Memo objects may only contain + // MemoType, MemoData, and MemoFormat fields + for (auto const& memoElement : *memoObj) + { + if ((memoElement.getFName() != sfMemoType) && + (memoElement.getFName() != sfMemoData) && + (memoElement.getFName() != sfMemoFormat)) + { + return false; + } + } + + } + return true; } diff --git a/src/ripple/module/data/protocol/SerializeDeclarations.h b/src/ripple/module/data/protocol/SerializeDeclarations.h index 4d86dbb7c..3c3932567 100644 --- a/src/ripple/module/data/protocol/SerializeDeclarations.h +++ b/src/ripple/module/data/protocol/SerializeDeclarations.h @@ -162,6 +162,7 @@ FIELD (ExpireCode, VL, 10) FIELD (CreateCode, VL, 11) FIELD (MemoType, VL, 12) FIELD (MemoData, VL, 13) +FIELD (MemoFormat, VL, 14) // account FIELD (Account, ACCOUNT, 1)