Fix logger string truncation with UTF-8

fixes #1365
pull/1372/head^2
Jack Christensen 2022-11-03 20:50:28 -05:00
parent 6f90866f58
commit 39676004de
2 changed files with 51 additions and 1 deletions

View File

@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"time"
"unicode/utf8"
"github.com/jackc/pgx/v5"
)
@ -62,6 +63,7 @@ func (f LoggerFunc) Log(ctx context.Context, level LogLevel, msg string, data ma
// LogLevelFromString converts log level string to constant
//
// Valid levels:
//
// trace
// debug
// info
@ -100,7 +102,13 @@ func logQueryArgs(args []any) []any {
}
case string:
if len(v) > 64 {
a = fmt.Sprintf("%s (truncated %d bytes)", v[:64], len(v)-64)
var l int = 0
for w := 0; l < 64; l += w {
_, w = utf8.DecodeRuneInString(v[l:])
}
if len(v) > l {
a = fmt.Sprintf("%s (truncated %d bytes)", v[:l], len(v)-l)
}
}
}
logArgs = append(logArgs, a)

View File

@ -137,6 +137,48 @@ func TestLogQuery(t *testing.T) {
})
}
// https://github.com/jackc/pgx/issues/1365
func TestLogQueryArgsHandlesUTF8(t *testing.T) {
t.Parallel()
logger := &testLogger{}
tracer := &tracelog.TraceLog{
Logger: logger,
LogLevel: tracelog.LogLevelTrace,
}
ctr := defaultConnTestRunner
ctr.CreateConfig = func(ctx context.Context, t testing.TB) *pgx.ConnConfig {
config := defaultConnTestRunner.CreateConfig(ctx, t)
config.Tracer = tracer
return config
}
pgxtest.RunWithQueryExecModes(context.Background(), t, ctr, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
logger.logs = logger.logs[0:0] // Clear any logs written when establishing connection
var s string
for i := 0; i < 63; i++ {
s += "0"
}
s += "😊"
_, err := conn.Exec(ctx, `select $1::text`, s)
require.NoError(t, err)
require.Len(t, logger.logs, 1)
require.Equal(t, "Query", logger.logs[0].msg)
require.Equal(t, tracelog.LogLevelInfo, logger.logs[0].lvl)
require.Equal(t, s, logger.logs[0].data["args"].([]any)[0])
_, err = conn.Exec(ctx, `select $1::text`, s+"000")
require.NoError(t, err)
require.Len(t, logger.logs, 2)
require.Equal(t, "Query", logger.logs[1].msg)
require.Equal(t, tracelog.LogLevelInfo, logger.logs[1].lvl)
require.Equal(t, s+" (truncated 3 bytes)", logger.logs[1].data["args"].([]any)[0])
})
}
func TestLogCopyFrom(t *testing.T) {
t.Parallel()