@@ -294,63 +294,74 @@ func (a *Analyzer) Log(msg string, args ...interface{}) {
294294 if a != nil && a .Debug {
295295 if len (a .contextStack ) > 0 {
296296 ctx := strings .Join (a .contextStack , "/" )
297- log .Infof ("%s: " + msg , append ([]interface {}{ctx }, sanitizeArguments (args )... )... )
297+ sanitizedArgs := sanitizeArguments (args )
298+ log .Infof ("%s: " + msg , append ([]interface {}{ctx }, sanitizedArgs ... )... )
298299 } else {
299- log .Infof (msg , sanitizeArguments (args )... )
300+ sanitizedArgs := sanitizeArguments (args )
301+ log .Infof (msg , sanitizedArgs ... )
300302 }
301303 }
302304}
303305
304306func sanitizeArguments (args []interface {}) []interface {} {
307+ sanitizedArgs := make ([]interface {}, len (args ))
305308 for i , arg := range args {
306309 switch v := arg .(type ) {
307310 case string :
308311 if isSensitiveString (v ) {
309- args [i ] = "[REDACTED]"
312+ sanitizedArgs [i ] = "[REDACTED]"
313+ } else {
314+ sanitizedArgs [i ] = v
310315 }
311316 case map [string ]interface {}:
312- args [i ] = sanitizeMap (v )
317+ sanitizedArgs [i ] = sanitizeMap (v )
313318 case []interface {}:
314- args [i ] = sanitizeArguments (v )
319+ sanitizedArgs [i ] = sanitizeArguments (v )
315320 case plan.AuthenticationMysqlNativePassword :
316- args [i ] = "[PASSWORD_REDACTED]"
321+ sanitizedArgs [i ] = "[PASSWORD_REDACTED]"
317322 default :
318323 // Use reflection to handle structs and pointers to structs
319324 rv := reflect .ValueOf (arg )
320325 if rv .Kind () == reflect .Ptr {
321326 rv = rv .Elem ()
322327 if rv .Kind () == reflect .Struct {
323- args [i ] = sanitizeStruct (rv )
328+ sanitizedArgs [i ] = sanitizeStruct (rv )
324329 continue
325330 }
326331 }
327332 if rv .Kind () == reflect .Struct {
328- args [i ] = sanitizeStruct (rv )
333+ sanitizedArgs [i ] = sanitizeStruct (rv )
329334 } else if rv .Kind () == reflect .Slice {
330335 // Recursively sanitize slice elements
331336 slice := make ([]interface {}, rv .Len ())
332337 for j := 0 ; j < rv .Len (); j ++ {
333338 slice [j ] = sanitizeArguments ([]interface {}{rv .Index (j ).Interface ()})[0 ]
334339 }
335- args [i ] = slice
340+ sanitizedArgs [i ] = slice
336341 } else if rv .Kind () == reflect .Map {
337342 // Recursively sanitize map values
338343 mapSanitized := make (map [interface {}]interface {})
339344 for _ , key := range rv .MapKeys () {
340345 val := rv .MapIndex (key ).Interface ()
341- if isSensitiveString (fmt .Sprintf ("%v" , key .Interface ())) || isSensitive (val ) {
346+ keyStr := fmt .Sprintf ("%v" , key .Interface ())
347+ if isSensitiveString (keyStr ) || isSensitive (val ) {
342348 mapSanitized [key .Interface ()] = "[REDACTED]"
343349 } else {
344350 mapSanitized [key .Interface ()] = sanitizeArguments ([]interface {}{val })[0 ]
345351 }
346352 }
347- args [i ] = mapSanitized
353+ sanitizedArgs [i ] = mapSanitized
348354 } else {
349- args [i ] = "[REDACTED]"
355+ // Catch-all for unhandled types
356+ if strVal := fmt .Sprintf ("%v" , arg ); isSensitiveString (strVal ) {
357+ sanitizedArgs [i ] = "[REDACTED]"
358+ } else {
359+ sanitizedArgs [i ] = arg
360+ }
350361 }
351362 }
352363 }
353- return args
364+ return sanitizedArgs
354365}
355366
356367func sanitizeStruct (rv reflect.Value ) interface {} {
@@ -380,7 +391,8 @@ func sanitizeStruct(rv reflect.Value) interface{} {
380391 mapSanitized := make (map [interface {}]interface {})
381392 for _ , key := range rv .Field (i ).MapKeys () {
382393 val := rv .Field (i ).MapIndex (key ).Interface ()
383- if isSensitiveString (fmt .Sprintf ("%v" , key .Interface ())) || isSensitive (val ) {
394+ keyStr := fmt .Sprintf ("%v" , key .Interface ())
395+ if isSensitiveString (keyStr ) || isSensitive (val ) {
384396 mapSanitized [key .Interface ()] = "[REDACTED]"
385397 } else {
386398 mapSanitized [key .Interface ()] = sanitizeArguments ([]interface {}{val })[0 ]
@@ -396,9 +408,10 @@ func sanitizeStruct(rv reflect.Value) interface{} {
396408}
397409
398410func sanitizeMap (m map [string ]interface {}) map [string ]interface {} {
411+ result := make (map [string ]interface {})
399412 for key , value := range m {
400413 if isSensitiveString (key ) || isSensitive (value ) {
401- m [key ] = "[REDACTED]"
414+ result [key ] = "[REDACTED]"
402415 } else {
403416 rv := reflect .ValueOf (value )
404417 switch rv .Kind () {
@@ -407,31 +420,33 @@ func sanitizeMap(m map[string]interface{}) map[string]interface{} {
407420 subMap := make (map [interface {}]interface {})
408421 for _ , subKey := range rv .MapKeys () {
409422 val := rv .MapIndex (subKey ).Interface ()
410- if isSensitiveString (fmt .Sprintf ("%v" , subKey .Interface ())) || isSensitive (val ) {
423+ keyStr := fmt .Sprintf ("%v" , subKey .Interface ())
424+ if isSensitiveString (keyStr ) || isSensitive (val ) {
411425 subMap [subKey .Interface ()] = "[REDACTED]"
412426 } else {
413427 subMap [subKey .Interface ()] = sanitizeArguments ([]interface {}{val })[0 ]
414428 }
415429 }
416- m [key ] = subMap
430+ result [key ] = subMap
417431 case reflect .Slice :
418432 slice := make ([]interface {}, rv .Len ())
419433 for j := 0 ; j < rv .Len (); j ++ {
420434 slice [j ] = sanitizeArguments ([]interface {}{rv .Index (j ).Interface ()})[0 ]
421435 }
422- m [key ] = slice
436+ result [key ] = slice
423437 case reflect .Struct :
424- m [key ] = sanitizeStruct (rv )
438+ result [key ] = sanitizeStruct (rv )
425439 default :
426- m [key ] = value
440+ result [key ] = value
427441 }
428442 }
429443 }
430- return m
444+ return result
431445}
432446
447+ // isSensitiveString checks if a string contains sensitive information
433448func isSensitiveString (str string ) bool {
434- sensitiveKeywords := []string {"password" , "secret" , "token" , "key" }
449+ sensitiveKeywords := []string {"password" , "secret" , "token" , "key" , "auth" , "credential" , "private" }
435450 str = strings .ToLower (str )
436451 for _ , keyword := range sensitiveKeywords {
437452 if strings .Contains (str , keyword ) {
@@ -441,13 +456,19 @@ func isSensitiveString(str string) bool {
441456 return false
442457}
443458
459+ // isSensitive checks if a value contains sensitive information
444460func isSensitive (arg interface {}) bool {
445- // Add logic to identify sensitive data (e.g., passwords)
446- // This may involve checking types or specific fields
447- if str , ok := arg .(string ); ok && strings .Contains (strings .ToLower (str ), "password" ) {
448- return true
461+ if arg == nil {
462+ return false
449463 }
450- return false
464+
465+ // Check strings directly
466+ if str , ok := arg .(string ); ok {
467+ return isSensitiveString (str )
468+ }
469+
470+ // Check string representation
471+ return isSensitiveString (fmt .Sprintf ("%v" , arg ))
451472}
452473
453474// LogNode prints the node given if Verbose logging is enabled.
0 commit comments