From 29fa0a369d28eedbf6741a7699ce257175275029 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi <shawntabrizi@gmail.com> Date: Thu, 17 Jun 2021 12:51:36 +0100 Subject: [PATCH] Add XCM Decode Limit (#3273) * Add XCM Decode Limit of 256 * use `decode_all_*` * Update xcm/src/double_encoded.rs --- polkadot/xcm/src/double_encoded.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/polkadot/xcm/src/double_encoded.rs b/polkadot/xcm/src/double_encoded.rs index d9ba93d7d6e..4bd5dc0eb59 100644 --- a/polkadot/xcm/src/double_encoded.rs +++ b/polkadot/xcm/src/double_encoded.rs @@ -15,7 +15,10 @@ // along with Polkadot. If not, see <http://www.gnu.org/licenses/>. use alloc::vec::Vec; -use parity_scale_codec::{Encode, Decode}; +use parity_scale_codec::{Encode, Decode, DecodeLimit}; + +/// Maximum nesting level for XCM decoding. +pub const MAX_XCM_DECODE_DEPTH: u32 = 8; /// Wrapper around the encoded and decoded versions of a value. /// Caches the decoded value once computed. @@ -69,14 +72,22 @@ impl<T: Decode> DoubleEncoded<T> { /// Returns a reference to the value in case of success and `Err(())` in case the decoding fails. pub fn ensure_decoded(&mut self) -> Result<&T, ()> { if self.decoded.is_none() { - self.decoded = T::decode(&mut &self.encoded[..]).ok(); + self.decoded = T::decode_all_with_depth_limit( + MAX_XCM_DECODE_DEPTH, + &mut &self.encoded[..], + ).ok(); } self.decoded.as_ref().ok_or(()) } /// Move the decoded value out or (if not present) decode `encoded`. pub fn take_decoded(&mut self) -> Result<T, ()> { - self.decoded.take().or_else(|| T::decode(&mut &self.encoded[..]).ok()).ok_or(()) + self.decoded.take().or_else(|| { + T::decode_all_with_depth_limit( + MAX_XCM_DECODE_DEPTH, + &mut &self.encoded[..], + ).ok() + }).ok_or(()) } /// Provides an API similar to `TryInto` that allows fallible conversion to the inner value type. -- GitLab