loofah 2.2.3 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of loofah might be problematic. Click here for more details.

Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +124 -31
  3. data/README.md +12 -16
  4. data/lib/loofah.rb +35 -18
  5. data/lib/loofah/elements.rb +74 -73
  6. data/lib/loofah/helpers.rb +18 -7
  7. data/lib/loofah/html/document.rb +1 -0
  8. data/lib/loofah/html/document_fragment.rb +4 -2
  9. data/lib/loofah/html5/libxml2_workarounds.rb +8 -7
  10. data/lib/loofah/html5/safelist.rb +819 -0
  11. data/lib/loofah/html5/scrub.rb +63 -46
  12. data/lib/loofah/instance_methods.rb +5 -3
  13. data/lib/loofah/metahelpers.rb +2 -1
  14. data/lib/loofah/scrubber.rb +8 -7
  15. data/lib/loofah/scrubbers.rb +12 -11
  16. data/lib/loofah/version.rb +5 -0
  17. data/lib/loofah/xml/document.rb +1 -0
  18. data/lib/loofah/xml/document_fragment.rb +2 -1
  19. metadata +40 -112
  20. data/.gemtest +0 -0
  21. data/Gemfile +0 -22
  22. data/Manifest.txt +0 -40
  23. data/Rakefile +0 -79
  24. data/benchmark/benchmark.rb +0 -149
  25. data/benchmark/fragment.html +0 -96
  26. data/benchmark/helper.rb +0 -73
  27. data/benchmark/www.slashdot.com.html +0 -2560
  28. data/lib/loofah/html5/whitelist.rb +0 -186
  29. data/test/assets/msword.html +0 -63
  30. data/test/assets/testdata_sanitizer_tests1.dat +0 -502
  31. data/test/helper.rb +0 -18
  32. data/test/html5/test_sanitizer.rb +0 -382
  33. data/test/integration/test_ad_hoc.rb +0 -204
  34. data/test/integration/test_helpers.rb +0 -43
  35. data/test/integration/test_html.rb +0 -72
  36. data/test/integration/test_scrubbers.rb +0 -400
  37. data/test/integration/test_xml.rb +0 -55
  38. data/test/unit/test_api.rb +0 -142
  39. data/test/unit/test_encoding.rb +0 -20
  40. data/test/unit/test_helpers.rb +0 -62
  41. data/test/unit/test_scrubber.rb +0 -229
  42. data/test/unit/test_scrubbers.rb +0 -14
@@ -1,104 +1,122 @@
1
- require 'cgi'
2
- require 'crass'
1
+ # frozen_string_literal: true
2
+ require "cgi"
3
+ require "crass"
3
4
 
4
5
  module Loofah
5
6
  module HTML5 # :nodoc:
6
7
  module Scrub
