From 0a612226277e74e6f05b1a47bce283d392049384 Mon Sep 17 00:00:00 2001
From: Aliaksandr Valialkin <valyala@victoriametrics.com>
Date: Mon, 7 Oct 2024 14:31:16 +0200
Subject: [PATCH] lib/logstorage: quote logfmt strings only if they contain
 special chars, which could break logfmt parsing and/or reading

(cherry picked from commit 462b7cd597fff42bde22d8155f2f3a32eeb9a2ff)
---
 lib/logstorage/pipe_pack_logfmt_test.go |  2 +-
 lib/logstorage/rows.go                  | 14 +++++++++++++-
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/lib/logstorage/pipe_pack_logfmt_test.go b/lib/logstorage/pipe_pack_logfmt_test.go
index 57c9503c80..f138377d74 100644
--- a/lib/logstorage/pipe_pack_logfmt_test.go
+++ b/lib/logstorage/pipe_pack_logfmt_test.go
@@ -45,7 +45,7 @@ func TestPipePackLogfmt(t *testing.T) {
 		},
 	}, [][]Field{
 		{
-			{"_msg", `_msg=x foo=abc bar="cde=ab"`},
+			{"_msg", `_msg=x foo=abc bar=cde=ab`},
 			{"foo", `abc`},
 			{"bar", `cde=ab`},
 		},
diff --git a/lib/logstorage/rows.go b/lib/logstorage/rows.go
index bee9fbd8d3..9d0d77e9c8 100644
--- a/lib/logstorage/rows.go
+++ b/lib/logstorage/rows.go
@@ -91,13 +91,25 @@ func getFieldValue(fields []Field, name string) string {
 
 func needLogfmtQuoting(s string) bool {
 	for _, c := range s {
-		if !isTokenRune(c) {
+		if isLogfmtSpecialChar(c) {
 			return true
 		}
 	}
 	return false
 }
 
+func isLogfmtSpecialChar(c rune) bool {
+	if c <= 0x20 {
+		return true
+	}
+	switch c {
+	case '"', '\\':
+		return true
+	default:
+		return false
+	}
+}
+
 // RenameField renames field with the oldName to newName in Fields
 func RenameField(fields []Field, oldName, newName string) {
 	if oldName == "" {