Defect #44586 ยป 0004-Stop-escaping-the-attributes-of-the-HTML-tags-allowe.patch
| lib/redmine/wiki_formatting/textile/redcloth3.rb | ||
|---|---|---|
| 1216 | 1216 |
all, tag, close = $1, $2, $3 |
| 1217 | 1217 | |
| 1218 | 1218 |
if close.present? && (ALLOWED_TAGS.include?(tag) || (tag =~ /\Aredpre#\d+\z/)) |
| 1219 |
"<#{htmlesc all}#{close}"
|
|
| 1219 |
"<#{all}#{close}"
|
|
| 1220 | 1220 |
else |
| 1221 | 1221 |
"<#{htmlesc all}#{'>' unless close.blank?}"
|
| 1222 | 1222 |
end |
| lib/redmine/wiki_formatting/textile/sanitization_filter.rb | ||
|---|---|---|
| 29 | 29 | |
| 30 | 30 |
def default_allowlist |
| 31 | 31 |
allowlist = super |
| 32 |
allowlist[:elements] += %w[font] |
|
| 32 | 33 |
allowlist[:attributes][:all] += %w[class id] |
| 34 |
allowlist[:attributes]['font'] = %w[face] |
|
| 33 | 35 |
allowlist |
| 34 | 36 |
end |
| 35 | 37 | |
| test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb | ||
|---|---|---|
| 857 | 857 |
assert_includes to_html(%{version:"foo <bar>"}), %{version:"foo <bar>"}
|
| 858 | 858 |
end |
| 859 | 859 | |
| 860 |
def test_should_keep_quoted_attributes_of_allowed_tags |
|
| 861 |
with_allowed_tags('font', 'a') do
|
|
| 862 |
assert_html_output( |
|
| 863 |
{
|
|
| 864 |
%{<font color="red" size='3'>text</font>} => '<font color="red" size="3">text</font>',
|
|
| 865 |
'<a href="https://example.com/" title="Example">text</a>' => |
|
| 866 |
'<p><a href="https://example.com/" title="Example">text</a></p>', |
|
| 867 |
}, |
|
| 868 |
false |
|
| 869 |
) |
|
| 870 |
end |
|
| 871 |
end |
|
| 872 | ||
| 873 |
def test_should_remove_unsafe_attributes_from_allowed_tags |
|
| 874 |
with_allowed_tags('a') do
|
|
| 875 |
assert_html_output( |
|
| 876 |
{
|
|
| 877 |
'<a href="javascript:alert(1)">text</a>' => '<p><a>text</a></p>', |
|
| 878 |
'<a href="/" onclick="alert(1)">text</a>' => '<p><a href="/">text</a></p>', |
|
| 879 |
}, |
|
| 880 |
false |
|
| 881 |
) |
|
| 882 |
end |
|
| 883 |
end |
|
| 884 | ||
| 860 | 885 |
def test_nested_notextile_tag_boundaries |
| 861 | 886 |
["<<notextile>div class=foo >", |
| 862 | 887 |
"<</notextile>div class=foo >"].each do |payload| |
| ... | ... | |
| 871 | 896 | |
| 872 | 897 |
private |
| 873 | 898 | |
| 899 |
def with_allowed_tags(*tags) |
|
| 900 |
allowed_tags = Redmine::WikiFormatting::Textile::Filter::ALLOWED_TAGS |
|
| 901 |
original_tags = allowed_tags.dup |
|
| 902 |
allowed_tags.concat(tags) |
|
| 903 |
yield |
|
| 904 |
ensure |
|
| 905 |
allowed_tags.replace(original_tags) |
|
| 906 |
end |
|
| 907 | ||
| 874 | 908 |
def assert_html_output(to_test, expect_paragraph = true) |
| 875 | 909 |
to_test.each do |text, expected| |
| 876 | 910 |
assert_equal( |