aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/encoding/xml/xml.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/encoding/xml/xml.go')
-rw-r--r--libgo/go/encoding/xml/xml.go55
1 files changed, 52 insertions, 3 deletions
diff --git a/libgo/go/encoding/xml/xml.go b/libgo/go/encoding/xml/xml.go
index 0a21c93..45f4157 100644
--- a/libgo/go/encoding/xml/xml.go
+++ b/libgo/go/encoding/xml/xml.go
@@ -227,7 +227,8 @@ func NewDecoder(r io.Reader) *Decoder {
//
// Token guarantees that the StartElement and EndElement
// tokens it returns are properly nested and matched:
-// if Token encounters an unexpected end element,
+// if Token encounters an unexpected end element
+// or EOF before all expected end elements,
// it will return an error.
//
// Token implements XML name spaces as described by
@@ -245,6 +246,9 @@ func (d *Decoder) Token() (t Token, err error) {
t = d.nextToken
d.nextToken = nil
} else if t, err = d.rawToken(); err != nil {
+ if err == io.EOF && d.stk != nil && d.stk.kind != stkEOF {
+ err = d.syntaxError("unexpected EOF")
+ }
return
}
@@ -580,7 +584,7 @@ func (d *Decoder) rawToken() (Token, error) {
return nil, d.err
}
enc := procInst("encoding", content)
- if enc != "" && enc != "utf-8" && enc != "UTF-8" {
+ if enc != "" && enc != "utf-8" && enc != "UTF-8" && !strings.EqualFold(enc, "utf-8") {
if d.CharsetReader == nil {
d.err = fmt.Errorf("xml: encoding %q declared but Decoder.CharsetReader is nil", enc)
return nil, d.err
@@ -621,7 +625,12 @@ func (d *Decoder) rawToken() (Token, error) {
return nil, d.err
}
d.buf.WriteByte(b)
- if b0 == '-' && b1 == '-' && b == '>' {
+ if b0 == '-' && b1 == '-' {
+ if b != '>' {
+ d.err = d.syntaxError(
+ `invalid sequence "--" not allowed in comments`)
+ return nil, d.err
+ }
break
}
b0, b1 = b1, b
@@ -1940,6 +1949,46 @@ func Escape(w io.Writer, s []byte) {
EscapeText(w, s)
}
+var (
+ cdataStart = []byte("<![CDATA[")
+ cdataEnd = []byte("]]>")
+ cdataEscape = []byte("]]]]><![CDATA[>")
+)
+
+// emitCDATA writes to w the CDATA-wrapped plain text data s.
+// It escapes CDATA directives nested in s.
+func emitCDATA(w io.Writer, s []byte) error {
+ if len(s) == 0 {
+ return nil
+ }
+ if _, err := w.Write(cdataStart); err != nil {
+ return err
+ }
+ for {
+ i := bytes.Index(s, cdataEnd)
+ if i >= 0 && i+len(cdataEnd) <= len(s) {
+ // Found a nested CDATA directive end.
+ if _, err := w.Write(s[:i]); err != nil {
+ return err
+ }
+ if _, err := w.Write(cdataEscape); err != nil {
+ return err
+ }
+ i += len(cdataEnd)
+ } else {
+ if _, err := w.Write(s); err != nil {
+ return err
+ }
+ break
+ }
+ s = s[i:]
+ }
+ if _, err := w.Write(cdataEnd); err != nil {
+ return err
+ }
+ return nil
+}
+
// procInst parses the `param="..."` or `param='...'`
// value out of the provided string, returning "" if not found.
func procInst(param, s string) string {