Project

General

Profile

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

Go MAEDA, 2026-10-09 07:24

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
test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb
859 859
    assert_includes to_html(%{version:"foo <bar>"}), %{version:"foo &lt;bar&gt;"}
860 860
  end
861 861

  
862
  def test_should_keep_quoted_attributes_of_allowed_tags
863
    with_allowed_tags('font', 'a') do
864
      assert_html_output(
865
        {
866
          %{<font color="red" size='3'>text</font>} => '<font color="red" size="3">text</font>',
867
          '<a href="https://example.com/" title="Example">text</a>' =>
868
            '<p><a href="https://example.com/" title="Example">text</a></p>',
869
        },
870
        false
871
      )
872
    end
873
  end
874

  
875
  def test_should_remove_unsafe_attributes_from_allowed_tags
876
    with_allowed_tags('font', 'a') do
877
      assert_html_output(
878
        {
879
          '<a href="javascript:alert(1)">text</a>' => '<p><a>text</a></p>',
880
          '<a href="/" onclick="alert(1)">text</a>' => '<p><a href="/">text</a></p>',
881
          '<a href="/" class="icon" id="main-menu">text</a>' => '<p><a href="/">text</a></p>',
882
          '<font style="color:red; position:fixed">text</font>' => '<font style="color:red; ">text</font>',
883
        },
884
        false
885
      )
886
    end
887
  end
888

  
889
  def test_should_escape_tags_not_in_allowed_tags
890
    with_allowed_tags('font') do
891
      assert_html_output('<a href="/foo">text</a>' => '&lt;a href="/foo"&gt;text&lt;/a&gt;')
892
    end
893
  end
894

  
895
  def test_should_remove_allowed_tags_not_accepted_by_sanitizer
896
    with_allowed_tags('iframe') do
897
      assert_html_output({'<iframe src="https://example.com/"></iframe>text' => 'text'}, false)
898
    end
899
  end
900

  
862 901
  def test_nested_notextile_tag_boundaries
863 902
    ["<<notextile>div class=foo >",
864 903
     "<</notextile>div class=foo >"].each do |payload|
......
873 912

  
874 913
  private
875 914

  
915
  def with_allowed_tags(*tags)
916
    allowed_tags = Redmine::WikiFormatting::Textile::Filter::ALLOWED_TAGS
917
    original_tags = allowed_tags.dup
918
    allowed_tags.concat(tags)
919
    yield
920
  ensure
921
    allowed_tags.replace(original_tags)
922
  end
923

  
876 924
  def assert_html_output(to_test, expect_paragraph = true)
877 925
    to_test.each do |text, expected|
878 926
      assert_equal(
    (1-1/1)