lib/logger: Strip control characters from log output (fixes #5428) (#5434)

This commit is contained in:
Jakob Borg 2019-01-05 11:31:02 +01:00 committed by GitHub
parent ad30192dca
commit 5503175854
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 1 deletions

View File

@ -70,7 +70,7 @@ type logger struct {
var DefaultLogger = New()
func New() Logger {
return newLogger(os.Stdout)
return newLogger(controlStripper{os.Stdout})
}
func newLogger(w io.Writer) Logger {
@ -376,3 +376,23 @@ func (r *recorder) append(l LogLevel, msg string) {
r.lines = append(r.lines, Line{time.Now(), "...", l})
}
}
// controlStripper is a Writer that replaces control characters
// with spaces.
type controlStripper struct {
io.Writer
}
func (s controlStripper) Write(data []byte) (int, error) {
for i, b := range data {
if b == '\n' || b == '\r' {
// Newlines are OK
continue
}
if b < 32 {
// Characters below 32 are control characters
data[i] = ' '
}
}
return s.Writer.Write(data)
}

View File

@ -6,6 +6,7 @@ package logger
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"strings"
"testing"
@ -166,3 +167,43 @@ func TestStackLevel(t *testing.T) {
t.Error("Should identify this file as the source (bad level?)")
}
}
func TestControlStripper(t *testing.T) {
b := new(bytes.Buffer)
l := newLogger(controlStripper{b})
l.Infoln("testing\x07testing\ntesting")
res := b.String()
if !strings.Contains(res, "testing testing\ntesting") {
t.Logf("%q", res)
t.Error("Control character should become space")
}
if strings.Contains(res, "\x07") {
t.Logf("%q", res)
t.Error("Control character should be removed")
}
}
func BenchmarkLog(b *testing.B) {
l := newLogger(controlStripper{ioutil.Discard})
benchmarkLogger(b, l)
}
func BenchmarkLogNoStripper(b *testing.B) {
l := newLogger(ioutil.Discard)
benchmarkLogger(b, l)
}
func benchmarkLogger(b *testing.B, l Logger) {
l.SetFlags(log.Lshortfile | log.Lmicroseconds)
l.SetPrefix("ABCDEFG")
for i := 0; i < b.N; i++ {
l.Infoln("This is a somewhat representative log line")
l.Infof("This is a log line with a couple of formatted things: %d %q", 42, "a file name maybe, who knows?")
}
b.ReportAllocs()
b.SetBytes(2) // log entries per iteration
}