in xray/sql_context.go [690:757]
func stripPasswords(dsn string) string {
var (
tok bytes.Buffer
res bytes.Buffer
isPassword bool
inBraces bool
delimiter byte = ' '
)
flush := func() {
if inBraces {
return
}
if !isPassword {
res.Write(tok.Bytes())
}
tok.Reset()
isPassword = false
}
if strings.Count(dsn, ";") > strings.Count(dsn, " ") {
delimiter = ';'
}
buf := strings.NewReader(dsn)
for c, err := buf.ReadByte(); err == nil; c, err = buf.ReadByte() {
tok.WriteByte(c)
switch c {
case ':', delimiter:
flush()
case '=':
tokStr := strings.ToLower(tok.String())
isPassword = `password=` == tokStr || `pwd=` == tokStr
if b, err := buf.ReadByte(); err != nil {
break
} else {
inBraces = b == '{'
}
if err := buf.UnreadByte(); err != nil {
panic(err)
}
case '}':
b, err := buf.ReadByte()
if err != nil {
break
}
if b == '}' {
tok.WriteByte(b)
} else {
inBraces = false
if err := buf.UnreadByte(); err != nil {
panic(err)
}
}
case '@':
if strings.Contains(res.String(), ":") {
resLen := res.Len()
if resLen > 0 && res.Bytes()[resLen-1] == ':' {
res.Truncate(resLen - 1)
}
isPassword = true
flush()
res.WriteByte(c)
}
}
}
inBraces = false
flush()
return res.String()
}