Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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)) {

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/);
}
});
});