From b06eef79d0f294af319455a59b1341d539282307 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Thu, 29 Jan 2026 12:40:35 +0800 Subject: [PATCH 1/3] Defend against driver buffer reuse --- src/main.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main.go b/src/main.go index b93b2a5..72e78db 100644 --- a/src/main.go +++ b/src/main.go @@ -976,6 +976,16 @@ func dumpToByteRows(rows *sql.Rows) ([]*byteRows, error) { return nil, errors.Trace(err) } + for i, col := range tmp { + if col == nil { + continue + } + // Defensive copy to avoid driver buffer reuse corrupting large results. + copied := make([]byte, len(col)) + copy(copied, col) + tmp[i] = copied + } + data = append(data, byteRow{tmp}) } From 34c28db587ac68fd6c4be00a22e2efc063261bbd Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Thu, 29 Jan 2026 13:58:32 +0800 Subject: [PATCH 2/3] Truncate long SQL in error logs --- src/main.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main.go b/src/main.go index 72e78db..ddcac5a 100644 --- a/src/main.go +++ b/src/main.go @@ -16,6 +16,7 @@ package main import ( "bytes" "context" + "crypto/sha256" "database/sql" "flag" "fmt" @@ -361,6 +362,23 @@ func (t *tester) addSuccess(testSuite *XUnitTestSuite, startTime *time.Time, cnt }) } +func formatSQLForLog(sql string) string { + const maxLen = 1024 + if len(sql) <= maxLen { + return sql + } + const headLen = 256 + const tailLen = 256 + sum := sha256.Sum256([]byte(sql)) + head := sql[:headLen] + tail := sql[len(sql)-tailLen:] + head = strings.ReplaceAll(head, "\n", " ") + head = strings.ReplaceAll(head, "\r", " ") + tail = strings.ReplaceAll(tail, "\n", " ") + tail = strings.ReplaceAll(tail, "\r", " ") + return fmt.Sprintf("len=%d sha256=%x head=%q tail=%q", len(sql), sum, head, tail) +} + func (t *tester) Run() error { t.preProcess() defer t.postProcess() @@ -443,7 +461,7 @@ func (t *tester) Run() error { if t.enableConcurrent { concurrentQueue = append(concurrentQueue, q) } else if err = t.execute(q); err != nil { - err = errors.Annotate(err, fmt.Sprintf("sql:%v", q.Query)) + err = errors.Annotate(err, fmt.Sprintf("sql:%s", formatSQLForLog(q.Query))) t.addFailure(&testSuite, &err, testCnt) return err } From b5ecc7b65a5a725174019a46a00001aef359aa98 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Thu, 29 Jan 2026 17:49:53 +0800 Subject: [PATCH 3/3] Preserve newlines in log formatter --- src/color.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/color.go b/src/color.go index 0e0ae5d..8adf20a 100644 --- a/src/color.go +++ b/src/color.go @@ -48,15 +48,20 @@ func shouldUseColor() bool { } func configureLogging() { + base := &log.TextFormatter{DisableQuote: true} switch normalizeColorMode(colorMode) { case colorModeAlways: - log.SetFormatter(&log.TextFormatter{ForceColors: true}) + base.ForceColors = true + log.SetFormatter(base) case colorModeNever: - log.SetFormatter(&log.TextFormatter{DisableColors: true}) + base.DisableColors = true + log.SetFormatter(base) case colorModeAuto: - // Use logrus default auto behavior. + // Use logrus default auto behavior with DisableQuote enabled. + log.SetFormatter(base) default: - log.SetFormatter(&log.TextFormatter{ForceColors: true}) + base.ForceColors = true + log.SetFormatter(base) } }