Commit 9490fbf7 authored by Giulio Iotti's avatar Giulio Iotti Committed by Russ Cox

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/8961Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
parent a13606e6
......@@ -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])
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment