Skip to content

Commit

Permalink
match_query: avoid exceptional control flow in date parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
liamwhite committed Mar 17, 2024
1 parent 0cbe1ce commit aae69bb
Showing 1 changed file with 13 additions and 15 deletions.
28 changes: 13 additions & 15 deletions assets/js/query/date.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { assertNotNull } from '../utils/assert';
import { FieldMatcher, ParseError, RangeEqualQualifier } from './types';

type Year = number;
Expand Down Expand Up @@ -32,8 +33,10 @@ function makeMatcher(bottomDate: PosixTimeMs, topDate: PosixTimeMs, qual: RangeE
}
}

const relativeDateMatch = /(\d+) (second|minute|hour|day|week|month|year)s? ago/;

function makeRelativeDateMatcher(dateVal: string, qual: RangeEqualQualifier): FieldMatcher {
const match = /(\d+) (second|minute|hour|day|week|month|year)s? ago/.exec(dateVal);
const match = assertNotNull(relativeDateMatch.exec(dateVal));
const bounds: Record<string, number> = {
second: 1000,
minute: 60000,
Expand All @@ -44,18 +47,14 @@ function makeRelativeDateMatcher(dateVal: string, qual: RangeEqualQualifier): Fi
year: 31536000000
};

if (match) {
const amount = parseInt(match[1], 10);
const scale = bounds[match[2]];

const now = new Date().getTime();
const bottomDate = new Date(now - amount * scale).getTime();
const topDate = new Date(now - (amount - 1) * scale).getTime();
const amount = parseInt(match[1], 10);
const scale = bounds[match[2]];

return makeMatcher(bottomDate, topDate, qual);
}
const now = new Date().getTime();
const bottomDate = new Date(now - amount * scale).getTime();
const topDate = new Date(now - (amount - 1) * scale).getTime();

throw new ParseError(`Cannot parse date string: ${dateVal}`);
return makeMatcher(bottomDate, topDate, qual);
}

function makeAbsoluteDateMatcher(dateVal: string, qual: RangeEqualQualifier): FieldMatcher {
Expand Down Expand Up @@ -133,10 +132,9 @@ function makeAbsoluteDateMatcher(dateVal: string, qual: RangeEqualQualifier): Fi
}

export function makeDateMatcher(dateVal: string, qual: RangeEqualQualifier): FieldMatcher {
try {
return makeAbsoluteDateMatcher(dateVal, qual);
}
catch {
if (relativeDateMatch.test(dateVal)) {
return makeRelativeDateMatcher(dateVal, qual);
}

return makeAbsoluteDateMatcher(dateVal, qual);
}

0 comments on commit aae69bb

Please sign in to comment.