@@ -5,6 +5,15 @@ import type { Codec, CodecClass, Registry } from '../types/index.js';
55
66import { u8aToHex } from '@polkadot/util' ;
77
8+ const MAX_DEPTH = 1024 ;
9+
10+ /** @internal */
11+ function isComplexType ( Type : CodecClass ) : boolean {
12+ const typeName = Type . name ?. toLowerCase ( ) || '' ;
13+
14+ return [ 'enum' , 'hashmap' , 'linkage' , 'null' , 'option' , 'range' , 'rangeinclusive' , 'result' , 'struct' , 'tuple' , 'vec' , 'vecfixed' ] . includes ( typeName ) ;
15+ }
16+
817/** @internal */
918function formatFailure ( registry : Registry , fn : 'decodeU8a' | 'decodeU8aStruct' | 'decodeU8aVec' , _result : unknown [ ] , { message } : Error , u8a : Uint8Array , i : number , count : number , Type : CodecClass , key ?: string ) : string {
1019 let type = '' ;
@@ -63,6 +72,10 @@ export function decodeU8aStruct (registry: Registry, result: [string, Codec][],
6372 let offset = 0 ;
6473 let i = 0 ;
6574
75+ if ( count > MAX_DEPTH && isComplexType ( Types [ i ] ) ) {
76+ throw new Error ( `decodeU8aStruct: Maximum depth exceeded, received ${ count } elements, limit ${ MAX_DEPTH } ` ) ;
77+ }
78+
6679 try {
6780 while ( i < count ) {
6881 const value = new Types [ i ] ( registry , u8a . subarray ( offset ) ) ;
@@ -86,6 +99,11 @@ export function decodeU8aStruct (registry: Registry, result: [string, Codec][],
8699 */
87100export function decodeU8aVec < T extends Codec = Codec > ( registry : Registry , result : unknown [ ] , u8a : Uint8Array , startAt : number , Type : CodecClass < T > ) : [ number , number ] {
88101 const count = result . length ;
102+
103+ if ( count > MAX_DEPTH && isComplexType ( Type ) ) {
104+ throw new Error ( `decodeU8aVec: Maximum depth exceeded, received ${ count } elements, limit ${ MAX_DEPTH } ` ) ;
105+ }
106+
89107 let offset = startAt ;
90108 let i = 0 ;
91109
0 commit comments