@@ -33,13 +33,24 @@ export default class Sanitizer {
3333 *
3434 * @param data - any object to sanitize
3535 * @param depth - current depth of recursion
36+ * @param seen - Set of already seen objects to prevent circular references
3637 */
37- public static sanitize ( data : any , depth = 0 ) : any {
38+ public static sanitize ( data : any , depth = 0 , seen = new WeakSet < object > ( ) ) : any {
39+ /**
40+ * Check for circular references on objects and arrays
41+ */
42+ if ( data !== null && typeof data === 'object' ) {
43+ if ( seen . has ( data ) ) {
44+ return '<circular>' ;
45+ }
46+ seen . add ( data ) ;
47+ }
48+
3849 /**
3950 * If value is an Array, apply sanitizing for each element
4051 */
4152 if ( Sanitizer . isArray ( data ) ) {
42- return this . sanitizeArray ( data , depth + 1 ) ;
53+ return this . sanitizeArray ( data , depth + 1 , seen ) ;
4354
4455 /**
4556 * If value is an Element, format it as string with outer HTML
@@ -66,7 +77,7 @@ export default class Sanitizer {
6677 * If values is an object, do recursive call
6778 */
6879 } else if ( Sanitizer . isObject ( data ) ) {
69- return Sanitizer . sanitizeObject ( data , depth + 1 ) ;
80+ return Sanitizer . sanitizeObject ( data , depth + 1 , seen ) ;
7081
7182 /**
7283 * If values is a string, trim it for max-length
@@ -86,8 +97,9 @@ export default class Sanitizer {
8697 *
8798 * @param arr - array to sanitize
8899 * @param depth - current depth of recursion
100+ * @param seen - Set of already seen objects to prevent circular references
89101 */
90- private static sanitizeArray ( arr : any [ ] , depth : number ) : any [ ] {
102+ private static sanitizeArray ( arr : any [ ] , depth : number , seen : WeakSet < object > ) : any [ ] {
91103 /**
92104 * If the maximum length is reached, slice array to max length and add a placeholder
93105 */
@@ -99,7 +111,7 @@ export default class Sanitizer {
99111 }
100112
101113 return arr . map ( ( item : any ) => {
102- return Sanitizer . sanitize ( item , depth ) ;
114+ return Sanitizer . sanitize ( item , depth , seen ) ;
103115 } ) ;
104116 }
105117
@@ -108,8 +120,9 @@ export default class Sanitizer {
108120 *
109121 * @param data - object to beautify
110122 * @param depth - current depth of recursion
123+ * @param seen - Set of already seen objects to prevent circular references
111124 */
112- private static sanitizeObject ( data : { [ key : string ] : any } , depth : number ) : Record < string , any > | '<deep object>' | '<big object>' {
125+ private static sanitizeObject ( data : { [ key : string ] : any } , depth : number , seen : WeakSet < object > ) : Record < string , any > | '<deep object>' | '<big object>' {
113126 /**
114127 * If the maximum depth is reached, return a placeholder
115128 */
@@ -128,7 +141,7 @@ export default class Sanitizer {
128141
129142 for ( const key in data ) {
130143 if ( Object . prototype . hasOwnProperty . call ( data , key ) ) {
131- result [ key ] = Sanitizer . sanitize ( data [ key ] , depth ) ;
144+ result [ key ] = Sanitizer . sanitize ( data [ key ] , depth , seen ) ;
132145 }
133146 }
134147
@@ -268,7 +281,7 @@ export default class Sanitizer {
268281 private static formatClassPrototype ( target : any ) : string {
269282 const className = Sanitizer . getClassNameByPrototype ( target ) ;
270283
271- return `<instance of ${ className } >` ;
284+ return `<class ${ className } >` ;
272285 }
273286
274287 /**
@@ -279,6 +292,6 @@ export default class Sanitizer {
279292 private static formatClassInstance ( target : any ) : string {
280293 const className = Sanitizer . getClassNameByInstance ( target ) ;
281294
282- return `<class ${ className } >` ;
295+ return `<instance of ${ className } >` ;
283296 }
284297}
0 commit comments