Escape adjacent quotation marks marshaling in multiline string (#365)

This commit is contained in:
Allen
2020-04-25 09:38:04 +08:00
committed by GitHub
parent 323fe5d063
commit a30fd2239c
2 changed files with 62 additions and 2 deletions
+49
View File
@@ -1467,6 +1467,55 @@ func TestMarshalCustomMultiline(t *testing.T) {
}
}
func TestMultilineWithAdjacentQuotationMarks(t *testing.T) {
type testStruct struct {
Str string `multiline:"true"`
}
type testCase struct {
expected []byte
data testStruct
}
testCases := []testCase{
{
expected: []byte(`Str = """
hello\""""
`),
data: testStruct{
Str: "hello\"",
},
},
{
expected: []byte(`Str = """
""\"""\"""\""""
`),
data: testStruct{
Str: "\"\"\"\"\"\"\"\"\"",
},
},
}
for i := range testCases {
result, err := Marshal(testCases[i].data)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(result, testCases[i].expected) {
t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n",
testCases[i].expected, result)
} else {
var data testStruct
if err = Unmarshal(result, &data); err != nil {
t.Fatal(err)
}
if data.Str != testCases[i].data.Str {
t.Errorf("Round trip test fail: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n",
testCases[i].data.Str, data.Str)
}
}
}
}
func TestMarshalEmbedTree(t *testing.T) {
expected := []byte(`OuterField1 = "Out"
OuterField2 = 1024
+13 -2
View File
@@ -30,9 +30,15 @@ type sortNode struct {
// are preserved. Quotation marks and backslashes are also not escaped.
func encodeMultilineTomlString(value string, commented string) string {
var b bytes.Buffer
adjacentQuoteCount := 0
b.WriteString(commented)
for _, rr := range value {
for i, rr := range value {
if rr != '"' {
adjacentQuoteCount = 0
} else {
adjacentQuoteCount++
}
switch rr {
case '\b':
b.WriteString(`\b`)
@@ -45,7 +51,12 @@ func encodeMultilineTomlString(value string, commented string) string {
case '\r':
b.WriteString("\r")
case '"':
b.WriteString(`"`)
if adjacentQuoteCount >= 3 || i == len(value)-1 {
adjacentQuoteCount = 0
b.WriteString(`\"`)
} else {
b.WriteString(`"`)
}
case '\\':
b.WriteString(`\`)
default: