summaryrefslogtreecommitdiff
path: root/lib/banzai/filter/ascii_doc_sanitization_filter.rb
diff options
context:
space:
mode:
authorGuillaume Grossetie <ggrossetie@gmail.com>2019-07-03 10:53:00 +0200
committerGuillaume Grossetie <ggrossetie@gmail.com>2019-07-12 09:35:50 +0200
commita546b9fbc5abdb010c19a2fb24e8df50001374f7 (patch)
tree794bd6bc4b055eef18046ca945936648ae055138 /lib/banzai/filter/ascii_doc_sanitization_filter.rb
parentdece84065f9dee04661e54af4f7016e7c50b63a6 (diff)
downloadgitlab-ce-a546b9fbc5abdb010c19a2fb24e8df50001374f7.tar.gz
Prevent excessive sanitization of AsciiDoc ouptut
Diffstat (limited to 'lib/banzai/filter/ascii_doc_sanitization_filter.rb')
-rw-r--r--lib/banzai/filter/ascii_doc_sanitization_filter.rb62
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/banzai/filter/ascii_doc_sanitization_filter.rb b/lib/banzai/filter/ascii_doc_sanitization_filter.rb
new file mode 100644
index 00000000000..a78bb60103c
--- /dev/null
+++ b/lib/banzai/filter/ascii_doc_sanitization_filter.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+module Banzai
+ module Filter
+ # Sanitize HTML produced by AsciiDoc/Asciidoctor.
+ #
+ # Extends Banzai::Filter::BaseSanitizationFilter with specific rules.
+ class AsciiDocSanitizationFilter < Banzai::Filter::BaseSanitizationFilter
+ # Classes used by Asciidoctor to style components
+ ADMONITION_CLASSES = %w(fa icon-note icon-tip icon-warning icon-caution icon-important).freeze
+ CALLOUT_CLASSES = ['conum'].freeze
+ CHECKLIST_CLASSES = %w(fa fa-check-square-o fa-square-o).freeze
+
+ LIST_CLASSES = %w(checklist none no-bullet unnumbered unstyled).freeze
+
+ ELEMENT_CLASSES_WHITELIST = {
+ span: %w(big small underline overline line-through).freeze,
+ div: ['admonitionblock'].freeze,
+ td: ['icon'].freeze,
+ i: ADMONITION_CLASSES + CALLOUT_CLASSES + CHECKLIST_CLASSES,
+ ul: LIST_CLASSES,
+ ol: LIST_CLASSES
+ }.freeze
+
+ def customize_whitelist(whitelist)
+ # Allow marks
+ whitelist[:elements].push('mark')
+
+ # Allow any classes in `span`, `i`, `div`, `td`, `ul` and `ol` elements
+ # but then remove any unknown classes
+ whitelist[:attributes]['span'] = %w(class)
+ whitelist[:attributes]['div'].push('class')
+ whitelist[:attributes]['td'] = %w(class)
+ whitelist[:attributes]['i'] = %w(class)
+ whitelist[:attributes]['ul'] = %w(class)
+ whitelist[:attributes]['ol'] = %w(class)
+ whitelist[:transformers].push(self.class.remove_element_classes)
+
+ whitelist
+ end
+
+ class << self
+ def remove_element_classes
+ lambda do |env|
+ node = env[:node]
+
+ return unless (classes_whitelist = ELEMENT_CLASSES_WHITELIST[node.name.to_sym])
+ return unless node.has_attribute?('class')
+
+ classes = node['class'].strip.split(' ')
+ allowed_classes = (classes & classes_whitelist)
+ if allowed_classes.empty?
+ node.remove_attribute('class')
+ else
+ node['class'] = allowed_classes.join(' ')
+ end
+ end
+ end
+ end
+ end
+ end
+end