mirror of
https://github.com/golang/go
synced 2024-11-18 08:54:45 -07:00
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>
This commit is contained in:
parent
cf6e6abc68
commit
a05934639b
@ -286,7 +286,10 @@ func (d *Decoder) Token() (Token, error) {
|
|||||||
t = d.nextToken
|
t = d.nextToken
|
||||||
d.nextToken = nil
|
d.nextToken = nil
|
||||||
} else if t, err = d.rawToken(); err != 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")
|
err = d.syntaxError("unexpected EOF")
|
||||||
}
|
}
|
||||||
return t, err
|
return t, err
|
||||||
|
@ -14,6 +14,51 @@ import (
|
|||||||
"unicode/utf8"
|
"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 = `
|
const testInput = `
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
Loading…
Reference in New Issue
Block a user