summaryrefslogtreecommitdiffstats
path: root/vendor/github.com
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2020-12-29 00:28:27 +0800
committerGitHub <noreply@github.com>2020-12-29 00:28:27 +0800
commit11555d850b0b5977d49b458db2be6305fe4f645d (patch)
treed75468bf043878f67298f91e2b5376c2315e9538 /vendor/github.com
parent3175d08626232e85df64bec95fa62aac227e252a (diff)
downloadgitea-11555d850b0b5977d49b458db2be6305fe4f645d.tar.gz
gitea-11555d850b0b5977d49b458db2be6305fe4f645d.zip
Fix bug of link query order on markdown render (#14156)
* Fix bug of link query order on markdown render * Fix bluemonday bug and fix one wrong test Co-authored-by: 6543 <6543@obermui.de>
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/microcosm-cc/bluemonday/sanitize.go79
1 files changed, 68 insertions, 11 deletions
diff --git a/vendor/github.com/microcosm-cc/bluemonday/sanitize.go b/vendor/github.com/microcosm-cc/bluemonday/sanitize.go
index 103f39f6e5..a58333aa65 100644
--- a/vendor/github.com/microcosm-cc/bluemonday/sanitize.go
+++ b/vendor/github.com/microcosm-cc/bluemonday/sanitize.go
@@ -122,22 +122,79 @@ func escapeUrlComponent(val string) string {
return w.String()
}
-func sanitizedUrl(val string) (string, error) {
+// Query represents a query
+type Query struct {
+ Key string
+ Value string
+}
+
+func parseQuery(query string) (values []Query, err error) {
+ for query != "" {
+ key := query
+ if i := strings.IndexAny(key, "&;"); i >= 0 {
+ key, query = key[:i], key[i+1:]
+ } else {
+ query = ""
+ }
+ if key == "" {
+ continue
+ }
+ value := ""
+ if i := strings.Index(key, "="); i >= 0 {
+ key, value = key[:i], key[i+1:]
+ }
+ key, err1 := url.QueryUnescape(key)
+ if err1 != nil {
+ if err == nil {
+ err = err1
+ }
+ continue
+ }
+ value, err1 = url.QueryUnescape(value)
+ if err1 != nil {
+ if err == nil {
+ err = err1
+ }
+ continue
+ }
+ values = append(values, Query{
+ Key: key,
+ Value: value,
+ })
+ }
+ return values, err
+}
+
+func encodeQueries(queries []Query) string {
+ var b strings.Builder
+ for i, query := range queries {
+ b.WriteString(url.QueryEscape(query.Key))
+ b.WriteString("=")
+ b.WriteString(url.QueryEscape(query.Value))
+ if i < len(queries)-1 {
+ b.WriteString("&")
+ }
+ }
+ return b.String()
+}
+
+func sanitizedURL(val string) (string, error) {
u, err := url.Parse(val)
if err != nil {
return "", err
}
+
+ // we use parseQuery but not u.Query to keep the order not change because
+ // url.Values is a map which has a random order.
+ queryValues, err := parseQuery(u.RawQuery)
+ if err != nil {
+ return "", err
+ }
// sanitize the url query params
- sanitizedQueryValues := make(url.Values, 0)
- queryValues := u.Query()
- for k, vals := range queryValues {
- sk := html.EscapeString(k)
- for _, v := range vals {
- sv := v
- sanitizedQueryValues.Add(sk, sv)
- }
+ for i, query := range queryValues {
+ queryValues[i].Key = html.EscapeString(query.Key)
}
- u.RawQuery = sanitizedQueryValues.Encode()
+ u.RawQuery = encodeQueries(queryValues)
// u.String() will also sanitize host/scheme/user/pass
return u.String(), nil
}
@@ -158,7 +215,7 @@ func (p *Policy) writeLinkableBuf(buff *bytes.Buffer, token *html.Token) {
tokenBuff.WriteString(html.EscapeString(attr.Val))
continue
}
- u, err := sanitizedUrl(u)
+ u, err := sanitizedURL(u)
if err == nil {
tokenBuff.WriteString(u)
} else {