Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ export class Encoder<ContextType = undefined> {
}

private encodeBigInt64(object: bigint): void {
if (object < -(BigInt(2) ** BigInt(63)) || object > BigInt(2) ** BigInt(64) - BigInt(1)) {
Comment on lines 292 to +294

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private encodeBigInt64(object: bigint): void {
if (object < -(BigInt(2) ** BigInt(63)) || object > BigInt(2) ** BigInt(64) - BigInt(1)) {
const INT64_MIN = -(BigInt(2) ** BigInt(63));
const UINT64_MAX = BigInt(2) ** BigInt(64) - BigInt(1);
private encodeBigInt64(object: bigint): void {
if (object < INT64_MIN || object > UINT64_MAX) {

throw new Error(`Cannot encode BigInt as int64/uint64 because it is out of range: ${object}`);
}
if (object >= BigInt(0)) {
// uint 64
this.writeU8(0xcf);
Expand Down
26 changes: 26 additions & 0 deletions test/bigint64.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,30 @@ describe("useBigInt64: true", () => {
const encoded = encode(value, { useBigInt64: true });
assert.deepStrictEqual(decode(encoded, { useBigInt64: true }), value);
});

it("round-trips the boundary values of int64/uint64", () => {
const values = [
BigInt(0),
BigInt(42),
BigInt(2) ** BigInt(63) - BigInt(1), // max int64
-(BigInt(2) ** BigInt(63)), // min int64
BigInt(2) ** BigInt(64) - BigInt(1), // max uint64
];
for (const value of values) {
const encoded = encode(value, { useBigInt64: true });
assert.deepStrictEqual(decode(encoded, { useBigInt64: true }), value);
}
});

it("throws when a bigint is out of the int64/uint64 range", () => {
const values = [
BigInt(2) ** BigInt(64), // uint64 max + 1
BigInt(2) ** BigInt(64) + BigInt(1),
-(BigInt(2) ** BigInt(63)) - BigInt(1), // int64 min - 1
-(BigInt(2) ** BigInt(100)),
];
for (const value of values) {
assert.throws(() => encode(value, { useBigInt64: true }), /out of range/);
}
});
});