diff --git a/vendor/plugins/HTML5lib/lib/html5/sanitizer.rb b/vendor/plugins/HTML5lib/lib/html5/sanitizer.rb index 1b771b23..8d05e96c 100644 --- a/vendor/plugins/HTML5lib/lib/html5/sanitizer.rb +++ b/vendor/plugins/HTML5lib/lib/html5/sanitizer.rb @@ -78,8 +78,12 @@ module HTML5 ATTR_VAL_IS_URI = %w[href src cite action longdesc xlink:href xml:base] - SVG_ATTR_VAL_ALLOWS_REF = %w[clip-path fill filter marker marker-start - marker-mid marker-end mask stroke textpath] + SVG_ATTR_VAL_ALLOWS_REF = %w[clip-path color-profile cursor fill + filter marker marker-start marker-mid marker-end mask stroke] + + SVG_ALLOW_LOCAL_HREF = %w[altGlyph animate animateColor animateMotion + animateTransform cursor feImage filter linearGradient pattern + radialGradient textpath tref set use] ACCEPTABLE_CSS_PROPERTIES = %w[azimuth background-color border-bottom-color border-collapse border-color border-left-color @@ -127,6 +131,9 @@ module HTML5 SVG_ATTR_VAL_ALLOWS_REF.each do |attr| attrs[attr] = attrs[attr].to_s.gsub(/url\s*\(\s*[^#\s][^)]+?\)/m, ' ') if attrs[attr] end + if SVG_ALLOW_LOCAL_HREF.include?(token[:name]) && attrs['xlink:href'] && attrs['xlink:href'] =~ /^\s*[^#\s].*/m + attrs.delete 'xlink:href' + end if attrs['style'] attrs['style'] = sanitize_css(attrs['style']) end diff --git a/vendor/plugins/HTML5lib/tests/test_sanitizer.rb b/vendor/plugins/HTML5lib/tests/test_sanitizer.rb index 375a1a15..d53df925 100644 --- a/vendor/plugins/HTML5lib/tests/test_sanitizer.rb +++ b/vendor/plugins/HTML5lib/tests/test_sanitizer.rb @@ -110,6 +110,37 @@ class SanitizeTest < Test::Unit::TestCase end end + HTMLSanitizer::SVG_ALLOW_LOCAL_HREF.each do |tag_name| + next unless HTMLSanitizer::ALLOWED_ELEMENTS.include?(tag_name) + define_method "test_#{tag_name}_should_allow_local_href" do + input = %(<#{tag_name} xlink:href="#foo"/>) + output = "<#{tag_name.downcase} xlink:href='#foo'/>" + xhtmloutput = "<#{tag_name} xlink:href='#foo'>" + check_sanitization(input, output, xhtmloutput, xhtmloutput) + end + + define_method "test_#{tag_name}_should_allow_local_href_with_newline" do + input = %(<#{tag_name} xlink:href="\n#foo"/>) + output = "<#{tag_name.downcase} xlink:href='\n#foo'/>" + xhtmloutput = "<#{tag_name} xlink:href='\n#foo'>" + check_sanitization(input, output, xhtmloutput, xhtmloutput) + end + + define_method "test_#{tag_name}_should_forbid_nonlocal_href" do + input = %(<#{tag_name} xlink:href="http://bad.com/foo"/>) + output = "<#{tag_name.downcase}/>" + xhtmloutput = "<#{tag_name}>" + check_sanitization(input, output, xhtmloutput, xhtmloutput) + end + + define_method "test_#{tag_name}_should_forbid_nonlocal_href_with_newline" do + input = %(<#{tag_name} xlink:href="\nhttp://bad.com/foo"/>) + output = "<#{tag_name.downcase}/>" + xhtmloutput = "<#{tag_name}>" + check_sanitization(input, output, xhtmloutput, xhtmloutput) + end + end + def test_should_handle_astral_plane_characters input = "

𝒵 𝔸

" output = "

\360\235\222\265 \360\235\224\270

"