mirror of
https://github.com/miniflux/v2.git
synced 2025-06-27 16:36:00 +00:00
feat(sanitizer): add support for fetchpriority and decoding attributes in img tags
This commit is contained in:
parent
d59990f1dd
commit
21d22d7f0b
2 changed files with 117 additions and 1 deletions
|
@ -46,7 +46,7 @@ var (
|
||||||
"h6": {"id"},
|
"h6": {"id"},
|
||||||
"hr": {},
|
"hr": {},
|
||||||
"iframe": {"width", "height", "frameborder", "src", "allowfullscreen"},
|
"iframe": {"width", "height", "frameborder", "src", "allowfullscreen"},
|
||||||
"img": {"alt", "title", "src", "srcset", "sizes", "width", "height"},
|
"img": {"alt", "title", "src", "srcset", "sizes", "width", "height", "fetchpriority", "decoding"},
|
||||||
"ins": {},
|
"ins": {},
|
||||||
"kbd": {},
|
"kbd": {},
|
||||||
"li": {"id"},
|
"li": {"id"},
|
||||||
|
@ -234,6 +234,18 @@ func sanitizeAttributes(baseURL, tagName string, attributes []html.Attribute, sa
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tagName == "img" && attribute.Key == "fetchpriority" {
|
||||||
|
if !isValidFetchPriorityValue(value) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tagName == "img" && attribute.Key == "decoding" {
|
||||||
|
if !isValidDecodingValue(value) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (tagName == "img" || tagName == "source") && attribute.Key == "srcset" {
|
if (tagName == "img" || tagName == "source") && attribute.Key == "srcset" {
|
||||||
value = sanitizeSrcsetAttr(baseURL, value)
|
value = sanitizeSrcsetAttr(baseURL, value)
|
||||||
}
|
}
|
||||||
|
@ -540,3 +552,13 @@ func getIntegerAttributeValue(name string, attributes []html.Attribute) int {
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isValidFetchPriorityValue(value string) bool {
|
||||||
|
allowedValues := []string{"high", "low", "auto"}
|
||||||
|
return slices.Contains(allowedValues, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isValidDecodingValue(value string) bool {
|
||||||
|
allowedValues := []string{"sync", "async", "auto"}
|
||||||
|
return slices.Contains(allowedValues, value)
|
||||||
|
}
|
||||||
|
|
|
@ -139,6 +139,100 @@ func TestImgWithSrcsetAndNoSrcAttribute(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestImgWithFetchPriorityAttribute(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
input string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
`<img src="https://example.org/image.png" fetchpriority="high">`,
|
||||||
|
`<img src="https://example.org/image.png" fetchpriority="high" loading="lazy">`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`<img src="https://example.org/image.png" fetchpriority="low">`,
|
||||||
|
`<img src="https://example.org/image.png" fetchpriority="low" loading="lazy">`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`<img src="https://example.org/image.png" fetchpriority="auto">`,
|
||||||
|
`<img src="https://example.org/image.png" fetchpriority="auto" loading="lazy">`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
output := SanitizeHTMLWithDefaultOptions("http://example.org/", tc.input)
|
||||||
|
if output != tc.expected {
|
||||||
|
t.Errorf(`Wrong output for input %q: expected %q, got %q`, tc.input, tc.expected, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestImgWithInvalidFetchPriorityAttribute(t *testing.T) {
|
||||||
|
input := `<img src="https://example.org/image.png" fetchpriority="invalid">`
|
||||||
|
expected := `<img src="https://example.org/image.png" loading="lazy">`
|
||||||
|
output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
|
||||||
|
|
||||||
|
if output != expected {
|
||||||
|
t.Errorf(`Wrong output: expected %q, got %q`, expected, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNonImgWithFetchPriorityAttribute(t *testing.T) {
|
||||||
|
input := `<p fetchpriority="high">Text</p>`
|
||||||
|
expected := `<p>Text</p>`
|
||||||
|
output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
|
||||||
|
|
||||||
|
if output != expected {
|
||||||
|
t.Errorf(`Wrong output: expected %q, got %q`, expected, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestImgWithDecodingAttribute(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
input string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
`<img src="https://example.org/image.png" decoding="sync">`,
|
||||||
|
`<img src="https://example.org/image.png" decoding="sync" loading="lazy">`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`<img src="https://example.org/image.png" decoding="async">`,
|
||||||
|
`<img src="https://example.org/image.png" decoding="async" loading="lazy">`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`<img src="https://example.org/image.png" decoding="auto">`,
|
||||||
|
`<img src="https://example.org/image.png" decoding="auto" loading="lazy">`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
output := SanitizeHTMLWithDefaultOptions("http://example.org/", tc.input)
|
||||||
|
if output != tc.expected {
|
||||||
|
t.Errorf(`Wrong output for input %q: expected %q, got %q`, tc.input, tc.expected, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestImgWithInvalidDecodingAttribute(t *testing.T) {
|
||||||
|
input := `<img src="https://example.org/image.png" decoding="invalid">`
|
||||||
|
expected := `<img src="https://example.org/image.png" loading="lazy">`
|
||||||
|
output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
|
||||||
|
|
||||||
|
if output != expected {
|
||||||
|
t.Errorf(`Wrong output: expected %q, got %q`, expected, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNonImgWithDecodingAttribute(t *testing.T) {
|
||||||
|
input := `<p decoding="async">Text</p>`
|
||||||
|
expected := `<p>Text</p>`
|
||||||
|
output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
|
||||||
|
|
||||||
|
if output != expected {
|
||||||
|
t.Errorf(`Wrong output: expected %q, got %q`, expected, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSourceWithSrcsetAndMedia(t *testing.T) {
|
func TestSourceWithSrcsetAndMedia(t *testing.T) {
|
||||||
input := `<picture><source media="(min-width: 800px)" srcset="elva-800w.jpg"></picture>`
|
input := `<picture><source media="(min-width: 800px)" srcset="elva-800w.jpg"></picture>`
|
||||||
expected := `<picture><source media="(min-width: 800px)" srcset="http://example.org/elva-800w.jpg"></picture>`
|
expected := `<picture><source media="(min-width: 800px)" srcset="http://example.org/elva-800w.jpg"></picture>`
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue