소스 검색

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 <[email protected]>
Josh Bleecher Snyder 4 년 전
부모
커밋
9fe5ece833
2개의 변경된 파일32개의 추가작업 그리고 9개의 파일을 삭제
  1. 20 9
      logtail/logtail.go
  2. 12 0
      logtail/logtail_test.go

+ 20 - 9
logtail/logtail.go

@@ -431,6 +431,21 @@ func (l *Logger) encodeText(buf []byte, skipClientTime bool) []byte {
 	// For now just factor in a dozen.
 	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 = append(b, '{')
 
@@ -449,7 +464,7 @@ func (l *Logger) encodeText(buf []byte, skipClientTime bool) []byte {
 	}
 
 	b = append(b, "\"text\": \""...)
-	for i, c := range buf {
+	for _, c := range buf {
 		switch c {
 		case '\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?
 			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"...)
 	return b

+ 12 - 0
logtail/logtail_test.go

@@ -5,6 +5,7 @@
 package logtail
 
 import (
+	"bytes"
 	"context"
 	"encoding/json"
 	"io"
@@ -323,3 +324,14 @@ func unmarshalOne(t *testing.T, body []byte) map[string]interface{} {
 	}
 	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)
+	}
+}