Comparing version 1.3.8 to 1.4.0
@@ -87,2 +87,7 @@ 'use strict'; | ||
type: 'negint64' | ||
}, | ||
{ | ||
data: '3bffffffffffffffff', | ||
expected: BigInt('-18446744073709551616'), | ||
type: 'negint64' | ||
} | ||
@@ -89,0 +94,0 @@ ]; |
@@ -61,2 +61,26 @@ 'use strict'; | ||
}); | ||
it('handles large integers as BigInt', () => { | ||
const verify = (inp, str) => { | ||
if (str === undefined) { | ||
str = String(inp); | ||
} | ||
chai.assert.strictEqual(decode.decode(toBytes(str), { allowBigInt: true }), inp); | ||
chai.assert.strictEqual(decode.decode(toBytes(str)), parseFloat(str)); | ||
}; | ||
verify(Number.MAX_SAFE_INTEGER); | ||
verify(-Number.MAX_SAFE_INTEGER); | ||
verify(BigInt('9007199254740992')); | ||
verify(BigInt('9007199254740993')); | ||
verify(BigInt('11959030306112471731')); | ||
verify(BigInt('18446744073709551615')); | ||
verify(BigInt('9223372036854775807')); | ||
verify(BigInt('-9007199254740992')); | ||
verify(BigInt('-9007199254740993')); | ||
verify(BigInt('-9223372036854776000')); | ||
verify(BigInt('-11959030306112471732')); | ||
verify(BigInt('-18446744073709551616')); | ||
verify(-9007199254740992, '-9007199254740992.0'); | ||
verify(-9223372036854776000, '-9223372036854776000.0'); | ||
verify(-18446744073709552000, '-18446744073709551616.0'); | ||
}); | ||
it('can round-trip string literals', () => { | ||
@@ -252,3 +276,4 @@ const testCases = [ | ||
chai.assert.throws(() => decode.decode(toBytes('[fa]')), 'CBOR decode error: unexpected end of input at position 1'); | ||
chai.assert.throws(() => decode.decode(toBytes('-0..1')), 'CBOR decode error: unexpected token at position 3'); | ||
}); | ||
}); |
@@ -46,2 +46,3 @@ 'use strict'; | ||
let negative = false; | ||
let float = false; | ||
const swallow = chars => { | ||
@@ -65,2 +66,3 @@ while (!this.done()) { | ||
this.pos++; | ||
float = true; | ||
} else { | ||
@@ -86,2 +88,6 @@ return new token.Token(token.Type.uint, 0, this.pos - startPos); | ||
if (!this.done() && this.ch() === 46) { | ||
if (float) { | ||
throw new Error(`${ common.decodeErrPrefix } unexpected token at position ${ this.pos }`); | ||
} | ||
float = true; | ||
this.pos++; | ||
@@ -102,2 +108,3 @@ swallow([ | ||
if (!this.done() && (this.ch() === 101 || this.ch() === 69)) { | ||
float = true; | ||
this.pos++; | ||
@@ -120,4 +127,11 @@ if (!this.done() && (this.ch() === 43 || this.ch() === 45)) { | ||
} | ||
const float = parseFloat(String.fromCharCode.apply(null, this.data.subarray(startPos, this.pos))); | ||
return new token.Token(Number.isInteger(float) ? float >= 0 ? token.Type.uint : token.Type.negint : token.Type.float, float, this.pos - startPos); | ||
const numStr = String.fromCharCode.apply(null, this.data.subarray(startPos, this.pos)); | ||
const num = parseFloat(numStr); | ||
if (float) { | ||
return new token.Token(token.Type.float, num, this.pos - startPos); | ||
} | ||
if (this.options.allowBigInt !== true || Number.isSafeInteger(num)) { | ||
return new token.Token(num >= 0 ? token.Type.uint : token.Type.negint, num, this.pos - startPos); | ||
} | ||
return new token.Token(num >= 0 ? token.Type.uint : token.Type.negint, BigInt(numStr), this.pos - startPos); | ||
} | ||
@@ -124,0 +138,0 @@ parseString() { |
@@ -87,2 +87,7 @@ 'use strict'; | ||
type: 'negint64' | ||
}, | ||
{ | ||
data: '3bffffffffffffffff', | ||
expected: BigInt('-18446744073709551616'), | ||
type: 'negint64' | ||
} | ||
@@ -89,0 +94,0 @@ ]; |
@@ -61,2 +61,26 @@ 'use strict'; | ||
}); | ||
it('handles large integers as BigInt', () => { | ||
const verify = (inp, str) => { | ||
if (str === undefined) { | ||
str = String(inp); | ||
} | ||
chai.assert.strictEqual(decode.decode(toBytes(str), { allowBigInt: true }), inp); | ||
chai.assert.strictEqual(decode.decode(toBytes(str)), parseFloat(str)); | ||
}; | ||
verify(Number.MAX_SAFE_INTEGER); | ||
verify(-Number.MAX_SAFE_INTEGER); | ||
verify(BigInt('9007199254740992')); | ||
verify(BigInt('9007199254740993')); | ||
verify(BigInt('11959030306112471731')); | ||
verify(BigInt('18446744073709551615')); | ||
verify(BigInt('9223372036854775807')); | ||
verify(BigInt('-9007199254740992')); | ||
verify(BigInt('-9007199254740993')); | ||
verify(BigInt('-9223372036854776000')); | ||
verify(BigInt('-11959030306112471732')); | ||
verify(BigInt('-18446744073709551616')); | ||
verify(-9007199254740992, '-9007199254740992.0'); | ||
verify(-9223372036854776000, '-9223372036854776000.0'); | ||
verify(-18446744073709552000, '-18446744073709551616.0'); | ||
}); | ||
it('can round-trip string literals', () => { | ||
@@ -252,3 +276,4 @@ const testCases = [ | ||
chai.assert.throws(() => decode.decode(toBytes('[fa]')), 'CBOR decode error: unexpected end of input at position 1'); | ||
chai.assert.throws(() => decode.decode(toBytes('-0..1')), 'CBOR decode error: unexpected token at position 3'); | ||
}); | ||
}); |
@@ -84,2 +84,7 @@ import chai from 'chai'; | ||
type: 'negint64' | ||
}, | ||
{ | ||
data: '3bffffffffffffffff', | ||
expected: BigInt('-18446744073709551616'), | ||
type: 'negint64' | ||
} | ||
@@ -86,0 +91,0 @@ ]; |
@@ -59,2 +59,26 @@ import { assert } from 'chai'; | ||
}); | ||
it('handles large integers as BigInt', () => { | ||
const verify = (inp, str) => { | ||
if (str === undefined) { | ||
str = String(inp); | ||
} | ||
assert.strictEqual(decode(toBytes(str), { allowBigInt: true }), inp); | ||
assert.strictEqual(decode(toBytes(str)), parseFloat(str)); | ||
}; | ||
verify(Number.MAX_SAFE_INTEGER); | ||
verify(-Number.MAX_SAFE_INTEGER); | ||
verify(BigInt('9007199254740992')); | ||
verify(BigInt('9007199254740993')); | ||
verify(BigInt('11959030306112471731')); | ||
verify(BigInt('18446744073709551615')); | ||
verify(BigInt('9223372036854775807')); | ||
verify(BigInt('-9007199254740992')); | ||
verify(BigInt('-9007199254740993')); | ||
verify(BigInt('-9223372036854776000')); | ||
verify(BigInt('-11959030306112471732')); | ||
verify(BigInt('-18446744073709551616')); | ||
verify(-9007199254740992, '-9007199254740992.0'); | ||
verify(-9223372036854776000, '-9223372036854776000.0'); | ||
verify(-18446744073709552000, '-18446744073709551616.0'); | ||
}); | ||
it('can round-trip string literals', () => { | ||
@@ -250,3 +274,4 @@ const testCases = [ | ||
assert.throws(() => decode(toBytes('[fa]')), 'CBOR decode error: unexpected end of input at position 1'); | ||
assert.throws(() => decode(toBytes('-0..1')), 'CBOR decode error: unexpected token at position 3'); | ||
}); | ||
}); |
@@ -44,2 +44,3 @@ import { decode as _decode } from '../decode.js'; | ||
let negative = false; | ||
let float = false; | ||
const swallow = chars => { | ||
@@ -63,2 +64,3 @@ while (!this.done()) { | ||
this.pos++; | ||
float = true; | ||
} else { | ||
@@ -84,2 +86,6 @@ return new Token(Type.uint, 0, this.pos - startPos); | ||
if (!this.done() && this.ch() === 46) { | ||
if (float) { | ||
throw new Error(`${ decodeErrPrefix } unexpected token at position ${ this.pos }`); | ||
} | ||
float = true; | ||
this.pos++; | ||
@@ -100,2 +106,3 @@ swallow([ | ||
if (!this.done() && (this.ch() === 101 || this.ch() === 69)) { | ||
float = true; | ||
this.pos++; | ||
@@ -118,4 +125,11 @@ if (!this.done() && (this.ch() === 43 || this.ch() === 45)) { | ||
} | ||
const float = parseFloat(String.fromCharCode.apply(null, this.data.subarray(startPos, this.pos))); | ||
return new Token(Number.isInteger(float) ? float >= 0 ? Type.uint : Type.negint : Type.float, float, this.pos - startPos); | ||
const numStr = String.fromCharCode.apply(null, this.data.subarray(startPos, this.pos)); | ||
const num = parseFloat(numStr); | ||
if (float) { | ||
return new Token(Type.float, num, this.pos - startPos); | ||
} | ||
if (this.options.allowBigInt !== true || Number.isSafeInteger(num)) { | ||
return new Token(num >= 0 ? Type.uint : Type.negint, num, this.pos - startPos); | ||
} | ||
return new Token(num >= 0 ? Type.uint : Type.negint, BigInt(numStr), this.pos - startPos); | ||
} | ||
@@ -122,0 +136,0 @@ parseString() { |
@@ -84,2 +84,7 @@ import chai from 'chai'; | ||
type: 'negint64' | ||
}, | ||
{ | ||
data: '3bffffffffffffffff', | ||
expected: BigInt('-18446744073709551616'), | ||
type: 'negint64' | ||
} | ||
@@ -86,0 +91,0 @@ ]; |
@@ -59,2 +59,26 @@ import { assert } from 'chai'; | ||
}); | ||
it('handles large integers as BigInt', () => { | ||
const verify = (inp, str) => { | ||
if (str === undefined) { | ||
str = String(inp); | ||
} | ||
assert.strictEqual(decode(toBytes(str), { allowBigInt: true }), inp); | ||
assert.strictEqual(decode(toBytes(str)), parseFloat(str)); | ||
}; | ||
verify(Number.MAX_SAFE_INTEGER); | ||
verify(-Number.MAX_SAFE_INTEGER); | ||
verify(BigInt('9007199254740992')); | ||
verify(BigInt('9007199254740993')); | ||
verify(BigInt('11959030306112471731')); | ||
verify(BigInt('18446744073709551615')); | ||
verify(BigInt('9223372036854775807')); | ||
verify(BigInt('-9007199254740992')); | ||
verify(BigInt('-9007199254740993')); | ||
verify(BigInt('-9223372036854776000')); | ||
verify(BigInt('-11959030306112471732')); | ||
verify(BigInt('-18446744073709551616')); | ||
verify(-9007199254740992, '-9007199254740992.0'); | ||
verify(-9223372036854776000, '-9223372036854776000.0'); | ||
verify(-18446744073709552000, '-18446744073709551616.0'); | ||
}); | ||
it('can round-trip string literals', () => { | ||
@@ -250,3 +274,4 @@ const testCases = [ | ||
assert.throws(() => decode(toBytes('[fa]')), 'CBOR decode error: unexpected end of input at position 1'); | ||
assert.throws(() => decode(toBytes('-0..1')), 'CBOR decode error: unexpected token at position 3'); | ||
}); | ||
}); |
@@ -74,2 +74,3 @@ import { decode as _decode } from '../decode.js' | ||
let negative = false | ||
let float = false | ||
@@ -99,2 +100,3 @@ /** | ||
this.pos++ | ||
float = true | ||
} else { | ||
@@ -109,2 +111,6 @@ return new Token(Type.uint, 0, this.pos - startPos) | ||
if (!this.done() && this.ch() === 46) { // '.' | ||
if (float) { | ||
throw new Error(`${decodeErrPrefix} unexpected token at position ${this.pos}`) | ||
} | ||
float = true | ||
this.pos++ | ||
@@ -114,2 +120,3 @@ swallow([48, 49, 50, 51, 52, 53, 54, 55, 56, 57]) // DIGIT | ||
if (!this.done() && (this.ch() === 101 || this.ch() === 69)) { // '[eE]' | ||
float = true | ||
this.pos++ | ||
@@ -121,6 +128,12 @@ if (!this.done() && (this.ch() === 43 || this.ch() === 45)) { // '+', '-' | ||
} | ||
// TODO: check canonical form of this number? | ||
// @ts-ignore | ||
const float = parseFloat(String.fromCharCode.apply(null, this.data.subarray(startPos, this.pos))) | ||
return new Token(Number.isInteger(float) ? float >= 0 ? Type.uint : Type.negint : Type.float, float, this.pos - startPos) | ||
const numStr = String.fromCharCode.apply(null, this.data.subarray(startPos, this.pos)) | ||
const num = parseFloat(numStr) | ||
if (float) { | ||
return new Token(Type.float, num, this.pos - startPos) | ||
} | ||
if (this.options.allowBigInt !== true || Number.isSafeInteger(num)) { | ||
return new Token(num >= 0 ? Type.uint : Type.negint, num, this.pos - startPos) | ||
} | ||
return new Token(num >= 0 ? Type.uint : Type.negint, BigInt(numStr), this.pos - startPos) | ||
} | ||
@@ -127,0 +140,0 @@ |
{ | ||
"name": "cborg", | ||
"version": "1.3.8", | ||
"version": "1.4.0", | ||
"description": "Fast CBOR with a focus on strictness", | ||
@@ -5,0 +5,0 @@ "main": "./cjs/cborg.js", |
@@ -293,2 +293,6 @@ # cborg - fast CBOR with a focus on strictness | ||
Special notes on options specific to the JSON: | ||
* Decoder `allowBigInt` option: is repurposed for the JSON decoder and defaults to `false`. When `false`, all numbers are decoded as `Number`, possibly losing precision when encountering numbers outside of the JavaScript safe integer range. When `true` numbers that have a decimal point (`.`, even if just `.0`) are returned as a `Number`, but for numbers without a decimal point _and_ that are outside of the JavaScript safe integer range, they are returned as `BigInt`s. This behaviour differs from CBOR decoding which will error when decoding integer and negative integer tokens that are outside of the JavaScript safe integer range if `allowBigInt` is `false`. | ||
See **[@ipld/dag-json](https://github.com/ipld/js-dag-json)** for an advanced use of the **cborg** JSON encoder and decoder including round-tripping of `Uint8Array`s and custom JavaScript classes (IPLD `CID` objects in this case). | ||
@@ -295,0 +299,0 @@ |
@@ -27,3 +27,4 @@ /* eslint-env mocha */ | ||
{ data: '3b0020000000000000', expected: BigInt('-9007199254740993') /* Number.MIN_SAFE_INTEGER - 2 */, type: 'negint64' }, | ||
{ data: '3ba5f702b3a5f702b3', expected: BigInt('-11959030306112471732'), type: 'negint64' } | ||
{ data: '3ba5f702b3a5f702b3', expected: BigInt('-11959030306112471732'), type: 'negint64' }, | ||
{ data: '3bffffffffffffffff', expected: BigInt('-18446744073709551616'), type: 'negint64' } | ||
] | ||
@@ -30,0 +31,0 @@ |
@@ -61,2 +61,29 @@ /* eslint-env mocha,es2020 */ | ||
it('handles large integers as BigInt', () => { | ||
const verify = (inp, str) => { | ||
if (str === undefined) { | ||
str = String(inp) | ||
} | ||
assert.strictEqual(decode(toBytes(str), { allowBigInt: true }), inp) | ||
assert.strictEqual(decode(toBytes(str)), parseFloat(str)) // no BigInt for you | ||
} | ||
verify(Number.MAX_SAFE_INTEGER) | ||
verify(-Number.MAX_SAFE_INTEGER) | ||
verify(BigInt('9007199254740992')) // Number.MAX_SAFE_INTEGER+1 | ||
verify(BigInt('9007199254740993')) | ||
verify(BigInt('11959030306112471731')) | ||
verify(BigInt('18446744073709551615')) // max uint64 | ||
verify(BigInt('9223372036854775807')) // max int64 | ||
verify(BigInt('-9007199254740992')) | ||
verify(BigInt('-9007199254740993')) | ||
verify(BigInt('-9223372036854776000')) // min int64 | ||
verify(BigInt('-11959030306112471732')) | ||
verify(BigInt('-18446744073709551616')) // min -uint64 | ||
// these are "floats", distinct from "ints" which wouldn't have the `.` in them | ||
verify(-9007199254740992, '-9007199254740992.0') | ||
verify(-9223372036854776000, '-9223372036854776000.0') | ||
verify(-18446744073709551616, '-18446744073709551616.0') | ||
}) | ||
it('can round-trip string literals', () => { | ||
@@ -158,3 +185,4 @@ const testCases = [ | ||
assert.throws(() => decode(toBytes('[fa]')), 'CBOR decode error: unexpected end of input at position 1') | ||
assert.throws(() => decode(toBytes('-0..1')), 'CBOR decode error: unexpected token at position 3') | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
752976
24250
331