diff --git a/packages/kbn-config-schema/src/byte_size_value/index.test.ts b/packages/kbn-config-schema/src/byte_size_value/index.test.ts index a5d0142853416..4c896c5278f8f 100644 --- a/packages/kbn-config-schema/src/byte_size_value/index.test.ts +++ b/packages/kbn-config-schema/src/byte_size_value/index.test.ts @@ -30,11 +30,33 @@ describe('parsing units', () => { expect(ByteSizeValue.parse('1gb').getValueInBytes()).toBe(1073741824); }); + test('case insensitive units', () => { + expect(ByteSizeValue.parse('1KB').getValueInBytes()).toBe(1024); + expect(ByteSizeValue.parse('1Mb').getValueInBytes()).toBe(1024 * 1024); + }); + + test('parses the max safe integer', () => { + expect(ByteSizeValue.parse('9007199254740991').getValueInBytes()).toBe(9007199254740991); + expect(ByteSizeValue.parse('9007199254740991b').getValueInBytes()).toBe(9007199254740991); + }); + test('throws an error when unsupported unit specified', () => { expect(() => ByteSizeValue.parse('1tb')).toThrowErrorMatchingInlineSnapshot( `"Failed to parse value as byte value. Value must be either number of bytes, or follow the format [b|kb|mb|gb] (e.g., '1024kb', '200mb', '1gb'), where the number is a safe positive integer."` ); }); + + test('throws an error when unsafe integer', () => { + expect(() => ByteSizeValue.parse('9007199254740992')).toThrowErrorMatchingInlineSnapshot( + `"Value in bytes is expected to be a safe positive integer."` + ); + }); + + test('throws an error on unusually long input', () => { + expect(() => ByteSizeValue.parse('19007199254740991kb')).toThrowErrorMatchingInlineSnapshot( + `"Value in bytes is expected to be a safe positive integer."` + ); + }); }); describe('#constructor', () => { diff --git a/packages/kbn-config-schema/src/byte_size_value/index.ts b/packages/kbn-config-schema/src/byte_size_value/index.ts index fb90bd70ed5c6..3260d3cf5664e 100644 --- a/packages/kbn-config-schema/src/byte_size_value/index.ts +++ b/packages/kbn-config-schema/src/byte_size_value/index.ts @@ -22,7 +22,11 @@ function renderUnit(value: number, unit: string) { export class ByteSizeValue { public static parse(text: string): ByteSizeValue { - const match = /([1-9][0-9]*)(b|kb|mb|gb)/.exec(text); + if (text.length > 18) { + // Exit early on large input where uses more than 16 digits and is therefore larger than Number.MAX_SAFE_INTEGER + throw new Error('Value in bytes is expected to be a safe positive integer.'); + } + const match = /([1-9][0-9]*)(b|kb|mb|gb)/i.exec(text); if (!match) { const number = Number(text); if (typeof number !== 'number' || isNaN(number)) {