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
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…
Reference in New Issue