7
-
8
8
  CONTROL_CHARACTERS = /[`\u0000-\u0020\u007f\u0080-\u0101]/
9
- 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/
10
- CRASS_SEMICOLON = {:node => :semicolon, :raw => ";"}
9
+ CSS_KEYWORDISH = /\A(#[0-9a-fA-F]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|-?\d{0,3}\.?\d{0,10}(ch|cm|r?em|ex|in|lh|mm|pc|pt|px|Q|vmax|vmin|vw|vh|%|,|\))?)\z/
10
+ CRASS_SEMICOLON = { node: :semicolon, raw: ";" }
11
+ CSS_IMPORTANT = '!important'
11
12
 
12
13
  class << self
13
-
14
- def allowed_element? element_name
15
- ::Loofah::HTML5::WhiteList::ALLOWED_ELEMENTS_WITH_LIBXML2.include? element_name
14
+ def allowed_element?(element_name)
15
+ ::Loofah::HTML5::SafeList::ALLOWED_ELEMENTS_WITH_LIBXML2.include?(element_name)
16
16
  end
17
17
 
18
18
  # alternative implementation of the html5lib attribute scrubbing algorithm
19
- def scrub_attributes node
19
+ def scrub_attributes(node)
20
20
  node.attribute_nodes.each do |attr_node|
21
21
  attr_name = if attr_node.namespace
22
- "#{attr_node.namespace.prefix}:#{attr_node.node_name}"
23
- else
24
- attr_node.node_name
25
- end
22
+ "#{attr_node.namespace.prefix}:#{attr_node.node_name}"
23
+ else
24
+ attr_node.node_name
25
+ end
26
26
 
27
27
  if attr_name =~ /\Adata-[\w-]+\z/
28
28
  next
29
29
  end
30
30
 
31
- unless WhiteList::ALLOWED_ATTRIBUTES.include?(attr_name)
31
+ unless SafeList::ALLOWED_ATTRIBUTES.include?(attr_name)
32
32
  attr_node.remove
33
33
  next
34
34
  end
35
35
 
36
- if WhiteList::ATTR_VAL_IS_URI.include?(attr_name)
36
+ if SafeList::ATTR_VAL_IS_URI.include?(attr_name)
37
37
  # this block lifted nearly verbatim from HTML5 sanitization
38
- val_unescaped = CGI.unescapeHTML(attr_node.value).gsub(CONTROL_CHARACTERS,'').downcase
39
- if val_unescaped =~ /^[a-z0-9][-+.a-z0-9]*:/ && ! WhiteList::ALLOWED_PROTOCOLS.include?(val_unescaped.split(WhiteList::PROTOCOL_SEPARATOR)[0])
38
+ val_unescaped = CGI.unescapeHTML(attr_node.value).gsub(CONTROL_CHARACTERS, "").downcase
39
+ if val_unescaped =~ /^[a-z0-9][-+.a-z0-9]*:/ && !SafeList::ALLOWED_PROTOCOLS.include?(val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)[0])
40
40
  attr_node.remove
41
41
  next
42
- elsif val_unescaped.split(WhiteList::PROTOCOL_SEPARATOR)[0] == 'data'
42
+ elsif val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)[0] == "data"
43
43
  # permit only allowed data mediatypes
44
- mediatype = val_unescaped.split(WhiteList::PROTOCOL_SEPARATOR)[1]
45
- mediatype, _ = mediatype.split(';')[0..1] if mediatype
46
- if mediatype && !WhiteList::ALLOWED_URI_DATA_MEDIATYPES.include?(mediatype)
44
+ mediatype = val_unescaped.split(SafeList::PROTOCOL_SEPARATOR)[1]
45
+ mediatype, _ = mediatype.split(";")[0..1] if mediatype
46
+ if mediatype && !SafeList::ALLOWED_URI_DATA_MEDIATYPES.include?(mediatype)
47
47
  attr_node.remove
48
48
  next
49
49
  end
50
50
  end
51
51
  end
52
- if WhiteList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name)
53
- attr_node.value = attr_node.value.gsub(/url\s*\(\s*[^#\s][^)]+?\)/m, ' ') if attr_node.value
52
+ if SafeList::SVG_ATTR_VAL_ALLOWS_REF.include?(attr_name)
53
+ attr_node.value = attr_node.value.gsub(/url\s*\(\s*[^#\s][^)]+?\)/m, " ") if attr_node.value
54
54
  end
55
- if WhiteList::SVG_ALLOW_LOCAL_HREF.include?(node.name) && attr_name == 'xlink:href' && attr_node.value =~ /^\s*[^#\s].*/m
55
+ if SafeList::SVG_ALLOW_LOCAL_HREF.include?(node.name) && attr_name == "xlink:href" && attr_node.value =~ /^\s*[^#\s].*/m
56
56
  attr_node.remove
57
57
  next
58
58
  end
59
59
  end
60
60
 
61
- scrub_css_attribute node
61
+ scrub_css_attribute(node)
62
62
 
63
63
  node.attribute_nodes.each do |attr_node|
64
64
  node.remove_attribute(attr_node.name) if attr_node.value !~ /[^[:space:]]/
65
65
  end
66
66
 
67
- force_correct_attribute_escaping! node
67
+ force_correct_attribute_escaping!(node)
68
68
  end
69
69
 
70
- def scrub_css_attribute node
71
- style = node.attributes['style']
70
+ def scrub_css_attribute(node)
71
+ style = node.attributes["style"]
72
72
  style.value = scrub_css(style.value) if style
73
73
  end
74
74
 
75
- def scrub_css style
76
- style_tree = Crass.parse_properties style
75
+ def scrub_css(style)
76
+ style_tree = Crass.parse_properties(style)
77
77
  sanitized_tree = []
78
78
 
79
79
  style_tree.each do |node|
80
80
  next unless node[:node] == :property
81
81
  next if node[:children].any? do |child|
82
- [:url, :bad_url].include?(child[:node]) || (child[:node] == :function && !WhiteList::ALLOWED_CSS_FUNCTIONS.include?(child[:name].downcase))
82
+ [:url, :bad_url].include?(child[:node])
83
83
  end
84
+
84
85
  name = node[:name].downcase
85
- if WhiteList::ALLOWED_CSS_PROPERTIES.include?(name) || WhiteList::ALLOWED_SVG_PROPERTIES.include?(name)
86
- sanitized_tree << node << CRASS_SEMICOLON
87
- elsif WhiteList::SHORTHAND_CSS_PROPERTIES.include?(name.split('-').first)
88
- value = node[:value].split.map do |keyword|
89
- if WhiteList::ALLOWED_CSS_KEYWORDS.include?(keyword) || keyword =~ CSS_KEYWORDISH
86
+ next unless SafeList::ALLOWED_CSS_PROPERTIES.include?(name) ||
87
+ SafeList::ALLOWED_SVG_PROPERTIES.include?(name) ||
88
+ SafeList::SHORTHAND_CSS_PROPERTIES.include?(name.split("-").first)
89
+
90
+ value = node[:children].map do |child|
91
+ case child[:node]
92
+ when :whitespace
93
+ nil
94
+ when :string
95
+ nil
96
+ when :function
97
+ if SafeList::ALLOWED_CSS_FUNCTIONS.include?(child[:name].downcase)
98
+ Crass::Parser.stringify(child)
99
+ end
100
+ when :ident
101
+ keyword = child[:value]
102
+ if !SafeList::SHORTHAND_CSS_PROPERTIES.include?(name.split("-").first) ||
103
+ SafeList::ALLOWED_CSS_KEYWORDS.include?(keyword) ||
104
+ (keyword =~ CSS_KEYWORDISH)
90
105
  keyword
91
106
  end
92
- end.compact
93
- unless value.empty?
94
- propstring = sprintf "%s:%s", name, value.join(" ")
95
- sanitized_node = Crass.parse_properties(propstring).first
96
- sanitized_tree << sanitized_node << CRASS_SEMICOLON
107
+ else
108
+ child[:raw]
97
109
  end
98
- end
110
+ end.compact
111
+
112
+ next if value.empty?
113
+ value << CSS_IMPORTANT if node[:important]
114
+ propstring = format("%s:%s", name, value.join(" "))
115
+ sanitized_node = Crass.parse_properties(propstring).first
116
+ sanitized_tree << sanitized_node << CRASS_SEMICOLON
99
117
  end
100
118
 
101
- Crass::Parser.stringify sanitized_tree
119
+ Crass::Parser.stringify(sanitized_tree)
102
120
  end
103
121
 
104
122
  #
@@ -106,7 +124,7 @@ module Loofah
106
124
  #
107
125
  # see comments about CVE-2018-8048 within the tests for more information
108
126
  #
109
- def force_correct_attribute_escaping! node
127
+ def force_correct_attribute_escaping!(node)
110
128
  return unless Nokogiri::VersionInfo.instance.libxml2?
111
129
 
112
130
  node.attribute_nodes.each do |attr_node|
@@ -122,11 +140,10 @@ module Loofah
122
140
  #
123
141
  encoding = attr_node.value.encoding
124
142
  attr_node.value = attr_node.value.gsub(/[ "]/) do |m|
125
- '%' + m.unpack('H2' * m.bytesize).join('%').upcase
143
+ "%" + m.unpack("H2" * m.bytesize).join("%").upcase
126
144
  end.force_encoding(encoding)
127
145
  end
128
146
  end
129
-
130
147
  end
131
148
  end
132
149
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Loofah
2
3
  #
3
4
  # Mixes +scrub!+ into Document, DocumentFragment, Node and NodeSet.
@@ -91,7 +92,7 @@ module Loofah
91
92
  # # decidedly not ok for browser:
92
93
  # frag.text(:encode_special_chars => false) # => "<script>alert('EVIL');</script>"
93
94
  #
94
- def text(options={})
95
+ def text(options = {})
95
96
  result = serialize_root.children.inner_text rescue ""
96
97
  if options[:encode_special_chars] == false
97
98
  result # possibly dangerous if rendered in a browser
@@ -99,8 +100,9 @@ module Loofah
99
100
  encode_special_chars result
100
101
  end
101
102
  end
103
+
102
104
  alias :inner_text :text
103
- alias :to_str :text
105
+ alias :to_str :text
104
106
 
105
107
  #
106
108
  # Returns a plain-text version of the markup contained by the
@@ -112,7 +114,7 @@ module Loofah
112
114
  # Loofah.document("<h1>Title</h1><div>Content</div>").to_text
113
115
  # # => "\nTitle\n\nContent\n"
114
116
  #
115
- def to_text(options={})
117
+ def to_text(options = {})
116
118
  Loofah.remove_extraneous_whitespace self.dup.scrub!(:newline_block_elements).text(options)
117
119
  end
118
120
  end
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
1
2
  module Loofah
2
3
  module MetaHelpers # :nodoc:
3
- def self.add_downcased_set_members_to_all_set_constants mojule
4
+ def self.add_downcased_set_members_to_all_set_constants(mojule)
4
5
  mojule.constants.each do |constant_sym|
5
6
  constant = mojule.const_get constant_sym
6
7
  next unless Set === constant
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  module Loofah
2
3
  #
3
4
  # A RuntimeError raised when Loofah could not find an appropriate scrubber.
4
5
  #
5
- class ScrubberNotFound < RuntimeError ; end
6
+ class ScrubberNotFound < RuntimeError; end
6
7
 
7
8
  #
8
9
  # A Scrubber wraps up a block (or method) that is run on an HTML node (element):
@@ -36,7 +37,7 @@ module Loofah
36
37
  CONTINUE = Object.new.freeze
37
38
 
38
39
  # Top-down Scrubbers may return STOP to indicate that the subtree should not be traversed.
39
- STOP = Object.new.freeze
40
+ STOP = Object.new.freeze
40
41
 
41
42
  # When a scrubber is initialized, the :direction may be specified
42
43
  # as :top_down (the default) or :bottom_up.
@@ -64,7 +65,7 @@ module Loofah
64
65
  def initialize(options = {}, &block)
65
66
  direction = options[:direction] || :top_down
66
67
  unless [:top_down, :bottom_up].include?(direction)
67
- raise ArgumentError, "direction #{direction} must be one of :top_down or :bottom_up"
68
+ raise ArgumentError, "direction #{direction} must be one of :top_down or :bottom_up"
68
69
  end
69
70
  @direction, @block = direction, block
70
71
  end
@@ -91,10 +92,10 @@ module Loofah
91
92
  # If the attribute is set, don't overwrite the existing value
92
93
  #
93
94
  def append_attribute(node, attribute, value)
94
- current_value = node.get_attribute(attribute) || ''
95
+ current_value = node.get_attribute(attribute) || ""
95
96
  current_values = current_value.split(/\s+/)
96
97
  updated_value = current_values | [value]
97
- node.set_attribute(attribute, updated_value.join(' '))
98
+ node.set_attribute(attribute, updated_value.join(" "))
98
99
  end
99
100
 
100
101
  private
@@ -118,11 +119,11 @@ module Loofah
118
119
  else
119
120
  return if scrub(node) == STOP
120
121
  end
121
- node.children.each {|j| traverse_conditionally_top_down(j)}
122
+ node.children.each { |j| traverse_conditionally_top_down(j) }
122
123
  end
123
124
 
124
125
  def traverse_conditionally_bottom_up(node)
125
- node.children.each {|j| traverse_conditionally_bottom_up(j)}
126
+ node.children.each { |j| traverse_conditionally_bottom_up(j) }
126
127
  if block
127
128
  block.call(node)
128
129
  else
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  module Loofah
2
3
  #
3
4
  # Loofah provides some built-in scrubbers for sanitizing with
4
- # HTML5lib's whitelist and for accomplishing some common
5
+ # HTML5lib's safelist and for accomplishing some common
5
6
  # transformation tasks.
6
7
  #
7
8
  #
@@ -205,8 +206,8 @@ module Loofah
205
206
  end
206
207
 
207
208
  def scrub(node)
208
- return CONTINUE unless (node.type == Nokogiri::XML::Node::ELEMENT_NODE) && (node.name == 'a')
209
- append_attribute(node, 'rel', 'nofollow')
209
+ return CONTINUE unless (node.type == Nokogiri::XML::Node::ELEMENT_NODE) && (node.name == "a")
210
+ append_attribute(node, "rel", "nofollow")
210
211
  return STOP
211
212
  end
212
213
  end
@@ -226,8 +227,8 @@ module Loofah
226
227
  end
227
228
 
228
229
  def scrub(node)
229
- return CONTINUE unless (node.type == Nokogiri::XML::Node::ELEMENT_NODE) && (node.name == 'a')
230
- append_attribute(node, 'rel', 'noopener')
230
+ return CONTINUE unless (node.type == Nokogiri::XML::Node::ELEMENT_NODE) && (node.name == "a")
231
+ append_attribute(node, "rel", "noopener")
231
232
  return STOP
232
233
  end
233
234
  end
@@ -267,7 +268,7 @@ module Loofah
267
268
 
268
269
  def scrub(node)
269
270
  if node.type == Nokogiri::XML::Node::TEXT_NODE || node.type == Nokogiri::XML::Node::CDATA_SECTION_NODE
270
- node.content = node.content.gsub(/\u2028|\u2029/, '')
271
+ node.content = node.content.gsub(/\u2028|\u2029/, "")
271
272
  end
272
273
  CONTINUE
273
274
  end
@@ -277,14 +278,14 @@ module Loofah
277
278
  # A hash that maps a symbol (like +:prune+) to the appropriate Scrubber (Loofah::Scrubbers::Prune).
278
279
  #
279
280
  MAP = {
280
- :escape => Escape,
281
- :prune => Prune,
281
+ :escape => Escape,
282
+ :prune => Prune,
282
283
  :whitewash => Whitewash,
283
- :strip => Strip,
284
- :nofollow => NoFollow,
284
+ :strip => Strip,
285
+ :nofollow => NoFollow,
285
286
  :noopener => NoOpener,
286
287
  :newline_block_elements => NewlineBlockElements,
287
- :unprintable => Unprintable
288
+ :unprintable => Unprintable,
288
289
  }
289
290
 
290
291
  #
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+ module Loofah
3
+ # The version of Loofah you are using
4
+ VERSION = "2.9.0"
5
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Loofah
2
3
  module XML # :nodoc:
3
4
  #
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Loofah
2
3
  module XML # :nodoc:
3
4
  #
@@ -12,7 +13,7 @@ module Loofah
12
13
  # constructor. Applications should use Loofah.fragment to
13
14
  # parse a fragment.
14
15
  #
15
- def parse tags
16
+ def parse(tags)
16
17
  doc = Loofah::XML::Document.new
17
18
  doc.encoding = tags.encoding.name if tags.respond_to?(:encoding)
18
19
  self.new(doc, tags)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loofah
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.3
4
+ version: 2.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Dalessio
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-10-30 00:00:00.000000000 Z
12
+ date: 2021-01-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -43,30 +43,30 @@ dependencies:
43
43
  name: rake
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - ">="
46
+ - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '0.8'
48
+ version: '13.0'
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - ">="
53
+ - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '0.8'
55
+ version: '13.0'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: minitest
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '2.2'
62
+ version: '5.14'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '2.2'
69
+ version: '5.14'
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: rr
72
72
  requirement: !ruby/object:Gem::Requirement
@@ -85,86 +85,44 @@ dependencies:
85
85
  name: json
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- version: '0'
91
- type: :development
92
- prerelease: false
93
- version_requirements: !ruby/object:Gem::Requirement
94
- requirements:
95
- - - ">="
96
- - !ruby/object:Gem::Version
97
- version: '0'
98
- - !ruby/object:Gem::Dependency
99
- name: hoe-gemspec
100
- requirement: !ruby/object:Gem::Requirement
101
- requirements:
102
- - - ">="
103
- - !ruby/object:Gem::Version
104
- version: '0'
105
- type: :development
106
- prerelease: false
107
- version_requirements: !ruby/object:Gem::Requirement
108
- requirements:
109
- - - ">="
110
- - !ruby/object:Gem::Version
111
- version: '0'
112
- - !ruby/object:Gem::Dependency
113
- name: hoe-debugging
114
- requirement: !ruby/object:Gem::Requirement
115
- requirements:
116
- - - ">="
117
- - !ruby/object:Gem::Version
118
- version: '0'
119
- type: :development
120
- prerelease: false
121
- version_requirements: !ruby/object:Gem::Requirement
122
- requirements:
123
- - - ">="
124
- - !ruby/object:Gem::Version
125
- version: '0'
126
- - !ruby/object:Gem::Dependency
127
- name: hoe-bundler
128
- requirement: !ruby/object:Gem::Requirement
129
- requirements:
130
- - - ">="
88
+ - - "~>"
131
89
  - !ruby/object:Gem::Version
132
- version: '0'
90
+ version: '2.2'
133
91
  type: :development
134
92
  prerelease: false
135
93
  version_requirements: !ruby/object:Gem::Requirement
136
94
  requirements:
137
- - - ">="
95
+ - - "~>"
138
96
  - !ruby/object:Gem::Version
139
- version: '0'
97
+ version: '2.2'
140
98
  - !ruby/object:Gem::Dependency
141
- name: hoe-git
99
+ name: concourse
142
100
  requirement: !ruby/object:Gem::Requirement
143
101
  requirements:
144
- - - ">="
102
+ - - "~>"
145
103
  - !ruby/object:Gem::Version
146
- version: '0'
104
+ version: '0.33'
147
105
  type: :development
148
106
  prerelease: false
149
107
  version_requirements: !ruby/object:Gem::Requirement
150
108
  requirements:
151
- - - ">="
109
+ - - "~>"
152
110
  - !ruby/object:Gem::Version
153
- version: '0'
111
+ version: '0.33'
154
112
  - !ruby/object:Gem::Dependency
155
- name: concourse
113
+ name: rubocop
156
114
  requirement: !ruby/object:Gem::Requirement
157
115
  requirements:
158
- - - ">="
116
+ - - "~>"
159
117
  - !ruby/object:Gem::Version
160
- version: 0.15.0
118
+ version: '1.1'
161
119
  type: :development
162
120
  prerelease: false
163
121
  version_requirements: !ruby/object:Gem::Requirement
164
122
  requirements:
165
- - - ">="
123
+ - - "~>"
166
124
  - !ruby/object:Gem::Version
167
- version: 0.15.0
125
+ version: '1.1'
168
126
  - !ruby/object:Gem::Dependency
169
127
  name: rdoc
170
128
  requirement: !ruby/object:Gem::Requirement
@@ -186,91 +144,62 @@ dependencies:
186
144
  - !ruby/object:Gem::Version
187
145
  version: '7'
188
146
  - !ruby/object:Gem::Dependency
189
- name: hoe
147
+ name: hoe-markdown
190
148
  requirement: !ruby/object:Gem::Requirement
191
149
  requirements:
192
150
  - - "~>"
193
151
  - !ruby/object:Gem::Version
194
- version: '3.17'
152
+ version: '1.3'
195
153
  type: :development
196
154
  prerelease: false
197
155
  version_requirements: !ruby/object:Gem::Requirement
198
156
  requirements:
199
157
  - - "~>"
200
158
  - !ruby/object:Gem::Version
201
- version: '3.17'
159
+ version: '1.3'
202
160
  description: |-
203
- Loofah is a general library for manipulating and transforming HTML/XML
204
- documents and fragments. It's built on top of Nokogiri and libxml2, so
205
- it's fast and has a nice API.
161
+ Loofah is a general library for manipulating and transforming HTML/XML documents and fragments, built on top of Nokogiri.
206
162
 
207
- Loofah excels at HTML sanitization (XSS prevention). It includes some
208
- nice HTML sanitizers, which are based on HTML5lib's whitelist, so it
209
- most likely won't make your codes less secure. (These statements have
210
- not been evaluated by Netexperts.)
163
+ Loofah excels at HTML sanitization (XSS prevention). It includes some nice HTML sanitizers, which are based on HTML5lib's safelist, so it most likely won't make your codes less secure. (These statements have not been evaluated by Netexperts.)
211
164
 
212
- ActiveRecord extensions for sanitization are available in the
213
- [`loofah-activerecord` gem](https://github.com/flavorjones/loofah-activerecord).
165
+ ActiveRecord extensions for sanitization are available in the [`loofah-activerecord` gem](https://github.com/flavorjones/loofah-activerecord).
214
166
  email:
215
167
  - mike.dalessio@gmail.com
216
168
  - bryan@brynary.com
217
169
  executables: []
218
170
  extensions: []
219
- extra_rdoc_files:
220
- - CHANGELOG.md
221
- - MIT-LICENSE.txt
222
- - Manifest.txt
223
- - README.md
224
- - SECURITY.md
171
+ extra_rdoc_files: []
225
172
  files:
226
- - ".gemtest"
227
173
  - CHANGELOG.md
228
- - Gemfile
229
174
  - MIT-LICENSE.txt
230
- - Manifest.txt
231
175
  - README.md
232
- - Rakefile
233
176
  - SECURITY.md
234
- - benchmark/benchmark.rb
235
- - benchmark/fragment.html
236
- - benchmark/helper.rb
237
- - benchmark/www.slashdot.com.html
238
177
  - lib/loofah.rb
239
178
  - lib/loofah/elements.rb
240
179
  - lib/loofah/helpers.rb
241
180
  - lib/loofah/html/document.rb
242
181
  - lib/loofah/html/document_fragment.rb
243
182
  - lib/loofah/html5/libxml2_workarounds.rb
183
+ - lib/loofah/html5/safelist.rb
244
184
  - lib/loofah/html5/scrub.rb
245
- - lib/loofah/html5/whitelist.rb
246
185
  - lib/loofah/instance_methods.rb
247
186
  - lib/loofah/metahelpers.rb
248
187
  - lib/loofah/scrubber.rb
249
188
  - lib/loofah/scrubbers.rb
189
+ - lib/loofah/version.rb
250
190
  - lib/loofah/xml/document.rb
251
191
  - lib/loofah/xml/document_fragment.rb
252
- - test/assets/msword.html
253
- - test/assets/testdata_sanitizer_tests1.dat
254
- - test/helper.rb
255
- - test/html5/test_sanitizer.rb
256
- - test/integration/test_ad_hoc.rb
257
- - test/integration/test_helpers.rb
258
- - test/integration/test_html.rb
259
- - test/integration/test_scrubbers.rb
260
- - test/integration/test_xml.rb
261
- - test/unit/test_api.rb
262
- - test/unit/test_encoding.rb
263
- - test/unit/test_helpers.rb
264
- - test/unit/test_scrubber.rb
265
- - test/unit/test_scrubbers.rb
266
192
  homepage: https://github.com/flavorjones/loofah
267
193
  licenses:
268
194
  - MIT
269
- metadata: {}
195
+ metadata:
196
+ homepage_uri: https://github.com/flavorjones/loofah
197
+ source_code_uri: https://github.com/flavorjones/loofah
198
+ bug_tracker_uri: https://github.com/flavorjones/loofah/issues
199
+ changelog_uri: https://github.com/flavorjones/loofah/blob/master/CHANGELOG.md
200
+ documentation_uri: https://www.rubydoc.info/gems/loofah/
270
201
  post_install_message:
271
- rdoc_options:
272
- - "--main"
273
- - README.md
202
+ rdoc_options: []
274
203
  require_paths:
275
204
  - lib
276
205
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -284,10 +213,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
284
213
  - !ruby/object:Gem::Version
285
214
  version: '0'
286
215
  requirements: []
287
- rubyforge_project:
288
- rubygems_version: 2.7.7
216
+ rubygems_version: 3.1.4
289
217
  signing_key:
290
218
  specification_version: 4
291
219
  summary: Loofah is a general library for manipulating and transforming HTML/XML documents
292
- and fragments
220
+ and fragments, built on top of Nokogiri
293
221
  test_files: []