summaryrefslogtreecommitdiff
path: root/src/encoding/xml
diff options
context:
space:
mode:
authorSam Whited <sam@samwhited.com>2018-08-21 17:11:30 -0500
committerBrad Fitzpatrick <bradfitz@golang.org>2019-10-30 19:47:52 +0000
commita05934639bde593326f8d7ed9eb3f73f9ba6eb53 (patch)
tree2cb22c7c63f0ac71bbad76f6bca32f9cf5cbb5e3 /src/encoding/xml
parentcf6e6abc68fb1d20475bafaa65d9f96b23ae3773 (diff)
downloadgo-git-a05934639bde593326f8d7ed9eb3f73f9ba6eb53.tar.gz
encoding/xml: fix token decoder on early EOF
The documentation for TokenReader suggests that implementations of the interface may return a token and io.EOF together, indicating that it is the last token in the stream. This is similar to io.Reader. However, if you wrap such a TokenReader in a Decoder it complained about the EOF. A test was added to ensure this behavior on Decoder's. Change-Id: I9083c91d9626180d3bcf5c069a017050f3c7c4a8 Reviewed-on: https://go-review.googlesource.com/c/go/+/130556 Run-TryBot: Sam Whited <sam@samwhited.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/encoding/xml')
-rw-r--r--src/encoding/xml/xml.go5
-rw-r--r--src/encoding/xml/xml_test.go45
2 files changed, 49 insertions, 1 deletions
diff --git a/src/encoding/xml/xml.go b/src/encoding/xml/xml.go
index ca059440a1..5e73dcf731 100644
--- a/src/encoding/xml/xml.go
+++ b/src/encoding/xml/xml.go
@@ -286,7 +286,10 @@ func (d *Decoder) Token() (Token, 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 {
+ switch {
+ case err == io.EOF && d.t != nil:
+ err = nil
+ case err == io.EOF && d.stk != nil && d.stk.kind != stkEOF:
err = d.syntaxError("unexpected EOF")
}
return t, err
diff --git a/src/encoding/xml/xml_test.go b/src/encoding/xml/xml_test.go
index ee4ffa2420..efddca43e9 100644
--- a/src/encoding/xml/xml_test.go
+++ b/src/encoding/xml/xml_test.go
@@ -14,6 +14,51 @@ import (
"unicode/utf8"
)
+type toks struct {
+ earlyEOF bool
+ t []Token
+}
+
+func (t *toks) Token() (Token, error) {
+ if len(t.t) == 0 {
+ return nil, io.EOF
+ }
+ var tok Token
+ tok, t.t = t.t[0], t.t[1:]
+ if t.earlyEOF && len(t.t) == 0 {
+ return tok, io.EOF
+ }
+ return tok, nil
+}
+
+func TestDecodeEOF(t *testing.T) {
+ start := StartElement{Name: Name{Local: "test"}}
+ t.Run("EarlyEOF", func(t *testing.T) {
+ d := NewTokenDecoder(&toks{earlyEOF: true, t: []Token{
+ start,
+ start.End(),
+ }})
+ err := d.Decode(&struct {
+ XMLName Name `xml:"test"`
+ }{})
+ if err != nil {
+ t.Error(err)
+ }
+ })
+ t.Run("LateEOF", func(t *testing.T) {
+ d := NewTokenDecoder(&toks{t: []Token{
+ start,
+ start.End(),
+ }})
+ err := d.Decode(&struct {
+ XMLName Name `xml:"test"`
+ }{})
+ if err != nil {
+ t.Error(err)
+ }
+ })
+}
+
const testInput = `
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"