1
0
mirror of https://github.com/golang/go synced 2024-11-20 07:34:40 -07:00

xml: permit nested directives

Return <!DOCTYPE ...> with nested directives as one big token.

Fixes #1549.

R=niemeyer, rsc
CC=golang-dev
https://golang.org/cl/4216050
This commit is contained in:
Chris Dollin 2011-02-28 14:09:04 -05:00 committed by Russ Cox
parent b2efedbf36
commit b00f7310f3
2 changed files with 67 additions and 2 deletions

View File

@ -541,17 +541,36 @@ func (p *Parser) RawToken() (Token, os.Error) {
}
// Probably a directive: <!DOCTYPE ...>, <!ENTITY ...>, etc.
// We don't care, but accumulate for caller.
// We don't care, but accumulate for caller. Quoted angle
// brackets do not count for nesting.
p.buf.Reset()
p.buf.WriteByte(b)
inquote := uint8(0)
depth := 0
for {
if b, ok = p.mustgetc(); !ok {
return nil, p.err
}
if b == '>' {
if inquote == 0 && b == '>' && depth == 0 {
break
}
p.buf.WriteByte(b)
switch {
case b == inquote:
inquote = 0
case inquote != 0:
// in quotes, no special action
case b == '\'' || b == '"':
inquote = b
case b == '>' && inquote == 0:
depth--
case b == '<' && inquote == 0:
depth++
}
}
return Directive(p.buf.Bytes()), nil
}

View File

@ -185,6 +185,52 @@ func TestRawToken(t *testing.T) {
}
}
// Ensure that directives (specifically !DOCTYPE) include the complete
// text of any nested directives, noting that < and > do not change
// nesting depth if they are in single or double quotes.
var nestedDirectivesInput = `
<!DOCTYPE [<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]>
<!DOCTYPE [<!ENTITY xlt ">">]>
<!DOCTYPE [<!ENTITY xlt "<">]>
<!DOCTYPE [<!ENTITY xlt '>'>]>
<!DOCTYPE [<!ENTITY xlt '<'>]>
<!DOCTYPE [<!ENTITY xlt '">'>]>
<!DOCTYPE [<!ENTITY xlt "'<">]>
`
var nestedDirectivesTokens = []Token{
CharData([]byte("\n")),
Directive([]byte(`DOCTYPE [<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]`)),
CharData([]byte("\n")),
Directive([]byte(`DOCTYPE [<!ENTITY xlt ">">]`)),
CharData([]byte("\n")),
Directive([]byte(`DOCTYPE [<!ENTITY xlt "<">]`)),
CharData([]byte("\n")),
Directive([]byte(`DOCTYPE [<!ENTITY xlt '>'>]`)),
CharData([]byte("\n")),
Directive([]byte(`DOCTYPE [<!ENTITY xlt '<'>]`)),
CharData([]byte("\n")),
Directive([]byte(`DOCTYPE [<!ENTITY xlt '">'>]`)),
CharData([]byte("\n")),
Directive([]byte(`DOCTYPE [<!ENTITY xlt "'<">]`)),
CharData([]byte("\n")),
}
func TestNestedDirectives(t *testing.T) {
p := NewParser(StringReader(nestedDirectivesInput))
for i, want := range nestedDirectivesTokens {
have, err := p.Token()
if err != nil {
t.Fatalf("token %d: unexpected error: %s", i, err)
}
if !reflect.DeepEqual(have, want) {
t.Errorf("token %d = %#v want %#v", i, have, want)
}
}
}
func TestToken(t *testing.T) {
p := NewParser(StringReader(testInput))