loofah 2.21.3 → 2.23.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '00569b28a0bc6307a0a8eb8704ad374f10269008dada5d09470c1a2a87da0a6f'
4
- data.tar.gz: eff12a44f1152dc377ac0a6859be97f85b5a0a031a0b7688387c73f7130351d3
3
+ metadata.gz: 9817bf69ee1ad2d7e93edad53209db1347c9ec360076520532cdf60ad158a8f6
4
+ data.tar.gz: 3381ac563f4b70c4ccca49301ba369f22716da405dd7641af535209e6817258b
5
5
  SHA512:
6
- metadata.gz: fbcf412c0105203fe3d9ee057dc146cc7f8e9f29587c0f97b9c03a5206eacd31f7170042c74050d40093875b8109f524434a0960ef9305269fdda536e3049e3b
7
- data.tar.gz: 48c3f2c0f4a0b2316c46ad1826c61ded9c3438ace28c477d7b67cc345847a00bb5747bab5b22cf5d774e82c90bedd085a9878c40609f93abda49f6aa01257f7c
6
+ metadata.gz: 482eeac3b61aba7e1b517aaab8a6d010ae44bd5b99b749cdabb5381936b4b9e8f97c62d99a60bdf1fbf64c2dba8c33062b676083f4e82d7e07f33e7666fe148f
7
+ data.tar.gz: 69234fb9c4d7d55eb63a18008d035df1117bb6ea10f0f15b57bacc5152103fc0830a53a8d98a63e817360332975e257dbeda223ed43e42813724ce30a3b8d7e6
data/CHANGELOG.md CHANGED
@@ -1,7 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.23.1 / 2024-10-25
4
+
5
+ ### Added
6
+
7
+ * Allow CSS properties `min-height` and `max-height`. [#288] @lazyatom
8
+
9
+
10
+ ## 2.23.0 / 2024-10-24
11
+
12
+ ### Added
13
+
14
+ * Allow CSS property `min-width`. [#287] @lazyatom
15
+
16
+
17
+ ## 2.22.0 / 2023-11-13
18
+
19
+ ### Added
20
+
21
+ * A `:targetblank` HTML scrubber which ensures all hyperlinks have `target="_blank"`. [#275] @stefannibrasil and @thdaraujo
22
+ * A `:noreferrer` HTML scrubber which ensures all hyperlinks have `rel=noreferrer`, similar to the `:nofollow` and `:noopener` scrubbers. [#277] @wynksaiddestroy
23
+
24
+
25
+ ## 2.21.4 / 2023-10-10
26
+
27
+ ### Fixed
28
+
29
+ * `Loofah::HTML5::Scrub.scrub_css` is more consistent in preserving whitespace (and lack of whitespace) in CSS property values. In particular, `.scrub_css` no longer inserts whitespace between tokens that did not already have whitespace between them. [[#273](https://github.com/flavorjones/loofah/issues/273), fixes [#271](https://github.com/flavorjones/loofah/issues/271)]
30
+
31
+
3
32
  ## 2.21.3 / 2023-05-15
4
33
 
34
+ ### Fixed
35
+
5
36
  * Quash "instance variable not initialized" warning in Ruby < 3.0. [[#268](https://github.com/flavorjones/loofah/issues/268)] (Thanks, [@dharamgollapudi](https://github.com/dharamgollapudi)!)
6
37
 
7
38
 
data/README.md CHANGED
@@ -29,6 +29,7 @@ Active Record extensions for HTML sanitization are available in the [`loofah-act
29
29
  * _Whitewash_ the markup, removing all attributes and namespaced nodes.
30
30
  * Other common HTML transformations are built-in:
31
31
  * Add the _nofollow_ attribute to all hyperlinks.
32
+ * Add the _target=\_blank_ attribute to all hyperlinks.
32
33
  * Remove _unprintable_ characters from text nodes.
33
34
  * Format markup as plain text, with (or without) sensible whitespace handling around block elements.
34
35
  * Replace Rails's `strip_tags` and `sanitize` view helper methods.
@@ -229,8 +230,11 @@ doc.scrub!(:whitewash) # removes unknown/unsafe/namespaced tags and their chi
229
230
  Loofah also comes with some common transformation tasks:
230
231
 
231
232
  ``` ruby
232
- doc.scrub!(:nofollow) # adds rel="nofollow" attribute to links
233
+ doc.scrub!(:nofollow) # adds rel="nofollow" attribute to links
234
+ doc.scrub!(:noopener) # adds rel="noopener" attribute to links
235
+ doc.scrub!(:noreferrer) # adds rel="noreferrer" attribute to links
233
236
  doc.scrub!(:unprintable) # removes unprintable characters from text nodes
237
+ doc.scrub!(:targetblank) # adds target="_blank" attribute to links
234
238
  ```
235
239
 
236
240
  See `Loofah::Scrubbers` for more details and example usage.
@@ -333,20 +337,64 @@ See [`SECURITY.md`](SECURITY.md) for vulnerability reporting details.
333
337
 
334
338
  Featuring code contributed by:
335
339
 
336
- * Aaron Patterson
337
- * John Barnette
338
- * Josh Owens
339
- * Paul Dix
340
- * Luke Melia
340
+ * [@flavorjones](https://github.com/flavorjones)
341
+ * [@brynary](https://github.com/brynary)
342
+ * [@olleolleolle](https://github.com/olleolleolle)
343
+ * [@JuanitoFatas](https://github.com/JuanitoFatas)
344
+ * [@kaspth](https://github.com/kaspth)
345
+ * [@tenderlove](https://github.com/tenderlove)
346
+ * [@ktdreyer](https://github.com/ktdreyer)
347
+ * [@orien](https://github.com/orien)
348
+ * [@asok](https://github.com/asok)
349
+ * [@junaruga](https://github.com/junaruga)
350
+ * [@MothOnMars](https://github.com/MothOnMars)
351
+ * [@nick-desteffen](https://github.com/nick-desteffen)
352
+ * [@NikoRoberts](https://github.com/NikoRoberts)
353
+ * [@trans](https://github.com/trans)
354
+ * [@andreynering](https://github.com/andreynering)
355
+ * [@aried3r](https://github.com/aried3r)
356
+ * [@baopham](https://github.com/baopham)
357
+ * [@batter](https://github.com/batter)
358
+ * [@brendon](https://github.com/brendon)
359
+ * [@cjba7](https://github.com/cjba7)
360
+ * [@christiankisssner](https://github.com/christiankisssner)
361
+ * [@dacort](https://github.com/dacort)
362
+ * [@danfstucky](https://github.com/danfstucky)
363
+ * [@david-a-wheeler](https://github.com/david-a-wheeler)
364
+ * [@dharamgollapudi](https://github.com/dharamgollapudi)
365
+ * [@georgeclaghorn](https://github.com/georgeclaghorn)
366
+ * [@gogainda](https://github.com/gogainda)
367
+ * [@jaredbeck](https://github.com/jaredbeck)
368
+ * [@ThatHurleyGuy](https://github.com/ThatHurleyGuy)
369
+ * [@jstorimer](https://github.com/jstorimer)
370
+ * [@jbarnette](https://github.com/jbarnette)
371
+ * [@queso](https://github.com/queso)
372
+ * [@technicalpickles](https://github.com/technicalpickles)
373
+ * [@kyoshidajp](https://github.com/kyoshidajp)
374
+ * [@kristianfreeman](https://github.com/kristianfreeman)
375
+ * [@louim](https://github.com/louim)
376
+ * [@mrpasquini](https://github.com/mrpasquini)
377
+ * [@olivierlacan](https://github.com/olivierlacan)
378
+ * [@pauldix](https://github.com/pauldix)
379
+ * [@sampokuokkanen](https://github.com/sampokuokkanen)
380
+ * [@stefannibrasil](https://github.com/stefannibrasil)
381
+ * [@tastycode](https://github.com/tastycode)
382
+ * [@vipulnsward](https://github.com/vipulnsward)
383
+ * [@joncalhoun](https://github.com/joncalhoun)
384
+ * [@ahorek](https://github.com/ahorek)
385
+ * [@rmacklin](https://github.com/rmacklin)
386
+ * [@y-yagi](https://github.com/y-yagi)
387
+ * [@lazyatom](https://github.com/lazyatom)
341
388
 
342
389
  And a big shout-out to Corey Innis for the name, and feedback on the API.
343
390
 
344
391
 
345
392
  ## Thank You
346
393
 
347
- The following people have generously funded Loofah:
394
+ The following people have generously funded Loofah with financial sponsorship:
348
395
 
349
396
  * Bill Harding
397
+ * [Sentry](https://sentry.io/) @getsentry
350
398
 
351
399
 
352
400
  ## Historical Note
@@ -662,7 +662,10 @@ module Loofah
662
662
  "line-height",
663
663
  "list-style",
664
664
  "list-style-type",
665
+ "max-height",
665
666
  "max-width",
667
+ "min-height",
668
+ "min-width",
666
669
  "order",
667
670
  "overflow",
668
671
  "overflow-x",
@@ -10,6 +10,7 @@ module Loofah
10
10
  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/ # rubocop:disable Layout/LineLength
11
11
  CRASS_SEMICOLON = { node: :semicolon, raw: ";" }
12
12
  CSS_IMPORTANT = "!important"
13
+ CSS_WHITESPACE = " "
13
14
  CSS_PROPERTY_STRING_WITHOUT_EMBEDDED_QUOTES = /\A(["'])?[^"']+\1\z/
14
15
  DATA_ATTRIBUTE_NAME = /\Adata-[\w-]+\z/
15
16
 
@@ -87,7 +88,7 @@ module Loofah
87
88
  value = node[:children].map do |child|
88
89
  case child[:node]
89
90
  when :whitespace
90
- nil
91
+ CSS_WHITESPACE
91
92
  when :string
92
93
  if CSS_PROPERTY_STRING_WITHOUT_EMBEDDED_QUOTES.match?(child[:raw])
93
94
  Crass::Parser.stringify(child)
@@ -106,12 +107,12 @@ module Loofah
106
107
  else
107
108
  child[:raw]
108
109
  end
109
- end.compact
110
+ end.compact.join.strip
110
111
 
111
112
  next if value.empty?
112
113
 
113
- value << CSS_IMPORTANT if node[:important]
114
- propstring = format("%s:%s", name, value.join(" "))
114
+ value << CSS_WHITESPACE << CSS_IMPORTANT if node[:important]
115
+ propstring = format("%s:%s", name, value)
115
116
  sanitized_node = Crass.parse_properties(propstring).first
116
117
  sanitized_tree << sanitized_node << CRASS_SEMICOLON
117
118
  end
@@ -61,6 +61,15 @@ module Loofah
61
61
  # => "ohai! <a href='http://www.myswarmysite.com/' rel="nofollow">I like your blog post</a>"
62
62
  #
63
63
  #
64
+ # === Loofah::Scrubbers::TargetBlank / scrub!(:targetblank)
65
+ #
66
+ # +:targetblank+ adds a target="_blank" attribute to all links
67
+ #
68
+ # link_farmers_markup = "ohai! <a href='http://www.myswarmysite.com/'>I like your blog post</a>"
69
+ # Loofah.html5_fragment(link_farmers_markup).scrub!(:targetblank)
70
+ # => "ohai! <a href='http://www.myswarmysite.com/' target="_blank">I like your blog post</a>"
71
+ #
72
+ #
64
73
  # === Loofah::Scrubbers::NoOpener / scrub!(:noopener)
65
74
  #
66
75
  # +:noopener+ adds a rel="noopener" attribute to all links
@@ -69,6 +78,14 @@ module Loofah
69
78
  # Loofah.html5_fragment(link_farmers_markup).scrub!(:noopener)
70
79
  # => "ohai! <a href='http://www.myswarmysite.com/' rel="noopener">I like your blog post</a>"
71
80
  #
81
+ # === Loofah::Scrubbers::NoReferrer / scrub!(:noreferrer)
82
+ #
83
+ # +:noreferrer+ adds a rel="noreferrer" attribute to all links
84
+ #
85
+ # link_farmers_markup = "ohai! <a href='http://www.myswarmysite.com/'>I like your blog post</a>"
86
+ # Loofah.html5_fragment(link_farmers_markup).scrub!(:noreferrer)
87
+ # => "ohai! <a href='http://www.myswarmysite.com/' rel="noreferrer">I like your blog post</a>"
88
+ #
72
89
  #
73
90
  # === Loofah::Scrubbers::Unprintable / scrub!(:unprintable)
74
91
  #
@@ -213,6 +230,33 @@ module Loofah
213
230
  end
214
231
  end
215
232
 
233
+ #
234
+ # === scrub!(:targetblank)
235
+ #
236
+ # +:targetblank+ adds a target="_blank" attribute to all links.
237
+ # If there is a target already set, replaces it with target="_blank".
238
+ #
239
+ # link_farmers_markup = "ohai! <a href='http://www.myswarmysite.com/'>I like your blog post</a>"
240
+ # Loofah.html5_fragment(link_farmers_markup).scrub!(:targetblank)
241
+ # => "ohai! <a href='http://www.myswarmysite.com/' target="_blank">I like your blog post</a>"
242
+ #
243
+ # On modern browsers, setting target="_blank" on anchor elements implicitly provides the same
244
+ # behavior as setting rel="noopener".
245
+ #
246
+ class TargetBlank < Scrubber
247
+ def initialize # rubocop:disable Lint/MissingSuper
248
+ @direction = :top_down
249
+ end
250
+
251
+ def scrub(node)
252
+ return CONTINUE unless (node.type == Nokogiri::XML::Node::ELEMENT_NODE) && (node.name == "a")
253
+
254
+ node.set_attribute("target", "_blank")
255
+
256
+ STOP
257
+ end
258
+ end
259
+
216
260
  #
217
261
  # === scrub!(:noopener)
218
262
  #
@@ -235,6 +279,28 @@ module Loofah
235
279
  end
236
280
  end
237
281
 
282
+ #
283
+ # === scrub!(:noreferrer)
284
+ #
285
+ # +:noreferrer+ adds a rel="noreferrer" attribute to all links
286
+ #
287
+ # link_farmers_markup = "ohai! <a href='http://www.myswarmysite.com/'>I like your blog post</a>"
288
+ # Loofah.html5_fragment(link_farmers_markup).scrub!(:noreferrer)
289
+ # => "ohai! <a href='http://www.myswarmysite.com/' rel="noreferrer">I like your blog post</a>"
290
+ #
291
+ class NoReferrer < Scrubber
292
+ def initialize # rubocop:disable Lint/MissingSuper
293
+ @direction = :top_down
294
+ end
295
+
296
+ def scrub(node)
297
+ return CONTINUE unless (node.type == Nokogiri::XML::Node::ELEMENT_NODE) && (node.name == "a")
298
+
299
+ append_attribute(node, "rel", "noreferrer")
300
+ STOP
301
+ end
302
+ end
303
+
238
304
  # This class probably isn't useful publicly, but is used for #to_text's current implemention
239
305
  class NewlineBlockElements < Scrubber # :nodoc:
240
306
  def initialize # rubocop:disable Lint/MissingSuper
@@ -292,6 +358,8 @@ module Loofah
292
358
  strip: Strip,
293
359
  nofollow: NoFollow,
294
360
  noopener: NoOpener,
361
+ noreferrer: NoReferrer,
362
+ targetblank: TargetBlank,
295
363
  newline_block_elements: NewlineBlockElements,
296
364
  unprintable: Unprintable,
297
365
  }
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Loofah
4
4
  # The version of Loofah you are using
5
- VERSION = "2.21.3"
5
+ VERSION = "2.23.1"
6
6
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loofah
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.21.3
4
+ version: 2.23.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Dalessio
8
8
  - Bryan Helmkamp
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-05-15 00:00:00.000000000 Z
12
+ date: 2024-10-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: crass
@@ -82,7 +82,7 @@ metadata:
82
82
  bug_tracker_uri: https://github.com/flavorjones/loofah/issues
83
83
  changelog_uri: https://github.com/flavorjones/loofah/blob/main/CHANGELOG.md
84
84
  documentation_uri: https://www.rubydoc.info/gems/loofah/
85
- post_install_message:
85
+ post_install_message:
86
86
  rdoc_options: []
87
87
  require_paths:
88
88
  - lib
@@ -97,8 +97,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
97
  - !ruby/object:Gem::Version
98
98
  version: '0'
99
99
  requirements: []
100
- rubygems_version: 3.4.10
101
- signing_key:
100
+ rubygems_version: 3.5.22
101
+ signing_key:
102
102
  specification_version: 4
103
103
  summary: Loofah is a general library for manipulating and transforming HTML/XML documents
104
104
  and fragments, built on top of Nokogiri.