Patch #37750 » 0003-uses-the-new-html-sanitizer-for-links-rendered-by-cu.patch
| 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 |