mirror of
https://github.com/documize/community.git
synced 2025-07-25 16:19:46 +02:00
Bump version to 5.11.0
This commit is contained in:
parent
a32510b8e6
commit
510e1bd0bd
370 changed files with 18825 additions and 5454 deletions
9
vendor/github.com/microcosm-cc/bluemonday/CONTRIBUTING.md
generated
vendored
9
vendor/github.com/microcosm-cc/bluemonday/CONTRIBUTING.md
generated
vendored
|
@ -10,6 +10,7 @@ Third-party patches are essential for keeping bluemonday secure and offering the
|
|||
|
||||
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.
|
||||
3. This module does not participate in hacktober, please make your contributions meaningful.
|
||||
|
||||
## Submitting an Issue
|
||||
|
||||
|
@ -45,8 +46,6 @@ We haven't gone for the formal "Sign a Contributor Licence Agreement" thing that
|
|||
|
||||
But we do need to know that we can accept and merge your contributions, so for now the act of contributing a pull request should be considered equivalent to agreeing to a contributor licence agreement, specifically:
|
||||
|
||||
You accept that the act of submitting code to the bluemonday project is to grant a copyright licence to the project that is perpetual, worldwide, non-exclusive, no-charge, royalty free and irrevocable.
|
||||
|
||||
You accept that all who comply with the licence of the project (BSD 3-clause) are permitted to use your contributions to the project.
|
||||
|
||||
You accept, and by submitting code do declare, that you have the legal right to grant such a licence to the project and that each of the contributions is your own original creation.
|
||||
* You accept that the act of submitting code to the bluemonday project is to grant a copyright licence to the project that is perpetual, worldwide, non-exclusive, no-charge, royalty free and irrevocable.
|
||||
* You accept that all who comply with the licence of the project (BSD 3-clause) are permitted to use your contributions to the project.
|
||||
* You accept, and by submitting code do declare, that you have the legal right to grant such a licence to the project and that each of the contributions is your own original creation.
|
||||
|
|
3
vendor/github.com/microcosm-cc/bluemonday/LICENSE.md
generated
vendored
3
vendor/github.com/microcosm-cc/bluemonday/LICENSE.md
generated
vendored
|
@ -1,3 +1,6 @@
|
|||
SPDX short identifier: BSD-3-Clause
|
||||
https://opensource.org/licenses/BSD-3-Clause
|
||||
|
||||
Copyright (c) 2014, David Kitchen <david@buro9.com>
|
||||
|
||||
All rights reserved.
|
||||
|
|
8
vendor/github.com/microcosm-cc/bluemonday/Makefile
generated
vendored
8
vendor/github.com/microcosm-cc/bluemonday/Makefile
generated
vendored
|
@ -6,7 +6,7 @@
|
|||
# fmt-check: Check if the source files are formated
|
||||
# build: Builds the code locally
|
||||
# vet: Vets the code
|
||||
# lint: Runs lint over the code (you do not need to fix everything)
|
||||
# staticcheck: Runs staticcheck over the code
|
||||
# test: Runs the tests
|
||||
# cover: Gives you the URL to a nice test coverage report
|
||||
#
|
||||
|
@ -33,8 +33,8 @@ build:
|
|||
vet:
|
||||
@go vet
|
||||
|
||||
lint:
|
||||
@golint *.go
|
||||
staticcheck:
|
||||
@staticcheck ./...
|
||||
|
||||
test:
|
||||
@go test -v ./...
|
||||
|
@ -42,7 +42,7 @@ test:
|
|||
cover: COVERAGE_FILE := coverage.out
|
||||
cover:
|
||||
@go test -coverprofile=$(COVERAGE_FILE) && \
|
||||
cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE)
|
||||
go tool cover -html=$(COVERAGE_FILE) && rm $(COVERAGE_FILE)
|
||||
|
||||
install:
|
||||
@go install ./...
|
||||
|
|
2
vendor/github.com/microcosm-cc/bluemonday/README.md
generated
vendored
2
vendor/github.com/microcosm-cc/bluemonday/README.md
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
# bluemonday [](https://travis-ci.org/microcosm-cc/bluemonday) [](https://godoc.org/github.com/microcosm-cc/bluemonday) [](https://sourcegraph.com/github.com/microcosm-cc/bluemonday?badge)
|
||||
# bluemonday [](https://godoc.org/github.com/microcosm-cc/bluemonday) [](https://sourcegraph.com/github.com/microcosm-cc/bluemonday?badge)
|
||||
|
||||
bluemonday is a HTML sanitizer implemented in Go. It is fast and highly configurable.
|
||||
|
||||
|
|
276
vendor/github.com/microcosm-cc/bluemonday/css/handlers.go
generated
vendored
276
vendor/github.com/microcosm-cc/bluemonday/css/handlers.go
generated
vendored
|
@ -280,6 +280,49 @@ var (
|
|||
"slategray", "slategrey", "snow", "springgreen", "steelblue", "tan",
|
||||
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
|
||||
"whitesmoke", "yellow", "yellowgreen"}
|
||||
|
||||
Alpha = regexp.MustCompile(`^[a-z]+$`)
|
||||
Blur = regexp.MustCompile(`^blur\([0-9]+px\)$`)
|
||||
BrightnessCont = regexp.MustCompile(`^(brightness|contrast)\([0-9]+\%\)$`)
|
||||
Count = regexp.MustCompile(`^[0-9]+[\.]?[0-9]*$`)
|
||||
CubicBezier = regexp.MustCompile(`^cubic-bezier\(([ ]*(0(.[0-9]+)?|1(.0)?),){3}[ ]*(0(.[0-9]+)?|1)\)$`)
|
||||
Digits = regexp.MustCompile(`^digits [2-4]$`)
|
||||
DropShadow = regexp.MustCompile(`drop-shadow\(([-]?[0-9]+px) ([-]?[0-9]+px)( [-]?[0-9]+px)?( ([-]?[0-9]+px))?`)
|
||||
Font = regexp.MustCompile(`^('[a-z \-]+'|[a-z \-]+)$`)
|
||||
Grayscale = regexp.MustCompile(`^grayscale\(([0-9]{1,2}|100)%\)$`)
|
||||
GridTemplateAreas = regexp.MustCompile(`^['"]?[a-z ]+['"]?$`)
|
||||
HexRGB = regexp.MustCompile(`^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$`)
|
||||
HSL = regexp.MustCompile(`^hsl\([ ]*([012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%\)$`)
|
||||
HSLA = regexp.MustCompile(`^hsla\(([ ]*[012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%,[ ]*(1|1\.0|0|(0\.[0-9]+))\)$`)
|
||||
HueRotate = regexp.MustCompile(`^hue-rotate\(([12]?[0-9]{1,2}|3[0-5][0-9]|360)?\)$`)
|
||||
Invert = regexp.MustCompile(`^invert\(([0-9]{1,2}|100)%\)$`)
|
||||
Length = regexp.MustCompile(`^[\-]?([0-9]+|[0-9]*[\.][0-9]+)(%|cm|mm|in|px|pt|pc|em|ex|ch|rem|vw|vh|vmin|vmax|deg|rad|turn)?$`)
|
||||
Matrix = regexp.MustCompile(`^matrix\(([ ]*[0-9]+[\.]?[0-9]*,){5}([ ]*[0-9]+[\.]?[0-9]*)\)$`)
|
||||
Matrix3D = regexp.MustCompile(`^matrix3d\(([ ]*[0-9]+[\.]?[0-9]*,){15}([ ]*[0-9]+[\.]?[0-9]*)\)$`)
|
||||
NegTime = regexp.MustCompile(`^[\-]?[0-9]+[\.]?[0-9]*(s|ms)?$`)
|
||||
Numeric = regexp.MustCompile(`^[0-9]+$`)
|
||||
NumericDecimal = regexp.MustCompile(`^[0-9\.]+$`)
|
||||
Opactiy = regexp.MustCompile(`^opacity\(([0-9]{1,2}|100)%\)$`)
|
||||
Perspective = regexp.MustCompile(`perspective\(`)
|
||||
Position = regexp.MustCompile(`^[\-]*[0-9]+[cm|mm|in|px|pt|pc\%]* [[\-]*[0-9]+[cm|mm|in|px|pt|pc\%]*]*$`)
|
||||
Opacity = regexp.MustCompile(`^(0[.]?[0-9]*)|(1.0)$`)
|
||||
QuotedAlpha = regexp.MustCompile(`^["'][a-z]+["']$`)
|
||||
Quotes = regexp.MustCompile(`^([ ]*["'][\x{0022}\x{0027}\x{2039}\x{2039}\x{203A}\x{00AB}\x{00BB}\x{2018}\x{2019}\x{201C}-\x{201E}]["'] ["'][\x{0022}\x{0027}\x{2039}\x{2039}\x{203A}\x{00AB}\x{00BB}\x{2018}\x{2019}\x{201C}-\x{201E}]["'])+$`)
|
||||
Rect = regexp.MustCompile(`^rect\([0-9]+px,[ ]*[0-9]+px,[ ]*[0-9]+px,[ ]*[0-9]+px\)$`)
|
||||
RGB = regexp.MustCompile(`^rgb\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){2}([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))))\)$`)
|
||||
RGBA = regexp.MustCompile(`^rgba\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){3}[ ]*(1(\.0)?|0|(0\.[0-9]+))\)$`)
|
||||
Rotate = regexp.MustCompile(`^rotate(x|y|z)?\(([12]?|3[0-5][0-9]|360)\)$`)
|
||||
Rotate3D = regexp.MustCompile(`^rotate3d\(([ ]?(1(\.0)?|0\.[0-9]+),){3}([12]?|3[0-5][0-9]|360)\)$`)
|
||||
Saturate = regexp.MustCompile(`^saturate\([0-9]+%\)$`)
|
||||
Sepia = regexp.MustCompile(`^sepia\(([0-9]{1,2}|100)%\)$`)
|
||||
Skew = regexp.MustCompile(`skew(x|y)?\(`)
|
||||
Span = regexp.MustCompile(`^span [0-9]+$`)
|
||||
Steps = regexp.MustCompile(`^steps\([ ]*[0-9]+([ ]*,[ ]*(start|end)?)\)$`)
|
||||
Time = regexp.MustCompile(`^[0-9]+[\.]?[0-9]*(s|ms)?$`)
|
||||
TransitionProp = regexp.MustCompile(`^([a-zA-Z]+,[ ]?)*[a-zA-Z]+$`)
|
||||
TranslateScale = regexp.MustCompile(`(translate|translate3d|translatex|translatey|translatez|scale|scale3d|scalex|scaley|scalez)\(`)
|
||||
URL = regexp.MustCompile(`^url\([\"\']?((https|http)[a-z0-9\.\\/_:]+[\"\']?)\)$`)
|
||||
ZIndex = regexp.MustCompile(`^[\-]?[0-9]+$`)
|
||||
)
|
||||
|
||||
func multiSplit(value string, seps ...string) []string {
|
||||
|
@ -323,10 +366,11 @@ func in(value []string, arr []string) bool {
|
|||
|
||||
func splitValues(value string) []string {
|
||||
values := strings.Split(value, ",")
|
||||
newValues := []string{}
|
||||
for _, strippedValue := range values {
|
||||
strippedValue = strings.ToLower(strings.TrimSpace(strippedValue))
|
||||
newValues = append(newValues, strings.ToLower(strings.TrimSpace(strippedValue)))
|
||||
}
|
||||
return values
|
||||
return newValues
|
||||
}
|
||||
|
||||
func GetDefaultHandler(attr string) func(string) bool {
|
||||
|
@ -388,9 +432,7 @@ func AnimationHandler(value string) bool {
|
|||
}
|
||||
|
||||
func AnimationDelayHandler(value string) bool {
|
||||
reg := regexp.MustCompile(`[\-]?[0-9]+[\.]?[0-9]*[s|ms]?`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if NegTime.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"initial", "inherit"}
|
||||
|
@ -405,9 +447,7 @@ func AnimationDirectionHandler(value string) bool {
|
|||
}
|
||||
|
||||
func AnimationDurationHandler(value string) bool {
|
||||
reg := regexp.MustCompile(`[0-9]+[\.]?[0-9]*[s|ms]?`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Time.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"initial", "inherit"}
|
||||
|
@ -422,9 +462,7 @@ func AnimationFillModeHandler(value string) bool {
|
|||
}
|
||||
|
||||
func AnimationIterationCountHandler(value string) bool {
|
||||
reg := regexp.MustCompile(`[0-9]+[\.]?[0-9]*`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Count.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"infinite", "initial", "inherit"}
|
||||
|
@ -433,9 +471,7 @@ func AnimationIterationCountHandler(value string) bool {
|
|||
}
|
||||
|
||||
func AnimationNameHandler(value string) bool {
|
||||
reg := regexp.MustCompile(`[a-z]+`)
|
||||
reg.Longest()
|
||||
return reg.FindString(value) == value && value != ""
|
||||
return Alpha.MatchString(value)
|
||||
}
|
||||
|
||||
func AnimationPlayStateHandler(value string) bool {
|
||||
|
@ -450,14 +486,10 @@ func TimingFunctionHandler(value string) bool {
|
|||
if in(splitVals, values) {
|
||||
return true
|
||||
}
|
||||
reg := regexp.MustCompile(`cubic-bezier\(([ ]*(0(.[0-9]+)?|1(.0)?),){3}[ ]*(0(.[0-9]+)?|1)\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if CubicBezier.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`steps\([ ]*[0-9]+([ ]*,[ ]*(start|end)?)\)`)
|
||||
reg.Longest()
|
||||
return reg.FindString(value) == value && value != ""
|
||||
return Steps.MatchString(value)
|
||||
}
|
||||
|
||||
func BackfaceVisibilityHandler(value string) bool {
|
||||
|
@ -518,9 +550,7 @@ func ImageHandler(value string) bool {
|
|||
if in(splitVals, values) {
|
||||
return true
|
||||
}
|
||||
reg := regexp.MustCompile(`url\([\"\']?((https|http)[a-z0-9\.\\/_:]+[\"\']?)\)`)
|
||||
reg.Longest()
|
||||
return reg.FindString(value) == value && value != ""
|
||||
return URL.MatchString(value)
|
||||
}
|
||||
|
||||
func BackgroundOriginHandler(value string) bool {
|
||||
|
@ -535,12 +565,7 @@ func BackgroundPositionHandler(value string) bool {
|
|||
if in(splitVals, values) {
|
||||
return true
|
||||
}
|
||||
reg := regexp.MustCompile(`[\-]*[0-9]+[cm|mm|in|px|pt|pc\%]* [[\-]*[0-9]+[cm|mm|in|px|pt|pc\%]*]*`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return Position.MatchString(value)
|
||||
}
|
||||
|
||||
func BackgroundRepeatHandler(value string) bool {
|
||||
|
@ -816,31 +841,19 @@ func CaretColorHandler(value string) bool {
|
|||
if in(splitVals, colorValues) {
|
||||
return true
|
||||
}
|
||||
reg := regexp.MustCompile(`#[0-9abcdef]{6}`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if HexRGB.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`rgb\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){2}([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))))\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if RGB.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`rgba\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){3}[ ]*(1(\.0)?|0|(0\.[0-9]+))\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if RGBA.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`hsl\([ ]*([012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%\)`)
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if HSL.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`hsla\(([ ]*[012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%,[ ]*(1|1\.0|0|(0\.[0-9]+))\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return HSLA.MatchString(value)
|
||||
}
|
||||
|
||||
func ClearHandler(value string) bool {
|
||||
|
@ -850,9 +863,7 @@ func ClearHandler(value string) bool {
|
|||
}
|
||||
|
||||
func ClipHandler(value string) bool {
|
||||
reg := regexp.MustCompile(`rect\([0-9]+px,[ ]*[0-9]+px,[ ]*[0-9]+px,[ ]*[0-9]+px\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Rect.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"auto", "initial", "inherit"}
|
||||
|
@ -865,38 +876,23 @@ func ColorHandler(value string) bool {
|
|||
if in(splitVals, colorValues) {
|
||||
return true
|
||||
}
|
||||
reg := regexp.MustCompile(`#[0-9abcdef]{6}`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if HexRGB.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`rgb\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){2}([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))))\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if RGB.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`rgba\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){3}[ ]*(1(\.0)?|0|(0\.[0-9]+))\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if RGBA.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`hsl\([ ]*([012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if HSL.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`hsla\(([ ]*[012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%,[ ]*(1|1\.0|0|(0\.[0-9]+))\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return HSLA.MatchString(value)
|
||||
}
|
||||
|
||||
func ColumnCountHandler(value string) bool {
|
||||
reg := regexp.MustCompile(`[0-9]+`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Numeric.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"auto", "initial", "inherit"}
|
||||
|
@ -1000,54 +996,35 @@ func FilterHandler(value string) bool {
|
|||
if in(splitVals, values) {
|
||||
return true
|
||||
}
|
||||
reg := regexp.MustCompile(`blur\([0-9]+px\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Blur.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`(brightness|contrast)\([0-9]+\%\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if BrightnessCont.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`drop-shadow\(([-]?[0-9]+px) ([-]?[0-9]+px)( [-]?[0-9]+px)?( ([-]?[0-9]+px))?`)
|
||||
reg.Longest()
|
||||
colorValue := strings.TrimSuffix(string(reg.ReplaceAll([]byte(value), []byte{})), ")")
|
||||
if DropShadow.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
colorValue := strings.TrimSuffix(string(DropShadow.ReplaceAll([]byte(value), []byte{})), ")")
|
||||
if ColorHandler(colorValue) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`grayscale\(([0-9]{1,2}|100)%\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Grayscale.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`hue-rotate\(([12]?[0-9]{1,2}|3[0-5][0-9]|360)?\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if HueRotate.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`invert\(([0-9]{1,2}|100)%\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Invert.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`opacity\(([0-9]{1,2}|100)%\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Opacity.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`saturate\([0-9]+%\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Saturate.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`sepia\(([0-9]{1,2}|100)%\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
return true
|
||||
}
|
||||
//Not allowing URLs
|
||||
return false
|
||||
return Sepia.MatchString(value)
|
||||
}
|
||||
|
||||
func FlexHandler(value string) bool {
|
||||
|
@ -1092,9 +1069,7 @@ func FlexFlowHandler(value string) bool {
|
|||
}
|
||||
|
||||
func FlexGrowHandler(value string) bool {
|
||||
reg := regexp.MustCompile(`[0-9\.]+`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if NumericDecimal.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
splitVals := strings.Split(value, ";")
|
||||
|
@ -1144,11 +1119,9 @@ func FontFamilyHandler(value string) bool {
|
|||
if in(splitVals, values) {
|
||||
return true
|
||||
}
|
||||
reg := regexp.MustCompile(`('[a-z \-]+'|[a-z \-]+)`)
|
||||
reg.Longest()
|
||||
for _, i := range splitVals {
|
||||
i = strings.TrimSpace(i)
|
||||
if reg.FindString(i) != i {
|
||||
if Font.FindString(i) != i {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -1162,9 +1135,7 @@ func FontKerningHandler(value string) bool {
|
|||
}
|
||||
|
||||
func FontLanguageOverrideHandler(value string) bool {
|
||||
reg := regexp.MustCompile(`[a-z]+`)
|
||||
reg.Longest()
|
||||
return reg.FindString(value) == value && value != ""
|
||||
return Alpha.MatchString(value)
|
||||
}
|
||||
|
||||
func FontSizeHandler(value string) bool {
|
||||
|
@ -1177,9 +1148,7 @@ func FontSizeHandler(value string) bool {
|
|||
}
|
||||
|
||||
func FontSizeAdjustHandler(value string) bool {
|
||||
reg := regexp.MustCompile(`[0-9]+[\.]?[0-9]*`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Count.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"auto", "initial", "inherit"}
|
||||
|
@ -1298,9 +1267,7 @@ func GridColumnGapHandler(value string) bool {
|
|||
}
|
||||
|
||||
func LengthHandler(value string) bool {
|
||||
reg := regexp.MustCompile(`[\-]?[0-9]+[\.]?[0-9]*(%|cm|mm|in|px|pt|pc|em|ex|ch|rem|vw|vh|vmin|vmax|deg|rad|turn)?`)
|
||||
reg.Longest()
|
||||
return reg.FindString(value) == value && value != ""
|
||||
return Length.MatchString(value)
|
||||
}
|
||||
|
||||
func LineBreakHandler(value string) bool {
|
||||
|
@ -1310,12 +1277,10 @@ func LineBreakHandler(value string) bool {
|
|||
}
|
||||
|
||||
func GridAxisStartEndHandler(value string) bool {
|
||||
reg := regexp.MustCompile(`[0-9]+`)
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Numeric.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`span [0-9]+`)
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Span.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"auto"}
|
||||
|
@ -1366,9 +1331,7 @@ func GridTemplateAreasHandler(value string) bool {
|
|||
if in([]string{value}, values) {
|
||||
return true
|
||||
}
|
||||
reg := regexp.MustCompile(`['"]?[a-z ]+['"]?`)
|
||||
reg.Longest()
|
||||
return reg.FindString(value) == value && value != ""
|
||||
return GridTemplateAreas.MatchString(value)
|
||||
}
|
||||
|
||||
func GridTemplateColumnsHandler(value string) bool {
|
||||
|
@ -1551,9 +1514,7 @@ func ObjectPositionHandler(value string) bool {
|
|||
}
|
||||
|
||||
func OpacityHandler(value string) bool {
|
||||
reg := regexp.MustCompile("(0[.]?[0-9]*)|(1.0)")
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Opacity.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"initial", "inherit"}
|
||||
|
@ -1562,9 +1523,7 @@ func OpacityHandler(value string) bool {
|
|||
}
|
||||
|
||||
func OrderHandler(value string) bool {
|
||||
reg := regexp.MustCompile("[0-9]+")
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Numeric.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"initial", "inherit"}
|
||||
|
@ -1629,9 +1588,7 @@ func OverflowWrapHandler(value string) bool {
|
|||
}
|
||||
|
||||
func OrphansHandler(value string) bool {
|
||||
reg := regexp.MustCompile(`[0-9]+`)
|
||||
reg.Longest()
|
||||
return reg.FindString(value) == value && value != ""
|
||||
return Numeric.MatchString(value)
|
||||
}
|
||||
|
||||
func PaddingHandler(value string) bool {
|
||||
|
@ -1716,9 +1673,7 @@ func QuotesHandler(value string) bool {
|
|||
if in(splitVals, values) {
|
||||
return true
|
||||
}
|
||||
reg := regexp.MustCompile(`([ ]*["'][\x{0022}\x{0027}\x{2039}\x{2039}\x{203A}\x{00AB}\x{00BB}\x{2018}\x{2019}\x{201C}-\x{201E}]["'] ["'][\x{0022}\x{0027}\x{2039}\x{2039}\x{203A}\x{00AB}\x{00BB}\x{2018}\x{2019}\x{201C}-\x{201E}]["'])+`)
|
||||
reg.Longest()
|
||||
return reg.FindString(value) == value && value != ""
|
||||
return Quotes.MatchString(value)
|
||||
}
|
||||
|
||||
func ResizeHandler(value string) bool {
|
||||
|
@ -1766,9 +1721,7 @@ func TextCombineUprightHandler(value string) bool {
|
|||
if in(splitVals, values) {
|
||||
return true
|
||||
}
|
||||
reg := regexp.MustCompile(`digits [2-4]`)
|
||||
reg.Longest()
|
||||
return reg.FindString(value) == value && value != ""
|
||||
return Digits.MatchString(value)
|
||||
}
|
||||
|
||||
func TextDecorationHandler(value string) bool {
|
||||
|
@ -1813,9 +1766,7 @@ func TextJustifyHandler(value string) bool {
|
|||
}
|
||||
|
||||
func TextOverflowHandler(value string) bool {
|
||||
reg := regexp.MustCompile("[\"'][a-z]+[\"']")
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if QuotedAlpha.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"clip", "ellipsis", "initial", "inherit"}
|
||||
|
@ -1868,18 +1819,13 @@ func TransformHandler(value string) bool {
|
|||
if in([]string{value}, values) {
|
||||
return true
|
||||
}
|
||||
reg := regexp.MustCompile(`matrix\(([ ]*[0-9]+[\.]?[0-9]*,){5}([ ]*[0-9]+[\.]?[0-9]*)\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Matrix.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`matrix3d\(([ ]*[0-9]+[\.]?[0-9]*,){15}([ ]*[0-9]+[\.]?[0-9]*)\)`)
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Matrix3D.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`(translate|translate3d|translatex|translatey|translatez|scale|scale3d|scalex|scaley|scalez)\(`)
|
||||
reg.Longest()
|
||||
subValue := string(reg.ReplaceAll([]byte(value), []byte{}))
|
||||
subValue := string(TranslateScale.ReplaceAll([]byte(value), []byte{}))
|
||||
trimValue := strings.Split(strings.TrimSuffix(subValue, ")"), ",")
|
||||
valid := true
|
||||
for _, i := range trimValue {
|
||||
|
@ -1891,19 +1837,13 @@ func TransformHandler(value string) bool {
|
|||
if valid && trimValue != nil {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`rotate(x|y|z)?\(([12]?|3[0-5][0-9]|360)\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Rotate.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`rotate3d\(([ ]?(1(\.0)?|0\.[0-9]+),){3}([12]?|3[0-5][0-9]|360)\)`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Rotate3D.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`skew(x|y)?\(`)
|
||||
reg.Longest()
|
||||
subValue = string(reg.ReplaceAll([]byte(value), []byte{}))
|
||||
subValue = string(Skew.ReplaceAll([]byte(value), []byte{}))
|
||||
subValue = strings.TrimSuffix(subValue, ")")
|
||||
trimValue = strings.Split(subValue, ",")
|
||||
valid = true
|
||||
|
@ -1916,9 +1856,7 @@ func TransformHandler(value string) bool {
|
|||
if valid {
|
||||
return true
|
||||
}
|
||||
reg = regexp.MustCompile(`perspective\(`)
|
||||
reg.Longest()
|
||||
subValue = string(reg.ReplaceAll([]byte(value), []byte{}))
|
||||
subValue = string(Perspective.ReplaceAll([]byte(value), []byte{}))
|
||||
subValue = strings.TrimSuffix(subValue, ")")
|
||||
return LengthHandler(subValue)
|
||||
}
|
||||
|
@ -1973,9 +1911,7 @@ func TransitionHandler(value string) bool {
|
|||
}
|
||||
|
||||
func TransitionDelayHandler(value string) bool {
|
||||
reg := regexp.MustCompile("[0-9]+[.]?[0-9]*(s|ms)?")
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Time.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"initial", "inherit"}
|
||||
|
@ -1984,9 +1920,7 @@ func TransitionDelayHandler(value string) bool {
|
|||
}
|
||||
|
||||
func TransitionDurationHandler(value string) bool {
|
||||
reg := regexp.MustCompile("[0-9]+[.]?[0-9]*(s|ms)?")
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if Time.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"initial", "inherit"}
|
||||
|
@ -1995,9 +1929,7 @@ func TransitionDurationHandler(value string) bool {
|
|||
}
|
||||
|
||||
func TransitionPropertyHandler(value string) bool {
|
||||
reg := regexp.MustCompile("([a-zA-Z]+,[ ]?)*[a-zA-Z]+")
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if TransitionProp.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"none", "all", "initial", "inherit"}
|
||||
|
@ -2075,9 +2007,7 @@ func WritingModeHandler(value string) bool {
|
|||
}
|
||||
|
||||
func ZIndexHandler(value string) bool {
|
||||
reg := regexp.MustCompile(`[\-]?[0-9]+`)
|
||||
reg.Longest()
|
||||
if reg.FindString(value) == value && value != "" {
|
||||
if ZIndex.MatchString(value) {
|
||||
return true
|
||||
}
|
||||
values := []string{"auto", "initial", "inherit"}
|
||||
|
|
30
vendor/github.com/microcosm-cc/bluemonday/doc.go
generated
vendored
30
vendor/github.com/microcosm-cc/bluemonday/doc.go
generated
vendored
|
@ -35,31 +35,31 @@ the allowlist will be stripped.
|
|||
|
||||
The default bluemonday.UGCPolicy().Sanitize() turns this:
|
||||
|
||||
Hello <STYLE>.XSS{background-image:url("javascript:alert('XSS')");}</STYLE><A CLASS=XSS></A>World
|
||||
Hello <STYLE>.XSS{background-image:url("javascript:alert('XSS')");}</STYLE><A CLASS=XSS></A>World
|
||||
|
||||
Into the more harmless:
|
||||
|
||||
Hello World
|
||||
Hello World
|
||||
|
||||
And it turns this:
|
||||
|
||||
<a href="javascript:alert('XSS1')" onmouseover="alert('XSS2')">XSS<a>
|
||||
<a href="javascript:alert('XSS1')" onmouseover="alert('XSS2')">XSS<a>
|
||||
|
||||
Into this:
|
||||
|
||||
XSS
|
||||
XSS
|
||||
|
||||
Whilst still allowing this:
|
||||
|
||||
<a href="http://www.google.com/">
|
||||
<img src="https://ssl.gstatic.com/accounts/ui/logo_2x.png"/>
|
||||
</a>
|
||||
<a href="http://www.google.com/">
|
||||
<img src="https://ssl.gstatic.com/accounts/ui/logo_2x.png"/>
|
||||
</a>
|
||||
|
||||
To pass through mostly unaltered (it gained a rel="nofollow"):
|
||||
|
||||
<a href="http://www.google.com/" rel="nofollow">
|
||||
<img src="https://ssl.gstatic.com/accounts/ui/logo_2x.png"/>
|
||||
</a>
|
||||
<a href="http://www.google.com/" rel="nofollow">
|
||||
<img src="https://ssl.gstatic.com/accounts/ui/logo_2x.png"/>
|
||||
</a>
|
||||
|
||||
The primary purpose of bluemonday is to take potentially unsafe user generated
|
||||
content (from things like Markdown, HTML WYSIWYG tools, etc) and make it safe
|
||||
|
@ -95,10 +95,10 @@ attributes are considered safe for your scenario. OWASP provide an XSS
|
|||
prevention cheat sheet ( https://www.google.com/search?q=xss+prevention+cheat+sheet )
|
||||
to help explain the risks, but essentially:
|
||||
|
||||
1. Avoid allowing anything other than plain HTML elements
|
||||
2. Avoid allowing `script`, `style`, `iframe`, `object`, `embed`, `base`
|
||||
elements
|
||||
3. Avoid allowing anything other than plain HTML elements with simple
|
||||
values that you can match to a regexp
|
||||
1. Avoid allowing anything other than plain HTML elements
|
||||
2. Avoid allowing `script`, `style`, `iframe`, `object`, `embed`, `base`
|
||||
elements
|
||||
3. Avoid allowing anything other than plain HTML elements with simple
|
||||
values that you can match to a regexp
|
||||
*/
|
||||
package bluemonday
|
||||
|
|
17
vendor/github.com/microcosm-cc/bluemonday/helpers.go
generated
vendored
17
vendor/github.com/microcosm-cc/bluemonday/helpers.go
generated
vendored
|
@ -117,7 +117,7 @@ var (
|
|||
// This is not exported as it's not useful by itself, and only has value
|
||||
// within the AllowDataURIImages func
|
||||
dataURIImagePrefix = regexp.MustCompile(
|
||||
`^image/(gif|jpeg|png|webp);base64,`,
|
||||
`^image/(gif|jpeg|png|svg\+xml|webp);base64,`,
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -193,10 +193,11 @@ func (p *Policy) AllowImages() {
|
|||
// http://en.wikipedia.org/wiki/Data_URI_scheme
|
||||
//
|
||||
// Images must have a mimetype matching:
|
||||
// image/gif
|
||||
// image/jpeg
|
||||
// image/png
|
||||
// image/webp
|
||||
//
|
||||
// image/gif
|
||||
// image/jpeg
|
||||
// image/png
|
||||
// image/webp
|
||||
//
|
||||
// NOTE: There is a potential security risk to allowing data URIs and you should
|
||||
// only permit them on content you already trust.
|
||||
|
@ -221,11 +222,7 @@ func (p *Policy) AllowDataURIImages() {
|
|||
}
|
||||
|
||||
_, err := base64.StdEncoding.DecodeString(url.Opaque[len(matched):])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
return err == nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
53
vendor/github.com/microcosm-cc/bluemonday/policy.go
generated
vendored
53
vendor/github.com/microcosm-cc/bluemonday/policy.go
generated
vendored
|
@ -117,6 +117,19 @@ type Policy struct {
|
|||
// returning true are allowed.
|
||||
allowURLSchemes map[string][]urlPolicy
|
||||
|
||||
// These regexps are used to match allowed URL schemes, for example
|
||||
// if one would want to allow all URL schemes, they would add `.+`.
|
||||
// However pay attention as this can lead to XSS being rendered thus
|
||||
// defeating the purpose of using a HTML sanitizer.
|
||||
// The regexps are only considered if a schema was not explicitly
|
||||
// handled by `AllowURLSchemes` or `AllowURLSchemeWithCustomPolicy`.
|
||||
allowURLSchemeRegexps []*regexp.Regexp
|
||||
|
||||
// If srcRewriter is not nil, it is used to rewrite the src attribute
|
||||
// of tags that download resources, such as <img> and <script>.
|
||||
// It requires that the URL is parsable by "net/url" url.Parse().
|
||||
srcRewriter urlRewriter
|
||||
|
||||
// If an element has had all attributes removed as a result of a policy
|
||||
// being applied, then the element would be removed from the output.
|
||||
//
|
||||
|
@ -192,6 +205,8 @@ type stylePolicyBuilder struct {
|
|||
|
||||
type urlPolicy func(url *url.URL) (allowUrl bool)
|
||||
|
||||
type urlRewriter func(*url.URL)
|
||||
|
||||
type SandboxValue int64
|
||||
|
||||
const (
|
||||
|
@ -221,6 +236,7 @@ func (p *Policy) init() {
|
|||
p.elsMatchingAndStyles = make(map[*regexp.Regexp]map[string][]stylePolicy)
|
||||
p.globalStyles = make(map[string][]stylePolicy)
|
||||
p.allowURLSchemes = make(map[string][]urlPolicy)
|
||||
p.allowURLSchemeRegexps = make([]*regexp.Regexp, 0)
|
||||
p.setOfElementsAllowedWithoutAttrs = make(map[string]struct{})
|
||||
p.setOfElementsToSkipContent = make(map[string]struct{})
|
||||
p.initialized = true
|
||||
|
@ -563,6 +579,40 @@ func (p *Policy) AllowElementsMatching(regex *regexp.Regexp) *Policy {
|
|||
return p
|
||||
}
|
||||
|
||||
// AllowURLSchemesMatching will append URL schemes to the allowlist if they
|
||||
// match a regexp.
|
||||
func (p *Policy) AllowURLSchemesMatching(r *regexp.Regexp) *Policy {
|
||||
p.allowURLSchemeRegexps = append(p.allowURLSchemeRegexps, r)
|
||||
return p
|
||||
}
|
||||
|
||||
// RewriteSrc will rewrite the src attribute of a resource downloading tag
|
||||
// (e.g. <img>, <script>, <iframe>) using the provided function.
|
||||
//
|
||||
// Typically the use case here is that if the content that we're sanitizing
|
||||
// is untrusted then the content that is inlined is also untrusted.
|
||||
// To prevent serving this content on the same domain as the content appears
|
||||
// on it is good practise to proxy the content through an additional domain
|
||||
// name as this will force the web client to consider the inline content as
|
||||
// third party to the main content, thus providing browser isolation around
|
||||
// the inline content.
|
||||
//
|
||||
// An example of this is a web mail provider like fastmail.com , when an
|
||||
// email (user generated content) is displayed, the email text is shown on
|
||||
// fastmail.com but the inline attachments and content are rendered from
|
||||
// fastmailusercontent.com . This proxying of the external content on a
|
||||
// domain that is different to the content domain forces the browser domain
|
||||
// security model to kick in. Note that this only applies to differences
|
||||
// below the suffix (as per the publix suffix list).
|
||||
//
|
||||
// This is a good practise to adopt as it prevents the content from being
|
||||
// able to set cookies on the main domain and thus prevents the content on
|
||||
// the main domain from being able to read those cookies.
|
||||
func (p *Policy) RewriteSrc(fn urlRewriter) *Policy {
|
||||
p.srcRewriter = fn
|
||||
return p
|
||||
}
|
||||
|
||||
// RequireNoFollowOnLinks will result in all a, area, link tags having a
|
||||
// rel="nofollow"added to them if one does not already exist
|
||||
//
|
||||
|
@ -707,7 +757,7 @@ func (p *Policy) AllowURLSchemeWithCustomPolicy(
|
|||
func (p *Policy) RequireSandboxOnIFrame(vals ...SandboxValue) {
|
||||
p.requireSandboxOnIFrame = make(map[string]bool)
|
||||
|
||||
for val := range vals {
|
||||
for _, val := range vals {
|
||||
switch SandboxValue(val) {
|
||||
case SandboxAllowDownloads:
|
||||
p.requireSandboxOnIFrame["allow-downloads"] = true
|
||||
|
@ -879,6 +929,7 @@ func (p *Policy) addDefaultElementsWithoutAttrs() {
|
|||
p.setOfElementsAllowedWithoutAttrs["optgroup"] = struct{}{}
|
||||
p.setOfElementsAllowedWithoutAttrs["option"] = struct{}{}
|
||||
p.setOfElementsAllowedWithoutAttrs["p"] = struct{}{}
|
||||
p.setOfElementsAllowedWithoutAttrs["picture"] = struct{}{}
|
||||
p.setOfElementsAllowedWithoutAttrs["pre"] = struct{}{}
|
||||
p.setOfElementsAllowedWithoutAttrs["q"] = struct{}{}
|
||||
p.setOfElementsAllowedWithoutAttrs["rp"] = struct{}{}
|
||||
|
|
80
vendor/github.com/microcosm-cc/bluemonday/sanitize.go
generated
vendored
80
vendor/github.com/microcosm-cc/bluemonday/sanitize.go
generated
vendored
|
@ -95,41 +95,6 @@ func (p *Policy) SanitizeReaderToWriter(r io.Reader, w io.Writer) error {
|
|||
return p.sanitize(r, w)
|
||||
}
|
||||
|
||||
const escapedURLChars = "'<>\"\r"
|
||||
|
||||
func escapeUrlComponent(w stringWriterWriter, val string) error {
|
||||
i := strings.IndexAny(val, escapedURLChars)
|
||||
for i != -1 {
|
||||
if _, err := w.WriteString(val[:i]); err != nil {
|
||||
return err
|
||||
}
|
||||
var esc string
|
||||
switch val[i] {
|
||||
case '\'':
|
||||
// "'" is shorter than "'" and apos was not in HTML until HTML5.
|
||||
esc = "'"
|
||||
case '<':
|
||||
esc = "<"
|
||||
case '>':
|
||||
esc = ">"
|
||||
case '"':
|
||||
// """ is shorter than """.
|
||||
esc = """
|
||||
case '\r':
|
||||
esc = " "
|
||||
default:
|
||||
panic("unrecognized escape character")
|
||||
}
|
||||
val = val[i+1:]
|
||||
if _, err := w.WriteString(esc); err != nil {
|
||||
return err
|
||||
}
|
||||
i = strings.IndexAny(val, escapedURLChars)
|
||||
}
|
||||
_, err := w.WriteString(val)
|
||||
return err
|
||||
}
|
||||
|
||||
// Query represents a single part of the query string, a query param
|
||||
type Query struct {
|
||||
Key string
|
||||
|
@ -322,9 +287,7 @@ func (p *Policy) sanitize(r io.Reader, w io.Writer) error {
|
|||
aps = aa
|
||||
}
|
||||
if len(token.Attr) != 0 {
|
||||
token.Attr = escapeAttributes(
|
||||
p.sanitizeAttrs(token.Data, token.Attr, aps),
|
||||
)
|
||||
token.Attr = p.sanitizeAttrs(token.Data, token.Attr, aps)
|
||||
}
|
||||
|
||||
if len(token.Attr) == 0 {
|
||||
|
@ -434,7 +397,7 @@ func (p *Policy) sanitize(r io.Reader, w io.Writer) error {
|
|||
}
|
||||
|
||||
if len(token.Attr) != 0 {
|
||||
token.Attr = escapeAttributes(p.sanitizeAttrs(token.Data, token.Attr, aps))
|
||||
token.Attr = p.sanitizeAttrs(token.Data, token.Attr, aps)
|
||||
}
|
||||
|
||||
if len(token.Attr) == 0 && !p.allowNoAttrs(token.Data) {
|
||||
|
@ -442,8 +405,8 @@ func (p *Policy) sanitize(r io.Reader, w io.Writer) error {
|
|||
if _, err := buff.WriteString(" "); err != nil {
|
||||
return err
|
||||
}
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
if !skipElementContent {
|
||||
if _, err := buff.WriteString(token.String()); err != nil {
|
||||
|
@ -565,11 +528,9 @@ 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)
|
||||
}
|
||||
}
|
||||
|
@ -616,6 +577,14 @@ attrsLoop:
|
|||
case "audio", "embed", "iframe", "img", "script", "source", "track", "video":
|
||||
if htmlAttr.Key == "src" {
|
||||
if u, ok := p.validURL(htmlAttr.Val); ok {
|
||||
if p.srcRewriter != nil {
|
||||
parsedURL, err := url.Parse(u)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
p.srcRewriter(parsedURL)
|
||||
u = parsedURL.String()
|
||||
}
|
||||
htmlAttr.Val = u
|
||||
tmpAttrs = append(tmpAttrs, htmlAttr)
|
||||
}
|
||||
|
@ -856,6 +825,7 @@ func (p *Policy) sanitizeStyles(attr html.Attribute, elementName string) html.At
|
|||
}
|
||||
|
||||
//Add semi-colon to end to fix parsing issue
|
||||
attr.Val = strings.TrimRight(attr.Val, " ")
|
||||
if len(attr.Val) > 0 && attr.Val[len(attr.Val)-1] != ';' {
|
||||
attr.Val = attr.Val + ";"
|
||||
}
|
||||
|
@ -973,9 +943,14 @@ func (p *Policy) validURL(rawurl string) (string, bool) {
|
|||
}
|
||||
|
||||
if u.Scheme != "" {
|
||||
|
||||
urlPolicies, ok := p.allowURLSchemes[u.Scheme]
|
||||
if !ok {
|
||||
for _, r := range p.allowURLSchemeRegexps {
|
||||
if r.MatchString(u.Scheme) {
|
||||
return u.String(), true
|
||||
}
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
|
||||
|
@ -984,7 +959,7 @@ func (p *Policy) validURL(rawurl string) (string, bool) {
|
|||
}
|
||||
|
||||
for _, urlPolicy := range urlPolicies {
|
||||
if urlPolicy(u) == true {
|
||||
if urlPolicy(u) {
|
||||
return u.String(), true
|
||||
}
|
||||
}
|
||||
|
@ -1023,7 +998,7 @@ func linkable(elementName string) bool {
|
|||
// stringInSlice returns true if needle exists in haystack
|
||||
func stringInSlice(needle string, haystack []string) bool {
|
||||
for _, straw := range haystack {
|
||||
if strings.ToLower(straw) == strings.ToLower(needle) {
|
||||
if strings.EqualFold(straw, needle) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -1112,18 +1087,3 @@ 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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue