From c00359ec96654e6364f5196566cdb0b3c6c80a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez?= Date: Fri, 10 Jul 2020 11:55:56 +0200 Subject: [PATCH] [Logs UI] Limit `extendDatemath` to valid ranges (#71113) Co-authored-by: Elastic Machine --- .../infra/public/utils/datemath.test.ts | 16 +++++++ x-pack/plugins/infra/public/utils/datemath.ts | 43 ++++++++++++++----- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/infra/public/utils/datemath.test.ts b/x-pack/plugins/infra/public/utils/datemath.test.ts index c8fbe5583db2..e073afb231b0 100644 --- a/x-pack/plugins/infra/public/utils/datemath.test.ts +++ b/x-pack/plugins/infra/public/utils/datemath.test.ts @@ -196,6 +196,15 @@ describe('extendDatemath()', () => { diffUnit: 'y', }); }); + + it('Returns no difference if the next value would result in an epoch smaller than 0', () => { + // FIXME: Test will fail in ~551 years + expect(extendDatemath('now-500y', 'before')).toBeUndefined(); + + expect( + extendDatemath('1970-01-01T00:00:00.000Z', 'before', '1970-01-01T00:00:00.001Z') + ).toBeUndefined(); + }); }); describe('with a positive operator', () => { @@ -573,6 +582,13 @@ describe('extendDatemath()', () => { diffUnit: 'y', }); }); + + it('Returns no difference if the next value would result in an epoch bigger than the max JS date', () => { + expect(extendDatemath('now+275760y', 'after')).toBeUndefined(); + expect( + extendDatemath('+275760-09-13T00:00:00.000Z', 'after', '+275760-09-12T23:59:59.999Z') + ).toBeUndefined(); + }); }); }); }); diff --git a/x-pack/plugins/infra/public/utils/datemath.ts b/x-pack/plugins/infra/public/utils/datemath.ts index f2bd5d94ac2c..791fe4bdb8da 100644 --- a/x-pack/plugins/infra/public/utils/datemath.ts +++ b/x-pack/plugins/infra/public/utils/datemath.ts @@ -6,6 +6,8 @@ import dateMath, { Unit } from '@elastic/datemath'; +const JS_MAX_DATE = 8640000000000000; + export function isValidDatemath(value: string): boolean { const parsedValue = dateMath.parse(value); return !!(parsedValue && parsedValue.isValid()); @@ -136,18 +138,24 @@ function extendRelativeDatemath( // if `diffAmount` is not an integer after normalization, express the difference in the original unit const shouldKeepDiffUnit = diffAmount % 1 !== 0; - return { - value: `now${operator}${normalizedAmount}${normalizedUnit}`, - diffUnit: shouldKeepDiffUnit ? unit : newUnit, - diffAmount: shouldKeepDiffUnit ? Math.abs(newAmount - parsedAmount) : diffAmount, - }; + const nextValue = `now${operator}${normalizedAmount}${normalizedUnit}`; + + if (isDateInRange(nextValue)) { + return { + value: nextValue, + diffUnit: shouldKeepDiffUnit ? unit : newUnit, + diffAmount: shouldKeepDiffUnit ? Math.abs(newAmount - parsedAmount) : diffAmount, + }; + } else { + return undefined; + } } function extendAbsoluteDatemath( value: string, direction: 'before' | 'after', oppositeEdge: string -): DatemathExtension { +): DatemathExtension | undefined { const valueTimestamp = datemathToEpochMillis(value)!; const oppositeEdgeTimestamp = datemathToEpochMillis(oppositeEdge)!; const actualTimestampDiff = Math.abs(valueTimestamp - oppositeEdgeTimestamp); @@ -159,11 +167,15 @@ function extendAbsoluteDatemath( ? valueTimestamp - normalizedTimestampDiff : valueTimestamp + normalizedTimestampDiff; - return { - value: new Date(newValue).toISOString(), - diffUnit: normalizedDiff.unit, - diffAmount: normalizedDiff.amount, - }; + if (isDateInRange(newValue)) { + return { + value: new Date(newValue).toISOString(), + diffUnit: normalizedDiff.unit, + diffAmount: normalizedDiff.amount, + }; + } else { + return undefined; + } } const CONVERSION_RATIOS: Record> = { @@ -265,3 +277,12 @@ export function normalizeDate(amount: number, unit: Unit): { amount: number; uni // Cannot go one one unit above. Return as it is return { amount, unit }; } + +function isDateInRange(date: string | number): boolean { + try { + const epoch = typeof date === 'string' ? datemathToEpochMillis(date) ?? -1 : date; + return epoch >= 0 && epoch <= JS_MAX_DATE; + } catch { + return false; + } +}