Skip to content

Commit e2e1a6a

Browse files
committed
fix: guard canSkipPage BigInt coercion against NaN/Infinity filter values
All 6 BigInt(Math.trunc()) sites in canSkipPage now skip coercion for non-finite numbers: eq/gt/gte/lt/lte (continue), in/not_in (return false = don't skip), between/not_between (break = don't skip). Conservative: non-finite filter values never cause false page skips. Prevents BigInt(NaN) RangeError when int64 columns meet float filters.
1 parent 97e2b9c commit e2e1a6a

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

src/decode.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export function canSkipPage(page: PageInfo, filters: QueryDescriptor["filters"],
1818
let val = filter.value;
1919
if (typeof val === "object" && !Array.isArray(val)) continue;
2020

21-
// Coerce bigint↔number for cross-type comparisons
22-
if (typeof min === "bigint" && typeof val === "number") val = BigInt(Math.trunc(val as number));
21+
// Coerce bigint↔number for cross-type comparisons (skip non-finite numbers — BigInt(NaN) throws)
22+
if (typeof min === "bigint" && typeof val === "number") { if (!Number.isFinite(val)) continue; val = BigInt(Math.trunc(val as number)); }
2323
else if (typeof min === "number" && typeof val === "bigint") { min = BigInt(Math.trunc(min)); max = BigInt(Math.trunc(max as number)); }
2424

2525
switch (filter.op) {
@@ -35,7 +35,7 @@ export function canSkipPage(page: PageInfo, filters: QueryDescriptor["filters"],
3535
if (!Array.isArray(filter.value)) break;
3636
if (filter.value.every(v => {
3737
let cv = v;
38-
if (typeof min === "bigint" && typeof cv === "number") cv = BigInt(Math.trunc(cv));
38+
if (typeof min === "bigint" && typeof cv === "number") { if (!Number.isFinite(cv)) return false; cv = BigInt(Math.trunc(cv)); }
3939
else if (typeof min === "number" && typeof cv === "bigint") { min = BigInt(Math.trunc(min as number)); max = BigInt(Math.trunc(max as number)); }
4040
return cv < min || cv > max;
4141
})) return true;
@@ -46,7 +46,7 @@ export function canSkipPage(page: PageInfo, filters: QueryDescriptor["filters"],
4646
if (!Array.isArray(filter.value) || min !== max) break;
4747
if (filter.value.some(v => {
4848
let cv = v;
49-
if (typeof min === "bigint" && typeof cv === "number") cv = BigInt(Math.trunc(cv));
49+
if (typeof min === "bigint" && typeof cv === "number") { if (!Number.isFinite(cv)) return false; cv = BigInt(Math.trunc(cv)); }
5050
else if (typeof min === "number" && typeof cv === "bigint") { min = BigInt(Math.trunc(min as number)); max = BigInt(Math.trunc(max as number)); }
5151
return cv === min;
5252
})) return true;
@@ -56,7 +56,7 @@ export function canSkipPage(page: PageInfo, filters: QueryDescriptor["filters"],
5656
if (!Array.isArray(filter.value) || filter.value.length !== 2) break;
5757
let lo = filter.value[0];
5858
let hi = filter.value[1];
59-
if (typeof min === "bigint" && typeof lo === "number") { lo = BigInt(Math.trunc(lo)); hi = BigInt(Math.trunc(hi as number)); }
59+
if (typeof min === "bigint" && typeof lo === "number") { if (!Number.isFinite(lo) || !Number.isFinite(hi as number)) break; lo = BigInt(Math.trunc(lo)); hi = BigInt(Math.trunc(hi as number)); }
6060
else if (typeof min === "number" && typeof lo === "bigint") { min = BigInt(Math.trunc(min)); max = BigInt(Math.trunc(max as number)); }
6161
if (max < lo || min > hi) return true;
6262
break;
@@ -65,7 +65,7 @@ export function canSkipPage(page: PageInfo, filters: QueryDescriptor["filters"],
6565
if (!Array.isArray(filter.value) || filter.value.length !== 2) break;
6666
let lo = filter.value[0];
6767
let hi = filter.value[1];
68-
if (typeof min === "bigint" && typeof lo === "number") { lo = BigInt(Math.trunc(lo)); hi = BigInt(Math.trunc(hi as number)); }
68+
if (typeof min === "bigint" && typeof lo === "number") { if (!Number.isFinite(lo) || !Number.isFinite(hi as number)) break; lo = BigInt(Math.trunc(lo)); hi = BigInt(Math.trunc(hi as number)); }
6969
else if (typeof min === "number" && typeof lo === "bigint") { min = BigInt(Math.trunc(min)); max = BigInt(Math.trunc(max as number)); }
7070
// Skip if all values are within [lo, hi] — NOT BETWEEN would exclude them all
7171
if (min >= lo && max <= hi) return true;

0 commit comments

Comments
 (0)