diff --git a/src/cjs/index.cjs b/src/cjs/index.cjs index 7336f35..d1d11e9 100644 --- a/src/cjs/index.cjs +++ b/src/cjs/index.cjs @@ -88,6 +88,8 @@ function decode(buffer, offset) { } else if (first === 0xfd) { const val = tools.readUInt16(buffer, offset + 1, 'LE'); + if (val < 0xfd) + throw new Error('non-minimal encoding'); return { numberValue: val, bigintValue: BigInt(val), @@ -97,6 +99,8 @@ function decode(buffer, offset) { } else if (first === 0xfe) { const val = tools.readUInt32(buffer, offset + 1, 'LE'); + if (val <= 0xffff) + throw new Error('non-minimal encoding'); return { numberValue: val, bigintValue: BigInt(val), @@ -106,6 +110,8 @@ function decode(buffer, offset) { } else { const number = tools.readUInt64(buffer, offset + 1, 'LE'); + if (number <= 0xffffffffn) + throw new Error('non-minimal encoding'); return { numberValue: number <= Number.MAX_SAFE_INTEGER ? Number(number) : null, bigintValue: number, bytes: 9 }; } } diff --git a/src/esm/index.js b/src/esm/index.js index ec06d97..0fddd4b 100644 --- a/src/esm/index.js +++ b/src/esm/index.js @@ -61,6 +61,8 @@ export function decode(buffer, offset) { } else if (first === 0xfd) { const val = tools.readUInt16(buffer, offset + 1, 'LE'); + if (val < 0xfd) + throw new Error('non-minimal encoding'); return { numberValue: val, bigintValue: BigInt(val), @@ -70,6 +72,8 @@ export function decode(buffer, offset) { } else if (first === 0xfe) { const val = tools.readUInt32(buffer, offset + 1, 'LE'); + if (val <= 0xffff) + throw new Error('non-minimal encoding'); return { numberValue: val, bigintValue: BigInt(val), @@ -79,6 +83,8 @@ export function decode(buffer, offset) { } else { const number = tools.readUInt64(buffer, offset + 1, 'LE'); + if (number <= 0xffffffffn) + throw new Error('non-minimal encoding'); return { numberValue: number <= Number.MAX_SAFE_INTEGER ? Number(number) : null, bigintValue: number, bytes: 9 }; } } diff --git a/test/index.js b/test/index.js index bb8582d..90a00a5 100644 --- a/test/index.js +++ b/test/index.js @@ -102,6 +102,19 @@ tape("decode", function (t) { t.end(); }); + t.test("should reject a non-minimal encoding", function (t) { + t.throws(function () { + decode(Buffer.from("fd0100", "hex")); + }, new Error("non-minimal encoding")); + t.throws(function () { + decode(Buffer.from("fe01000000", "hex")); + }, new Error("non-minimal encoding")); + t.throws(function () { + decode(Buffer.from("ff0100000000000000", "hex")); + }, new Error("non-minimal encoding")); + t.end(); + }); + t.test("should return null if a number is invalid", function (t) { var buffer = Buffer.alloc(18); buffer.writeUIntBE(0xff, 0, 1); diff --git a/ts_src/index.ts b/ts_src/index.ts index 686a076..c3d88e1 100644 --- a/ts_src/index.ts +++ b/ts_src/index.ts @@ -77,6 +77,7 @@ export function decode ( // 16 bit } else if (first === 0xfd) { const val = tools.readUInt16(buffer, offset + 1, 'LE') + if (val < 0xfd) throw new Error('non-minimal encoding') return { numberValue: val, bigintValue: BigInt(val), @@ -86,6 +87,7 @@ export function decode ( // 32 bit } else if (first === 0xfe) { const val = tools.readUInt32(buffer, offset + 1, 'LE') + if (val <= 0xffff) throw new Error('non-minimal encoding') return { numberValue: val, bigintValue: BigInt(val), @@ -95,6 +97,7 @@ export function decode ( // 64 bit } else { const number = tools.readUInt64(buffer, offset + 1, 'LE') + if (number <= 0xffffffffn) throw new Error('non-minimal encoding') return { numberValue: number <= Number.MAX_SAFE_INTEGER ? Number(number) : null, bigintValue: number, bytes: 9 } }