diff options
Diffstat (limited to 'libgo/go/encoding/xml/xml.go')
-rw-r--r-- | libgo/go/encoding/xml/xml.go | 55 |
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 { |