Project

General

Profile

Patch #37750 » 0003-uses-the-new-html-sanitizer-for-links-rendered-by-cu.patch

Jens Krämer, 2022-10-04 13:32

View differences:

lib/redmine/field_format.rb
255 255
            [text, url]
256 256
          end
257 257
          links = texts_and_urls.sort_by(&:first).map do |text, url|
258
            css_class = (/^https?:\/\//.match?(url)) ? 'external' : nil
259
            view.link_to_if uri_with_safe_scheme?(url), text, url, :class => css_class
258
            view.link_to text, url
260 259
          end
261
          links.join(', ').html_safe
260
          sanitize_html links.join(', ')
262 261
        else
263 262
          casted
264 263
        end
265 264
      end
266 265

  
266
      def sanitize_html(html)
267
        Redmine::WikiFormatting::HtmlSanitizer.call(html).html_safe
268
      end
269

  
267 270
      # Returns an URL generated with the custom field URL pattern
268 271
      # and variables substitution:
269 272
      # %value% => the custom field value
......
463 466
              url = "http://" + url
464 467
            end
465 468
          end
466
          css_class = (/^https?:\/\//.match?(url)) ? 'external' : nil
467
          view.link_to value.to_s.truncate(40), url, :class => css_class
469
          sanitize_html view.link_to(value.to_s.truncate(40), url)
468 470
        else
469 471
          value.to_s
470 472
        end
test/unit/lib/redmine/field_format/field_format_test.rb
79 79
    custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "bar")
80 80

  
81 81
    assert_equal "bar", field.format.formatted_custom_value(self, custom_value, false)
82
    assert_equal '<a class="external" href="http://foo/bar">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
82
    assert_equal '<a href="http://foo/bar" class="external">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
83 83
  end
84 84

  
85 85
  def test_text_field_with_url_pattern_and_value_containing_a_space_should_format_as_link
......
87 87
    custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "foo bar")
88 88

  
89 89
    assert_equal "foo bar", field.format.formatted_custom_value(self, custom_value, false)
90
    assert_equal '<a class="external" href="http://foo/foo%20bar">foo bar</a>', field.format.formatted_custom_value(self, custom_value, true)
90
    assert_equal '<a href="http://foo/foo%20bar" class="external">foo bar</a>', field.format.formatted_custom_value(self, custom_value, true)
91 91
  end
92 92

  
93 93
  def test_text_field_with_url_pattern_should_not_encode_url_pattern
......
95 95
    custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "1")
96 96

  
97 97
    assert_equal "1", field.format.formatted_custom_value(self, custom_value, false)
98
    assert_equal '<a class="external" href="http://foo/bar#anchor">1</a>', field.format.formatted_custom_value(self, custom_value, true)
98
    assert_equal '<a href="http://foo/bar#anchor" class="external">1</a>', field.format.formatted_custom_value(self, custom_value, true)
99 99
  end
100 100

  
101 101
  def test_text_field_with_url_pattern_should_encode_values
......
103 103
    custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "foo bar")
104 104

  
105 105
    assert_equal "foo bar", field.format.formatted_custom_value(self, custom_value, false)
106
    assert_equal '<a class="external" href="http://foo/foo%20bar#anchor">foo bar</a>', field.format.formatted_custom_value(self, custom_value, true)
106
    assert_equal '<a href="http://foo/foo%20bar#anchor" class="external">foo bar</a>', field.format.formatted_custom_value(self, custom_value, true)
107 107
  end
108 108
end
test/unit/lib/redmine/field_format/link_format_test.rb
31 31
    custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "bar")
32 32

  
33 33
    assert_equal "bar", field.format.formatted_custom_value(self, custom_value, false)
34
    assert_equal '<a class="external" href="http://foo/bar">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
34
    assert_equal '<a href="http://foo/bar" class="external">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
35 35
  end
36 36

  
37 37
  def test_link_field_should_substitute_object_id_in_url
......
42 42
    custom_value = CustomValue.new(:custom_field => field, :customized => object, :value => "bar")
43 43

  
44 44
    assert_equal "bar", field.format.formatted_custom_value(self, custom_value, false)
45
    assert_equal '<a class="external" href="http://foo/10">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
45
    assert_equal '<a href="http://foo/10" class="external">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
46 46
  end
47 47

  
48 48
  def test_link_field_should_substitute_project_id_in_url
