Skip to content

Commit

Permalink
requested changes
Browse files Browse the repository at this point in the history
  • Loading branch information
aditi-khare-mongoDB committed Apr 24, 2024
1 parent 9e90f06 commit 1ead83d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 23 deletions.
32 changes: 13 additions & 19 deletions src/long.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,17 +252,11 @@ export class Long extends BSONValue {
* @param str - The textual representation of the Long
* @param radix - The radix in which the text is written (2-36), defaults to 10
*/
static validateStringCharacters(str: string, radix?: number): false | string {
private static validateStringCharacters(str: string, radix?: number): false | string {
radix = radix ?? 10;

let regexInputString = '';
if (radix <= 10) {
regexInputString = `[^-0-${radix - 1}+]`;
} else {
const validCharRangeEnd = String.fromCharCode('a'.charCodeAt(0) + (radix - 11));
regexInputString = `[^-0-9+(a-${validCharRangeEnd})]`;
}
const regex = new RegExp(regexInputString, 'i');
const validCharacters = '0123456789abcdefghijklmnopqrstuvwxyz'.slice(0, radix);
// regex is case insensitive and checks that each character within the string is one of the validCharacters
const regex = new RegExp(`[^-+${validCharacters}]`, 'i');
return regex.test(str) ? false : str;
}

Expand All @@ -273,16 +267,16 @@ export class Long extends BSONValue {
* - the string contains invalid characters for the given radix
* - the string contains whitespace
* @param str - The textual representation of the Long
* @param validateStringCharacters - Whether or not invalid characters should throw an error
* @param unsigned - Whether unsigned or not, defaults to signed
* @param radix - The radix in which the text is written (2-36), defaults to 10
* @param throwsError - Whether or not throwing an error is permitted
* @returns The corresponding Long value
*/
static fromStringHelper(
private static _fromString(
str: string,
validateStringCharacters: boolean,
unsigned?: boolean,
radix?: number,
throwsError?: boolean
): Long {
if (str.length === 0) throw new BSONError('empty string');
if (str === 'NaN' || str === 'Infinity' || str === '+Infinity' || str === '-Infinity')
Expand All @@ -297,17 +291,17 @@ export class Long extends BSONValue {

if (radix < 2 || 36 < radix) throw new BSONError('radix');

if (throwsError && !Long.validateStringCharacters(str, radix)) {
if (validateStringCharacters && !Long.validateStringCharacters(str, radix)) {
throw new BSONError(`Input: '${str}' contains invalid characters for radix: ${radix}`);
}
if (throwsError && str.trim() !== str) {
throw new BSONError(`Input: '${str}' contains whitespace.`);
if (validateStringCharacters && str.trim() !== str) {
throw new BSONError(`Input: '${str}' contains leading and/or trailing whitespace.`);
}

let p;
if ((p = str.indexOf('-')) > 0) throw new BSONError('interior hyphen');
else if (p === 0) {
return Long.fromStringHelper(str.substring(1), unsigned, radix, throwsError).neg();
return Long._fromString(str.substring(1), validateStringCharacters, unsigned, radix).neg();
}

// Do several (8) digits each time through the loop, so as to
Expand Down Expand Up @@ -345,7 +339,7 @@ export class Long extends BSONValue {
// remove leading zeros (for later string comparison and to make math faster)
const cleanedStr = removeLeadingZeros(str);
// doing this check outside of recursive function so cleanedStr value is consistent
const result = Long.fromStringHelper(cleanedStr, unsigned, radix, true);
const result = Long._fromString(cleanedStr, true, unsigned, radix);
if (result.toString(radix).toLowerCase() !== cleanedStr.toLowerCase()) {
throw new BSONError(
`Input: ${str} is not representable as ${result.unsigned ? 'an unsigned' : 'a signed'} 64-bit Long with radix: ${radix}`
Expand All @@ -362,7 +356,7 @@ export class Long extends BSONValue {
* @returns The corresponding Long value
*/
static fromString(str: string, unsigned?: boolean, radix?: number): Long {
return Long.fromStringHelper(str, unsigned, radix, false);
return Long._fromString(str, false, unsigned, radix);
}

/**
Expand Down
15 changes: 11 additions & 4 deletions test/node/long.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,13 @@ describe('Long', function () {
});

describe('static fromStringStrict()', function () {
const successInputs = [
const successInputs: [
name: string,
input: string,
unsigned: boolean,
radix: number,
expectedStr?: string
][] = [
['basic no alphabet low radix', '1236', true, 8],
['negative basic no alphabet low radix', '-1236', false, 8],
['valid upper and lower case letters in string with radix > 10', 'eEe', true, 15],
Expand All @@ -187,12 +193,12 @@ describe('Long', function () {
['unsigned zero', '0', true, 10]
];

const failureInputs = [
const failureInputs: [name: string, input: string, unsigned: boolean, radix: number][] = [
['empty string', '', true, 2],
['invalid numbers in binary string', '234', true, 2],
['non a-z or numeric string', '~~', true, 36],
['alphabet in radix < 10', 'a', true, 9],
['radix does not allow all alphabet letters', 'eee', 14],
['radix does not allow all alphabet letters', 'eee', false, 14],
['over max unsigned binary input', Long.MAX_UNSIGNED_VALUE.toString(2) + '1', true, 2],
['over max unsigned decimal input', Long.MAX_UNSIGNED_VALUE.toString(10) + '1', true, 10],
['over max unsigned hex input', Long.MAX_UNSIGNED_VALUE.toString(16) + '1', true, 16],
Expand Down Expand Up @@ -227,7 +233,8 @@ describe('Long', function () {
const successInputs = [
['radix does allows given alphabet letter', 'eEe', 15],
['empty string', '', 2],
['all possible hexadecimal characters', '12efabc689873dADCDEF', 16]
['all possible hexadecimal characters', '12efabc689873dADCDEF', 16],
['leading zeros', '0000000004567e', 16]
];

const failureInputs = [
Expand Down

0 comments on commit 1ead83d

Please sign in to comment.