vendor: golang.org/x/net v0.56.0
full diff: https://github.com/golang/net/compare/v0.55.0...v0.56.0 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -227,7 +227,7 @@ require (
|
|||||||
go.opentelemetry.io/proto/otlp v1.10.0 // indirect
|
go.opentelemetry.io/proto/otlp v1.10.0 // indirect
|
||||||
go.yaml.in/yaml/v2 v2.4.4 // indirect
|
go.yaml.in/yaml/v2 v2.4.4 // indirect
|
||||||
go.yaml.in/yaml/v4 v4.0.0-rc.4 // indirect
|
go.yaml.in/yaml/v4 v4.0.0-rc.4 // indirect
|
||||||
golang.org/x/net v0.55.0 // indirect
|
golang.org/x/net v0.56.0 // indirect
|
||||||
golang.org/x/oauth2 v0.36.0 // indirect
|
golang.org/x/oauth2 v0.36.0 // indirect
|
||||||
golang.org/x/time v0.15.0 // indirect
|
golang.org/x/time v0.15.0 // indirect
|
||||||
golang.org/x/tools v0.45.0 // indirect
|
golang.org/x/tools v0.45.0 // indirect
|
||||||
|
|||||||
@@ -654,8 +654,8 @@ golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
|
|||||||
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
|
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
|
||||||
golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
|
golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
|
||||||
golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0=
|
golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0=
|
||||||
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
|
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
|
||||||
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
|
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
|
||||||
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
||||||
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
||||||
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
|
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
|
||||||
|
|||||||
+2
-3
@@ -2156,9 +2156,8 @@ var entity = map[string]rune{
|
|||||||
|
|
||||||
// HTML entities that are two unicode codepoints.
|
// HTML entities that are two unicode codepoints.
|
||||||
var entity2 = map[string][2]rune{
|
var entity2 = map[string][2]rune{
|
||||||
// TODO(nigeltao): Handle replacements that are wider than their names.
|
"nLt;": {'\u226A', '\u20D2'},
|
||||||
// "nLt;": {'\u226A', '\u20D2'},
|
"nGt;": {'\u226B', '\u20D2'},
|
||||||
// "nGt;": {'\u226B', '\u20D2'},
|
|
||||||
"NotEqualTilde;": {'\u2242', '\u0338'},
|
"NotEqualTilde;": {'\u2242', '\u0338'},
|
||||||
"NotGreaterFullEqual;": {'\u2267', '\u0338'},
|
"NotGreaterFullEqual;": {'\u2267', '\u0338'},
|
||||||
"NotGreaterGreater;": {'\u226B', '\u0338'},
|
"NotGreaterGreater;": {'\u226B', '\u0338'},
|
||||||
|
|||||||
+92
-52
@@ -6,6 +6,7 @@ package html
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
@@ -50,25 +51,24 @@ var replacementTable = [...]rune{
|
|||||||
// 0x0D->'\u000D' is a no-op.
|
// 0x0D->'\u000D' is a no-op.
|
||||||
}
|
}
|
||||||
|
|
||||||
// unescapeEntity reads an entity like "<" from b[src:] and writes the
|
// unescapeEntity attempts to consume a character reference from s[src:],
|
||||||
// corresponding "<" to b[dst:], returning the incremented dst and src cursors.
|
// returning the rune, potential second rune, and number of bytes consumed
|
||||||
// Precondition: b[src] == '&' && dst <= src.
|
// (which indicates the length of the character reference). It is assumed that
|
||||||
// attribute should be true if parsing an attribute value.
|
// the first byte of s is '&'. attribute should be true if parsing an attribute
|
||||||
func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {
|
// value.
|
||||||
|
func unescapeEntity(s []byte, attribute bool) (rune, rune, int) {
|
||||||
// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference
|
// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference
|
||||||
|
|
||||||
// i starts at 1 because we already know that s[0] == '&'.
|
// i starts at 1 because we already know that s[0] == '&'.
|
||||||
i, s := 1, b[src:]
|
i := 1
|
||||||
|
|
||||||
if len(s) <= 1 {
|
if len(s) <= 1 {
|
||||||
b[dst] = b[src]
|
return '&', 0, 1
|
||||||
return dst + 1, src + 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if s[i] == '#' {
|
if s[i] == '#' {
|
||||||
if len(s) <= 3 { // We need to have at least "&#.".
|
if len(s) <= 2 { // We need to have at least "&#".
|
||||||
b[dst] = b[src]
|
return '&', 0, 1
|
||||||
return dst + 1, src + 1
|
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
c := s[i]
|
c := s[i]
|
||||||
@@ -78,34 +78,43 @@ func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i0 := i
|
||||||
x := '\x00'
|
x := '\x00'
|
||||||
for i < len(s) {
|
for i < len(s) {
|
||||||
c = s[i]
|
c = s[i]
|
||||||
i++
|
var d rune
|
||||||
|
var mult rune
|
||||||
if hex {
|
if hex {
|
||||||
|
mult = 16
|
||||||
if '0' <= c && c <= '9' {
|
if '0' <= c && c <= '9' {
|
||||||
x = 16*x + rune(c) - '0'
|
d = rune(c) - '0'
|
||||||
continue
|
|
||||||
} else if 'a' <= c && c <= 'f' {
|
} else if 'a' <= c && c <= 'f' {
|
||||||
x = 16*x + rune(c) - 'a' + 10
|
d = rune(c) - 'a' + 10
|
||||||
continue
|
|
||||||
} else if 'A' <= c && c <= 'F' {
|
} else if 'A' <= c && c <= 'F' {
|
||||||
x = 16*x + rune(c) - 'A' + 10
|
d = rune(c) - 'A' + 10
|
||||||
continue
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mult = 10
|
||||||
|
if '0' <= c && c <= '9' {
|
||||||
|
d = rune(c) - '0'
|
||||||
|
} else {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
} else if '0' <= c && c <= '9' {
|
|
||||||
x = 10*x + rune(c) - '0'
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
if c != ';' {
|
if x <= 0x10FFFF {
|
||||||
i--
|
x = mult*x + d
|
||||||
}
|
}
|
||||||
break
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
if i <= 3 { // No characters matched.
|
if i == i0 { // No characters matched.
|
||||||
b[dst] = b[src]
|
return '&', 0, 1
|
||||||
return dst + 1, src + 1
|
}
|
||||||
|
|
||||||
|
if i < len(s) && s[i] == ';' {
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
if 0x80 <= x && x <= 0x9F {
|
if 0x80 <= x && x <= 0x9F {
|
||||||
@@ -116,7 +125,7 @@ func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {
|
|||||||
x = '\uFFFD'
|
x = '\uFFFD'
|
||||||
}
|
}
|
||||||
|
|
||||||
return dst + utf8.EncodeRune(b[dst:], x), src + i
|
return x, 0, i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consume the maximum number of characters possible, with the
|
// Consume the maximum number of characters possible, with the
|
||||||
@@ -141,10 +150,9 @@ func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {
|
|||||||
} else if attribute && entityName[len(entityName)-1] != ';' && len(s) > i && s[i] == '=' {
|
} else if attribute && entityName[len(entityName)-1] != ';' && len(s) > i && s[i] == '=' {
|
||||||
// No-op.
|
// No-op.
|
||||||
} else if x := entity[entityName]; x != 0 {
|
} else if x := entity[entityName]; x != 0 {
|
||||||
return dst + utf8.EncodeRune(b[dst:], x), src + i
|
return x, 0, i
|
||||||
} else if x := entity2[entityName]; x[0] != 0 {
|
} else if x := entity2[entityName]; x[0] != 0 {
|
||||||
dst1 := dst + utf8.EncodeRune(b[dst:], x[0])
|
return x[0], x[1], i
|
||||||
return dst1 + utf8.EncodeRune(b[dst1:], x[1]), src + i
|
|
||||||
} else if !attribute {
|
} else if !attribute {
|
||||||
maxLen := len(entityName) - 1
|
maxLen := len(entityName) - 1
|
||||||
if maxLen > longestEntityWithoutSemicolon {
|
if maxLen > longestEntityWithoutSemicolon {
|
||||||
@@ -152,35 +160,67 @@ func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {
|
|||||||
}
|
}
|
||||||
for j := maxLen; j > 1; j-- {
|
for j := maxLen; j > 1; j-- {
|
||||||
if x := entity[entityName[:j]]; x != 0 {
|
if x := entity[entityName[:j]]; x != 0 {
|
||||||
return dst + utf8.EncodeRune(b[dst:], x), src + j + 1
|
return x, 0, j + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dst1, src1 = dst+i, src+i
|
return '&', 0, 1
|
||||||
copy(b[dst:dst1], b[src:src1])
|
|
||||||
return dst1, src1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// unescape unescapes b's entities in-place, so that "a<b" becomes "a<b".
|
// unescape unescapes b's entites, so that "a<b" becomes "a<b". It attempts
|
||||||
// attribute should be true if parsing an attribute value.
|
// to do so in place, but if the unescaped value is longer than the input it
|
||||||
|
// allocates a new slice. attribute should be true if parsing an attribute
|
||||||
|
// value.
|
||||||
func unescape(b []byte, attribute bool) []byte {
|
func unescape(b []byte, attribute bool) []byte {
|
||||||
for i, c := range b {
|
firstAmp := slices.Index(b, '&')
|
||||||
if c == '&' {
|
if firstAmp == -1 {
|
||||||
dst, src := unescapeEntity(b, i, i, attribute)
|
return b
|
||||||
for src < len(b) {
|
|
||||||
c := b[src]
|
|
||||||
if c == '&' {
|
|
||||||
dst, src = unescapeEntity(b, dst, src, attribute)
|
|
||||||
} else {
|
|
||||||
b[dst] = c
|
|
||||||
dst, src = dst+1, src+1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b[0:dst]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return b
|
|
||||||
|
out := b[:firstAmp]
|
||||||
|
src := firstAmp
|
||||||
|
reusingB := true
|
||||||
|
for src < len(b) {
|
||||||
|
if b[src] != '&' {
|
||||||
|
out = append(out, b[src])
|
||||||
|
src++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
r1, r2, entityNameLen := unescapeEntity(b[src:], attribute)
|
||||||
|
if entityNameLen == 1 && r1 == '&' {
|
||||||
|
// Not an entity
|
||||||
|
out = append(out, '&')
|
||||||
|
src++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute replacement length
|
||||||
|
replLen := utf8.RuneLen(r1)
|
||||||
|
if r2 != 0 {
|
||||||
|
replLen += utf8.RuneLen(r2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the name of the entity is shorter than the width of the
|
||||||
|
// replacement runes then we need to expand the output slice to
|
||||||
|
// fit the replacement.
|
||||||
|
if replLen > entityNameLen {
|
||||||
|
if reusingB {
|
||||||
|
out = slices.Clone(out)
|
||||||
|
reusingB = false
|
||||||
|
}
|
||||||
|
out = slices.Grow(out, replLen)
|
||||||
|
}
|
||||||
|
out = utf8.AppendRune(out, r1)
|
||||||
|
if r2 != 0 {
|
||||||
|
out = utf8.AppendRune(out, r2)
|
||||||
|
}
|
||||||
|
|
||||||
|
src += entityNameLen
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// lower lower-cases the A-Z bytes in b in-place, so that "aBc" becomes "abc".
|
// lower lower-cases the A-Z bytes in b in-place, so that "aBc" becomes "abc".
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ func adjustForeignAttributes(aa []Attribute) {
|
|||||||
}
|
}
|
||||||
switch a.Key {
|
switch a.Key {
|
||||||
case "xlink:actuate", "xlink:arcrole", "xlink:href", "xlink:role", "xlink:show",
|
case "xlink:actuate", "xlink:arcrole", "xlink:href", "xlink:role", "xlink:show",
|
||||||
"xlink:title", "xlink:type", "xml:base", "xml:lang", "xml:space", "xmlns:xlink":
|
"xlink:title", "xlink:type", "xml:lang", "xml:space", "xmlns:xlink":
|
||||||
j := strings.Index(a.Key, ":")
|
j := strings.Index(a.Key, ":")
|
||||||
aa[i].Namespace = a.Key[:j]
|
aa[i].Namespace = a.Key[:j]
|
||||||
aa[i].Key = a.Key[j+1:]
|
aa[i].Key = a.Key[j+1:]
|
||||||
|
|||||||
+67
-182
@@ -63,7 +63,7 @@ func (p *parser) top() *Node {
|
|||||||
// Stop tags for use in popUntil. These come from section 12.2.4.2.
|
// Stop tags for use in popUntil. These come from section 12.2.4.2.
|
||||||
var (
|
var (
|
||||||
defaultScopeStopTags = map[string][]a.Atom{
|
defaultScopeStopTags = map[string][]a.Atom{
|
||||||
"": {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object, a.Template},
|
"": {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object, a.Template, a.Select},
|
||||||
"math": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext},
|
"math": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext},
|
||||||
"svg": {a.Desc, a.ForeignObject, a.Title},
|
"svg": {a.Desc, a.ForeignObject, a.Title},
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,6 @@ const (
|
|||||||
tableScope
|
tableScope
|
||||||
tableRowScope
|
tableRowScope
|
||||||
tableBodyScope
|
tableBodyScope
|
||||||
selectScope
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// popUntil pops the stack of open elements at the highest element whose tag
|
// popUntil pops the stack of open elements at the highest element whose tag
|
||||||
@@ -133,10 +132,6 @@ func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int {
|
|||||||
if tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template {
|
if tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
case selectScope:
|
|
||||||
if tagAtom != a.Optgroup && tagAtom != a.Option {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("html: internal error: indexOfElementInScope unknown scope: %d", s))
|
panic(fmt.Sprintf("html: internal error: indexOfElementInScope unknown scope: %d", s))
|
||||||
}
|
}
|
||||||
@@ -460,21 +455,6 @@ func (p *parser) resetInsertionMode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch n.DataAtom {
|
switch n.DataAtom {
|
||||||
case a.Select:
|
|
||||||
if !last {
|
|
||||||
for ancestor, first := n, p.oe[0]; ancestor != first; {
|
|
||||||
ancestor = p.oe[p.oe.index(ancestor)-1]
|
|
||||||
switch ancestor.DataAtom {
|
|
||||||
case a.Template:
|
|
||||||
p.im = inSelectIM
|
|
||||||
return
|
|
||||||
case a.Table:
|
|
||||||
p.im = inSelectInTableIM
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p.im = inSelectIM
|
|
||||||
case a.Td, a.Th:
|
case a.Td, a.Th:
|
||||||
// TODO: remove this divergence from the HTML5 spec.
|
// TODO: remove this divergence from the HTML5 spec.
|
||||||
//
|
//
|
||||||
@@ -1002,7 +982,10 @@ func inBodyIM(p *parser) bool {
|
|||||||
p.popUntil(buttonScope, a.P)
|
p.popUntil(buttonScope, a.P)
|
||||||
p.addElement()
|
p.addElement()
|
||||||
case a.Button:
|
case a.Button:
|
||||||
p.popUntil(defaultScope, a.Button)
|
if p.elementInScope(defaultScope, a.Button) {
|
||||||
|
p.generateImpliedEndTags()
|
||||||
|
p.popUntil(defaultScope, a.Button)
|
||||||
|
}
|
||||||
p.reconstructActiveFormattingElements()
|
p.reconstructActiveFormattingElements()
|
||||||
p.addElement()
|
p.addElement()
|
||||||
p.framesetOK = false
|
p.framesetOK = false
|
||||||
@@ -1040,7 +1023,18 @@ func inBodyIM(p *parser) bool {
|
|||||||
p.framesetOK = false
|
p.framesetOK = false
|
||||||
p.im = inTableIM
|
p.im = inTableIM
|
||||||
return true
|
return true
|
||||||
case a.Area, a.Br, a.Embed, a.Img, a.Input, a.Keygen, a.Wbr:
|
case a.Area, a.Br, a.Embed, a.Img, a.Keygen, a.Wbr:
|
||||||
|
p.reconstructActiveFormattingElements()
|
||||||
|
p.addElement()
|
||||||
|
p.oe.pop()
|
||||||
|
p.acknowledgeSelfClosingTag()
|
||||||
|
p.framesetOK = false
|
||||||
|
case a.Input:
|
||||||
|
if p.fragment && p.context.DataAtom == a.Select {
|
||||||
|
// Ignore the token.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
p.popUntil(defaultScope, a.Select)
|
||||||
p.reconstructActiveFormattingElements()
|
p.reconstructActiveFormattingElements()
|
||||||
p.addElement()
|
p.addElement()
|
||||||
p.oe.pop()
|
p.oe.pop()
|
||||||
@@ -1061,7 +1055,13 @@ func inBodyIM(p *parser) bool {
|
|||||||
p.oe.pop()
|
p.oe.pop()
|
||||||
p.acknowledgeSelfClosingTag()
|
p.acknowledgeSelfClosingTag()
|
||||||
case a.Hr:
|
case a.Hr:
|
||||||
p.popUntil(buttonScope, a.P)
|
if p.elementInScope(buttonScope, a.P) {
|
||||||
|
p.generateImpliedEndTags("p")
|
||||||
|
p.popUntil(defaultScope, a.P)
|
||||||
|
}
|
||||||
|
if p.elementInScope(defaultScope, a.Select) {
|
||||||
|
p.generateImpliedEndTags()
|
||||||
|
}
|
||||||
p.addElement()
|
p.addElement()
|
||||||
p.oe.pop()
|
p.oe.pop()
|
||||||
p.acknowledgeSelfClosingTag()
|
p.acknowledgeSelfClosingTag()
|
||||||
@@ -1095,13 +1095,30 @@ func inBodyIM(p *parser) bool {
|
|||||||
// Don't let the tokenizer go into raw text mode when scripting is disabled.
|
// Don't let the tokenizer go into raw text mode when scripting is disabled.
|
||||||
p.tokenizer.NextIsNotRawText()
|
p.tokenizer.NextIsNotRawText()
|
||||||
case a.Select:
|
case a.Select:
|
||||||
|
if p.fragment && p.context.DataAtom == a.Select {
|
||||||
|
// Ignore the token.
|
||||||
|
return true
|
||||||
|
} else if p.popUntil(defaultScope, a.Select) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
p.reconstructActiveFormattingElements()
|
p.reconstructActiveFormattingElements()
|
||||||
p.addElement()
|
p.addElement()
|
||||||
p.framesetOK = false
|
p.framesetOK = false
|
||||||
p.im = inSelectIM
|
|
||||||
return true
|
return true
|
||||||
case a.Optgroup, a.Option:
|
case a.Option:
|
||||||
if p.top().DataAtom == a.Option {
|
if p.elementInScope(defaultScope, a.Select) {
|
||||||
|
p.generateImpliedEndTags("optgroup")
|
||||||
|
// If oe has option element in scope, parse error?
|
||||||
|
} else if p.top().DataAtom == a.Option {
|
||||||
|
p.oe.pop()
|
||||||
|
}
|
||||||
|
p.reconstructActiveFormattingElements()
|
||||||
|
p.addElement()
|
||||||
|
case a.Optgroup:
|
||||||
|
if p.elementInScope(defaultScope, a.Select) {
|
||||||
|
p.generateImpliedEndTags()
|
||||||
|
// If oe has option or optgroup element in scope, parse error?
|
||||||
|
} else if p.top().DataAtom == a.Option {
|
||||||
p.oe.pop()
|
p.oe.pop()
|
||||||
}
|
}
|
||||||
p.reconstructActiveFormattingElements()
|
p.reconstructActiveFormattingElements()
|
||||||
@@ -1149,7 +1166,12 @@ func inBodyIM(p *parser) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dialog, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Main, a.Menu, a.Nav, a.Ol, a.Pre, a.Search, a.Section, a.Summary, a.Ul:
|
case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dialog, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Main, a.Menu, a.Nav, a.Ol, a.Pre, a.Search, a.Section, a.Select, a.Summary, a.Ul:
|
||||||
|
if !p.elementInScope(defaultScope, p.tok.DataAtom) {
|
||||||
|
// Ignore the token.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
p.generateImpliedEndTags()
|
||||||
p.popUntil(defaultScope, p.tok.DataAtom)
|
p.popUntil(defaultScope, p.tok.DataAtom)
|
||||||
case a.Form:
|
case a.Form:
|
||||||
if p.oe.contains(a.Template) {
|
if p.oe.contains(a.Template) {
|
||||||
@@ -1488,17 +1510,6 @@ func inTableIM(p *parser) bool {
|
|||||||
}
|
}
|
||||||
p.addElement()
|
p.addElement()
|
||||||
p.form = p.oe.pop()
|
p.form = p.oe.pop()
|
||||||
case a.Select:
|
|
||||||
p.reconstructActiveFormattingElements()
|
|
||||||
switch p.top().DataAtom {
|
|
||||||
case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
|
|
||||||
p.fosterParenting = true
|
|
||||||
}
|
|
||||||
p.addElement()
|
|
||||||
p.fosterParenting = false
|
|
||||||
p.framesetOK = false
|
|
||||||
p.im = inSelectInTableIM
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
case EndTagToken:
|
case EndTagToken:
|
||||||
switch p.tok.DataAtom {
|
switch p.tok.DataAtom {
|
||||||
@@ -1547,12 +1558,6 @@ func inCaptionIM(p *parser) bool {
|
|||||||
p.clearActiveFormattingElements()
|
p.clearActiveFormattingElements()
|
||||||
p.im = inTableIM
|
p.im = inTableIM
|
||||||
return false
|
return false
|
||||||
case a.Select:
|
|
||||||
p.reconstructActiveFormattingElements()
|
|
||||||
p.addElement()
|
|
||||||
p.framesetOK = false
|
|
||||||
p.im = inSelectInTableIM
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
case EndTagToken:
|
case EndTagToken:
|
||||||
switch p.tok.DataAtom {
|
switch p.tok.DataAtom {
|
||||||
@@ -1762,12 +1767,6 @@ func inCellIM(p *parser) bool {
|
|||||||
}
|
}
|
||||||
// Ignore the token.
|
// Ignore the token.
|
||||||
return true
|
return true
|
||||||
case a.Select:
|
|
||||||
p.reconstructActiveFormattingElements()
|
|
||||||
p.addElement()
|
|
||||||
p.framesetOK = false
|
|
||||||
p.im = inSelectInTableIM
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
case EndTagToken:
|
case EndTagToken:
|
||||||
switch p.tok.DataAtom {
|
switch p.tok.DataAtom {
|
||||||
@@ -1798,118 +1797,6 @@ func inCellIM(p *parser) bool {
|
|||||||
return inBodyIM(p)
|
return inBodyIM(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Section 12.2.6.4.16.
|
|
||||||
func inSelectIM(p *parser) bool {
|
|
||||||
switch p.tok.Type {
|
|
||||||
case TextToken:
|
|
||||||
p.addText(strings.Replace(p.tok.Data, "\x00", "", -1))
|
|
||||||
case StartTagToken:
|
|
||||||
switch p.tok.DataAtom {
|
|
||||||
case a.Html:
|
|
||||||
return inBodyIM(p)
|
|
||||||
case a.Option:
|
|
||||||
if p.top().DataAtom == a.Option {
|
|
||||||
p.oe.pop()
|
|
||||||
}
|
|
||||||
p.addElement()
|
|
||||||
case a.Optgroup:
|
|
||||||
if p.top().DataAtom == a.Option {
|
|
||||||
p.oe.pop()
|
|
||||||
}
|
|
||||||
if p.top().DataAtom == a.Optgroup {
|
|
||||||
p.oe.pop()
|
|
||||||
}
|
|
||||||
p.addElement()
|
|
||||||
case a.Select:
|
|
||||||
if !p.popUntil(selectScope, a.Select) {
|
|
||||||
// Ignore the token.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
p.resetInsertionMode()
|
|
||||||
case a.Input, a.Keygen, a.Textarea:
|
|
||||||
if p.elementInScope(selectScope, a.Select) {
|
|
||||||
p.parseImpliedToken(EndTagToken, a.Select, a.Select.String())
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// In order to properly ignore <textarea>, we need to change the tokenizer mode.
|
|
||||||
p.tokenizer.NextIsNotRawText()
|
|
||||||
// Ignore the token.
|
|
||||||
return true
|
|
||||||
case a.Script, a.Template:
|
|
||||||
return inHeadIM(p)
|
|
||||||
case a.Iframe, a.Noembed, a.Noframes, a.Noscript, a.Plaintext, a.Style, a.Title, a.Xmp:
|
|
||||||
// Don't let the tokenizer go into raw text mode when there are raw tags
|
|
||||||
// to be ignored. These tags should be ignored from the tokenizer
|
|
||||||
// properly.
|
|
||||||
p.tokenizer.NextIsNotRawText()
|
|
||||||
// Ignore the token.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
case EndTagToken:
|
|
||||||
switch p.tok.DataAtom {
|
|
||||||
case a.Option:
|
|
||||||
if p.top().DataAtom == a.Option {
|
|
||||||
p.oe.pop()
|
|
||||||
}
|
|
||||||
case a.Optgroup:
|
|
||||||
i := len(p.oe) - 1
|
|
||||||
if p.oe[i].DataAtom == a.Option {
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
if p.oe[i].DataAtom == a.Optgroup {
|
|
||||||
p.oe = p.oe[:i]
|
|
||||||
}
|
|
||||||
case a.Select:
|
|
||||||
if !p.popUntil(selectScope, a.Select) {
|
|
||||||
// Ignore the token.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
p.resetInsertionMode()
|
|
||||||
case a.Template:
|
|
||||||
return inHeadIM(p)
|
|
||||||
}
|
|
||||||
case CommentToken:
|
|
||||||
p.addChild(&Node{
|
|
||||||
Type: CommentNode,
|
|
||||||
Data: p.tok.Data,
|
|
||||||
})
|
|
||||||
case DoctypeToken:
|
|
||||||
// Ignore the token.
|
|
||||||
return true
|
|
||||||
case ErrorToken:
|
|
||||||
return inBodyIM(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section 12.2.6.4.17.
|
|
||||||
func inSelectInTableIM(p *parser) bool {
|
|
||||||
switch p.tok.Type {
|
|
||||||
case StartTagToken, EndTagToken:
|
|
||||||
switch p.tok.DataAtom {
|
|
||||||
case a.Caption, a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr, a.Td, a.Th:
|
|
||||||
if p.tok.Type == EndTagToken && !p.elementInScope(tableScope, p.tok.DataAtom) {
|
|
||||||
// Ignore the token.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// This is like p.popUntil(selectScope, a.Select), but it also
|
|
||||||
// matches <math select>, not just <select>. Matching the MathML
|
|
||||||
// tag is arguably incorrect (conceptually), but it mimics what
|
|
||||||
// Chromium does.
|
|
||||||
for i := len(p.oe) - 1; i >= 0; i-- {
|
|
||||||
if n := p.oe[i]; n.DataAtom == a.Select {
|
|
||||||
p.oe = p.oe[:i]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p.resetInsertionMode()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return inSelectIM(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section 12.2.6.4.18.
|
// Section 12.2.6.4.18.
|
||||||
func inTemplateIM(p *parser) bool {
|
func inTemplateIM(p *parser) bool {
|
||||||
switch p.tok.Type {
|
switch p.tok.Type {
|
||||||
@@ -2174,7 +2061,7 @@ func ignoreTheRemainingTokens(p *parser) bool {
|
|||||||
|
|
||||||
const whitespaceOrNUL = whitespace + "\x00"
|
const whitespaceOrNUL = whitespace + "\x00"
|
||||||
|
|
||||||
// Section 12.2.6.5
|
// Section 13.2.6.5
|
||||||
func parseForeignContent(p *parser) bool {
|
func parseForeignContent(p *parser) bool {
|
||||||
switch p.tok.Type {
|
switch p.tok.Type {
|
||||||
case TextToken:
|
case TextToken:
|
||||||
@@ -2189,28 +2076,26 @@ func parseForeignContent(p *parser) bool {
|
|||||||
Data: p.tok.Data,
|
Data: p.tok.Data,
|
||||||
})
|
})
|
||||||
case StartTagToken:
|
case StartTagToken:
|
||||||
if !p.fragment {
|
b := breakout[p.tok.Data]
|
||||||
b := breakout[p.tok.Data]
|
if p.tok.DataAtom == a.Font {
|
||||||
if p.tok.DataAtom == a.Font {
|
loop:
|
||||||
loop:
|
for _, attr := range p.tok.Attr {
|
||||||
for _, attr := range p.tok.Attr {
|
switch attr.Key {
|
||||||
switch attr.Key {
|
case "color", "face", "size":
|
||||||
case "color", "face", "size":
|
b = true
|
||||||
b = true
|
break loop
|
||||||
break loop
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if b {
|
}
|
||||||
for i := len(p.oe) - 1; i >= 0; i-- {
|
if b {
|
||||||
n := p.oe[i]
|
for i := len(p.oe) - 1; i >= 0; i-- {
|
||||||
if n.Namespace == "" || htmlIntegrationPoint(n) || mathMLTextIntegrationPoint(n) {
|
n := p.oe[i]
|
||||||
p.oe = p.oe[:i+1]
|
if n.Namespace == "" || htmlIntegrationPoint(n) || mathMLTextIntegrationPoint(n) {
|
||||||
break
|
p.oe = p.oe[:i+1]
|
||||||
}
|
break
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
return p.im(p)
|
||||||
}
|
}
|
||||||
current := p.adjustedCurrentNode()
|
current := p.adjustedCurrentNode()
|
||||||
switch current.Namespace {
|
switch current.Namespace {
|
||||||
|
|||||||
+36
-5
@@ -704,7 +704,11 @@ func (z *Tokenizer) readMarkupDeclaration() TokenType {
|
|||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
c[i] = z.readByte()
|
c[i] = z.readByte()
|
||||||
if z.err != nil {
|
if z.err != nil {
|
||||||
|
// bogus comment
|
||||||
z.data.end = z.raw.end
|
z.data.end = z.raw.end
|
||||||
|
if i == 1 && c[0] == '>' {
|
||||||
|
z.data.end--
|
||||||
|
}
|
||||||
return CommentToken
|
return CommentToken
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -732,6 +736,13 @@ func (z *Tokenizer) readDoctype() bool {
|
|||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
c := z.readByte()
|
c := z.readByte()
|
||||||
if z.err != nil {
|
if z.err != nil {
|
||||||
|
if z.err == io.EOF {
|
||||||
|
// Back up to read the fragment of "DOCTYPE" again, reset
|
||||||
|
// z.err to signal EOF on the next call
|
||||||
|
z.raw.end = z.data.start
|
||||||
|
z.err = nil
|
||||||
|
return false
|
||||||
|
}
|
||||||
z.data.end = z.raw.end
|
z.data.end = z.raw.end
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -757,6 +768,13 @@ func (z *Tokenizer) readCDATA() bool {
|
|||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
c := z.readByte()
|
c := z.readByte()
|
||||||
if z.err != nil {
|
if z.err != nil {
|
||||||
|
if z.err == io.EOF {
|
||||||
|
// Back up to read the fragment of "[CDATA[" again, reset
|
||||||
|
// z.err to signal EOF on the next call
|
||||||
|
z.raw.end = z.data.start
|
||||||
|
z.err = nil
|
||||||
|
return false
|
||||||
|
}
|
||||||
z.data.end = z.raw.end
|
z.data.end = z.raw.end
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -883,7 +901,7 @@ func (z *Tokenizer) readTag(saveAttr bool) {
|
|||||||
z.readTagAttrKey()
|
z.readTagAttrKey()
|
||||||
z.readTagAttrVal()
|
z.readTagAttrVal()
|
||||||
// Save pendingAttr if saveAttr and that attribute has a non-empty key, and the key hasn't been seen before.
|
// Save pendingAttr if saveAttr and that attribute has a non-empty key, and the key hasn't been seen before.
|
||||||
key := strings.ToLower(string(z.buf[z.pendingAttr[0].start:z.pendingAttr[0].end]))
|
key := string(lower(bytes.Clone(z.buf[z.pendingAttr[0].start:z.pendingAttr[0].end])))
|
||||||
if saveAttr && z.pendingAttr[0].start != z.pendingAttr[0].end && !z.attrNames[key] {
|
if saveAttr && z.pendingAttr[0].start != z.pendingAttr[0].end && !z.attrNames[key] {
|
||||||
z.attr = append(z.attr, z.pendingAttr)
|
z.attr = append(z.attr, z.pendingAttr)
|
||||||
z.attrNames[key] = true
|
z.attrNames[key] = true
|
||||||
@@ -1206,7 +1224,7 @@ func (z *Tokenizer) TagName() (name []byte, hasAttr bool) {
|
|||||||
if z.data.start < z.data.end {
|
if z.data.start < z.data.end {
|
||||||
switch z.tt {
|
switch z.tt {
|
||||||
case StartTagToken, EndTagToken, SelfClosingTagToken:
|
case StartTagToken, EndTagToken, SelfClosingTagToken:
|
||||||
s := z.buf[z.data.start:z.data.end]
|
s := bytes.ReplaceAll(z.buf[z.data.start:z.data.end], nul, replacement)
|
||||||
z.data.start = z.raw.end
|
z.data.start = z.raw.end
|
||||||
z.data.end = z.raw.end
|
z.data.end = z.raw.end
|
||||||
return lower(s), z.nAttrReturned < len(z.attr)
|
return lower(s), z.nAttrReturned < len(z.attr)
|
||||||
@@ -1224,8 +1242,8 @@ func (z *Tokenizer) TagAttr() (key, val []byte, moreAttr bool) {
|
|||||||
case StartTagToken, SelfClosingTagToken:
|
case StartTagToken, SelfClosingTagToken:
|
||||||
x := z.attr[z.nAttrReturned]
|
x := z.attr[z.nAttrReturned]
|
||||||
z.nAttrReturned++
|
z.nAttrReturned++
|
||||||
key = z.buf[x[0].start:x[0].end]
|
key = bytes.ReplaceAll(z.buf[x[0].start:x[0].end], nul, replacement)
|
||||||
val = z.buf[x[1].start:x[1].end]
|
val = bytes.ReplaceAll(z.buf[x[1].start:x[1].end], nul, replacement)
|
||||||
return lower(key), unescape(convertNewlines(val), true), z.nAttrReturned < len(z.attr)
|
return lower(key), unescape(convertNewlines(val), true), z.nAttrReturned < len(z.attr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1282,9 +1300,22 @@ func NewTokenizerFragment(r io.Reader, contextTag string) *Tokenizer {
|
|||||||
attrNames: make(map[string]bool),
|
attrNames: make(map[string]bool),
|
||||||
}
|
}
|
||||||
if contextTag != "" {
|
if contextTag != "" {
|
||||||
|
// Per the "Parsing HTML Fragments" portion of the spec:
|
||||||
|
// For performance reasons, an implementation that does not report errors
|
||||||
|
// and that uses the actual state machine described in this specification
|
||||||
|
// directly could use the PLAINTEXT state instead of the RAWTEXT and script
|
||||||
|
// data states where those are mentioned in the list above. Except for
|
||||||
|
// rules regarding parse errors, they are equivalent, since there is no
|
||||||
|
// appropriate end tag token in the fragment case, yet they involve far
|
||||||
|
// fewer state transitions.
|
||||||
|
//
|
||||||
|
// As such we just set everything to plaintext, which makes some complex parsing
|
||||||
|
// cases somewhat simpler.
|
||||||
switch s := strings.ToLower(contextTag); s {
|
switch s := strings.ToLower(contextTag); s {
|
||||||
case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "title", "textarea", "xmp":
|
case "title", "textarea":
|
||||||
z.rawTag = s
|
z.rawTag = s
|
||||||
|
case "style", "xmp", "iframe", "noembed", "noframes", "script", "noscript", "plaintext":
|
||||||
|
z.rawTag = "plaintext"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return z
|
return z
|
||||||
|
|||||||
+16
@@ -10,9 +10,11 @@ package http2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"slices"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -44,6 +46,20 @@ func configureServer(s *http.Server, conf *Server) error {
|
|||||||
h2.IdleTimeout = h1.ReadTimeout
|
h2.IdleTimeout = h1.ReadTimeout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register h2 and http/1.1 ALPN protocols on s.TLSConfig, matching
|
||||||
|
// the pre-wrapping implementation in server.go, so that TLS listeners
|
||||||
|
// built from s.TLSConfig still negotiate HTTP/2.
|
||||||
|
if s.TLSConfig == nil {
|
||||||
|
s.TLSConfig = new(tls.Config)
|
||||||
|
}
|
||||||
|
if !slices.Contains(s.TLSConfig.NextProtos, NextProtoTLS) {
|
||||||
|
s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS)
|
||||||
|
}
|
||||||
|
if !slices.Contains(s.TLSConfig.NextProtos, "http/1.1") {
|
||||||
|
s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "http/1.1")
|
||||||
|
}
|
||||||
|
|
||||||
conf.state = &serverInternalState{
|
conf.state = &serverInternalState{
|
||||||
s1: s,
|
s1: s,
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-2
@@ -22,8 +22,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func configureTransport(t1 *http.Transport) error {
|
func configureTransport(t1 *http.Transport) error {
|
||||||
// ConfigureTransport is a no-op: The http.Transport already supports HTTP/2.
|
_, err := configureTransports(t1)
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureTransports(t1 *http.Transport) (*Transport, error) {
|
func configureTransports(t1 *http.Transport) (*Transport, error) {
|
||||||
@@ -31,6 +31,17 @@ func configureTransports(t1 *http.Transport) (*Transport, error) {
|
|||||||
// linked to the http.Transport's.
|
// linked to the http.Transport's.
|
||||||
tr2 := &Transport{}
|
tr2 := &Transport{}
|
||||||
tr2.configure(t1)
|
tr2.configure(t1)
|
||||||
|
// Enable HTTP/2 on the transport, as the pre-wrapping implementation did:
|
||||||
|
// net/http does not auto-enable it for a transport with a custom
|
||||||
|
// TLSClientConfig or dialer.
|
||||||
|
if t1.TLSClientConfig == nil {
|
||||||
|
t1.TLSClientConfig = &tls.Config{}
|
||||||
|
}
|
||||||
|
if t1.Protocols == nil {
|
||||||
|
t1.Protocols = new(http.Protocols)
|
||||||
|
t1.Protocols.SetHTTP1(true)
|
||||||
|
}
|
||||||
|
t1.Protocols.SetHTTP2(true)
|
||||||
return tr2, nil
|
return tr2, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1340,7 +1340,7 @@ golang.org/x/mod/internal/lazyregexp
|
|||||||
golang.org/x/mod/module
|
golang.org/x/mod/module
|
||||||
golang.org/x/mod/semver
|
golang.org/x/mod/semver
|
||||||
golang.org/x/mod/sumdb/note
|
golang.org/x/mod/sumdb/note
|
||||||
# golang.org/x/net v0.55.0
|
# golang.org/x/net v0.56.0
|
||||||
## explicit; go 1.25.0
|
## explicit; go 1.25.0
|
||||||
golang.org/x/net/html
|
golang.org/x/net/html
|
||||||
golang.org/x/net/html/atom
|
golang.org/x/net/html/atom
|
||||||
|
|||||||
Reference in New Issue
Block a user