Skip to content

Commit 97e2b9c

Browse files
committed
fix: guard BigInt(Math.trunc()) against NaN/Infinity in cross-type comparisons
BigInt(NaN) and BigInt(Infinity) throw RangeError. The evaluator.ts already had Number.isFinite guards but executor.ts and decode.ts coerceCompare() did not — NaN/Infinity values from float columns or arithmetic would crash the sort comparator and filter matcher. Now guarded: Infinity compares as > all bigints, -Infinity as < all. NaN/Infinity pass through as-is in coerceCompare (JS < / > handle them).
1 parent 7bf9a06 commit 97e2b9c

2 files changed

Lines changed: 4 additions & 4 deletions

File tree

src/decode.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,8 @@ function vectorSearch(
471471
* Returns coerced values via out parameter to avoid tuple allocation on hot path. */
472472
const _cmp: [unknown, unknown] = [null, null];
473473
function coerceCompare(a: unknown, b: unknown): [unknown, unknown] {
474-
if (typeof a === "bigint" && typeof b === "number") { _cmp[0] = a; _cmp[1] = BigInt(Math.trunc(b)); }
475-
else if (typeof a === "number" && typeof b === "bigint") { _cmp[0] = BigInt(Math.trunc(a as number)); _cmp[1] = b; }
474+
if (typeof a === "bigint" && typeof b === "number") { _cmp[0] = a; _cmp[1] = Number.isFinite(b) ? BigInt(Math.trunc(b)) : b; }
475+
else if (typeof a === "number" && typeof b === "bigint") { _cmp[0] = Number.isFinite(a) ? BigInt(Math.trunc(a)) : a; _cmp[1] = b; }
476476
else { _cmp[0] = a; _cmp[1] = b; }
477477
return _cmp;
478478
}

src/sql/executor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ export class SqlWrappingExecutor implements QueryExecutor {
127127
let cmp: number;
128128
if (typeof av === "number" && typeof bv === "number") cmp = av - bv;
129129
else if (typeof av === "bigint" && typeof bv === "bigint") cmp = av < bv ? -1 : av > bv ? 1 : 0;
130-
else if (typeof av === "bigint" && typeof bv === "number") { const bb = BigInt(Math.trunc(bv)); cmp = av < bb ? -1 : av > bb ? 1 : 0; }
131-
else if (typeof av === "number" && typeof bv === "bigint") { const ab = BigInt(Math.trunc(av)); cmp = ab < bv ? -1 : ab > bv ? 1 : 0; }
130+
else if (typeof av === "bigint" && typeof bv === "number") { if (!Number.isFinite(bv)) { cmp = bv === Infinity ? -1 : 1; } else { const bb = BigInt(Math.trunc(bv)); cmp = av < bb ? -1 : av > bb ? 1 : 0; } }
131+
else if (typeof av === "number" && typeof bv === "bigint") { if (!Number.isFinite(av)) { cmp = av === Infinity ? 1 : -1; } else { const ab = BigInt(Math.trunc(av)); cmp = ab < bv ? -1 : ab > bv ? 1 : 0; } }
132132
else cmp = String(av).localeCompare(String(bv));
133133
if (cmp !== 0) return direction === "desc" ? -cmp : cmp;
134134
}

0 commit comments

Comments
 (0)