......
55 55
    custom_value = CustomValue.new(:custom_field => field, :customized => object, :value => "bar")
56 56

  
57 57
    assert_equal "bar", field.format.formatted_custom_value(self, custom_value, false)
58
    assert_equal '<a class="external" href="http://foo/52">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
58
    assert_equal '<a href="http://foo/52" class="external">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
59 59
  end
60 60

  
61 61
  def test_link_field_should_substitute_project_identifier_in_url
......
68 68
    custom_value = CustomValue.new(:custom_field => field, :customized => object, :value => "bar")
69 69

  
70 70
    assert_equal "bar", field.format.formatted_custom_value(self, custom_value, false)
71
    assert_equal '<a class="external" href="http://foo/foo_project-00">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
71
    assert_equal '<a href="http://foo/foo_project-00" class="external">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
72 72
  end
73 73

  
74 74
  def test_link_field_should_substitute_regexp_groups
......
76 76
    custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "56-142")
77 77

  
78 78
    assert_equal "56-142", field.format.formatted_custom_value(self, custom_value, false)
79
    assert_equal '<a class="external" href="http://foo/142/56">56-142</a>', field.format.formatted_custom_value(self, custom_value, true)
79
    assert_equal '<a href="http://foo/142/56" class="external">56-142</a>', field.format.formatted_custom_value(self, custom_value, true)
80 80
  end
81 81

  
82 82
  def test_link_field_without_url_pattern_should_link_to_value
......
84 84
    custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "http://foo/bar")
85 85

  
86 86
    assert_equal "http://foo/bar", field.format.formatted_custom_value(self, custom_value, false)
87
    assert_equal '<a class="external" href="http://foo/bar">http://foo/bar</a>', field.format.formatted_custom_value(self, custom_value, true)
87
    assert_equal '<a href="http://foo/bar" class="external">http://foo/bar</a>', field.format.formatted_custom_value(self, custom_value, true)
88 88
  end
89 89

  
90 90
  def test_link_field_without_url_pattern_should_link_to_value_with_http_by_default
......
92 92
    custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "foo.bar")
93 93

  
94 94
    assert_equal "foo.bar", field.format.formatted_custom_value(self, custom_value, false)
95
    assert_equal '<a class="external" href="http://foo.bar">foo.bar</a>', field.format.formatted_custom_value(self, custom_value, true)
95
    assert_equal '<a href="http://foo.bar" class="external">foo.bar</a>', field.format.formatted_custom_value(self, custom_value, true)
96 96
  end
97 97
end
test/unit/lib/redmine/field_format/list_format_test.rb
144 144
  def test_field_with_url_pattern_should_link_value
145 145
    field = IssueCustomField.new(:field_format => 'list', :url_pattern => 'http://localhost/%value%')
146 146
    formatted = field.format.formatted_value(self, field, 'foo', Issue.new, true)
147
    assert_equal '<a class="external" href="http://localhost/foo">foo</a>', formatted
147
    assert_equal '<a href="http://localhost/foo" class="external">foo</a>', formatted
148 148
    assert formatted.html_safe?
149 149
  end
150 150

  
151 151
  def test_field_with_url_pattern_and_multiple_values_should_link_values
152 152
    field = IssueCustomField.new(:field_format => 'list', :url_pattern => 'http://localhost/%value%')
153 153
    formatted = field.format.formatted_value(self, field, ['foo', 'bar'], Issue.new, true)
154
    assert_equal '<a class="external" href="http://localhost/bar">bar</a>, <a class="external" href="http://localhost/foo">foo</a>', formatted
154
    assert_equal '<a href="http://localhost/bar" class="external">bar</a>, <a href="http://localhost/foo" class="external">foo</a>', formatted
155 155
    assert formatted.html_safe?
156 156
  end
157 157

  
test/unit/lib/redmine/field_format/numeric_format_test.rb
32 32
    custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "3")
33 33

  
34 34
    assert_equal 3, field.format.formatted_custom_value(self, custom_value, false)
35
    assert_equal '<a class="external" href="http://foo/3">3</a>', field.format.formatted_custom_value(self, custom_value, true)
35
    assert_equal '<a href="http://foo/3" class="external">3</a>', field.format.formatted_custom_value(self, custom_value, true)
36 36
  end
37 37
end
(1-1/3)