mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 18:30:45 +00:00
log: properly escape character sequences (#20987)
This commit is contained in:
parent
25a7e096ff
commit
cd9e18984e
1 changed files with 11 additions and 43 deletions
|
|
@ -78,12 +78,11 @@ type TerminalStringer interface {
|
||||||
// a terminal with color-coded level output and terser human friendly timestamp.
|
// a terminal with color-coded level output and terser human friendly timestamp.
|
||||||
// This format should only be used for interactive programs or while developing.
|
// This format should only be used for interactive programs or while developing.
|
||||||
//
|
//
|
||||||
// [LEVEL] [TIME] MESAGE key=value key=value ...
|
// [LEVEL] [TIME] MESAGE key=value key=value ...
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// [DBUG] [May 16 20:58:45] remove route ns=haproxy addr=127.0.0.1:50002
|
// [DBUG] [May 16 20:58:45] remove route ns=haproxy addr=127.0.0.1:50002
|
||||||
//
|
|
||||||
func TerminalFormat(usecolor bool) Format {
|
func TerminalFormat(usecolor bool) Format {
|
||||||
return FormatFunc(func(r *Record) []byte {
|
return FormatFunc(func(r *Record) []byte {
|
||||||
var color = 0
|
var color = 0
|
||||||
|
|
@ -148,7 +147,6 @@ func TerminalFormat(usecolor bool) Format {
|
||||||
// format for key/value pairs.
|
// format for key/value pairs.
|
||||||
//
|
//
|
||||||
// For more details see: http://godoc.org/github.com/kr/logfmt
|
// For more details see: http://godoc.org/github.com/kr/logfmt
|
||||||
//
|
|
||||||
func LogfmtFormat() Format {
|
func LogfmtFormat() Format {
|
||||||
return FormatFunc(func(r *Record) []byte {
|
return FormatFunc(func(r *Record) []byte {
|
||||||
common := []interface{}{r.KeyNames.Time, r.Time, r.KeyNames.Lvl, r.Lvl, r.KeyNames.Msg, r.Msg}
|
common := []interface{}{r.KeyNames.Time, r.Time, r.KeyNames.Lvl, r.Lvl, r.KeyNames.Msg, r.Msg}
|
||||||
|
|
@ -358,49 +356,19 @@ func formatLogfmtValue(value interface{}, term bool) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var stringBufPool = sync.Pool{
|
// escapeString checks if the provided string needs escaping/quoting, and
|
||||||
New: func() interface{} { return new(bytes.Buffer) },
|
// calls strconv.Quote if needed
|
||||||
}
|
|
||||||
|
|
||||||
func escapeString(s string) string {
|
func escapeString(s string) string {
|
||||||
needsQuotes := false
|
needsQuoting := false
|
||||||
needsEscape := false
|
|
||||||
for _, r := range s {
|
for _, r := range s {
|
||||||
if r <= ' ' || r == '=' || r == '"' {
|
// We quote everything below " (0x34) and above~ (0x7E), plus equal-sign
|
||||||
needsQuotes = true
|
if r <= '"' || r > '~' || r == '=' {
|
||||||
}
|
needsQuoting = true
|
||||||
if r == '\\' || r == '"' || r == '\n' || r == '\r' || r == '\t' {
|
break
|
||||||
needsEscape = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !needsEscape && !needsQuotes {
|
if !needsQuoting {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
e := stringBufPool.Get().(*bytes.Buffer)
|
return strconv.Quote(s)
|
||||||
e.WriteByte('"')
|
|
||||||
for _, r := range s {
|
|
||||||
switch r {
|
|
||||||
case '\\', '"':
|
|
||||||
e.WriteByte('\\')
|
|
||||||
e.WriteByte(byte(r))
|
|
||||||
case '\n':
|
|
||||||
e.WriteString("\\n")
|
|
||||||
case '\r':
|
|
||||||
e.WriteString("\\r")
|
|
||||||
case '\t':
|
|
||||||
e.WriteString("\\t")
|
|
||||||
default:
|
|
||||||
e.WriteRune(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e.WriteByte('"')
|
|
||||||
var ret string
|
|
||||||
if needsQuotes {
|
|
||||||
ret = e.String()
|
|
||||||
} else {
|
|
||||||
ret = string(e.Bytes()[1 : e.Len()-1])
|
|
||||||
}
|
|
||||||
e.Reset()
|
|
||||||
stringBufPool.Put(e)
|
|
||||||
return ret
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue