Commit a0593463 authored by Sam Whited's avatar Sam Whited Committed by Brad Fitzpatrick

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: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent cf6e6abc
......@@ -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
......
......@@ -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"
......
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