@@ -316,8 +316,36 @@ 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+ if rv .Kind () == reflect .Ptr {
322+ rv = rv .Elem ()
323+ if rv .Kind () == reflect .Struct {
324+ args [i ] = sanitizeStruct (rv )
325+ continue
326+ }
327+ }
328+ if rv .Kind () == reflect .Struct {
329+ args [i ] = sanitizeStruct (rv )
330+ } else if rv .Kind () == reflect .Slice {
331+ // Recursively sanitize slice elements
332+ slice := make ([]interface {}, rv .Len ())
333+ for j := 0 ; j < rv .Len (); j ++ {
334+ slice [j ] = sanitizeArguments ([]interface {}{rv .Index (j ).Interface ()})[0 ]
335+ }
336+ args [i ] = slice
337+ } else if rv .Kind () == reflect .Map {
338+ // Recursively sanitize map values
339+ mapSanitized := make (map [interface {}]interface {})
340+ for _ , key := range rv .MapKeys () {
341+ val := rv .MapIndex (key ).Interface ()
342+ if isSensitiveString (fmt .Sprintf ("%v" , key .Interface ())) || isSensitive (val ) {
343+ mapSanitized [key .Interface ()] = "[REDACTED]"
344+ } else {
345+ mapSanitized [key .Interface ()] = sanitizeArguments ([]interface {}{val })[0 ]
346+ }
347+ }
348+ args [i ] = mapSanitized
321349 } else {
322350 args [i ] = "[REDACTED]"
323351 }
@@ -326,14 +354,78 @@ func sanitizeArguments(args []interface{}) []interface{} {
326354 return args
327355}
328356
357+ func sanitizeStruct (rv reflect.Value ) interface {} {
358+ if ! rv .IsValid () || rv .Kind () != reflect .Struct {
359+ return "[STRUCT_REDACTED]"
360+ }
361+ rt := rv .Type ()
362+ result := make (map [string ]interface {})
363+ for i := 0 ; i < rv .NumField (); i ++ {
364+ field := rt .Field (i )
365+ fieldName := field .Name
366+ fieldValue := rv .Field (i ).Interface ()
367+ if isSensitiveString (fieldName ) || isSensitive (fieldValue ) {
368+ result [fieldName ] = "[REDACTED]"
369+ } else {
370+ // Recursively sanitize nested structs, slices, and maps
371+ switch rv .Field (i ).Kind () {
372+ case reflect .Struct :
373+ result [fieldName ] = sanitizeStruct (rv .Field (i ))
374+ case reflect .Slice :
375+ slice := make ([]interface {}, rv .Field (i ).Len ())
376+ for j := 0 ; j < rv .Field (i ).Len (); j ++ {
377+ slice [j ] = sanitizeArguments ([]interface {}{rv .Field (i ).Index (j ).Interface ()})[0 ]
378+ }
379+ result [fieldName ] = slice
380+ case reflect .Map :
381+ mapSanitized := make (map [interface {}]interface {})
382+ for _ , key := range rv .Field (i ).MapKeys () {
383+ val := rv .Field (i ).MapIndex (key ).Interface ()
384+ if isSensitiveString (fmt .Sprintf ("%v" , key .Interface ())) || isSensitive (val ) {
385+ mapSanitized [key .Interface ()] = "[REDACTED]"
386+ } else {
387+ mapSanitized [key .Interface ()] = sanitizeArguments ([]interface {}{val })[0 ]
388+ }
389+ }
390+ result [fieldName ] = mapSanitized
391+ default :
392+ result [fieldName ] = fieldValue
393+ }
394+ }
395+ }
396+ return result
397+ }
398+
329399func sanitizeMap (m map [string ]interface {}) map [string ]interface {} {
330400 for key , value := range m {
331401 if isSensitiveString (key ) || isSensitive (value ) {
332402 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 )
403+ } else {
404+ rv := reflect .ValueOf (value )
405+ switch rv .Kind () {
406+ case reflect .Map :
407+ // Recursively sanitize map values
408+ subMap := make (map [interface {}]interface {})
409+ for _ , subKey := range rv .MapKeys () {
410+ val := rv .MapIndex (subKey ).Interface ()
411+ if isSensitiveString (fmt .Sprintf ("%v" , subKey .Interface ())) || isSensitive (val ) {
412+ subMap [subKey .Interface ()] = "[REDACTED]"
413+ } else {
414+ subMap [subKey .Interface ()] = sanitizeArguments ([]interface {}{val })[0 ]
415+ }
416+ }
417+ m [key ] = subMap
418+ case reflect .Slice :
419+ slice := make ([]interface {}, rv .Len ())
420+ for j := 0 ; j < rv .Len (); j ++ {
421+ slice [j ] = sanitizeArguments ([]interface {}{rv .Index (j ).Interface ()})[0 ]
422+ }
423+ m [key ] = slice
424+ case reflect .Struct :
425+ m [key ] = sanitizeStruct (rv )
426+ default :
427+ m [key ] = value
428+ }
337429 }
338430 }
339431 return m
0 commit comments