diff --git a/CHANGELOG.md b/CHANGELOG.md index 28135a08..ce4b1455 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 2.3.0 / unreleased + +Features: + +* Expand set of allowed protocols to include `tel:` and `line:`. [#104, #147] +* Expand set of allowed CSS functions. [related to #122] +* Allow greater precision in shorthand CSS values. [#149] (Thanks, @danfstucky!) + + ## Meta / 2018-10-27 The mailing list is now on Google Groups [#146](https://github.com/flavorjones/loofah/issues/146): diff --git a/lib/loofah/html5/scrub.rb b/lib/loofah/html5/scrub.rb index 9f268e1d..82e6b099 100644 --- a/lib/loofah/html5/scrub.rb +++ b/lib/loofah/html5/scrub.rb @@ -6,7 +6,7 @@ module HTML5 # :nodoc: module Scrub CONTROL_CHARACTERS = /[`\u0000-\u0020\u007f\u0080-\u0101]/ - CSS_KEYWORDISH = /\A(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|-?\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)\z/ + CSS_KEYWORDISH = /\A(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|-?\d{0,3}\.?\d{0,10}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)\z/ CRASS_SEMICOLON = {:node => :semicolon, :raw => ";"} class << self diff --git a/lib/loofah/html5/whitelist.rb b/lib/loofah/html5/whitelist.rb index 109356c1..6a3acb8c 100644 --- a/lib/loofah/html5/whitelist.rb +++ b/lib/loofah/html5/whitelist.rb @@ -46,111 +46,713 @@ module HTML5 # :nodoc: # module WhiteList - ACCEPTABLE_ELEMENTS = Set.new %w[a abbr acronym address area - article aside audio b bdi bdo big blockquote br button canvas - caption center cite code col colgroup command datalist dd del - details dfn dir div dl dt em fieldset figcaption figure footer - font form h1 h2 h3 h4 h5 h6 header hr i img input ins kbd label - legend li main map mark menu meter nav ol output optgroup option p - pre q s samp section select small span strike strong sub summary - sup table tbody td textarea tfoot th thead time tr tt u ul var - video] - - MATHML_ELEMENTS = Set.new %w[annotation annotation-xml maction math merror mfrac - mfenced mi mmultiscripts mn mo mover mpadded mphantom mprescripts mroot mrow - mspace msqrt mstyle msub msubsup msup mtable mtd mtext mtr munder - munderover none semantics] - - SVG_ELEMENTS = Set.new %w[a animate animateColor animateMotion animateTransform - circle clipPath defs desc ellipse feGaussianBlur filter font-face - font-face-name font-face-src foreignObject - g glyph hkern linearGradient line marker mask metadata missing-glyph - mpath path polygon polyline radialGradient rect set stop svg switch symbol - text textPath title tspan use] - - ACCEPTABLE_ATTRIBUTES = Set.new %w[abbr accept accept-charset accesskey action - align alt axis border cellpadding cellspacing char charoff charset - checked cite class clear cols colspan color compact coords datetime - dir disabled enctype for frame headers height href hreflang hspace id - ismap label lang longdesc loop loopcount loopend loopstart - maxlength media method multiple name nohref - noshade nowrap poster preload prompt readonly rel rev rows rowspan rules scope - selected shape size span src start style summary tabindex target title - type usemap valign value vspace width xml:lang] - - MATHML_ATTRIBUTES = Set.new %w[actiontype align close - columnalign columnlines columnspacing columnspan depth display - displaystyle encoding equalcolumns equalrows fence fontstyle fontweight - frame height linethickness lspace mathbackground mathcolor mathvariant - maxsize minsize open other rowalign rowlines - rowspacing rowspan rspace scriptlevel selection separator separators - stretchy width xlink:href xlink:show xlink:type xmlns xmlns:xlink] - - SVG_ATTRIBUTES = Set.new %w[accent-height accumulate additive alphabetic - arabic-form ascent attributeName attributeType baseProfile bbox begin - by calcMode cap-height class clip-path clip-rule color - color-interpolation-filters color-rendering content cx cy d dx - dy descent display dur end fill fill-opacity fill-rule - filterRes filterUnits font-family - font-size font-stretch font-style font-variant font-weight from fx fy g1 - g2 glyph-name gradientUnits hanging height horiz-adv-x horiz-origin-x id - ideographic k keyPoints keySplines keyTimes lang marker-end - marker-mid marker-start markerHeight markerUnits markerWidth - maskContentUnits maskUnits mathematical max method min name offset opacity orient origin - overline-position overline-thickness panose-1 path pathLength - patternContentUnits patternTransform patternUnits points - preserveAspectRatio primitiveUnits r refX refY repeatCount repeatDur - requiredExtensions requiredFeatures restart rotate rx ry slope spacing - startOffset stdDeviation stemh - stemv stop-color stop-opacity strikethrough-position - strikethrough-thickness stroke stroke-dasharray stroke-dashoffset - stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity - stroke-width systemLanguage target text-anchor to transform type u1 - u2 underline-position underline-thickness unicode unicode-range - units-per-em values version viewBox visibility width widths x - x-height x1 x2 xlink:actuate xlink:arcrole xlink:href xlink:role - xlink:show xlink:title xlink:type xml:base xml:lang xml:space xmlns - xmlns:xlink y y1 y2 zoomAndPan] - - ATTR_VAL_IS_URI = Set.new %w[href src cite action longdesc xlink:href xml:base poster preload] - - SVG_ATTR_VAL_ALLOWS_REF = Set.new %w[clip-path color-profile cursor fill - filter marker marker-start marker-mid marker-end mask stroke] - - SVG_ALLOW_LOCAL_HREF = Set.new %w[altGlyph animate animateColor animateMotion - animateTransform cursor feImage filter linearGradient pattern - radialGradient textpath tref set use] - - ACCEPTABLE_CSS_PROPERTIES = Set.new %w[azimuth background-color - border-bottom-color border-collapse border-color border-left-color - border-right-color border-top-color clear color cursor direction - display elevation float font font-family font-size font-style - font-variant font-weight height letter-spacing line-height list-style-type - overflow pause pause-after pause-before pitch pitch-range richness speak - speak-header speak-numeral speak-punctuation speech-rate stress - text-align text-decoration text-indent unicode-bidi vertical-align - voice-family volume white-space width] - - ACCEPTABLE_CSS_KEYWORDS = Set.new %w[auto aqua black block blue bold both bottom - brown center collapse dashed dotted fuchsia gray green !important - italic left lime maroon medium none navy normal nowrap olive pointer - purple red right solid silver teal top transparent underline white - yellow] - - ACCEPTABLE_CSS_FUNCTIONS = Set.new %w[calc rgb] - - SHORTHAND_CSS_PROPERTIES = Set.new %w[background border margin padding] - - ACCEPTABLE_SVG_PROPERTIES = Set.new %w[fill fill-opacity fill-rule stroke - stroke-width stroke-linecap stroke-linejoin stroke-opacity] + ACCEPTABLE_ELEMENTS = Set.new([ + "a", + "abbr", + "acronym", + "address", + "area", + "article", + "aside", + "audio", + "b", + "bdi", + "bdo", + "big", + "blockquote", + "br", + "button", + "canvas", + "caption", + "center", + "cite", + "code", + "col", + "colgroup", + "command", + "datalist", + "dd", + "del", + "details", + "dfn", + "dir", + "div", + "dl", + "dt", + "em", + "fieldset", + "figcaption", + "figure", + "font", + "footer", + "form", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "header", + "hr", + "i", + "img", + "input", + "ins", + "kbd", + "label", + "legend", + "li", + "main", + "map", + "mark", + "menu", + "meter", + "nav", + "ol", + "optgroup", + "option", + "output", + "p", + "pre", + "q", + "s", + "samp", + "section", + "select", + "small", + "span", + "strike", + "strong", + "sub", + "summary", + "sup", + "table", + "tbody", + "td", + "textarea", + "tfoot", + "th", + "thead", + "time", + "tr", + "tt", + "u", + "ul", + "var", + "video", + ]) + + MATHML_ELEMENTS = Set.new([ + "annotation", + "annotation-xml", + "maction", + "math", + "merror", + "mfenced", + "mfrac", + "mi", + "mmultiscripts", + "mn", + "mo", + "mover", + "mpadded", + "mphantom", + "mprescripts", + "mroot", + "mrow", + "mspace", + "msqrt", + "mstyle", + "msub", + "msubsup", + "msup", + "mtable", + "mtd", + "mtext", + "mtr", + "munder", + "munderover", + "none", + "semantics", + ]) + + SVG_ELEMENTS = Set.new([ + "a", + "animate", + "animateColor", + "animateMotion", + "animateTransform", + "circle", + "clipPath", + "defs", + "desc", + "ellipse", + "feGaussianBlur", + "filter", + "font-face", + "font-face-name", + "font-face-src", + "foreignObject", + "g", + "glyph", + "hkern", + "line", + "linearGradient", + "marker", + "mask", + "metadata", + "missing-glyph", + "mpath", + "path", + "polygon", + "polyline", + "radialGradient", + "rect", + "set", + "stop", + "svg", + "switch", + "symbol", + "text", + "textPath", + "title", + "tspan", + "use", + ]) + + ACCEPTABLE_ATTRIBUTES = Set.new([ + "abbr", + "accept", + "accept-charset", + "accesskey", + "action", + "align", + "alt", + "axis", + "border", + "cellpadding", + "cellspacing", + "char", + "charoff", + "charset", + "checked", + "cite", + "class", + "clear", + "color", + "cols", + "colspan", + "compact", + "coords", + "datetime", + "dir", + "disabled", + "enctype", + "for", + "frame", + "headers", + "height", + "href", + "hreflang", + "hspace", + "id", + "ismap", + "label", + "lang", + "longdesc", + "loop", + "loopcount", + "loopend", + "loopstart", + "maxlength", + "media", + "method", + "multiple", + "name", + "nohref", + "noshade", + "nowrap", + "poster", + "preload", + "prompt", + "readonly", + "rel", + "rev", + "rows", + "rowspan", + "rules", + "scope", + "selected", + "shape", + "size", + "span", + "src", + "start", + "style", + "summary", + "tabindex", + "target", + "title", + "type", + "usemap", + "valign", + "value", + "vspace", + "width", + "xml:lang", + ]) + + MATHML_ATTRIBUTES = Set.new([ + "actiontype", + "align", + "close", + "columnalign", + "columnlines", + "columnspacing", + "columnspan", + "depth", + "display", + "displaystyle", + "encoding", + "equalcolumns", + "equalrows", + "fence", + "fontstyle", + "fontweight", + "frame", + "height", + "linethickness", + "lspace", + "mathbackground", + "mathcolor", + "mathvariant", + "maxsize", + "minsize", + "open", + "other", + "rowalign", + "rowlines", + "rowspacing", + "rowspan", + "rspace", + "scriptlevel", + "selection", + "separator", + "separators", + "stretchy", + "width", + "xlink:href", + "xlink:show", + "xlink:type", + "xmlns", + "xmlns:xlink", + ]) + + SVG_ATTRIBUTES = Set.new([ + "accent-height", + "accumulate", + "additive", + "alphabetic", + "arabic-form", + "ascent", + "attributeName", + "attributeType", + "baseProfile", + "bbox", + "begin", + "by", + "calcMode", + "cap-height", + "class", + "clip-path", + "clip-rule", + "color", + "color-interpolation-filters", + "color-rendering", + "content", + "cx", + "cy", + "d", + "descent", + "display", + "dur", + "dx", + "dy", + "end", + "fill", + "fill-opacity", + "fill-rule", + "filterRes", + "filterUnits", + "font-family", + "font-size", + "font-stretch", + "font-style", + "font-variant", + "font-weight", + "from", + "fx", + "fy", + "g1", + "g2", + "glyph-name", + "gradientUnits", + "hanging", + "height", + "horiz-adv-x", + "horiz-origin-x", + "id", + "ideographic", + "k", + "keyPoints", + "keySplines", + "keyTimes", + "lang", + "marker-end", + "marker-mid", + "marker-start", + "markerHeight", + "markerUnits", + "markerWidth", + "maskContentUnits", + "maskUnits", + "mathematical", + "max", + "method", + "min", + "name", + "offset", + "opacity", + "orient", + "origin", + "overline-position", + "overline-thickness", + "panose-1", + "path", + "pathLength", + "patternContentUnits", + "patternTransform", + "patternUnits", + "points", + "preserveAspectRatio", + "primitiveUnits", + "r", + "refX", + "refY", + "repeatCount", + "repeatDur", + "requiredExtensions", + "requiredFeatures", + "restart", + "rotate", + "rx", + "ry", + "slope", + "spacing", + "startOffset", + "stdDeviation", + "stemh", + "stemv", + "stop-color", + "stop-opacity", + "strikethrough-position", + "strikethrough-thickness", + "stroke", + "stroke-dasharray", + "stroke-dashoffset", + "stroke-linecap", + "stroke-linejoin", + "stroke-miterlimit", + "stroke-opacity", + "stroke-width", + "systemLanguage", + "target", + "text-anchor", + "to", + "transform", + "type", + "u1", + "u2", + "underline-position", + "underline-thickness", + "unicode", + "unicode-range", + "units-per-em", + "values", + "version", + "viewBox", + "visibility", + "width", + "widths", + "x", + "x-height", + "x1", + "x2", + "xlink:actuate", + "xlink:arcrole", + "xlink:href", + "xlink:role", + "xlink:show", + "xlink:title", + "xlink:type", + "xml:base", + "xml:lang", + "xml:space", + "xmlns", + "xmlns:xlink", + "y", + "y1", + "y2", + "zoomAndPan", + ]) + + ATTR_VAL_IS_URI = Set.new([ + "action", + "cite", + "href", + "longdesc", + "poster", + "preload", + "src", + "xlink:href", + "xml:base", + ]) + + SVG_ATTR_VAL_ALLOWS_REF = Set.new([ + "clip-path", + "color-profile", + "cursor", + "fill", + "filter", + "marker", + "marker-end", + "marker-mid", + "marker-start", + "mask", + "stroke", + ]) + + SVG_ALLOW_LOCAL_HREF = Set.new([ + "altGlyph", + "animate", + "animateColor", + "animateMotion", + "animateTransform", + "cursor", + "feImage", + "filter", + "linearGradient", + "pattern", + "radialGradient", + "set", + "textpath", + "tref", + "use", + ]) + + ACCEPTABLE_CSS_PROPERTIES = Set.new([ + "azimuth", + "background-color", + "border-bottom-color", + "border-collapse", + "border-color", + "border-left-color", + "border-right-color", + "border-top-color", + "clear", + "color", + "cursor", + "direction", + "display", + "elevation", + "float", + "font", + "font-family", + "font-size", + "font-style", + "font-variant", + "font-weight", + "height", + "letter-spacing", + "line-height", + "list-style-type", + "overflow", + "pause", + "pause-after", + "pause-before", + "pitch", + "pitch-range", + "richness", + "speak", + "speak-header", + "speak-numeral", + "speak-punctuation", + "speech-rate", + "stress", + "text-align", + "text-decoration", + "text-indent", + "unicode-bidi", + "vertical-align", + "voice-family", + "volume", + "white-space", + "width", + ]) + + ACCEPTABLE_CSS_KEYWORDS = Set.new([ + "!important", + "aqua", + "auto", + "black", + "block", + "blue", + "bold", + "both", + "bottom", + "brown", + "center", + "collapse", + "dashed", + "dotted", + "fuchsia", + "gray", + "green", + "italic", + "left", + "lime", + "maroon", + "medium", + "navy", + "none", + "normal", + "nowrap", + "olive", + "pointer", + "purple", + "red", + "right", + "silver", + "solid", + "teal", + "top", + "transparent", + "underline", + "white", + "yellow", + ]) + + # see https://www.quackit.com/css/functions/ + # omit `url` and `image` from that list + ACCEPTABLE_CSS_FUNCTIONS = Set.new([ + "attr", + "blur", + "brightness", + "calc", + "circle", + "contrast", + "counter", + "counters", + "cubic-bezier", + "drop-shadow", + "ellipse", + "grayscale", + "hsl", + "hsla", + "hue-rotate", + "hwb", + "inset", + "invert", + "linear-gradient", + "matrix", + "matrix3d", + "opacity", + "perspective", + "polygon", + "radial-gradient", + "repeating-linear-gradient", + "repeating-radial-gradient", + "rgb", + "rgba", + "rotate", + "rotate3d", + "rotateX", + "rotateY", + "rotateZ", + "saturate", + "sepia", + "scale", + "scale3d", + "scaleX", + "scaleY", + "scaleZ", + "skew", + "skewX", + "skewY", + "symbols", + "translate", + "translate3d", + "translateX", + "translateY", + "translateZ", + ]) + + SHORTHAND_CSS_PROPERTIES = Set.new([ + "background", + "border", + "margin", + "padding", + ]) + + ACCEPTABLE_SVG_PROPERTIES = Set.new([ + "fill", + "fill-opacity", + "fill-rule", + "stroke", + "stroke-width", + "stroke-linecap", + "stroke-linejoin", + "stroke-opacity", + ]) PROTOCOL_SEPARATOR = /:|(�*58)|(p)|(�*3a)|(%|%)3A/i - ACCEPTABLE_PROTOCOLS = Set.new %w[ed2k ftp http https irc mailto news gopher nntp - telnet webcal xmpp callto feed urn aim rsync tag ssh sftp rtsp afs data] + ACCEPTABLE_PROTOCOLS = Set.new([ + "afs", + "aim", + "callto", + "data", + "ed2k", + "feed", + "ftp", + "gopher", + "http", + "https", + "irc", + "line", + "mailto", + "news", + "nntp", + "rsync", + "rtsp", + "sftp", + "ssh", + "tag", + "tel", + "telnet", + "urn", + "webcal", + "xmpp", + ]) - ACCEPTABLE_URI_DATA_MEDIATYPES = Set.new %w[text/plain text/css image/png image/gif - image/jpeg image/svg+xml] + ACCEPTABLE_URI_DATA_MEDIATYPES = Set.new([ + "image/gif", + "image/jpeg", + "image/png", + "image/svg+xml", + "text/css", + "text/plain", + ]) # subclasses may define their own versions of these constants ALLOWED_ELEMENTS = ACCEPTABLE_ELEMENTS + MATHML_ELEMENTS + SVG_ELEMENTS @@ -162,22 +764,26 @@ module WhiteList ALLOWED_PROTOCOLS = ACCEPTABLE_PROTOCOLS ALLOWED_URI_DATA_MEDIATYPES = ACCEPTABLE_URI_DATA_MEDIATYPES - VOID_ELEMENTS = Set.new %w[ - base - link - meta - hr - br - img - embed - param - area - col - input - ] + VOID_ELEMENTS = Set.new([ + "area", + "base", + "br", + "col", + "embed", + "hr", + "img", + "input", + "link", + "meta", + "param", + ]) # additional tags we should consider safe since we have libxml2 fixing up our documents. - TAGS_SAFE_WITH_LIBXML2 = Set.new %w[html head body] + TAGS_SAFE_WITH_LIBXML2 = Set.new([ + "body", + "head", + "html", + ]) ALLOWED_ELEMENTS_WITH_LIBXML2 = ALLOWED_ELEMENTS + TAGS_SAFE_WITH_LIBXML2 end diff --git a/tasks/dompurify-to-json b/tasks/dompurify-to-json new file mode 100755 index 00000000..8827652a --- /dev/null +++ b/tasks/dompurify-to-json @@ -0,0 +1,15 @@ +#! /usr/bin/env node + +require('babel-register')({ + presets: [ 'env' ] +}) + +const dir = "../../DOMPurify" ; +// const dir = "../tmp/DOMPUrify" ; + +metadata = { + "attrs": require(dir + "/src/attrs"), + "tags": require(dir + "/src/tags") +}; + +process.stdout.write(JSON.stringify(metadata)); diff --git a/tasks/generate-allowlists b/tasks/generate-allowlists new file mode 100755 index 00000000..cd2b13a0 --- /dev/null +++ b/tasks/generate-allowlists @@ -0,0 +1,56 @@ +#! /usr/bin/env ruby + +require "open3" +require "json" +require "fileutils" + +TEMP_DIR = "tmp" +DOMPURIFY_URL = "https://github.com/cure53/DOMPurify" +DOMPURIFY_VERSION = "1.0.8" + +# FileUtils.mkdir_p TEMP_DIR +# Dir.chdir TEMP_DIR do +# system("git clone #{DOMPURIFY_URL}")unless Dir.exist?("DOMPurify") + +# Dir.chdir "DOMPurify" do +# system("npm install") unless Dir.exist?("node_modules") +# system "git checkout #{DOMPURIFY_VERSION}" +# end +# end + +dompurify_metadata = Open3.popen2("tasks/dompurify-to-json") do |stdin, stdout, wait_thr| + raise wait_thr.value.to_s unless wait_thr.value.success? + JSON.parse(stdout.read) +end + +dompurify_metadata.each { |k, v| puts "#{k}: #{v.keys}" } + +require "loofah" + +pairs = { + "html:tags" => [Loofah::HTML5::WhiteList::ACCEPTABLE_ELEMENTS, dompurify_metadata["tags"]["html"]], + "mathml:tags" => [Loofah::HTML5::WhiteList::MATHML_ELEMENTS, dompurify_metadata["tags"]["mathMl"]], + "svg:tags" => [Loofah::HTML5::WhiteList::SVG_ELEMENTS, dompurify_metadata["tags"]["svg"]], + "html:attrs" => [Loofah::HTML5::WhiteList::ACCEPTABLE_ATTRIBUTES, dompurify_metadata["attrs"]["html"]], + "mathml:attrs" => [Loofah::HTML5::WhiteList::MATHML_ATTRIBUTES, dompurify_metadata["attrs"]["mathMl"]], + "svg:attrs" => [Loofah::HTML5::WhiteList::SVG_ATTRIBUTES, dompurify_metadata["attrs"]["svg"]], +} + +pairs.each do |name, v| + existing, updated = *v + + existing = existing.to_a.sort + updated = updated.to_a.sort + + removals = existing - updated + additions = updated - existing + + puts "#{name}:" + puts " removals (#{removals.length}):" + puts " #{removals}" + puts " additions (#{additions.length}):" + puts " #{additions}" + puts +end + +# TODO actually generate whitelists diff --git a/tasks/generate-whitelists b/tasks/generate-whitelists deleted file mode 100755 index f15d8f27..00000000 --- a/tasks/generate-whitelists +++ /dev/null @@ -1,63 +0,0 @@ -#! /usr/bin/env ruby - -LOOFAH_LIB = File.join(File.dirname(__FILE__), "..", "lib") - -require "nokogiri" -require "open-uri" -require "set" -require "yaml" - -whitelist = {} -# ymlfile = File.join(LOOFAH_LIB, "loofah", "html5", "whitelists.yml") - -html5_spec = Nokogiri.HTML open "http://www.w3.org/TR/html-markup/elements.html" -html5_els = Set.new html5_spec.css(".toc-section-name .element").map(&:content).map(&:downcase).map(&:strip) -raise "couldn't parse valid spec" unless html5_els.length > 100 -whitelist["HTML5_ELEMENTS"] = html5_els.to_a.sort -puts "found #{html5_els.length} html5 els in the spec:" -puts html5_els.to_a.sort.to_s -puts - -html4_spec = Nokogiri.HTML open "http://www.w3.org/TR/html4/index/elements.html" -html4_els = Set.new html4_spec.css("td a").map(&:content).map(&:downcase).map(&:strip) -raise "couldn't parse valid spec" unless html4_els.length > 90 -whitelist["HTML4_ELEMENTS"] = html4_els.to_a.sort -puts "found #{html4_els.length} html4 els in the spec:" -puts html4_els.to_a.sort.to_s -puts - -html_els = html5_els + html4_els -whitelist["HTML_ELEMENTS"] = html_els.to_a.sort -puts "there are #{html_els.length} html els specified:" -puts html_els.to_a.sort.to_s -puts - -# html5 attributes ??? -# html4 attributes http://www.w3.org/TR/html4/index/attributes.html -# mathml3 elements http://www.w3.org/TR/MathML3/appendixi.html#index.elem -# mathml3 attributes http://www.w3.org/TR/MathML3/appendixi.html#index.elem -# mathml2 elements http://www.w3.org/TR/MathML2/appendixl.html#index.elem -# mathml2 attributes http://www.w3.org/TR/MathML2/appendixl.html#index.elem -# svg1.1 elements http://www.w3.org/TR/SVG/eltindex.html -# svg1.1 attributes http://www.w3.org/TR/SVG/attindex.html -# svg1.1 properties http://www.w3.org/TR/SVG/propidx.html - -# File.open(ymlfile, "w") { |f| f.write whitelist.to_yaml } - - -# -# check for differences (for now) -# -$: << LOOFAH_LIB -require "loofah" - -surprising_spec_elements = html_els - Loofah::HTML5::WhiteList::ACCEPTABLE_ELEMENTS -interesting_whitelist_elements = Loofah::HTML5::WhiteList::ACCEPTABLE_ELEMENTS - html_els - -puts "found #{surprising_spec_elements.length} surprising new elements found in the spec:" -puts surprising_spec_elements.to_a.sort.to_s -puts - -puts "found #{interesting_whitelist_elements.length} interesting elements found in the whitelist:" -puts interesting_whitelist_elements.to_a.to_s -puts diff --git a/test/html5/test_sanitizer.rb b/test/html5/test_sanitizer.rb index 3eef9eb2..49c3974c 100755 --- a/test/html5/test_sanitizer.rb +++ b/test/html5/test_sanitizer.rb @@ -275,6 +275,12 @@ def test_css_negative_value_sanitization_shorthand_css_properties assert_match %r/-0.05em/, sane.inner_html end + def test_css_high_precision_value_shorthand_css_properties + html = "" + sane = Nokogiri::HTML(Loofah.scrub_fragment(html, :escape).to_xml) + assert_match %r/0.3333333334em/, sane.inner_html + end + def test_css_function_sanitization_leaves_whitelisted_functions_calc html = "" sane = Nokogiri::HTML(Loofah.scrub_fragment(html, :strip).to_html) @@ -298,11 +304,11 @@ def test_css_function_sanitization_leaves_whitelisted_list_style_type end def test_css_function_sanitization_strips_style_attributes_with_unsafe_functions - html = "" + html = "" sane = Nokogiri::HTML(Loofah.scrub_fragment(html, :strip).to_html) assert_match %r/<\/span>/, sane.inner_html - html = "" + html = "" sane = Nokogiri::HTML(Loofah.scrub_fragment(html, :strip).to_html) assert_match %r/<\/span>/, sane.inner_html end