Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 043668e

Browse files
committed
encoding/xml: normalize \t, \r and \n to space in attributes
This is required by the spec. Fixes: #20614
1 parent 239666c commit 043668e

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

src/encoding/xml/marshal_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,12 @@ var marshalTests = []struct {
602602
ExpectXML: `<Data Attr=""><Bytes></Bytes><Custom></Custom></Data>`,
603603
UnmarshalOnly: true,
604604
},
605+
// Check attribute value normalization (issue 20614).
606+
{
607+
Value: &Data{Bytes: []byte{}, Custom: MyBytes{}, Attr: []byte(" a b c d")},
608+
ExpectXML: "<Data Attr='\na\r\nb\tc\rd'><Bytes></Bytes><Custom></Custom></Data>",
609+
UnmarshalOnly: true,
610+
},
605611

606612
// Check that []byte works, including named []byte types.
607613
{

src/encoding/xml/xml.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,11 +1118,17 @@ Input:
11181118
return nil
11191119
}
11201120

1121-
// We must rewrite unescaped \r and \r\n into \n.
1122-
if b == '\r' {
1123-
d.buf.WriteByte('\n')
1121+
// We must rewrite unescaped \r and \r\n into \n outside quotes,
1122+
// and unescaped \r, \r\n, \n, and \t into space inside quotes.
1123+
if b >= ' ' {
1124+
d.buf.WriteByte(b)
11241125
} else if b1 == '\r' && b == '\n' {
11251126
// Skip \r\n--we already wrote \n.
1127+
} else if quote >= 0 && (b == '\r' || b == '\n' || b == '\t') {
1128+
// Normalize newline, CR, and tab into space
1129+
d.buf.WriteByte(' ')
1130+
} else if b == '\r' {
1131+
d.buf.WriteByte('\n')
11261132
} else {
11271133
d.buf.WriteByte(b)
11281134
}

src/encoding/xml/xml_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,30 @@ type item struct {
626626
FieldA string
627627
}
628628

629+
func TestIssue20614(t *testing.T) {
630+
data := "<item b='\n\r\t'/>"
631+
dec := NewDecoder(strings.NewReader(data))
632+
var tok1, tok2, tok3 Token
633+
var err error
634+
if tok1, err = dec.RawToken(); err != nil {
635+
t.Fatalf("RawToken() failed: %#v", err)
636+
}
637+
if tok2, err = dec.RawToken(); err != nil {
638+
t.Fatalf("RawToken() failed: %#v", err)
639+
}
640+
if tok3, err = dec.RawToken(); err != io.EOF || tok3 != nil {
641+
t.Fatalf("Missed EOF")
642+
}
643+
s := StartElement{Name{"", "item"}, []Attr{Attr{Name{"","b"}, " "}}}
644+
if !reflect.DeepEqual(tok1.(StartElement), s) {
645+
t.Error("Wrong start element")
646+
}
647+
e := EndElement{Name{"","item"}}
648+
if tok2.(EndElement) != e {
649+
t.Error("Wrong end element")
650+
}
651+
}
652+
629653
func TestIssue569(t *testing.T) {
630654
data := `<item><FieldA>abcd</FieldA></item>`
631655
var i item

0 commit comments

Comments
 (0)