logtail: cap the buffer size in encodeText

This started as an attempt to placate GitHub's code scanner,
but it's also probably generally a good idea.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
pull/3735/head
Josh Bleecher Snyder 3 years ago committed by Josh Bleecher Snyder
parent 5404a0557b
commit 9fe5ece833

@ -431,6 +431,21 @@ func (l *Logger) encodeText(buf []byte, skipClientTime bool) []byte {
// For now just factor in a dozen. // For now just factor in a dozen.
overhead += 12 overhead += 12
// Put a sanity cap on buf's size.
max := 16 << 10
if l.lowMem {
max = 255
}
var nTruncated int
if len(buf) > max {
nTruncated = len(buf) - max
// TODO: this can break a UTF-8 character
// mid-encoding. We don't tend to log
// non-ASCII stuff ourselves, but e.g. client
// names might be.
buf = buf[:max]
}
b := make([]byte, 0, len(buf)+overhead) b := make([]byte, 0, len(buf)+overhead)
b = append(b, '{') b = append(b, '{')
@ -449,7 +464,7 @@ func (l *Logger) encodeText(buf []byte, skipClientTime bool) []byte {
} }
b = append(b, "\"text\": \""...) b = append(b, "\"text\": \""...)
for i, c := range buf { for _, c := range buf {
switch c { switch c {
case '\b': case '\b':
b = append(b, '\\', 'b') b = append(b, '\\', 'b')
@ -469,14 +484,10 @@ func (l *Logger) encodeText(buf []byte, skipClientTime bool) []byte {
// TODO: what about binary gibberish or non UTF-8? // TODO: what about binary gibberish or non UTF-8?
b = append(b, c) b = append(b, c)
} }
if l.lowMem && i > 254 {
// TODO: this can break a UTF-8 character
// mid-encoding. We don't tend to log
// non-ASCII stuff ourselves, but e.g. client
// names might be.
b = append(b, "…"...)
break
} }
if nTruncated > 0 {
b = append(b, "…+"...)
b = strconv.AppendInt(b, int64(nTruncated), 10)
} }
b = append(b, "\"}\n"...) b = append(b, "\"}\n"...)
return b return b

@ -5,6 +5,7 @@
package logtail package logtail
import ( import (
"bytes"
"context" "context"
"encoding/json" "encoding/json"
"io" "io"
@ -323,3 +324,14 @@ func unmarshalOne(t *testing.T, body []byte) map[string]interface{} {
} }
return entries[0] return entries[0]
} }
func TestEncodeTextTruncation(t *testing.T) {
lg := &Logger{timeNow: time.Now, lowMem: true}
in := bytes.Repeat([]byte("a"), 300)
b := lg.encodeText(in, true)
got := string(b)
want := `{"text": "` + strings.Repeat("a", 255) + `…+45"}` + "\n"
if got != want {
t.Errorf("got:\n%qwant:\n%q\n", got, want)
}
}

Loading…
Cancel
Save