Skip to content

Commit f6787c6

Browse files
authored
Merge pull request #175 from yardenshoham/url-regexp
Allow custom URL schemes by matching regex
2 parents c506024 + e8dc3b7 commit f6787c6

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

policy.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ type Policy struct {
117117
// returning true are allowed.
118118
allowURLSchemes map[string][]urlPolicy
119119

120+
// These regexps are used to match allowed URL schemes, for example
121+
// if one would want to allow all URL schemes, they would add `.+`
122+
allowURLSchemeRegexps []*regexp.Regexp
123+
120124
// If an element has had all attributes removed as a result of a policy
121125
// being applied, then the element would be removed from the output.
122126
//
@@ -221,6 +225,7 @@ func (p *Policy) init() {
221225
p.elsMatchingAndStyles = make(map[*regexp.Regexp]map[string][]stylePolicy)
222226
p.globalStyles = make(map[string][]stylePolicy)
223227
p.allowURLSchemes = make(map[string][]urlPolicy)
228+
p.allowURLSchemeRegexps = make([]*regexp.Regexp, 0)
224229
p.setOfElementsAllowedWithoutAttrs = make(map[string]struct{})
225230
p.setOfElementsToSkipContent = make(map[string]struct{})
226231
p.initialized = true
@@ -563,6 +568,13 @@ func (p *Policy) AllowElementsMatching(regex *regexp.Regexp) *Policy {
563568
return p
564569
}
565570

571+
// AllowURLSchemesMatching will append URL schemes to the allowlist if they
572+
// match a regexp.
573+
func (p *Policy) AllowURLSchemesMatching(r *regexp.Regexp) *Policy {
574+
p.allowURLSchemeRegexps = append(p.allowURLSchemeRegexps, r)
575+
return p
576+
}
577+
566578
// RequireNoFollowOnLinks will result in all a, area, link tags having a
567579
// rel="nofollow"added to them if one does not already exist
568580
//

sanitize.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,11 @@ func (p *Policy) validURL(rawurl string) (string, bool) {
970970
}
971971

972972
if u.Scheme != "" {
973+
for _, r := range p.allowURLSchemeRegexps {
974+
if r.MatchString(u.Scheme) {
975+
return u.String(), true
976+
}
977+
}
973978

974979
urlPolicies, ok := p.allowURLSchemes[u.Scheme]
975980
if !ok {

sanitize_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3985,3 +3985,26 @@ func TestIssue171(t *testing.T) {
39853985
expected)
39863986
}
39873987
}
3988+
3989+
func TestIssue174(t *testing.T) {
3990+
// https://github.com/microcosm-cc/bluemonday/issues/174
3991+
//
3992+
// Allow all URL schemes
3993+
p := UGCPolicy()
3994+
p.AllowURLSchemesMatching(regexp.MustCompile(`.+`))
3995+
3996+
input := `<a href="cbthunderlink://somebase64string"></a>
3997+
<a href="matrix:roomid/psumPMeAfzgAeQpXMG:feneas.org?action=join"></a>
3998+
<a href="https://github.com"></a>`
3999+
out := p.Sanitize(input)
4000+
expected := `<a href="cbthunderlink://somebase64string" rel="nofollow"></a>
4001+
<a href="matrix:roomid/psumPMeAfzgAeQpXMG:feneas.org?action=join" rel="nofollow"></a>
4002+
<a href="https://github.com" rel="nofollow"></a>`
4003+
if out != expected {
4004+
t.Errorf(
4005+
"test failed;\ninput : %s\noutput : %s\nexpected: %s",
4006+
input,
4007+
out,
4008+
expected)
4009+
}
4010+
}

0 commit comments

Comments
 (0)