sanitize 6.1.3 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,123 +1,121 @@
1
- # encoding: utf-8
2
- require_relative 'common'
1
+ # frozen_string_literal: true
3
2
 
4
- describe 'Transformers' do
3
+ require_relative "common"
4
+
5
+ describe "Transformers" do
5
6
  make_my_diffs_pretty!
6
7
  parallelize_me!
7
8
 
8
- it 'should receive a complete env Hash as input' do
9
- Sanitize.fragment('<SPAN>foo</SPAN>',
10
- :foo => :bar,
11
- :transformers => lambda {|env|
9
+ it "should receive a complete env Hash as input" do
10
+ Sanitize.fragment("<SPAN>foo</SPAN>",
11
+ foo: :bar,
12
+ transformers: lambda { |env|
12
13
  return unless env[:node].element?
13
14
 
14
15
  _(env[:config][:foo]).must_equal :bar
15
16
  _(env[:is_allowlisted]).must_equal false
16
17
  _(env[:is_whitelisted]).must_equal env[:is_allowlisted]
17
18
  _(env[:node]).must_be_kind_of Nokogiri::XML::Node
18
- _(env[:node_name]).must_equal 'span'
19
+ _(env[:node_name]).must_equal "span"
19
20
  _(env[:node_allowlist]).must_be_kind_of Set
20
21
  _(env[:node_allowlist]).must_be_empty
21
22
  _(env[:node_whitelist]).must_equal env[:node_allowlist]
22
- }
23
- )
23
+ })
24
24
  end
25
25
 
26
- it 'should traverse all node types, including the fragment itself' do
26
+ it "should traverse all node types, including the fragment itself" do
27
27
  nodes = []
28
28
 
29
- Sanitize.fragment('<div>foo</div><!--bar--><script>cdata!</script>',
30
- :transformers => proc {|env| nodes << env[:node_name] }
31
- )
29
+ Sanitize.fragment("<div>foo</div><!--bar--><script>cdata!</script>",
30
+ transformers: proc { |env| nodes << env[:node_name] })
32
31
 
33
32
  _(nodes).must_equal %w[
34
33
  #document-fragment div text text text comment script text
35
34
  ]
36
35
  end
37
36
 
38
- it 'should perform top-down traversal' do
37
+ it "should perform top-down traversal" do
39
38
  nodes = []
40
39
 
41
- Sanitize.fragment('<div><span><strong>foo</strong></span><b></b></div><p>bar</p>',
42
- :transformers => proc {|env| nodes << env[:node_name] if env[:node].element? }
43
- )
40
+ Sanitize.fragment("<div><span><strong>foo</strong></span><b></b></div><p>bar</p>",
41
+ transformers: proc { |env| nodes << env[:node_name] if env[:node].element? })
44
42
 
45
43
  _(nodes).must_equal %w[div span strong b p]
46
44
  end
47
45
 
48
- it 'should allowlist nodes in the node allowlist' do
46
+ it "should allowlist nodes in the node allowlist" do
49
47
  _(Sanitize.fragment('<div class="foo">foo</div><span>bar</span>',
50
- :transformers => [
51
- proc {|env|
52
- {:node_allowlist => [env[:node]]} if env[:node_name] == 'div'
48
+ transformers: [
49
+ proc { |env|
50
+ {node_allowlist: [env[:node]]} if env[:node_name] == "div"
53
51
  },
54
52
 
55
- proc {|env|
56
- _(env[:is_allowlisted]).must_equal false unless env[:node_name] == 'div'
57
- _(env[:is_allowlisted]).must_equal true if env[:node_name] == 'div'
58
- _(env[:node_allowlist]).must_include env[:node] if env[:node_name] == 'div'
53
+ proc { |env|
54
+ _(env[:is_allowlisted]).must_equal false unless env[:node_name] == "div"
55
+ _(env[:is_allowlisted]).must_equal true if env[:node_name] == "div"
56
+ _(env[:node_allowlist]).must_include env[:node] if env[:node_name] == "div"
59
57
  _(env[:is_whitelisted]).must_equal env[:is_allowlisted]
60
58
  _(env[:node_whitelist]).must_equal env[:node_allowlist]
61
59
  }
62
- ]
63
- )).must_equal '<div class="foo">foo</div>bar'
60
+ ])).must_equal '<div class="foo">foo</div>bar'
64
61
  end
65
62
 
66
- it 'should clear the node allowlist after each fragment' do
63
+ it "should clear the node allowlist after each fragment" do
67
64
  called = false
68
65
 
69
- Sanitize.fragment('<div>foo</div>',
70
- :transformers => proc {|env| {:node_allowlist => [env[:node]]}}
71
- )
66
+ Sanitize.fragment("<div>foo</div>",
67
+ transformers: proc { |env| {node_allowlist: [env[:node]]} })
72
68
 
73
- Sanitize.fragment('<div>foo</div>',
74
- :transformers => proc {|env|
69
+ Sanitize.fragment("<div>foo</div>",
70
+ transformers: proc { |env|
75
71
  called = true
76
72
  _(env[:is_allowlisted]).must_equal false
77
73
  _(env[:is_whitelisted]).must_equal env[:is_allowlisted]
78
74
  _(env[:node_allowlist]).must_be_empty
79
75
  _(env[:node_whitelist]).must_equal env[:node_allowlist]
80
- }
81
- )
76
+ })
82
77
 
83
78
  _(called).must_equal true
84
79
  end
85
80
 
86
- it 'should accept a method transformer' do
87
- def transformer(env); end
88
- _(Sanitize.fragment('<div>foo</div>', :transformers => method(:transformer)))
89
- .must_equal(' foo ')
81
+ it "should accept a method transformer" do
82
+ def transformer(env)
83
+ end
84
+ _(Sanitize.fragment("<div>foo</div>", transformers: method(:transformer)))
85
+ .must_equal(" foo ")
90
86
  end
91
87
 
92
- describe 'Image allowlist transformer' do
93
- require 'uri'
88
+ describe "Image allowlist transformer" do
89
+ require "uri"
94
90
 
95
91
  image_allowlist_transformer = lambda do |env|
96
92
  # Ignore everything except <img> elements.
97
- return unless env[:node_name] == 'img'
93
+ return unless env[:node_name] == "img"
98
94
 
99
- node = env[:node]
100
- image_uri = URI.parse(node['src'])
95
+ node = env[:node]
96
+ image_uri = URI.parse(node["src"])
101
97
 
102
98
  # Only allow relative URLs or URLs with the example.com domain. The
103
99
  # image_uri.host.nil? check ensures that protocol-relative URLs like
104
- # "//evil.com/foo.jpg".
105
- unless image_uri.host == 'example.com' || (image_uri.host.nil? && image_uri.relative?)
106
- node.unlink # `Nokogiri::XML::Node#unlink` removes a node from the document
100
+ # "//evil.com/foo.jpg" are not allowed.
101
+ unless image_uri.host == "example.com"
102
+ unless image_uri.host.nil? && image_uri.relative?
103
+ node.unlink # `Nokogiri::XML::Node#unlink` removes a node from the document
104
+ end
107
105
  end
108
106
  end
109
107
 
110
108
  before do
111
109
  @s = Sanitize.new(Sanitize::Config.merge(Sanitize::Config::RELAXED,
112
- :transformers => image_allowlist_transformer))
110
+ transformers: image_allowlist_transformer))
113
111
  end
114
112
 
115
- it 'should allow images with relative URLs' do
113
+ it "should allow images with relative URLs" do
116
114
  input = '<img src="/foo/bar.jpg">'
117
115
  _(@s.fragment(input)).must_equal(input)
118
116
  end
119
117
 
120
- it 'should allow images at the example.com domain' do
118
+ it "should allow images at the example.com domain" do
121
119
  input = '<img src="http://example.com/foo/bar.jpg">'
122
120
  _(@s.fragment(input)).must_equal(input)
123
121
 
@@ -128,103 +126,103 @@ describe 'Transformers' do
128
126
  _(@s.fragment(input)).must_equal(input)
129
127
  end
130
128
 
131
- it 'should not allow images at other domains' do
129
+ it "should not allow images at other domains" do
132
130
  input = '<img src="http://evil.com/foo/bar.jpg">'
133
- _(@s.fragment(input)).must_equal('')
131
+ _(@s.fragment(input)).must_equal("")
134
132
 
135
133
  input = '<img src="https://evil.com/foo/bar.jpg">'
136
- _(@s.fragment(input)).must_equal('')
134
+ _(@s.fragment(input)).must_equal("")
137
135
 
138
136
  input = '<img src="//evil.com/foo/bar.jpg">'
139
- _(@s.fragment(input)).must_equal('')
137
+ _(@s.fragment(input)).must_equal("")
140
138
 
141
139
  input = '<img src="http://subdomain.example.com/foo/bar.jpg">'
142
- _(@s.fragment(input)).must_equal('')
140
+ _(@s.fragment(input)).must_equal("")
143
141
  end
144
142
  end
145
143
 
146
- describe 'YouTube transformer' do
144
+ describe "YouTube transformer" do
147
145
  youtube_transformer = lambda do |env|
148
- node = env[:node]
146
+ node = env[:node]
149
147
  node_name = env[:node_name]
150
148
 
151
149
  # Don't continue if this node is already allowlisted or is not an element.
152
150
  return if env[:is_allowlisted] || !node.element?
153
151
 
154
152
  # Don't continue unless the node is an iframe.
155
- return unless node_name == 'iframe'
153
+ return unless node_name == "iframe"
156
154
 
157
155
  # Verify that the video URL is actually a valid YouTube video URL.
158
- return unless node['src'] =~ %r|\A(?:https?:)?//(?:www\.)?youtube(?:-nocookie)?\.com/|
156
+ return unless %r{\A(?:https?:)?//(?:www\.)?youtube(?:-nocookie)?\.com/}.match?(node["src"])
159
157
 
160
158
  # We're now certain that this is a YouTube embed, but we still need to run
161
159
  # it through a special Sanitize step to ensure that no unwanted elements or
162
160
  # attributes that don't belong in a YouTube embed can sneak in.
163
161
  Sanitize.node!(node, {
164
- :elements => %w[iframe],
162
+ elements: %w[iframe],
165
163
 
166
- :attributes => {
167
- 'iframe' => %w[allowfullscreen frameborder height src width]
164
+ attributes: {
165
+ "iframe" => %w[allowfullscreen frameborder height src width]
168
166
  }
169
167
  })
170
168
 
171
169
  # Now that we're sure that this is a valid YouTube embed and that there are
172
170
  # no unwanted elements or attributes hidden inside it, we can tell Sanitize
173
171
  # to allowlist the current node.
174
- {:node_allowlist => [node]}
172
+ {node_allowlist: [node]}
175
173
  end
176
174
 
177
- it 'should allow HTTP YouTube video embeds' do
175
+ it "should allow HTTP YouTube video embeds" do
178
176
  input = '<iframe width="420" height="315" src="http://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen bogus="bogus"><script>alert()</script></iframe>'
179
177
 
180
- _(Sanitize.fragment(input, :transformers => youtube_transformer))
178
+ _(Sanitize.fragment(input, transformers: youtube_transformer))
181
179
  .must_equal '<iframe width="420" height="315" src="http://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen=""></iframe>'
182
180
  end
183
181
 
184
- it 'should allow HTTPS YouTube video embeds' do
182
+ it "should allow HTTPS YouTube video embeds" do
185
183
  input = '<iframe width="420" height="315" src="https://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen bogus="bogus"><script>alert()</script></iframe>'
186
184
 
187
- _(Sanitize.fragment(input, :transformers => youtube_transformer))
185
+ _(Sanitize.fragment(input, transformers: youtube_transformer))
188
186
  .must_equal '<iframe width="420" height="315" src="https://www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen=""></iframe>'
189
187
  end
190
188
 
191
- it 'should allow protocol-relative YouTube video embeds' do
189
+ it "should allow protocol-relative YouTube video embeds" do
192
190
  input = '<iframe width="420" height="315" src="//www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen bogus="bogus"><script>alert()</script></iframe>'
193
191
 
194
- _(Sanitize.fragment(input, :transformers => youtube_transformer))
192
+ _(Sanitize.fragment(input, transformers: youtube_transformer))
195
193
  .must_equal '<iframe width="420" height="315" src="//www.youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen=""></iframe>'
196
194
  end
197
195
 
198
- it 'should allow privacy-enhanced YouTube video embeds' do
196
+ it "should allow privacy-enhanced YouTube video embeds" do
199
197
  input = '<iframe width="420" height="315" src="https://www.youtube-nocookie.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen bogus="bogus"><script>alert()</script></iframe>'
200
198
 
201
- _(Sanitize.fragment(input, :transformers => youtube_transformer))
199
+ _(Sanitize.fragment(input, transformers: youtube_transformer))
202
200
  .must_equal '<iframe width="420" height="315" src="https://www.youtube-nocookie.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen=""></iframe>'
203
201
  end
204
202
 
205
- it 'should not allow non-YouTube video embeds' do
203
+ it "should not allow non-YouTube video embeds" do
206
204
  input = '<iframe width="420" height="315" src="http://www.fake-youtube.com/embed/QH2-TGUlwu4" frameborder="0" allowfullscreen></iframe>'
207
205
 
208
- _(Sanitize.fragment(input, :transformers => youtube_transformer))
209
- .must_equal('')
206
+ _(Sanitize.fragment(input, transformers: youtube_transformer))
207
+ .must_equal("")
210
208
  end
211
209
  end
212
210
 
213
- describe 'DOM modification transformer' do
211
+ describe "DOM modification transformer" do
214
212
  b_to_strong_tag_transformer = lambda do |env|
215
- node = env[:node]
213
+ node = env[:node]
216
214
  node_name = env[:node_name]
217
215
 
218
- if node_name == 'b'
219
- node.name = 'strong'
216
+ if node_name == "b"
217
+ node.name = "strong"
220
218
  end
221
219
  end
222
220
 
223
- it 'should allow the <b> tag to be changed to a <strong> tag' do
224
- input = '<b>text</b>'
221
+ it "should allow the <b> tag to be changed to a <strong> tag" do
222
+ input = "<b>text</b>"
225
223
 
226
- _(Sanitize.fragment(input, :elements => ['strong'], :transformers => b_to_strong_tag_transformer))
227
- .must_equal '<strong>text</strong>'
224
+ _(Sanitize.fragment(input, elements: ["strong"], transformers: b_to_strong_tag_transformer))
225
+ .must_equal "<strong>text</strong>"
228
226
  end
229
227
  end
230
228
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sanitize
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.3
4
+ version: 7.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Grove
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-08-14 00:00:00.000000000 Z
10
+ date: 2024-12-30 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: crass
@@ -30,51 +29,24 @@ dependencies:
30
29
  requirements:
31
30
  - - ">="
32
31
  - !ruby/object:Gem::Version
33
- version: 1.12.0
32
+ version: 1.16.8
34
33
  type: :runtime
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
- version: 1.12.0
41
- - !ruby/object:Gem::Dependency
42
- name: minitest
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '5.15'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '5.15'
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 13.0.6
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 13.0.6
69
- description: Sanitize is an allowlist-based HTML and CSS sanitizer. It removes all
70
- HTML and/or CSS from a string except the elements, attributes, and properties you
71
- choose to allow.
39
+ version: 1.16.8
40
+ description: |
41
+ Sanitize is an allowlist-based HTML and CSS sanitizer. It removes all HTML
42
+ and/or CSS from a string except the elements, attributes, and properties you
43
+ choose to allow.'
72
44
  email: ryan@wonko.com
73
45
  executables: []
74
46
  extensions: []
75
47
  extra_rdoc_files: []
76
48
  files:
77
- - HISTORY.md
49
+ - CHANGELOG.md
78
50
  - LICENSE
79
51
  - README.md
80
52
  - lib/sanitize.rb
@@ -106,9 +78,9 @@ homepage: https://github.com/rgrove/sanitize/
106
78
  licenses:
107
79
  - MIT
108
80
  metadata:
109
- changelog_uri: https://github.com/rgrove/sanitize/blob/main/HISTORY.md
81
+ changelog_uri: https://github.com/rgrove/sanitize/blob/main/CHANGELOG.md
110
82
  documentation_uri: https://rubydoc.info/github/rgrove/sanitize
111
- post_install_message:
83
+ rubygems_mfa_required: 'true'
112
84
  rdoc_options: []
113
85
  require_paths:
114
86
  - lib
@@ -116,15 +88,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
88
  requirements:
117
89
  - - ">="
118
90
  - !ruby/object:Gem::Version
119
- version: 2.5.0
91
+ version: 3.1.0
120
92
  required_rubygems_version: !ruby/object:Gem::Requirement
121
93
  requirements:
122
94
  - - ">="
123
95
  - !ruby/object:Gem::Version
124
- version: 1.2.0
96
+ version: '0'
125
97
  requirements: []
126
- rubygems_version: 3.5.11
127
- signing_key:
98
+ rubygems_version: 3.6.2
128
99
  specification_version: 4
129
100
  summary: Allowlist-based HTML and CSS sanitizer.
130
101
  test_files: []