Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Add XCM Decode Limit #3273

Merged
3 commits merged into from
Jun 17, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions xcm/src/double_encoded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down