diff --git a/src/json.test.ts b/src/json.test.ts index 40906e90..fd679b3d 100644 --- a/src/json.test.ts +++ b/src/json.test.ts @@ -778,7 +778,8 @@ describe('json', () => { ]); }); - it('should return true for validity for an object that contains same object multiple times', () => { + it('should return true for validity for an object that contains the same object multiple times', () => { + // This will test if false positives are removed from the circular reference detection const date = new Date(); const testObject = { value: 'whatever', @@ -806,6 +807,14 @@ describe('json', () => { something: null, somethingElse: null, anotherValue: null, + somethingAgain: testObject, + anotherOne: { + nested: { + multipleTimes: { + valueOne: testObject, + }, + }, + }, }, }; diff --git a/src/json.ts b/src/json.ts index a865f62f..6f1f21cf 100644 --- a/src/json.ts +++ b/src/json.ts @@ -355,10 +355,13 @@ export function validateJsonAndGetSize( return [false, 0]; } - // Handle circular objects + // Circular object detection (handling) + // Check if the same object already exists if (seenObjects.has(value)) { return [false, 0]; } + // Add new object to the seen objects set + // Only the plain objects should be added (Primitive types are skipped) seenObjects.add(value); // Continue object decomposition @@ -378,7 +381,12 @@ export function validateJsonAndGetSize( 'JSON validation did not pass. Validation process stopped.', ); } + + // Circular object detection + // Once a child node is visited and processed remove it from the set. + // This will prevent false positives with the same adjacent objects. seenObjects.delete(value); + if (skipSizing) { return 0; }