add decode with depth limit to opaque types (#11947)

Co-authored-by: parity-processbot <>
This commit is contained in:
Shawn Tabrizi
2022-08-11 15:39:56 +01:00
committed by GitHub
parent 98252cb900
commit a6c95cbb13
3 changed files with 33 additions and 3 deletions
+30 -3
View File
@@ -18,7 +18,7 @@
//! Smaller traits used in FRAME which don't need their own file.
use crate::dispatch::Parameter;
use codec::{CompactLen, Decode, DecodeAll, Encode, EncodeLike, Input, MaxEncodedLen};
use codec::{CompactLen, Decode, DecodeLimit, Encode, EncodeLike, Input, MaxEncodedLen};
use scale_info::{build::Fields, meta_type, Path, Type, TypeInfo, TypeParameter};
use sp_arithmetic::traits::{CheckedAdd, CheckedMul, CheckedSub, Saturating};
#[doc(hidden)]
@@ -745,7 +745,10 @@ impl<T: Encode> Encode for WrapperOpaque<T> {
impl<T: Decode> Decode for WrapperOpaque<T> {
fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
Ok(Self(T::decode_all(&mut &<Vec<u8>>::decode(input)?[..])?))
Ok(Self(T::decode_all_with_depth_limit(
sp_api::MAX_EXTRINSIC_DEPTH,
&mut &<Vec<u8>>::decode(input)?[..],
)?))
}
fn skip<I: Input>(input: &mut I) -> Result<(), codec::Error> {
@@ -807,7 +810,7 @@ impl<T: Decode> WrapperKeepOpaque<T> {
///
/// Returns `None` if the decoding failed.
pub fn try_decode(&self) -> Option<T> {
T::decode_all(&mut &self.data[..]).ok()
T::decode_all_with_depth_limit(sp_api::MAX_EXTRINSIC_DEPTH, &mut &self.data[..]).ok()
}
/// Returns the length of the encoded `T`.
@@ -939,6 +942,30 @@ impl<Hash> PreimageRecipient<Hash> for () {
#[cfg(test)]
mod test {
use super::*;
use sp_std::marker::PhantomData;
#[derive(Encode, Decode)]
enum NestedType {
Nested(Box<Self>),
Done,
}
#[test]
fn test_opaque_wrapper_decode_limit() {
let limit = sp_api::MAX_EXTRINSIC_DEPTH as usize;
let mut ok_bytes = vec![0u8; limit];
ok_bytes.push(1u8);
let mut err_bytes = vec![0u8; limit + 1];
err_bytes.push(1u8);
assert!(<WrapperOpaque<NestedType>>::decode(&mut &ok_bytes.encode()[..]).is_ok());
assert!(<WrapperOpaque<NestedType>>::decode(&mut &err_bytes.encode()[..]).is_err());
let ok_keep_opaque = WrapperKeepOpaque { data: ok_bytes, _phantom: PhantomData };
let err_keep_opaque = WrapperKeepOpaque { data: err_bytes, _phantom: PhantomData };
assert!(<WrapperKeepOpaque<NestedType>>::try_decode(&ok_keep_opaque).is_some());
assert!(<WrapperKeepOpaque<NestedType>>::try_decode(&err_keep_opaque).is_none());
}
#[test]
fn test_opaque_wrapper() {