]> Cypherpunks repositories - gostls13.git/commitdiff
xml: add check of version in document declaration
authorGiulio Iotti <dullgiulio@gmail.com>
Wed, 15 Apr 2015 13:59:49 +0000 (16:59 +0300)
committerRuss Cox <rsc@golang.org>
Thu, 18 Jun 2015 18:06:01 +0000 (18:06 +0000)
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>
src/encoding/xml/xml.go
src/encoding/xml/xml_test.go

index 00792c4f27ceb24a46be355d10436ea6216fb9af..3090750c483336006325e55567b2c44b19802f21 100644 (file)
@@ -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 ""
        }
index be995c0d52c035fbc8c6f93a7a7a66b8127c79be..312a7c98a5c50488fda5a98bed217598b6300eb0 100644 (file)
@@ -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])
                }
        }
 }