@@ -44,17 +44,20 @@ function resolveExternal (parser, options) {
4444 * @param {string } path - The full path of `obj`, possibly with a JSON Pointer in the hash
4545 * @param {$Refs } $refs
4646 * @param {$RefParserOptions } options
47+ * @param {Set } seen - Internal.
4748 *
4849 * @returns {Promise[] }
4950 * Returns an array of promises. There will be one promise for each JSON reference in `obj`.
5051 * If `obj` does not contain any JSON references, then the array will be empty.
5152 * If any of the JSON references point to files that contain additional JSON references,
5253 * then the corresponding promise will internally reference an array of promises.
5354 */
54- function crawl ( obj , path , $refs , options ) {
55+ function crawl ( obj , path , $refs , options , seen ) {
56+ seen = seen || new Set ( ) ;
5557 let promises = [ ] ;
5658
57- if ( obj && typeof obj === "object" && ! ArrayBuffer . isView ( obj ) ) {
59+ if ( obj && typeof obj === "object" && ! ArrayBuffer . isView ( obj ) && ! seen . has ( obj ) ) {
60+ seen . add ( obj ) ; // Track previously seen objects to avoid infinite recursion
5861 if ( $Ref . isExternal$Ref ( obj ) ) {
5962 promises . push ( resolve$Ref ( obj , path , $refs , options ) ) ;
6063 }
@@ -67,7 +70,7 @@ function crawl (obj, path, $refs, options) {
6770 promises . push ( resolve$Ref ( value , keyPath , $refs , options ) ) ;
6871 }
6972 else {
70- promises = promises . concat ( crawl ( value , keyPath , $refs , options ) ) ;
73+ promises = promises . concat ( crawl ( value , keyPath , $refs , options , seen ) ) ;
7174 }
7275 }
7376 }
0 commit comments