From e1533ab274a4361c4f9b6275d141944aef83d47f Mon Sep 17 00:00:00 2001 From: Paul Lecuq Date: Fri, 17 Mar 2023 13:16:58 +0100 Subject: [PATCH] updated dependencies --- go.mod | 10 +- go.sum | 32 ++++ vendor/github.com/antchfx/xmlquery/README.md | 3 + vendor/github.com/antchfx/xmlquery/node.go | 179 ++++++++++++++---- vendor/github.com/antchfx/xmlquery/parse.go | 34 +++- vendor/github.com/antchfx/xpath/build.go | 27 ++- vendor/github.com/antchfx/xpath/parse.go | 40 ++-- vendor/github.com/antchfx/xpath/query.go | 51 +++-- vendor/github.com/antchfx/xpath/xpath.go | 17 +- vendor/golang.org/x/net/html/doc.go | 15 ++ vendor/golang.org/x/net/html/escape.go | 81 ++++++++ vendor/golang.org/x/net/html/parse.go | 2 +- vendor/golang.org/x/net/html/render.go | 2 +- vendor/golang.org/x/net/html/token.go | 59 ++++-- .../x/text/encoding/internal/internal.go | 2 +- .../internal/language/compact/language.go | 2 +- .../x/text/internal/language/language.go | 2 +- vendor/golang.org/x/text/language/language.go | 2 +- vendor/modules.txt | 8 +- 19 files changed, 472 insertions(+), 96 deletions(-) diff --git a/go.mod b/go.mod index 90b4df5..7f402a7 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module git.paulbsd.com/paulbsd/fuelprices -go 1.19 +go 1.20 require ( - github.com/antchfx/xmlquery v1.3.12 - github.com/antchfx/xpath v1.2.1 // indirect + github.com/antchfx/xmlquery v1.3.15 + github.com/antchfx/xpath v1.2.4 // indirect github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c - golang.org/x/net v0.1.0 // indirect - golang.org/x/text v0.4.0 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/text v0.8.0 // indirect gopkg.in/ini.v1 v1.67.0 ) diff --git a/go.sum b/go.sum index 3e45245..8fc99f5 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,12 @@ github.com/antchfx/xmlquery v1.3.12 h1:6TMGpdjpO/P8VhjnaYPXuqT3qyJ/VsqoyNTmJzNBTQ4= github.com/antchfx/xmlquery v1.3.12/go.mod h1:3w2RvQvTz+DaT5fSgsELkSJcdNgkmg6vuXDEuhdwsPQ= +github.com/antchfx/xmlquery v1.3.15 h1:aJConNMi1sMha5G8YJoAIF5P+H+qG1L73bSItWHo8Tw= +github.com/antchfx/xmlquery v1.3.15/go.mod h1:zMDv5tIGjOxY/JCNNinnle7V/EwthZ5IT8eeCGJKRWA= github.com/antchfx/xpath v1.2.1 h1:qhp4EW6aCOVr5XIkT+l6LJ9ck/JsUH/yyauNgTQkBF8= github.com/antchfx/xpath v1.2.1/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= +github.com/antchfx/xpath v1.2.3/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= +github.com/antchfx/xpath v1.2.4 h1:dW1HB/JxKvGtJ9WyVGJ0sIoEcqftV3SqIstujI+B9XY= +github.com/antchfx/xpath v1.2.4/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -15,16 +20,43 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/vendor/github.com/antchfx/xmlquery/README.md b/vendor/github.com/antchfx/xmlquery/README.md index f9f7a3f..ac65ddc 100644 --- a/vendor/github.com/antchfx/xmlquery/README.md +++ b/vendor/github.com/antchfx/xmlquery/README.md @@ -235,6 +235,9 @@ title.FirstChild = title_text channel.FirstChild = title fmt.Println(doc.OutputXML(true)) // W3Schools Home Page + +fmt.Println(doc.OutputXMLWithOptions(WithOutputSelf())) +// W3Schools Home Page ``` Questions diff --git a/vendor/github.com/antchfx/xmlquery/node.go b/vendor/github.com/antchfx/xmlquery/node.go index 4643695..4c77ed6 100644 --- a/vendor/github.com/antchfx/xmlquery/node.go +++ b/vendor/github.com/antchfx/xmlquery/node.go @@ -1,7 +1,6 @@ package xmlquery import ( - "bytes" "encoding/xml" "fmt" "html" @@ -50,24 +49,55 @@ type Node struct { level int // node level in the tree } +type outputConfiguration struct { + printSelf bool + preserveSpaces bool + emptyElementTagSupport bool + skipComments bool +} + +type OutputOption func(*outputConfiguration) + +// WithOutputSelf configures the Node to print the root node itself +func WithOutputSelf() OutputOption { + return func(oc *outputConfiguration) { + oc.printSelf = true + } +} + +// WithEmptyTagSupport empty tags should be written as and +// not as +func WithEmptyTagSupport() OutputOption { + return func(oc *outputConfiguration) { + oc.emptyElementTagSupport = true + } +} + +// WithoutComments will skip comments in output +func WithoutComments() OutputOption { + return func(oc *outputConfiguration) { + oc.skipComments = true + } +} + // InnerText returns the text between the start and end tags of the object. func (n *Node) InnerText() string { - var output func(*bytes.Buffer, *Node) - output = func(buf *bytes.Buffer, n *Node) { + var output func(*strings.Builder, *Node) + output = func(b *strings.Builder, n *Node) { switch n.Type { case TextNode, CharDataNode: - buf.WriteString(n.Data) + b.WriteString(n.Data) case CommentNode: default: for child := n.FirstChild; child != nil; child = child.NextSibling { - output(buf, child) + output(b, child) } } } - var buf bytes.Buffer - output(&buf, n) - return buf.String() + var b strings.Builder + output(&b, n) + return b.String() } func (n *Node) sanitizedData(preserveSpaces bool) string { @@ -86,72 +116,106 @@ func calculatePreserveSpaces(n *Node, pastValue bool) bool { return pastValue } -func outputXML(buf *bytes.Buffer, n *Node, preserveSpaces bool) { +func outputXML(b *strings.Builder, n *Node, preserveSpaces bool, config *outputConfiguration) { preserveSpaces = calculatePreserveSpaces(n, preserveSpaces) switch n.Type { case TextNode: - buf.WriteString(html.EscapeString(n.sanitizedData(preserveSpaces))) + b.WriteString(html.EscapeString(n.sanitizedData(preserveSpaces))) return case CharDataNode: - buf.WriteString("") + b.WriteString("") return case CommentNode: - buf.WriteString("") + if !config.skipComments { + b.WriteString("") + } return case DeclarationNode: - buf.WriteString("") + b.WriteString("?>") } else { - buf.WriteString(">") + if n.FirstChild != nil || !config.emptyElementTagSupport { + b.WriteString(">") + } else { + b.WriteString("/>") + return + } } for child := n.FirstChild; child != nil; child = child.NextSibling { - outputXML(buf, child, preserveSpaces) + outputXML(b, child, preserveSpaces, config) } if n.Type != DeclarationNode { if n.Prefix == "" { - buf.WriteString(fmt.Sprintf("", n.Data)) + b.WriteString(fmt.Sprintf("", n.Data)) } else { - buf.WriteString(fmt.Sprintf("", n.Prefix, n.Data)) + b.WriteString(fmt.Sprintf("", n.Prefix, n.Data)) } } } // OutputXML returns the text that including tags name. func (n *Node) OutputXML(self bool) string { + + config := &outputConfiguration{ + printSelf: true, + emptyElementTagSupport: false, + } preserveSpaces := calculatePreserveSpaces(n, false) - var buf bytes.Buffer + var b strings.Builder if self && n.Type != DocumentNode { - outputXML(&buf, n, preserveSpaces) + outputXML(&b, n, preserveSpaces, config) } else { for n := n.FirstChild; n != nil; n = n.NextSibling { - outputXML(&buf, n, preserveSpaces) + outputXML(&b, n, preserveSpaces, config) } } - return buf.String() + return b.String() +} + +// OutputXMLWithOptions returns the text that including tags name. +func (n *Node) OutputXMLWithOptions(opts ...OutputOption) string { + + config := &outputConfiguration{} + // Set the options + for _, opt := range opts { + opt(config) + } + + preserveSpaces := calculatePreserveSpaces(n, false) + var b strings.Builder + if config.printSelf && n.Type != DocumentNode { + outputXML(&b, n, preserveSpaces, config) + } else { + for n := n.FirstChild; n != nil; n = n.NextSibling { + outputXML(&b, n, preserveSpaces, config) + } + } + + return b.String() } // AddAttr adds a new attribute specified by 'key' and 'val' to a node 'n'. @@ -172,6 +236,55 @@ func AddAttr(n *Node, key, val string) { n.Attr = append(n.Attr, attr) } +// SetAttr allows an attribute value with the specified name to be changed. +// If the attribute did not previously exist, it will be created. +func (n *Node) SetAttr(key, value string) { + if i := strings.Index(key, ":"); i > 0 { + space := key[:i] + local := key[i+1:] + for idx := 0; idx < len(n.Attr); idx++ { + if n.Attr[idx].Name.Space == space && n.Attr[idx].Name.Local == local { + n.Attr[idx].Value = value + return + } + } + + AddAttr(n, key, value) + } else { + for idx := 0; idx < len(n.Attr); idx++ { + if n.Attr[idx].Name.Local == key { + n.Attr[idx].Value = value + return + } + } + + AddAttr(n, key, value) + } +} + +// RemoveAttr removes the attribute with the specified name. +func (n *Node) RemoveAttr(key string) { + removeIdx := -1 + if i := strings.Index(key, ":"); i > 0 { + space := key[:i] + local := key[i+1:] + for idx := 0; idx < len(n.Attr); idx++ { + if n.Attr[idx].Name.Space == space && n.Attr[idx].Name.Local == local { + removeIdx = idx + } + } + } else { + for idx := 0; idx < len(n.Attr); idx++ { + if n.Attr[idx].Name.Local == key { + removeIdx = idx + } + } + } + if removeIdx != -1 { + n.Attr = append(n.Attr[:removeIdx], n.Attr[removeIdx+1:]...) + } +} + // AddChild adds a new node 'n' to a node 'parent' as its last child. func AddChild(parent, n *Node) { n.Parent = parent diff --git a/vendor/github.com/antchfx/xmlquery/parse.go b/vendor/github.com/antchfx/xmlquery/parse.go index 1e8f6a4..ff4bd44 100644 --- a/vendor/github.com/antchfx/xmlquery/parse.go +++ b/vendor/github.com/antchfx/xmlquery/parse.go @@ -3,7 +3,6 @@ package xmlquery import ( "bufio" "encoding/xml" - "errors" "fmt" "io" "net/http" @@ -92,23 +91,35 @@ func (p *parser) parse() (*Node, error) { case xml.StartElement: if p.level == 0 { // mising XML declaration - node := &Node{Type: DeclarationNode, Data: "xml", level: 1} + attributes := make([]Attr, 1) + attributes[0].Name = xml.Name{Local: "version"} + attributes[0].Value = "1.0" + node := &Node{ + Type: DeclarationNode, + Data: "xml", + Attr: attributes, + level: 1, + } AddChild(p.prev, node) p.level = 1 p.prev = node } // https://www.w3.org/TR/xml-names/#scoping-defaulting + var defaultNamespaceURL string for _, att := range tok.Attr { if att.Name.Local == "xmlns" { - p.space2prefix[att.Value] = "" + p.space2prefix[att.Value] = "" // reset empty if exist the default namespace + defaultNamespaceURL = att.Value } else if att.Name.Space == "xmlns" { - p.space2prefix[att.Value] = att.Name.Local + if _, ok := p.space2prefix[att.Value]; !ok { + p.space2prefix[att.Value] = att.Name.Local + } } } - if tok.Name.Space != "" { - if _, found := p.space2prefix[tok.Name.Space]; !found { - return nil, errors.New("xmlquery: invalid XML document, namespace is missing") + if space := tok.Name.Space; space != "" { + if _, found := p.space2prefix[space]; !found && p.decoder.Strict { + return nil, fmt.Errorf("xmlquery: invalid XML document, namespace %s is missing", space) } } @@ -128,7 +139,6 @@ func (p *parser) parse() (*Node, error) { node := &Node{ Type: ElementNode, Data: tok.Name.Local, - Prefix: p.space2prefix[tok.Name.Space], NamespaceURI: tok.Name.Space, Attr: attributes, level: p.level, @@ -144,6 +154,14 @@ func (p *parser) parse() (*Node, error) { } AddSibling(p.prev.Parent, node) } + if node.NamespaceURI != "" { + node.Prefix = p.space2prefix[node.NamespaceURI] + if defaultNamespaceURL != "" && node.NamespaceURI == defaultNamespaceURL { + node.Prefix = "" + } else if n := node.Parent; n != nil && node.NamespaceURI == n.NamespaceURI { + node.Prefix = n.Prefix + } + } // If we're in the streaming mode, we need to remember the node if it is the target node // so that when we finish processing the node's EndElement, we know how/what to return to // caller. Also we need to remove the target node from the tree upon next Read() call so diff --git a/vendor/github.com/antchfx/xpath/build.go b/vendor/github.com/antchfx/xpath/build.go index 10a5440..4129a21 100644 --- a/vendor/github.com/antchfx/xpath/build.go +++ b/vendor/github.com/antchfx/xpath/build.go @@ -44,6 +44,12 @@ func axisPredicate(root *axisNode) func(NodeNavigator) bool { predicate := func(n NodeNavigator) bool { if typ == n.NodeType() || typ == allNode { if nametest { + type namespaceURL interface { + NamespaceURL() string + } + if ns, ok := n.(namespaceURL); ok && root.hasNamespaceURI { + return root.LocalName == n.LocalName() && root.namespaceURI == ns.NamespaceURL() + } if root.LocalName == n.LocalName() && root.Prefix == n.Prefix() { return true } @@ -88,7 +94,10 @@ func (b *builder) processAxisNode(root *axisNode) (query, error) { } return v } - qyOutput = &descendantQuery{Input: qyGrandInput, Predicate: filter, Self: true} + // fix `//*[contains(@id,"food")]//*[contains(@id,"food")]`, see https://github.com/antchfx/htmlquery/issues/52 + // Skip the current node(Self:false) for the next descendants nodes. + _, ok := qyGrandInput.(*contextQuery) + qyOutput = &descendantQuery{Input: qyGrandInput, Predicate: filter, Self: ok} return qyOutput, nil } } @@ -347,7 +356,15 @@ func (b *builder) processFunctionNode(root *functionNode) (query, error) { }, } case "last": - qyOutput = &functionQuery{Input: b.firstInput, Func: lastFunc} + switch typ := b.firstInput.(type) { + case *groupQuery, *filterQuery: + // https://github.com/antchfx/xpath/issues/76 + // https://github.com/antchfx/xpath/issues/78 + qyOutput = &lastQuery{Input: typ} + default: + qyOutput = &functionQuery{Input: b.firstInput, Func: lastFunc} + } + case "position": qyOutput = &functionQuery{Input: b.firstInput, Func: positionFunc} case "boolean", "number", "string": @@ -511,6 +528,7 @@ func (b *builder) processNode(root node) (q query, err error) { b.firstInput = q case nodeFilter: q, err = b.processFilterNode(root.(*filterNode)) + b.firstInput = q case nodeFunction: q, err = b.processFunctionNode(root.(*functionNode)) case nodeOperator: @@ -521,12 +539,13 @@ func (b *builder) processNode(root node) (q query, err error) { return } q = &groupQuery{Input: q} + b.firstInput = q } return } // build builds a specified XPath expressions expr. -func build(expr string) (q query, err error) { +func build(expr string, namespaces map[string]string) (q query, err error) { defer func() { if e := recover(); e != nil { switch x := e.(type) { @@ -539,7 +558,7 @@ func build(expr string) (q query, err error) { } } }() - root := parse(expr) + root := parse(expr, namespaces) b := &builder{} return b.processNode(root) } diff --git a/vendor/github.com/antchfx/xpath/parse.go b/vendor/github.com/antchfx/xpath/parse.go index acb0db9..cbd289a 100644 --- a/vendor/github.com/antchfx/xpath/parse.go +++ b/vendor/github.com/antchfx/xpath/parse.go @@ -69,8 +69,9 @@ const ( ) type parser struct { - r *scanner - d int + r *scanner + d int + namespaces map[string]string } // newOperatorNode returns new operator node OperatorNode. @@ -84,8 +85,8 @@ func newOperandNode(v interface{}) node { } // newAxisNode returns new axis node AxisNode. -func newAxisNode(axeTyp, localName, prefix, prop string, n node) node { - return &axisNode{ +func newAxisNode(axeTyp, localName, prefix, prop string, n node, opts ...func(p *axisNode)) node { + a := axisNode{ nodeType: nodeAxis, LocalName: localName, Prefix: prefix, @@ -93,6 +94,10 @@ func newAxisNode(axeTyp, localName, prefix, prop string, n node) node { Prop: prop, Input: n, } + for _, o := range opts { + o(&a) + } + return &a } // newVariableNode returns new variable node VariableNode. @@ -469,7 +474,16 @@ func (p *parser) parseNodeTest(n node, axeTyp string) (opnd node) { if p.r.name == "*" { name = "" } - opnd = newAxisNode(axeTyp, name, prefix, "", n) + opnd = newAxisNode(axeTyp, name, prefix, "", n, func(a *axisNode) { + if prefix != "" && p.namespaces != nil { + if ns, ok := p.namespaces[prefix]; ok { + a.hasNamespaceURI = true + a.namespaceURI = ns + } else { + panic(fmt.Sprintf("prefix %s not defined.", prefix)) + } + } + }) } case itemStar: opnd = newAxisNode(axeTyp, "", "", "", n) @@ -531,11 +545,11 @@ func (p *parser) parseMethod(n node) node { } // Parse parsing the XPath express string expr and returns a tree node. -func parse(expr string) node { +func parse(expr string, namespaces map[string]string) node { r := &scanner{text: expr} r.nextChar() r.nextItem() - p := &parser{r: r} + p := &parser{r: r, namespaces: namespaces} return p.parseExpression(nil) } @@ -563,11 +577,13 @@ func (o *operatorNode) String() string { // axisNode holds a location step. type axisNode struct { nodeType - Input node - Prop string // node-test name.[comment|text|processing-instruction|node] - AxeType string // name of the axes.[attribute|ancestor|child|....] - LocalName string // local part name of node. - Prefix string // prefix name of node. + Input node + Prop string // node-test name.[comment|text|processing-instruction|node] + AxeType string // name of the axes.[attribute|ancestor|child|....] + LocalName string // local part name of node. + Prefix string // prefix name of node. + namespaceURI string // namespace URI of node + hasNamespaceURI bool // if namespace URI is set (can be "") } func (a *axisNode) String() string { diff --git a/vendor/github.com/antchfx/xpath/query.go b/vendor/github.com/antchfx/xpath/query.go index 6ceb033..4e6c634 100644 --- a/vendor/github.com/antchfx/xpath/query.go +++ b/vendor/github.com/antchfx/xpath/query.go @@ -56,7 +56,7 @@ func (c *contextQuery) Evaluate(iterator) interface{} { } func (c *contextQuery) Clone() query { - return &contextQuery{count: 0, Root: c.Root} + return &contextQuery{Root: c.Root} } // ancestorQuery is an XPath ancestor node query.(ancestor::*|ancestor-self::*) @@ -558,8 +558,8 @@ func (f *filterQuery) do(t iterator) bool { pt := getNodePosition(f.Input) return int(val.Float()) == pt default: - if q, ok := f.Predicate.(query); ok { - return q.Select(t) != nil + if f.Predicate != nil { + return f.Predicate.Select(t) != nil } } return false @@ -577,7 +577,7 @@ func (f *filterQuery) Select(t iterator) NodeNavigator { node := f.Input.Select(t) if node == nil { - return node + return nil } node = node.Copy() @@ -676,14 +676,12 @@ type groupQuery struct { } func (g *groupQuery) Select(t iterator) NodeNavigator { - for { - node := g.Input.Select(t) - if node == nil { - return nil - } - g.posit++ - return node.Copy() + node := g.Input.Select(t) + if node == nil { + return nil } + g.posit++ + return node } func (g *groupQuery) Evaluate(t iterator) interface{} { @@ -691,7 +689,7 @@ func (g *groupQuery) Evaluate(t iterator) interface{} { } func (g *groupQuery) Clone() query { - return &groupQuery{Input: g.Input} + return &groupQuery{Input: g.Input.Clone()} } func (g *groupQuery) position() int { @@ -896,6 +894,35 @@ func (u *unionQuery) Clone() query { return &unionQuery{Left: u.Left.Clone(), Right: u.Right.Clone()} } +type lastQuery struct { + buffer []NodeNavigator + counted bool + + Input query +} + +func (q *lastQuery) Select(t iterator) NodeNavigator { + return nil +} + +func (q *lastQuery) Evaluate(t iterator) interface{} { + if !q.counted { + for { + node := q.Input.Select(t) + if node == nil { + break + } + q.buffer = append(q.buffer, node.Copy()) + } + q.counted = true + } + return float64(len(q.buffer)) +} + +func (q *lastQuery) Clone() query { + return &lastQuery{Input: q.Input.Clone()} +} + func getHashCode(n NodeNavigator) uint64 { var sb bytes.Buffer switch n.NodeType() { diff --git a/vendor/github.com/antchfx/xpath/xpath.go b/vendor/github.com/antchfx/xpath/xpath.go index 5f6aa89..1c0a5a2 100644 --- a/vendor/github.com/antchfx/xpath/xpath.go +++ b/vendor/github.com/antchfx/xpath/xpath.go @@ -141,7 +141,7 @@ func Compile(expr string) (*Expr, error) { if expr == "" { return nil, errors.New("expr expression is nil") } - qy, err := build(expr) + qy, err := build(expr, nil) if err != nil { return nil, err } @@ -159,3 +159,18 @@ func MustCompile(expr string) *Expr { } return exp } + +// CompileWithNS compiles an XPath expression string, using given namespaces map. +func CompileWithNS(expr string, namespaces map[string]string) (*Expr, error) { + if expr == "" { + return nil, errors.New("expr expression is nil") + } + qy, err := build(expr, namespaces) + if err != nil { + return nil, err + } + if qy == nil { + return nil, fmt.Errorf(fmt.Sprintf("undeclared variable in XPath expression: %s", expr)) + } + return &Expr{s: expr, q: qy}, nil +} diff --git a/vendor/golang.org/x/net/html/doc.go b/vendor/golang.org/x/net/html/doc.go index 822ed42..7a96eae 100644 --- a/vendor/golang.org/x/net/html/doc.go +++ b/vendor/golang.org/x/net/html/doc.go @@ -92,6 +92,21 @@ example, to process each anchor node in depth-first order: The relevant specifications include: https://html.spec.whatwg.org/multipage/syntax.html and https://html.spec.whatwg.org/multipage/syntax.html#tokenization + +# Security Considerations + +Care should be taken when parsing and interpreting HTML, whether full documents +or fragments, within the framework of the HTML specification, especially with +regard to untrusted inputs. + +This package provides both a tokenizer and a parser. Only the parser constructs +a DOM according to the HTML specification, resolving malformed and misplaced +tags where appropriate. The tokenizer simply tokenizes the HTML presented to it, +and as such does not resolve issues that may exist in the processed HTML, +producing a literal interpretation of the input. + +If your use case requires semantically well-formed HTML, as defined by the +WHATWG specifiction, the parser should be used rather than the tokenizer. */ package html // import "golang.org/x/net/html" diff --git a/vendor/golang.org/x/net/html/escape.go b/vendor/golang.org/x/net/html/escape.go index d856139..04c6bec 100644 --- a/vendor/golang.org/x/net/html/escape.go +++ b/vendor/golang.org/x/net/html/escape.go @@ -193,6 +193,87 @@ func lower(b []byte) []byte { return b } +// escapeComment is like func escape but escapes its input bytes less often. +// Per https://github.com/golang/go/issues/58246 some HTML comments are (1) +// meaningful and (2) contain angle brackets that we'd like to avoid escaping +// unless we have to. +// +// "We have to" includes the '&' byte, since that introduces other escapes. +// +// It also includes those bytes (not including EOF) that would otherwise end +// the comment. Per the summary table at the bottom of comment_test.go, this is +// the '>' byte that, per above, we'd like to avoid escaping unless we have to. +// +// Studying the summary table (and T actions in its '>' column) closely, we +// only need to escape in states 43, 44, 49, 51 and 52. State 43 is at the +// start of the comment data. State 52 is after a '!'. The other three states +// are after a '-'. +// +// Our algorithm is thus to escape every '&' and to escape '>' if and only if: +// - The '>' is after a '!' or '-' (in the unescaped data) or +// - The '>' is at the start of the comment data (after the opening ""); err != nil { diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go index be3c754..5c2a1f4 100644 --- a/vendor/golang.org/x/net/html/token.go +++ b/vendor/golang.org/x/net/html/token.go @@ -110,7 +110,7 @@ func (t Token) String() string { case SelfClosingTagToken: return "<" + t.tagString() + "/>" case CommentToken: - return "" + return "" case DoctypeToken: return "" } @@ -598,6 +598,11 @@ scriptDataDoubleEscapeEnd: // readComment reads the next comment token starting with "") return } @@ -628,19 +632,52 @@ func (z *Tokenizer) readComment() { if dashCount >= 2 { c = z.readByte() if z.err != nil { - z.data.end = z.raw.end + z.data.end = z.calculateAbruptCommentDataEnd() return - } - if c == '>' { + } else if c == '>' { z.data.end = z.raw.end - len("--!>") return + } else if c == '-' { + dashCount = 1 + beginning = false + continue } } } dashCount = 0 + beginning = false } } +func (z *Tokenizer) calculateAbruptCommentDataEnd() int { + raw := z.Raw() + const prefixLen = len("