mirror of https://github.com/sirupsen/logrus.git
remove QuoteCharacter option
This seems to be one of the most reported issues, as it makes it a lot harder to safely escape strings. This option is very much an edge case, and it's causing too much issues compared to what it provide.
This commit is contained in:
parent
a3f95b5c42
commit
2727ac94b0
|
@ -52,10 +52,6 @@ type TextFormatter struct {
|
||||||
// QuoteEmptyFields will wrap empty fields in quotes if true
|
// QuoteEmptyFields will wrap empty fields in quotes if true
|
||||||
QuoteEmptyFields bool
|
QuoteEmptyFields bool
|
||||||
|
|
||||||
// QuoteCharacter can be set to the override the default quoting character "
|
|
||||||
// with something else. For example: ', or `.
|
|
||||||
QuoteCharacter string
|
|
||||||
|
|
||||||
// Whether the logger's out is to a terminal
|
// Whether the logger's out is to a terminal
|
||||||
isTerminal bool
|
isTerminal bool
|
||||||
|
|
||||||
|
@ -63,9 +59,6 @@ type TextFormatter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) init(entry *Entry) {
|
func (f *TextFormatter) init(entry *Entry) {
|
||||||
if len(f.QuoteCharacter) == 0 {
|
|
||||||
f.QuoteCharacter = "\""
|
|
||||||
}
|
|
||||||
if entry.Logger != nil {
|
if entry.Logger != nil {
|
||||||
f.isTerminal = IsTerminal(entry.Logger.Out)
|
f.isTerminal = IsTerminal(entry.Logger.Out)
|
||||||
}
|
}
|
||||||
|
@ -177,13 +170,6 @@ func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
||||||
if !f.needsQuoting(stringVal) {
|
if !f.needsQuoting(stringVal) {
|
||||||
b.WriteString(stringVal)
|
b.WriteString(stringVal)
|
||||||
} else {
|
} else {
|
||||||
b.WriteString(f.quoteString(stringVal))
|
b.WriteString(fmt.Sprintf("%q", stringVal))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) quoteString(v string) string {
|
|
||||||
escapedQuote := fmt.Sprintf("\\%s", f.QuoteCharacter)
|
|
||||||
escapedValue := strings.Replace(v, f.QuoteCharacter, escapedQuote, -1)
|
|
||||||
|
|
||||||
return fmt.Sprintf("%s%v%s", f.QuoteCharacter, escapedValue, f.QuoteCharacter)
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,10 +3,10 @@ package logrus
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestQuoting(t *testing.T) {
|
func TestQuoting(t *testing.T) {
|
||||||
|
@ -15,7 +15,7 @@ func TestQuoting(t *testing.T) {
|
||||||
checkQuoting := func(q bool, value interface{}) {
|
checkQuoting := func(q bool, value interface{}) {
|
||||||
b, _ := tf.Format(WithField("test", value))
|
b, _ := tf.Format(WithField("test", value))
|
||||||
idx := bytes.Index(b, ([]byte)("test="))
|
idx := bytes.Index(b, ([]byte)("test="))
|
||||||
cont := bytes.Contains(b[idx+5:], []byte(tf.QuoteCharacter))
|
cont := bytes.Contains(b[idx+5:], []byte("\""))
|
||||||
if cont != q {
|
if cont != q {
|
||||||
if q {
|
if q {
|
||||||
t.Errorf("quoting expected for: %#v", value)
|
t.Errorf("quoting expected for: %#v", value)
|
||||||
|
@ -41,23 +41,6 @@ func TestQuoting(t *testing.T) {
|
||||||
checkQuoting(false, errors.New("invalid"))
|
checkQuoting(false, errors.New("invalid"))
|
||||||
checkQuoting(true, errors.New("invalid argument"))
|
checkQuoting(true, errors.New("invalid argument"))
|
||||||
|
|
||||||
// Test for custom quote character.
|
|
||||||
tf.QuoteCharacter = "`"
|
|
||||||
checkQuoting(false, "")
|
|
||||||
checkQuoting(false, "abcd")
|
|
||||||
checkQuoting(false, "/foobar")
|
|
||||||
checkQuoting(false, "foo_bar")
|
|
||||||
checkQuoting(false, "foo@bar")
|
|
||||||
checkQuoting(false, "foobar^")
|
|
||||||
checkQuoting(true, "foobar$")
|
|
||||||
checkQuoting(true, "&foobar")
|
|
||||||
checkQuoting(true, errors.New("invalid argument"))
|
|
||||||
|
|
||||||
// Test for multi-character quotes.
|
|
||||||
tf.QuoteCharacter = "§~±"
|
|
||||||
checkQuoting(false, "abcd")
|
|
||||||
checkQuoting(true, errors.New("invalid argument"))
|
|
||||||
|
|
||||||
// Test for quoting empty fields.
|
// Test for quoting empty fields.
|
||||||
tf.QuoteEmptyFields = true
|
tf.QuoteEmptyFields = true
|
||||||
checkQuoting(true, "")
|
checkQuoting(true, "")
|
||||||
|
@ -65,7 +48,7 @@ func TestQuoting(t *testing.T) {
|
||||||
checkQuoting(true, errors.New("invalid argument"))
|
checkQuoting(true, errors.New("invalid argument"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEscaping_DefaultQuoteCharacter(t *testing.T) {
|
func TestEscaping(t *testing.T) {
|
||||||
tf := &TextFormatter{DisableColors: true}
|
tf := &TextFormatter{DisableColors: true}
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
|
@ -105,35 +88,13 @@ func TestEscaping_Interface(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEscaping_CustomQuoteCharacter(t *testing.T) {
|
|
||||||
tf := &TextFormatter{DisableColors: true}
|
|
||||||
|
|
||||||
testCases := []struct {
|
|
||||||
value string
|
|
||||||
expected string
|
|
||||||
quoteChar string
|
|
||||||
}{
|
|
||||||
{`ba"r`, `ba"r`, `'`},
|
|
||||||
{`ba'r`, `ba\'r`, `'`},
|
|
||||||
{`ba'r`, `ba'r`, `^`},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range testCases {
|
|
||||||
tf.QuoteCharacter = tc.quoteChar
|
|
||||||
b, _ := tf.Format(WithField("test", tc.value))
|
|
||||||
if !bytes.Contains(b, []byte(tc.expected)) {
|
|
||||||
t.Errorf("escaping expected for %q (result was %q instead of %q)", tc.value, string(b), tc.expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTimestampFormat(t *testing.T) {
|
func TestTimestampFormat(t *testing.T) {
|
||||||
checkTimeStr := func(format string) {
|
checkTimeStr := func(format string) {
|
||||||
customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format}
|
customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format}
|
||||||
customStr, _ := customFormatter.Format(WithField("test", "test"))
|
customStr, _ := customFormatter.Format(WithField("test", "test"))
|
||||||
timeStart := bytes.Index(customStr, ([]byte)("time="))
|
timeStart := bytes.Index(customStr, ([]byte)("time="))
|
||||||
timeEnd := bytes.Index(customStr, ([]byte)("level="))
|
timeEnd := bytes.Index(customStr, ([]byte)("level="))
|
||||||
timeStr := customStr[timeStart+5+len(customFormatter.QuoteCharacter) : timeEnd-1-len(customFormatter.QuoteCharacter)]
|
timeStr := customStr[timeStart+5+len("\"") : timeEnd-1-len("\"")]
|
||||||
if format == "" {
|
if format == "" {
|
||||||
format = time.RFC3339
|
format = time.RFC3339
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue