From bc20e7a90774f9d6e689ba586796320fd6a0e7bc Mon Sep 17 00:00:00 2001 From: Sean Reece Date: Wed, 21 Aug 2024 21:59:48 -0400 Subject: [PATCH 1/2] Improve isValid for strings --- src/objectid.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/objectid.ts b/src/objectid.ts index 98daecc8..13954071 100644 --- a/src/objectid.ts +++ b/src/objectid.ts @@ -112,7 +112,7 @@ export class ObjectId extends BSONValue { // If intstanceof matches we can escape calling ensure buffer in Node.js environments this.buffer = ByteUtils.toLocalBufferType(workingId); } else if (typeof workingId === 'string') { - if (workingId.length === 24 && checkForHexRegExp.test(workingId)) { + if (ObjectId.validateHexString(workingId)) { this.buffer = ByteUtils.fromHex(workingId); } else { throw new BSONError( @@ -143,6 +143,15 @@ export class ObjectId extends BSONValue { } } + /** + * @internal + * Validates the input string is a valid hex representation of an ObjectId. + */ + private static validateHexString(input: string): boolean { + if (input == null || input.length !== 24) return false; + return checkForHexRegExp.test(input); + } + /** Returns the ObjectId id as a 24 lowercase character hex string representation */ toHexString(): string { if (ObjectId.cacheHexString && this.__id) { @@ -329,6 +338,7 @@ export class ObjectId extends BSONValue { */ static isValid(id: string | number | ObjectId | ObjectIdLike | Uint8Array): boolean { if (id == null) return false; + if (typeof id === 'string') return ObjectId.validateHexString(id); try { new ObjectId(id); From bddabbf1515305a3d69303da650b00b0c8fb8d37 Mon Sep 17 00:00:00 2001 From: Sean Reece Date: Tue, 17 Sep 2024 10:27:27 -0400 Subject: [PATCH 2/2] Remove regex in favor of ascii code --- src/objectid.ts | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/objectid.ts b/src/objectid.ts index 13954071..e548aa81 100644 --- a/src/objectid.ts +++ b/src/objectid.ts @@ -4,9 +4,6 @@ import { type InspectFn, defaultInspect } from './parser/utils'; import { ByteUtils } from './utils/byte_utils'; import { NumberUtils } from './utils/number_utils'; -// Regular expression that checks for hex value -const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$'); - // Unique sequence for the current process (initialized on first use) let PROCESS_UNIQUE: Uint8Array | null = null; @@ -147,9 +144,23 @@ export class ObjectId extends BSONValue { * @internal * Validates the input string is a valid hex representation of an ObjectId. */ - private static validateHexString(input: string): boolean { - if (input == null || input.length !== 24) return false; - return checkForHexRegExp.test(input); + private static validateHexString(string: string): boolean { + if (string?.length !== 24) return false; + for (let i = 0; i < 24; i++) { + const char = string.charCodeAt(i); + if ( + // Check for ASCII 0-9 + (char >= 48 && char <= 57) || + // Check for ASCII a-f + (char >= 97 && char <= 102) || + // Check for ASCII A-F + (char >= 65 && char <= 70) + ) { + continue; + } + return false; + } + return true; } /** Returns the ObjectId id as a 24 lowercase character hex string representation */