mirror of
https://github.com/golang/go
synced 2024-11-11 23:10:23 -07:00
xml: add check of version in document declaration
Check that if a version is declared, for example in '<?xml version="XX" ?>', version must be '1.0'. Change-Id: I16ba9f78873a5f31977dcf75ac8e671fe6c08280 Reviewed-on: https://go-review.googlesource.com/8961 Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
a13606e619
commit
9490fbf755
@ -576,7 +576,6 @@ func (d *Decoder) rawToken() (Token, error) {
|
||||
|
||||
case '?':
|
||||
// <?: Processing instruction.
|
||||
// TODO(rsc): Should parse the <?xml declaration to make sure the version is 1.0.
|
||||
var target string
|
||||
if target, ok = d.name(); !ok {
|
||||
if d.err == nil {
|
||||
@ -601,7 +600,13 @@ func (d *Decoder) rawToken() (Token, error) {
|
||||
data = data[0 : len(data)-2] // chop ?>
|
||||
|
||||
if target == "xml" {
|
||||
enc := procInstEncoding(string(data))
|
||||
content := string(data)
|
||||
ver := procInst("version", content)
|
||||
if ver != "" && ver != "1.0" {
|
||||
d.err = fmt.Errorf("xml: unsupported version %q; only version 1.0 is supported", ver)
|
||||
return nil, d.err
|
||||
}
|
||||
enc := procInst("encoding", content)
|
||||
if enc != "" && enc != "utf-8" && enc != "UTF-8" {
|
||||
if d.CharsetReader == nil {
|
||||
d.err = fmt.Errorf("xml: encoding %q declared but Decoder.CharsetReader is nil", enc)
|
||||
@ -1962,16 +1967,17 @@ func Escape(w io.Writer, s []byte) {
|
||||
EscapeText(w, s)
|
||||
}
|
||||
|
||||
// procInstEncoding parses the `encoding="..."` or `encoding='...'`
|
||||
// procInst parses the `param="..."` or `param='...'`
|
||||
// value out of the provided string, returning "" if not found.
|
||||
func procInstEncoding(s string) string {
|
||||
func procInst(param, s string) string {
|
||||
// TODO: this parsing is somewhat lame and not exact.
|
||||
// It works for all actual cases, though.
|
||||
idx := strings.Index(s, "encoding=")
|
||||
param = param + "="
|
||||
idx := strings.Index(s, param)
|
||||
if idx == -1 {
|
||||
return ""
|
||||
}
|
||||
v := s[idx+len("encoding="):]
|
||||
v := s[idx+len(param):]
|
||||
if v == "" {
|
||||
return ""
|
||||
}
|
||||
|
@ -657,20 +657,23 @@ type procInstEncodingTest struct {
|
||||
}
|
||||
|
||||
var procInstTests = []struct {
|
||||
input, expect string
|
||||
input string
|
||||
expect [2]string
|
||||
}{
|
||||
{`version="1.0" encoding="utf-8"`, "utf-8"},
|
||||
{`version="1.0" encoding='utf-8'`, "utf-8"},
|
||||
{`version="1.0" encoding='utf-8' `, "utf-8"},
|
||||
{`version="1.0" encoding=utf-8`, ""},
|
||||
{`encoding="FOO" `, "FOO"},
|
||||
{`version="1.0" encoding="utf-8"`, [2]string{"1.0", "utf-8"}},
|
||||
{`version="1.0" encoding='utf-8'`, [2]string{"1.0", "utf-8"}},
|
||||
{`version="1.0" encoding='utf-8' `, [2]string{"1.0", "utf-8"}},
|
||||
{`version="1.0" encoding=utf-8`, [2]string{"1.0", ""}},
|
||||
{`encoding="FOO" `, [2]string{"", "FOO"}},
|
||||
}
|
||||
|
||||
func TestProcInstEncoding(t *testing.T) {
|
||||
for _, test := range procInstTests {
|
||||
got := procInstEncoding(test.input)
|
||||
if got != test.expect {
|
||||
t.Errorf("procInstEncoding(%q) = %q; want %q", test.input, got, test.expect)
|
||||
if got := procInst("version", test.input); got != test.expect[0] {
|
||||
t.Errorf("procInst(version, %q) = %q; want %q", test.input, got, test.expect[0])
|
||||
}
|
||||
if got := procInst("encoding", test.input); got != test.expect[1] {
|
||||
t.Errorf("procInst(encoding, %q) = %q; want %q", test.input, got, test.expect[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user