@@ -33,7 +33,7 @@ type ObjOrArray<T> = { [key: string]: T };
33
33
*/
34
34
export function normalize ( input : unknown , depth : number = + Infinity , maxProperties : number = + Infinity ) : any {
35
35
try {
36
- // since we're at the outermost level, there is no key
36
+ // since we're at the outermost level, we don't provide a key
37
37
return visit ( '' , input , depth , maxProperties ) ;
38
38
} catch ( err ) {
39
39
return { ERROR : `**non-serializable** (${ err } )` } ;
@@ -98,17 +98,27 @@ function visit(
98
98
return stringified ;
99
99
}
100
100
101
- // We're also done if we've reached the max depth
102
- if ( depth === 0 ) {
103
- // At this point we know `serialized` is a string of the form `"[object XXXX]"`. Clean it up so it's just `"[XXXX]"`.
104
- return stringified . replace ( 'object ' , '' ) ;
105
- }
101
+ // From here on, we can assert that `value` is either an object or an array!
106
102
107
103
// If we've already visited this branch, bail out, as it's circular reference. If not, note that we're seeing it now.
108
104
if ( memoize ( value ) ) {
109
105
return '[Circular ~]' ;
110
106
}
111
107
108
+ // Do not normalize objects that we know have already been normalized. This MUST be below the circ-ref check otherwise
109
+ // we might somehow accidentally produce circular references by skipping normalization.
110
+ // As a general rule, the "__sentry_skip_normalization__" property should only be used sparingly and only should only
111
+ // be set on objects that have already been normalized.
112
+ if ( ( value as ObjOrArray < unknown > ) [ '__sentry_skip_normalization__' ] ) {
113
+ return value as ObjOrArray < unknown > ;
114
+ }
115
+
116
+ // We're also done if we've reached the max depth
117
+ if ( depth === 0 ) {
118
+ // At this point we know `serialized` is a string of the form `"[object XXXX]"`. Clean it up so it's just `"[XXXX]"`.
119
+ return stringified . replace ( 'object ' , '' ) ;
120
+ }
121
+
112
122
// At this point we know we either have an object or an array, we haven't seen it before, and we're going to recurse
113
123
// because we haven't yet reached the max depth. Create an accumulator to hold the results of visiting each
114
124
// property/entry, and keep track of the number of items we add to it.
0 commit comments