From a6b77251b3b0477ab2389332a7f990a080ef1987 Mon Sep 17 00:00:00 2001 From: MAEDA Go Date: Sat, 10 Oct 2026 17:52:37 +0900 Subject: [PATCH 4/4] Stop escaping the attributes of the HTML tags allowed in Textile because unsafe attributes are now removed by the sanitizer --- .../wiki_formatting/textile/redcloth3.rb | 2 +- .../textile/sanitization_filter.rb | 2 ++ .../wiki_formatting/textile_formatter_test.rb | 34 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/redmine/wiki_formatting/textile/redcloth3.rb b/lib/redmine/wiki_formatting/textile/redcloth3.rb index e7f949a95..c62b81c9d 100644 --- a/lib/redmine/wiki_formatting/textile/redcloth3.rb +++ b/lib/redmine/wiki_formatting/textile/redcloth3.rb @@ -1216,7 +1216,7 @@ class RedCloth3 < String all, tag, close = $1, $2, $3 if close.present? && (ALLOWED_TAGS.include?(tag) || (tag =~ /\Aredpre#\d+\z/)) - "<#{htmlesc all}#{close}" + "<#{all}#{close}" else "<#{htmlesc all}#{'>' unless close.blank?}" end diff --git a/lib/redmine/wiki_formatting/textile/sanitization_filter.rb b/lib/redmine/wiki_formatting/textile/sanitization_filter.rb index 2fc11880e..4e6fa37a4 100644 --- a/lib/redmine/wiki_formatting/textile/sanitization_filter.rb +++ b/lib/redmine/wiki_formatting/textile/sanitization_filter.rb @@ -29,7 +29,9 @@ module Redmine def default_allowlist allowlist = super + allowlist[:elements] += %w[font] allowlist[:attributes][:all] += %w[class id] + allowlist[:attributes]['font'] = %w[face] allowlist end diff --git a/test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb b/test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb index 0e35ac91e..af908685d 100644 --- a/test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb +++ b/test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb @@ -857,6 +857,31 @@ class Redmine::WikiFormatting::TextileFormatterTest < Redmine::HelperTest assert_includes to_html(%{version:"foo "}), %{version:"foo <bar>"} end + def test_should_keep_quoted_attributes_of_allowed_tags + with_allowed_tags('font', 'a') do + assert_html_output( + { + %{text} => 'text', + 'text' => + '

text

', + }, + false + ) + end + end + + def test_should_remove_unsafe_attributes_from_allowed_tags + with_allowed_tags('a') do + assert_html_output( + { + 'text' => '

text

', + 'text' => '

text

', + }, + false + ) + end + end + def test_nested_notextile_tag_boundaries ["<div class=foo >", "<div class=foo >"].each do |payload| @@ -871,6 +896,15 @@ class Redmine::WikiFormatting::TextileFormatterTest < Redmine::HelperTest private + def with_allowed_tags(*tags) + allowed_tags = Redmine::WikiFormatting::Textile::Filter::ALLOWED_TAGS + original_tags = allowed_tags.dup + allowed_tags.concat(tags) + yield + ensure + allowed_tags.replace(original_tags) + end + def assert_html_output(to_test, expect_paragraph = true) to_test.each do |text, expected| assert_equal( -- 2.55.0