Skip to content

Commit 8ca0144

Browse files
authored
fix: limit incoming hamt width (#433)
Matches the undocumented limit in boxo.
1 parent 7b178e9 commit 8ca0144

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

packages/ipfs-unixfs/src/errors.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,14 @@ export class InvalidTypeError extends Error {
88
super(message)
99
}
1010
}
11+
12+
export class InvalidUnixFSMessageError extends Error {
13+
static name = 'InvalidUnixFSMessageError'
14+
static code = 'ERR_INVALID_MESSAGE'
15+
name = InvalidUnixFSMessageError.name
16+
code = InvalidUnixFSMessageError.code
17+
18+
constructor (message = 'Invalid message') {
19+
super(message)
20+
}
21+
}

packages/ipfs-unixfs/src/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
* ```
9191
*/
9292

93-
import { InvalidTypeError } from './errors.js'
93+
import { InvalidTypeError, InvalidUnixFSMessageError } from './errors.js'
9494
import { Data as PBData } from './unixfs.js'
9595

9696
export interface Mtime {
@@ -117,6 +117,9 @@ const dirTypes = [
117117
const DEFAULT_FILE_MODE = parseInt('0644', 8)
118118
const DEFAULT_DIRECTORY_MODE = parseInt('0755', 8)
119119

120+
// https://github.com/ipfs/boxo/blob/364c5040ec91ec8e2a61446e9921e9225704c34d/ipld/unixfs/hamt/hamt.go#L778
121+
const MAX_FANOUT = BigInt(1 << 10)
122+
120123
export interface UnixFSOptions {
121124
type?: string
122125
data?: Uint8Array
@@ -134,6 +137,10 @@ class UnixFS {
134137
static unmarshal (marshaled: Uint8Array): UnixFS {
135138
const message = PBData.decode(marshaled)
136139

140+
if (message.fanout != null && message.fanout > MAX_FANOUT) {
141+
throw new InvalidUnixFSMessageError(`Fanout size was too large - ${message.fanout} > ${MAX_FANOUT}`)
142+
}
143+
137144
const data = new UnixFS({
138145
type: types[message.Type != null ? message.Type.toString() : 'File'],
139146
data: message.Data,

packages/ipfs-unixfs/test/unixfs-format.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,4 +431,17 @@ describe('unixfs-format', () => {
431431

432432
expect(marshaled).to.deep.equal(Uint8Array.from([0x08, 0x02, 0x18, 0x00]))
433433
})
434+
435+
it('should limit maximum fanout size', () => {
436+
const data = new UnixFS({
437+
type: 'hamt-sharded-directory',
438+
fanout: 1025n
439+
})
440+
const marshaled = data.marshal()
441+
442+
expect(() => {
443+
UnixFS.unmarshal(marshaled)
444+
}).to.throw()
445+
.with.property('name', 'InvalidUnixFSMessageError')
446+
})
434447
})

0 commit comments

Comments
 (0)