func stripPasswords()

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()
}