@@ -202,12 +202,19 @@ func (s *scrubberImpl) Struct(val any) error {
202
202
return nil
203
203
}
204
204
205
- func (s * scrubberImpl ) deepCopyStruct (fieldName string , src reflect.Value , scrubTag string ) reflect.Value {
205
+ func (s * scrubberImpl ) deepCopyStruct (fieldName string , src reflect.Value , scrubTag string , skipScrub bool ) reflect.Value {
206
206
if src .Kind () == reflect .Ptr && src .IsNil () {
207
207
return reflect .New (src .Type ()).Elem ()
208
208
}
209
209
210
- if src .Kind () == reflect .String {
210
+ if src .CanInterface () {
211
+ value := src .Interface ()
212
+ if _ , ok := value .(TrustedValue ); ok {
213
+ skipScrub = true
214
+ }
215
+ }
216
+
217
+ if src .Kind () == reflect .String && ! skipScrub {
211
218
dst := reflect .New (src .Type ())
212
219
var (
213
220
setExplicitValue bool
@@ -241,7 +248,6 @@ func (s *scrubberImpl) deepCopyStruct(fieldName string, src reflect.Value, scrub
241
248
}
242
249
243
250
switch src .Kind () {
244
-
245
251
case reflect .Struct :
246
252
dst := reflect .New (src .Type ())
247
253
t := src .Type ()
@@ -275,7 +281,7 @@ func (s *scrubberImpl) deepCopyStruct(fieldName string, src reflect.Value, scrub
275
281
}
276
282
277
283
tagValue := f .Tag .Get ("scrub" )
278
- copied := s .deepCopyStruct (f .Name , srcValue , tagValue )
284
+ copied := s .deepCopyStruct (f .Name , srcValue , tagValue , skipScrub )
279
285
dstValue .Set (copied )
280
286
}
281
287
return dst .Elem ()
@@ -285,31 +291,31 @@ func (s *scrubberImpl) deepCopyStruct(fieldName string, src reflect.Value, scrub
285
291
keys := src .MapKeys ()
286
292
for i := 0 ; i < src .Len (); i ++ {
287
293
mValue := src .MapIndex (keys [i ])
288
- dst .SetMapIndex (keys [i ], s .deepCopyStruct (keys [i ].String (), mValue , "" ))
294
+ dst .SetMapIndex (keys [i ], s .deepCopyStruct (keys [i ].String (), mValue , "" , skipScrub ))
289
295
}
290
296
return dst
291
297
292
298
case reflect .Slice :
293
299
dst := reflect .MakeSlice (src .Type (), src .Len (), src .Cap ())
294
300
for i := 0 ; i < src .Len (); i ++ {
295
- dst .Index (i ).Set (s .deepCopyStruct (fieldName , src .Index (i ), "" ))
301
+ dst .Index (i ).Set (s .deepCopyStruct (fieldName , src .Index (i ), "" , skipScrub ))
296
302
}
297
303
return dst
298
304
299
305
case reflect .Array :
300
306
if src .Len () == 0 {
301
- return src // can not access to src.Index(0)
307
+ return src
302
308
}
303
309
304
310
dst := reflect .New (src .Type ()).Elem ()
305
311
for i := 0 ; i < src .Len (); i ++ {
306
- dst .Index (i ).Set (s .deepCopyStruct (fieldName , src .Index (i ), "" ))
312
+ dst .Index (i ).Set (s .deepCopyStruct (fieldName , src .Index (i ), "" , skipScrub ))
307
313
}
308
314
return dst
309
315
310
316
case reflect .Ptr :
311
317
dst := reflect .New (src .Elem ().Type ())
312
- copied := s .deepCopyStruct (fieldName , src .Elem (), scrubTag )
318
+ copied := s .deepCopyStruct (fieldName , src .Elem (), scrubTag , skipScrub )
313
319
dst .Elem ().Set (copied )
314
320
return dst
315
321
@@ -322,7 +328,7 @@ func (s *scrubberImpl) deepCopyStruct(fieldName string, src reflect.Value, scrub
322
328
323
329
// Struct implements Scrubber
324
330
func (s * scrubberImpl ) DeepCopyStruct (val any ) any {
325
- return s .deepCopyStruct ("" , reflect .ValueOf (val ), "" ).Interface ()
331
+ return s .deepCopyStruct ("" , reflect .ValueOf (val ), "" , false ).Interface ()
326
332
}
327
333
328
334
func (s * scrubberImpl ) scrubJsonObject (val map [string ]interface {}) error {
0 commit comments