Skip to content

Commit 18e4e57

Browse files
committed
feat!: disallow NaN, Infinity and -Infinity
Ref: ipld/specs#345
1 parent 4036264 commit 18e4e57

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

index.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,21 @@ function undefinedEncoder () {
3333
throw new Error('`undefined` is not supported by the IPLD Data Model and cannot be encoded')
3434
}
3535

36+
function numberEncoder (num) {
37+
if (Number.isNaN(num)) {
38+
throw new Error('`NaN` is not supported by the IPLD Data Model and cannot be encoded')
39+
}
40+
if (num === Infinity || num === -Infinity) {
41+
throw new Error('`Infinity` and `-Infinity` is not supported by the IPLD Data Model and cannot be encoded')
42+
}
43+
}
44+
3645
const encodeOptions = {
3746
float64: true,
3847
typeEncoders: {
3948
Object: cidEncoder,
40-
undefined: undefinedEncoder
49+
undefined: undefinedEncoder,
50+
number: numberEncoder
4151
}
4252
}
4353

@@ -55,6 +65,8 @@ function cidDecoder (bytes) {
5565
const decodeOptions = {
5666
allowIndefinite: false,
5767
allowUndefined: false,
68+
allowNaN: false,
69+
allowInfinity: false,
5870
allowBigInt: true, // this will lead to BigInt for ints outside of
5971
// safe-integer range, which may surprise users
6072
strict: true,

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
},
3030
"homepage": "https://github.com/ipld/js-dag-cbor",
3131
"dependencies": {
32-
"cborg": "^1.0.1",
32+
"cborg": "^1.0.2",
3333
"multiformats": "^4.0.0"
3434
},
3535
"devDependencies": {

test/test-basics.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,46 @@ describe('dag-cbor', () => {
7878
assert.throws(() => encode(objWithUndefined), /\Wundefined\W.*not supported/)
7979
})
8080

81+
test('error on decoding undefined', () => {
82+
// encoded forms from the encode() test above
83+
assert.throws(() => decode(bytes.fromHex('f7')), /\Wundefined\W.*not supported/)
84+
assert.throws(() => decode(bytes.fromHex('a2616161616162f7')), /\Wundefined\W.*not supported/)
85+
})
86+
87+
test('error on encoding IEEE 754 specials', () => {
88+
for (const special of [NaN, Infinity, -Infinity]) {
89+
assert.throws(() => encode(special), new RegExp(`\\W${String(special)}\\W.*not supported`))
90+
const objWithSpecial = { a: 'a', b: special }
91+
assert.throws(() => encode(objWithSpecial), new RegExp(`\\W${String(special)}\\W.*not supported`))
92+
const arrWithSpecial = [1, 1.1, -1, -1.1, Number.MAX_SAFE_INTEGER, special, Number.MIN_SAFE_INTEGER]
93+
assert.throws(() => encode(arrWithSpecial), new RegExp(`\\W${String(special)}\\W.*not supported`))
94+
}
95+
})
96+
97+
test('error on decoding IEEE 754 specials', () => {
98+
// encoded forms of each of the previous encode() tests
99+
const cases = [
100+
['NaN', 'f97e00'],
101+
['NaN', 'f97ff8'],
102+
['NaN', 'fa7ff80000'],
103+
['NaN', 'fb7ff8000000000000'],
104+
['NaN', 'a2616161616162fb7ff8000000000000'],
105+
['NaN', '8701fb3ff199999999999a20fbbff199999999999a1b001ffffffffffffffb7ff80000000000003b001ffffffffffffe'],
106+
['Infinity', 'f97c00'],
107+
['Infinity', 'fb7ff0000000000000'],
108+
['Infinity', 'a2616161616162fb7ff0000000000000'],
109+
['Infinity', '8701fb3ff199999999999a20fbbff199999999999a1b001ffffffffffffffb7ff00000000000003b001ffffffffffffe'],
110+
['-Infinity', 'f9fc00'],
111+
['-Infinity', 'fbfff0000000000000'],
112+
['-Infinity', 'a2616161616162fbfff0000000000000'],
113+
['-Infinity', '8701fb3ff199999999999a20fbbff199999999999a1b001ffffffffffffffbfff00000000000003b001ffffffffffffe']
114+
]
115+
for (const [typ, hex] of cases) {
116+
const byts = bytes.fromHex(hex)
117+
assert.throws(() => decode(byts), new RegExp(`\\W${typ.replace(/^-/, '')}\\W.*not supported`))
118+
}
119+
})
120+
81121
test('fuzz serialize and deserialize with garbage', () => {
82122
for (let ii = 0; ii < 1000; ii++) {
83123
const original = garbage(100)

0 commit comments

Comments
 (0)