Skip to content

Commit 5a40092

Browse files
Copilotmikefarah
andcommitted
Add test for string escape bug and implement fix
Co-authored-by: mikefarah <[email protected]>
1 parent bee10f1 commit 5a40092

File tree

2 files changed

+74
-3
lines changed

2 files changed

+74
-3
lines changed

pkg/yqlib/encoder_toml.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -614,9 +614,14 @@ func (te *tomlEncoder) colorizeToml(input []byte) []byte {
614614
if ch == '"' || ch == '\'' {
615615
quote := ch
616616
end := i + 1
617-
for end < len(toml) && toml[end] != quote {
618-
if toml[end] == '\\' {
619-
end++ // skip escaped char
617+
for end < len(toml) {
618+
if toml[end] == quote {
619+
break
620+
}
621+
if toml[end] == '\\' && end+1 < len(toml) {
622+
// Skip the backslash and the escaped character
623+
end += 2
624+
continue
620625
}
621626
end++
622627
}

pkg/yqlib/toml_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,3 +796,69 @@ func TestTomlColorisationNumberBug(t *testing.T) {
796796
})
797797
}
798798
}
799+
800+
// TestTomlStringEscapeColorization tests that string colorization correctly
801+
// handles escape sequences, particularly escaped quotes at the end of strings
802+
func TestTomlStringEscapeColorization(t *testing.T) {
803+
// Save and restore color state
804+
oldNoColor := color.NoColor
805+
color.NoColor = false
806+
defer func() { color.NoColor = oldNoColor }()
807+
808+
encoder := NewTomlEncoder()
809+
tomlEncoder := encoder.(*tomlEncoder)
810+
811+
testCases := []struct {
812+
name string
813+
input string
814+
description string
815+
}{
816+
{
817+
name: "escaped quote at end",
818+
input: `A = "test\""` + "\n",
819+
description: "String ending with escaped quote should be colorized correctly",
820+
},
821+
{
822+
name: "escaped backslash then quote",
823+
input: `A = "test\\\""` + "\n",
824+
description: "String with escaped backslash followed by escaped quote",
825+
},
826+
{
827+
name: "escaped quote in middle",
828+
input: `A = "test\"middle"` + "\n",
829+
description: "String with escaped quote in the middle should be colorized correctly",
830+
},
831+
{
832+
name: "multiple escaped quotes",
833+
input: `A = "\"test\""` + "\n",
834+
description: "String with escaped quotes at start and end",
835+
},
836+
{
837+
name: "escaped newline",
838+
input: `A = "test\n"` + "\n",
839+
description: "String with escaped newline should be colorized correctly",
840+
},
841+
{
842+
name: "single quote with escaped single quote",
843+
input: `A = 'test\''` + "\n",
844+
description: "Single-quoted string with escaped single quote",
845+
},
846+
}
847+
848+
for _, tt := range testCases {
849+
t.Run(tt.name, func(t *testing.T) {
850+
// The test should not panic and should return some output
851+
result := tomlEncoder.colorizeToml([]byte(tt.input))
852+
if len(result) == 0 {
853+
t.Error("Expected non-empty colorized output")
854+
}
855+
856+
// Check that the result contains the input string (with color codes)
857+
// At minimum, it should contain "A" and "="
858+
resultStr := string(result)
859+
if !strings.Contains(resultStr, "A") || !strings.Contains(resultStr, "=") {
860+
t.Errorf("Expected output to contain 'A' and '=', got: %q", resultStr)
861+
}
862+
})
863+
}
864+
}

0 commit comments

Comments
 (0)