New Upstream Release - golang-github-mmcdole-goxpp
Ready changes
Summary
Merged new upstream version: 0.0~git20230228.1430f15 (was: 0.0~git20221210.1ba3125).
Resulting package
Built on 2023-03-24T17:03 (took 4m4s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-releases golang-github-mmcdole-goxpp-dev
Lintian Result
Diff
diff --git a/debian/changelog b/debian/changelog
index 99e3358..b4eb371 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+golang-github-mmcdole-goxpp (0.0~git20230228.1430f15-1) UNRELEASED; urgency=low
+
+ * New upstream snapshot.
+ * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk> Fri, 24 Mar 2023 16:59:58 -0000
+
golang-github-mmcdole-goxpp (0.0~git20200921.2f3784f-2) unstable; urgency=medium
[ Aloïs Micard ]
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..3eefeee
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,11 @@
+module github.com/mmcdole/goxpp
+
+go 1.19
+
+require github.com/stretchr/testify v1.8.1
+
+require (
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..2ec90f7
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,17 @@
+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=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/xpp.go b/xpp.go
index a319468..ae4d135 100644
--- a/xpp.go
+++ b/xpp.go
@@ -5,12 +5,15 @@ import (
"errors"
"fmt"
"io"
+ "net/url"
"strings"
)
type XMLEventType int
type CharsetReader func(charset string, input io.Reader) (io.Reader, error)
+const xmlNSURI = "http://www.w3.org/XML/1998/namespace"
+
const (
StartDocument XMLEventType = iota
EndDocument
@@ -24,10 +27,33 @@ const (
// TODO: CDSECT ?
)
+type urlStack []*url.URL
+
+func (s *urlStack) push(u *url.URL) {
+ *s = append([]*url.URL{u}, *s...)
+}
+
+func (s *urlStack) pop() *url.URL {
+ if s == nil || len(*s) == 0 {
+ return nil
+ }
+ var top *url.URL
+ top, *s = (*s)[0], (*s)[1:]
+ return top
+}
+
+func (s *urlStack) Top() *url.URL {
+ if s == nil || len(*s) == 0 {
+ return nil
+ }
+ return (*s)[0]
+}
+
type XMLPullParser struct {
// Document State
Spaces map[string]string
SpacesStack []map[string]string
+ BaseStack urlStack
// Token State
Depth int
@@ -214,6 +240,7 @@ func (p *XMLPullParser) DecodeElement(v interface{}) error {
p.Depth--
p.Name = name
p.token = nil
+ p.popBase()
return nil
}
@@ -263,6 +290,26 @@ func (p *XMLPullParser) EventType(t xml.Token) (event XMLEventType) {
return
}
+// resolve the given string as a URL relative to current xml:base
+func (p *XMLPullParser) XmlBaseResolveUrl(u string) (*url.URL, error) {
+ curr := p.BaseStack.Top()
+ if curr == nil {
+ return nil, nil
+ }
+
+ relURL, err := url.Parse(u)
+ if err != nil {
+ return nil, err
+ }
+ if curr.Path != "" && u != "" && curr.Path[len(curr.Path)-1] != '/' {
+ // There's no reason someone would use a path in xml:base if they
+ // didn't mean for it to be a directory
+ curr.Path = curr.Path + "/"
+ }
+ absURL := curr.ResolveReference(relURL)
+ return absURL, nil
+}
+
func (p *XMLPullParser) processToken(t xml.Token) {
switch tt := t.(type) {
case xml.StartElement:
@@ -286,6 +333,7 @@ func (p *XMLPullParser) processStartToken(t xml.StartElement) {
p.Name = t.Name.Local
p.Space = t.Name.Space
p.trackNamespaces(t)
+ p.pushBase()
}
func (p *XMLPullParser) processEndToken(t xml.EndElement) {
@@ -297,6 +345,7 @@ func (p *XMLPullParser) processEndToken(t xml.EndElement) {
p.Spaces = p.SpacesStack[len(p.SpacesStack)-1]
}
p.Name = t.Name.Local
+ p.popBase()
}
func (p *XMLPullParser) processCharDataToken(t xml.CharData) {
@@ -340,3 +389,40 @@ func (p *XMLPullParser) trackNamespaces(t xml.StartElement) {
p.Spaces = newSpace
p.SpacesStack = append(p.SpacesStack, newSpace)
}
+
+// returns the popped base URL
+func (p *XMLPullParser) popBase() string {
+ url := p.BaseStack.pop()
+ if url != nil {
+ return url.String()
+ }
+ return ""
+}
+
+// Searches current attributes for xml:base and updates the urlStack
+func (p *XMLPullParser) pushBase() error {
+ var base string
+ // search list of attrs for "xml:base"
+ for _, attr := range p.Attrs {
+ if attr.Name.Local == "base" && attr.Name.Space == xmlNSURI {
+ base = attr.Value
+ break
+ }
+ }
+ if base == "" {
+ // no base attribute found
+ return nil
+ }
+
+ newURL, err := url.Parse(base)
+ if err != nil {
+ return err
+ }
+
+ topURL := p.BaseStack.Top()
+ if topURL != nil {
+ newURL = topURL.ResolveReference(newURL)
+ }
+ p.BaseStack.push(newURL)
+ return nil
+}
diff --git a/xpp_test.go b/xpp_test.go
index 211ff67..6d9bcb4 100644
--- a/xpp_test.go
+++ b/xpp_test.go
@@ -5,7 +5,7 @@ import (
"io"
"testing"
- "github.com/mmcdole/goxpp"
+ xpp "github.com/mmcdole/goxpp"
"github.com/stretchr/testify/assert"
)
@@ -85,6 +85,37 @@ func TestDecodeElementDepth(t *testing.T) {
p.DecodeElement(&v{})
}
+func TestXMLBase(t *testing.T) {
+ crReader := func(charset string, input io.Reader) (io.Reader, error) {
+ return input, nil
+ }
+ r := bytes.NewBufferString(`<root xml:base="https://example.org/"><d2 xml:base="relative">foo</d2><d2>bar</d2></root>`)
+ p := xpp.NewXMLPullParser(r, false, crReader)
+
+ type v struct{}
+
+ // move to root
+ p.NextTag()
+ assert.Equal(t, "root", p.Name)
+ assert.Equal(t, "https://example.org/", p.BaseStack.Top().String())
+
+ // decode first <d2>
+ p.NextTag()
+ assert.Equal(t, "d2", p.Name)
+ assert.Equal(t, "https://example.org/relative", p.BaseStack.Top().String())
+
+ resolved, err := p.XmlBaseResolveUrl("test")
+ assert.NoError(t, err)
+ assert.Equal(t, "https://example.org/relative/test", resolved.String())
+ p.DecodeElement(&v{})
+
+ // decode second <d2>
+ p.NextTag()
+ assert.Equal(t, "d2", p.Name)
+ assert.Equal(t, "https://example.org/", p.BaseStack.Top().String())
+ p.DecodeElement(&v{})
+}
+
func toNextStart(t *testing.T, p *xpp.XMLPullParser) {
for {
tok, err := p.NextToken()
Debdiff
[The following lists of changes regard files as different if they have different names, permissions or owners.]
Files in second set of .debs but not in first
-rw-r--r-- root/root /usr/share/gocode/src/github.com/mmcdole/goxpp/go.mod -rw-r--r-- root/root /usr/share/gocode/src/github.com/mmcdole/goxpp/go.sum
No differences were encountered in the control files