Skip to content

Commit 41de048

Browse files
authored
feat(types-codec): Add maximum depth limit in decodeU8a functions (#6168)
* feat(decodeU8a): add maximum depth check for complex types in decode functions * chore: lint
1 parent 559a02e commit 41de048

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

packages/types-codec/src/utils/decodeU8a.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ import type { Codec, CodecClass, Registry } from '../types/index.js';
55

66
import { 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 */
918
function 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
*/
87100
export 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

Comments
 (0)