@@ -316,8 +316,37 @@ func sanitizeArguments(args []interface{}) []interface{} {
316316 case plan.AuthenticationMysqlNativePassword :
317317 args [i ] = "[PASSWORD_REDACTED]"
318318 default :
319- if reflect .TypeOf (arg ).Kind () == reflect .Struct {
320- args [i ] = "[STRUCT_REDACTED]"
319+ // Use reflection to handle structs and pointers to structs
320+ rv := reflect .ValueOf (arg )
321+ rt := reflect .TypeOf (arg )
322+ if rv .Kind () == reflect .Ptr {
323+ rv = rv .Elem ()
324+ if rv .Kind () == reflect .Struct {
325+ args [i ] = sanitizeStruct (rv )
326+ continue
327+ }
328+ }
329+ if rv .Kind () == reflect .Struct {
330+ args [i ] = sanitizeStruct (rv )
331+ } else if rv .Kind () == reflect .Slice {
332+ // Recursively sanitize slice elements
333+ slice := make ([]interface {}, rv .Len ())
334+ for j := 0 ; j < rv .Len (); j ++ {
335+ slice [j ] = sanitizeArguments ([]interface {}{rv .Index (j ).Interface ()})[0 ]
336+ }
337+ args [i ] = slice
338+ } else if rv .Kind () == reflect .Map {
339+ // Recursively sanitize map values
340+ mapSanitized := make (map [interface {}]interface {})
341+ for _ , key := range rv .MapKeys () {
342+ val := rv .MapIndex (key ).Interface ()
343+ if isSensitiveString (fmt .Sprintf ("%v" , key .Interface ())) || isSensitive (val ) {
344+ mapSanitized [key .Interface ()] = "[REDACTED]"
345+ } else {
346+ mapSanitized [key .Interface ()] = sanitizeArguments ([]interface {}{val })[0 ]
347+ }
348+ }
349+ args [i ] = mapSanitized
321350 } else {
322351 args [i ] = "[REDACTED]"
323352 }
@@ -326,14 +355,78 @@ func sanitizeArguments(args []interface{}) []interface{} {
326355 return args
327356}
328357
358+ func sanitizeStruct (rv reflect.Value ) interface {} {
359+ if ! rv .IsValid () || rv .Kind () != reflect .Struct {
360+ return "[STRUCT_REDACTED]"
361+ }
362+ rt := rv .Type ()
363+ result := make (map [string ]interface {})
364+ for i := 0 ; i < rv .NumField (); i ++ {
365+ field := rt .Field (i )
366+ fieldName := field .Name
367+ fieldValue := rv .Field (i ).Interface ()
368+ if isSensitiveString (fieldName ) || isSensitive (fieldValue ) {
369+ result [fieldName ] = "[REDACTED]"
370+ } else {
371+ // Recursively sanitize nested structs, slices, and maps
372+ switch rv .Field (i ).Kind () {
373+ case reflect .Struct :
374+ result [fieldName ] = sanitizeStruct (rv .Field (i ))
375+ case reflect .Slice :
376+ slice := make ([]interface {}, rv .Field (i ).Len ())
377+ for j := 0 ; j < rv .Field (i ).Len (); j ++ {
378+ slice [j ] = sanitizeArguments ([]interface {}{rv .Field (i ).Index (j ).Interface ()})[0 ]
379+ }
380+ result [fieldName ] = slice
381+ case reflect .Map :
382+ mapSanitized := make (map [interface {}]interface {})
383+ for _ , key := range rv .Field (i ).MapKeys () {
384+ val := rv .Field (i ).MapIndex (key ).Interface ()
385+ if isSensitiveString (fmt .Sprintf ("%v" , key .Interface ())) || isSensitive (val ) {
386+ mapSanitized [key .Interface ()] = "[REDACTED]"
387+ } else {
388+ mapSanitized [key .Interface ()] = sanitizeArguments ([]interface {}{val })[0 ]
389+ }
390+ }
391+ result [fieldName ] = mapSanitized
392+ default :
393+ result [fieldName ] = fieldValue
394+ }
395+ }
396+ }
397+ return result
398+ }
399+
329400func sanitizeMap (m map [string ]interface {}) map [string ]interface {} {
330401 for key , value := range m {
331402 if isSensitiveString (key ) || isSensitive (value ) {
332403 m [key ] = "[REDACTED]"
333- } else if subMap , ok := value .(map [string ]interface {}); ok {
334- m [key ] = sanitizeMap (subMap )
335- } else if subSlice , ok := value .([]interface {}); ok {
336- m [key ] = sanitizeArguments (subSlice )
404+ } else {
405+ rv := reflect .ValueOf (value )
406+ switch rv .Kind () {
407+ case reflect .Map :
408+ // Recursively sanitize map values
409+ subMap := make (map [interface {}]interface {})
410+ for _ , subKey := range rv .MapKeys () {
411+ val := rv .MapIndex (subKey ).Interface ()
412+ if isSensitiveString (fmt .Sprintf ("%v" , subKey .Interface ())) || isSensitive (val ) {
413+ subMap [subKey .Interface ()] = "[REDACTED]"
414+ } else {
415+ subMap [subKey .Interface ()] = sanitizeArguments ([]interface {}{val })[0 ]
416+ }
417+ }
418+ m [key ] = subMap
419+ case reflect .Slice :
420+ slice := make ([]interface {}, rv .Len ())
421+ for j := 0 ; j < rv .Len (); j ++ {
422+ slice [j ] = sanitizeArguments ([]interface {}{rv .Index (j ).Interface ()})[0 ]
423+ }
424+ m [key ] = slice
425+ case reflect .Struct :
426+ m [key ] = sanitizeStruct (rv )
427+ default :
428+ m [key ] = value
429+ }
337430 }
338431 }
339432 return m
0 commit comments