Skip to content

Commit

Permalink
format: stricter quoting based on strconv
Browse files Browse the repository at this point in the history
  • Loading branch information
holiman committed Apr 28, 2020
1 parent b30bc20 commit d3f442c
Showing 1 changed file with 10 additions and 42 deletions.
52 changes: 10 additions & 42 deletions format.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"reflect"
"strconv"
"strings"
"sync"
"time"
)

Expand Down Expand Up @@ -208,10 +207,9 @@ func formatJSONValue(value interface{}) interface{} {

// formatValue formats a value for serialization
func formatLogfmtValue(value interface{}) string {
if value == nil {
if value == nil || (reflect.ValueOf(value).Kind() == reflect.Ptr && reflect.ValueOf(value).IsNil()) {
return "nil"
}

if t, ok := value.(time.Time); ok {
// Performance optimization: No need for escaping since the provided
// timeFormat doesn't have any escape characters, and escaping is
Expand All @@ -235,49 +233,19 @@ func formatLogfmtValue(value interface{}) string {
}
}

var stringBufPool = sync.Pool{
New: func() interface{} { return new(bytes.Buffer) },
}

// escapeString checks if the provided string needs escaping/quoting, and
// calls strconv.Quote if needed
func escapeString(s string) string {
needsQuotes := false
needsEscape := false
needsQuoting := false
for _, r := range s {
if r <= ' ' || r == '=' || r == '"' {
needsQuotes = true
}
if r == '\\' || r == '"' || r == '\n' || r == '\r' || r == '\t' {
needsEscape = true
// quote everything below " (0x34) and above~ (0x7E), plus equal-sign
if r <= '"' || r > '~' || r == '=' {
needsQuoting = true
break
}
}
if needsEscape == false && needsQuotes == false {
if !needsQuoting {
return s
}
e := stringBufPool.Get().(*bytes.Buffer)
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
return strconv.Quote(s)
}

0 comments on commit d3f442c

Please sign in to comment.