Project

General

Profile

Defect #44586 ยป 0004-Stop-escaping-the-attributes-of-the-HTML-tags-allowe.patch

Go MAEDA, 2026-10-10 11:15

View differences:

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
                "&lt;#{htmlesc all}#{'&gt;' 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 &lt;bar&gt;"}
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(
    (1-1/1)