diff --git a/contrib/update_dependencies.sh b/contrib/update_dependencies.sh old mode 100644 new mode 100755 diff --git a/go.mod b/go.mod index 0b773b3c65..5032acce99 100644 --- a/go.mod +++ b/go.mod @@ -80,7 +80,7 @@ require ( github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mattn/go-sqlite3 v1.14.7 github.com/mholt/archiver/v3 v3.5.0 - github.com/microcosm-cc/bluemonday v1.0.14 + github.com/microcosm-cc/bluemonday v1.0.15 github.com/miekg/dns v1.1.43 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/minio-go/v7 v7.0.12 diff --git a/go.sum b/go.sum index dcdba019d4..fc6e2422c8 100644 --- a/go.sum +++ b/go.sum @@ -795,8 +795,8 @@ github.com/mholt/acmez v0.1.3 h1:J7MmNIk4Qf9b8mAGqAh4XkNeowv3f1zW816yf4zt7Qk= github.com/mholt/acmez v0.1.3/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM= github.com/mholt/archiver/v3 v3.5.0 h1:nE8gZIrw66cu4osS/U7UW7YDuGMHssxKutU8IfWxwWE= github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc= -github.com/microcosm-cc/bluemonday v1.0.14 h1:Djd+GeTanVeA23todvVC0AO5hsI+vAwQMLTy794Zr5I= -github.com/microcosm-cc/bluemonday v1.0.14/go.mod h1:beubO5lmWoy1tU8niaMyXNriNgROO37H3U/tsrcZsy0= +github.com/microcosm-cc/bluemonday v1.0.15 h1:J4uN+qPng9rvkBZBoBb8YGR+ijuklIMpSOZZLjYpbeY= +github.com/microcosm-cc/bluemonday v1.0.15/go.mod h1:ZLvAzeakRwrGnzQEvstVzVt3ZpqOF2+sdFr0Om+ce30= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.42/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= @@ -1235,7 +1235,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210331060903-cb1fcc7394e5/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index a494c5bd18..dff9102bed 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -138,13 +138,13 @@ func TestRender_links(t *testing.T) { `

http://www.example.com/wpstyle/?p=364

`) test( "https://www.example.com/foo/?bar=baz&inga=42&quux", - `

https://www.example.com/foo/?bar=baz&inga=42&quux

`) + `

https://www.example.com/foo/?bar=baz&inga=42&quux

`) test( "http://142.42.1.1/", `

http://142.42.1.1/

`) test( "https://github.com/go-gitea/gitea/?p=aaa/bbb.html#ccc-ddd", - `

https://github.com/go-gitea/gitea/?p=aaa/bbb.html#ccc-ddd

`) + `

https://github.com/go-gitea/gitea/?p=aaa/bbb.html#ccc-ddd

`) test( "https://en.wikipedia.org/wiki/URL_(disambiguation)", `

https://en.wikipedia.org/wiki/URL_(disambiguation)

`) @@ -162,7 +162,7 @@ func TestRender_links(t *testing.T) { `

ftp://gitea.com/file.txt

`) test( "magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcadabcde&dn=download", - `

magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcadabcde&dn=download

`) + `

magnet:?xt=urn:btih:5dee65101db281ac9c46344cd6b175cdcadabcde&dn=download

`) // Test that should *not* be turned into URL test( diff --git a/vendor/github.com/microcosm-cc/bluemonday/CONTRIBUTING.md b/vendor/github.com/microcosm-cc/bluemonday/CONTRIBUTING.md index d2b12302f9..1d4b244345 100644 --- a/vendor/github.com/microcosm-cc/bluemonday/CONTRIBUTING.md +++ b/vendor/github.com/microcosm-cc/bluemonday/CONTRIBUTING.md @@ -9,6 +9,7 @@ Third-party patches are essential for keeping bluemonday secure and offering the ## Guidelines 1. Do not vendor dependencies. As a security package, were we to vendor dependencies the projects that then vendor bluemonday may not receive the latest security updates to the dependencies. By not vendoring dependencies the project that implements bluemonday will vendor the latest version of any dependent packages. Vendoring is a project problem, not a package problem. bluemonday will be tested against the latest version of dependencies periodically and during any PR/merge. +2. I do not care about spelling mistakes or whitespace and I do not believe that you should either. PRs therefore must be functional in their nature or be substantial and impactful if documentation or examples. ## Submitting an Issue diff --git a/vendor/github.com/microcosm-cc/bluemonday/go.mod b/vendor/github.com/microcosm-cc/bluemonday/go.mod index 02cf2eac30..0e9028a62f 100644 --- a/vendor/github.com/microcosm-cc/bluemonday/go.mod +++ b/vendor/github.com/microcosm-cc/bluemonday/go.mod @@ -3,7 +3,8 @@ module github.com/microcosm-cc/bluemonday go 1.16 require ( + github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d github.com/aymerick/douceur v0.2.0 github.com/gorilla/css v1.0.0 // indirect - golang.org/x/net v0.0.0-20210610132358-84b48f89b13b + golang.org/x/net v0.0.0-20210614182718-04defd469f4e ) diff --git a/vendor/github.com/microcosm-cc/bluemonday/go.sum b/vendor/github.com/microcosm-cc/bluemonday/go.sum index 930d271e36..049d51658e 100644 --- a/vendor/github.com/microcosm-cc/bluemonday/go.sum +++ b/vendor/github.com/microcosm-cc/bluemonday/go.sum @@ -1,3 +1,5 @@ +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= @@ -6,6 +8,8 @@ golang.org/x/net v0.0.0-20210421230115-4e50805a0758 h1:aEpZnXcAmXkd6AvLb2OPt+EN1 golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b h1:k+E048sYJHyVnsr1GDrRZWQ32D2C7lWs9JRc0bel53A= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/vendor/github.com/microcosm-cc/bluemonday/sanitize.go b/vendor/github.com/microcosm-cc/bluemonday/sanitize.go index 9bb87a6879..5f4b60d714 100644 --- a/vendor/github.com/microcosm-cc/bluemonday/sanitize.go +++ b/vendor/github.com/microcosm-cc/bluemonday/sanitize.go @@ -130,7 +130,7 @@ func escapeUrlComponent(w stringWriterWriter, val string) error { return err } -// Query represents a query +// Query represents a single part of the query string, a query param type Query struct { Key string Value string @@ -138,6 +138,10 @@ type Query struct { } func parseQuery(query string) (values []Query, err error) { + // This is essentially a copy of parseQuery from + // https://golang.org/src/net/url/url.go but adjusted to build our values + // based on our type, which we need to preserve the ordering of the query + // string for query != "" { key := query if i := strings.IndexAny(key, "&;"); i >= 0 { @@ -213,43 +217,6 @@ func sanitizedURL(val string) (string, error) { return u.String(), nil } -func (p *Policy) writeLinkableBuf(buff stringWriterWriter, token *html.Token) (int, error) { - // do not escape multiple query parameters - tokenBuff := bytes.NewBuffer(make([]byte, 0, 1024)) // This should stay on the stack unless it gets too big - - tokenBuff.WriteByte('<') - tokenBuff.WriteString(token.Data) - for _, attr := range token.Attr { - tokenBuff.WriteByte(' ') - tokenBuff.WriteString(attr.Key) - tokenBuff.Write([]byte{'=', '"'}) - switch attr.Key { - case "href", "src": - u, ok := p.validURL(attr.Val) - if !ok { - tokenBuff.WriteString(html.EscapeString(attr.Val)) - continue - } - u, err := sanitizedURL(u) - if err == nil { - tokenBuff.WriteString(u) - } else { - // fallthrough - tokenBuff.WriteString(html.EscapeString(attr.Val)) - } - default: - // re-apply - tokenBuff.WriteString(html.EscapeString(attr.Val)) - } - tokenBuff.WriteByte('"') - } - if token.Type == html.SelfClosingTagToken { - tokenBuff.WriteString("/") - } - tokenBuff.WriteString(">") - return buff.Write(tokenBuff.Bytes()) -} - // Performs the actual sanitization process. func (p *Policy) sanitizeWithBuff(r io.Reader) *bytes.Buffer { var buff bytes.Buffer @@ -344,7 +311,9 @@ func (p *Policy) sanitize(r io.Reader, w io.Writer) error { aps = aa } if len(token.Attr) != 0 { - token.Attr = p.sanitizeAttrs(token.Data, token.Attr, aps) + token.Attr = escapeAttributes( + p.sanitizeAttrs(token.Data, token.Attr, aps), + ) } if len(token.Attr) == 0 { @@ -361,15 +330,8 @@ func (p *Policy) sanitize(r io.Reader, w io.Writer) error { } if !skipElementContent { - // do not escape multiple query parameters - if linkable(token.Data) { - if _, err := p.writeLinkableBuf(buff, &token); err != nil { - return err - } - } else { - if _, err := buff.WriteString(token.String()); err != nil { - return err - } + if _, err := buff.WriteString(token.String()); err != nil { + return err } } @@ -439,7 +401,7 @@ func (p *Policy) sanitize(r io.Reader, w io.Writer) error { } if len(token.Attr) != 0 { - token.Attr = p.sanitizeAttrs(token.Data, token.Attr, aps) + token.Attr = escapeAttributes(p.sanitizeAttrs(token.Data, token.Attr, aps)) } if len(token.Attr) == 0 && !p.allowNoAttrs(token.Data) { @@ -451,15 +413,8 @@ func (p *Policy) sanitize(r io.Reader, w io.Writer) error { } } if !skipElementContent { - // do not escape multiple query parameters - if linkable(token.Data) { - if _, err := p.writeLinkableBuf(buff, &token); err != nil { - return err - } - } else { - if _, err := buff.WriteString(token.String()); err != nil { - return err - } + if _, err := buff.WriteString(token.String()); err != nil { + return err } } @@ -569,9 +524,11 @@ attrsLoop: for _, ap := range apl { if ap.regexp != nil { if ap.regexp.MatchString(htmlAttr.Val) { + htmlAttr.Val = escapeAttribute(htmlAttr.Val) cleanAttrs = append(cleanAttrs, htmlAttr) } } else { + htmlAttr.Val = escapeAttribute(htmlAttr.Val) cleanAttrs = append(cleanAttrs, htmlAttr) } } @@ -1087,3 +1044,18 @@ func normaliseElementName(str string) string { `"`, ) } + +func escapeAttributes(attrs []html.Attribute) []html.Attribute { + escapedAttrs := []html.Attribute{} + for _, attr := range attrs { + attr.Val = escapeAttribute(attr.Val) + escapedAttrs = append(escapedAttrs, attr) + } + return escapedAttrs +} + +func escapeAttribute(val string) string { + val = strings.Replace(val, string([]rune{'\u00A0'}), ` `, -1) + val = strings.Replace(val, `"`, `"`, -1) + return val +} \ No newline at end of file diff --git a/vendor/modules.txt b/vendor/modules.txt index 883b0189e4..41b6e2199f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -604,7 +604,7 @@ github.com/mholt/acmez/acme # github.com/mholt/archiver/v3 v3.5.0 ## explicit github.com/mholt/archiver/v3 -# github.com/microcosm-cc/bluemonday v1.0.14 +# github.com/microcosm-cc/bluemonday v1.0.15 ## explicit github.com/microcosm-cc/bluemonday github.com/microcosm-cc/bluemonday/css