actionview 8.1.4 → 8.1.4.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: bdc26346ea4cdff80ced71eaf5b63f7ab95815f92d4944ca5b554f5dc2092c98
4
- data.tar.gz: 148985bc4e994851ecef0b9a3cb80fd3e7701b4da44739952797a137863e7148
3
+ metadata.gz: 4ad9b7f3e9b8677cd772d696b4056bda5f44b3cb2074877698060d83eeb8f501
4
+ data.tar.gz: 6d484d054ced5d8990d0ae4b8134879eb192fea59540f8c6f1dd112ed946ec06
5
5
  SHA512:
6
- metadata.gz: 15f9fac8e9a8deea4e2ee57df40cd968a36c483e4701a3983e0bb078a2bfcbc5b561d20b5c40fb9cc70977489730f2f77fa377d8332df146d74030feb07ff5ac
7
- data.tar.gz: b40f142e9d6f4597f42f66d2fcb2395e882f2eabcab216ef53c013f0c245e2c6b9e9d8fb5efae7b89b9efd20a1cef6e0611b9574c79035959e14247c99ef0240
6
+ metadata.gz: 47f094fac7bbc29736cf46dcaa570b42d25cdee803cdd522ae81e37a8351f029991b82099a3d4b64c253ae396412e1f112feb509f2e941f4bf806bcab4a95272
7
+ data.tar.gz: 07ee062127ab3554407ea34d293611e347789e5cd65012340302b7a690e18b01ce6630d85483be9eb5e575869df10a3808891ebd98d14ceb674499acdf904594
data/CHANGELOG.md CHANGED
@@ -1,3 +1,59 @@
1
+ ## Rails 8.1.4.1 (November 03, 2026) ##
2
+
3
+ * Skip attribute names in tag helpers that are blank once converted to a
4
+ string.
5
+
6
+ A Symbol such as `:" "` is not blank, because `Symbol#blank?` is
7
+ `Symbol#empty?`, so it reached the escaping step and produced an attribute
8
+ with no name. The asset helpers symbolize their keys, so an ordinary String
9
+ key reached the same place.
10
+
11
+ [GHSA-68p9-83h6-5wpj]
12
+
13
+ *Mike Dalessio*
14
+
15
+ * Fix `strip_tags` to encode `"` and `'` in its output.
16
+
17
+ `strip_tags` returns an `html_safe` string, but was not encoding quotation
18
+ marks. The method now encodes all five HTML-significant characters (`&`,
19
+ `<`, `>`, `"`, `'`), consistent with the existing `html_safe` convention.
20
+
21
+ Output used outside HTML, such as in a text template or JSON, now contains
22
+ `&quot;` and `&#39;` where it contained `"` and `'`. `CGI.unescapeHTML`
23
+ decodes them.
24
+
25
+ [GHSA-rq8q-p985-fjq7]
26
+
27
+ *Mike Dalessio*
28
+
29
+ * Escape the matched phrase before substituting it into `highlight`'s
30
+ `:highlighter`.
31
+
32
+ A match was copied into each `\1` of the highlighter as it appeared in
33
+ the sanitized text, which keeps `"` and `'` as they are, so a match
34
+ containing a quote ended a quoted attribute value such as the
35
+ documented `'<a href="search?q=\1">\1</a>'` and added attributes of
36
+ its own. Each substituted group now goes through
37
+ `ERB::Util.html_escape_once`, so quotes in a match render as `&quot;`
38
+ and `&#39;`. Only the numbered placeholders `\0` to `\9` are expanded,
39
+ and a match never replaces the `>` that closes a tag.
40
+
41
+ [GHSA-v6rj-xm57-3p59]
42
+
43
+ *Jeremy Daer*
44
+
45
+ * Require rails-html-sanitizer 1.7.2 or later.
46
+
47
+ With the HTML5 sanitizer, Nokogiri before 1.19.5 left `<` and `>`
48
+ unescaped in attribute values. `highlight` and `simple_format`, which
49
+ edit the sanitized HTML as a string, could then turn markup inside an
50
+ attribute value into live elements. rails-html-sanitizer 1.7.2 requires
51
+ Loofah 2.25.3, which requires Nokogiri 1.19.5.
52
+
53
+ [GHSA-2p2f-4rq4-gjwc]
54
+
55
+ *Mike Dalessio*
56
+
1
57
  ## Rails 8.1.4 (September 24, 2026) ##
2
58
 
3
59
  * Fix non-ASCII strict locals defaults rendering as mojibake.
@@ -10,7 +10,7 @@ module ActionView
10
10
  MAJOR = 8
11
11
  MINOR = 1
12
12
  TINY = 4
13
- PRE = nil
13
+ PRE = "1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/string/output_safety"
3
4
  require "rails-html-sanitizer"
4
5
 
5
6
  module ActionView
@@ -33,6 +34,9 @@ module ActionView
33
34
  # Please note that sanitizing user-provided text does not guarantee that the
34
35
  # resulting markup is valid or even well-formed.
35
36
  #
37
+ # The output is markup, which is safe only as element content. Do not use it in an attribute
38
+ # value; use +strip_tags+ or a tag helper such as <tt>tag.a(title: ...)</tt> instead.
39
+ #
36
40
  # ==== Options
37
41
  #
38
42
  # [+:tags+]
@@ -137,7 +141,8 @@ module ActionView
137
141
  # strip_tags("> A quote from Smith & Wesson")
138
142
  # # => &gt; A quote from Smith &amp; Wesson
139
143
  def strip_tags(html)
140
- self.class.full_sanitizer.sanitize(html)&.html_safe
144
+ stripped = self.class.full_sanitizer.sanitize(html)
145
+ ERB::Util.html_escape_once(stripped) if stripped
141
146
  end
142
147
 
143
148
  # Strips all link tags from +html+ leaving just the link text.
@@ -239,18 +239,27 @@ module ActionView
239
239
  options.each_pair do |key, value|
240
240
  next if key.blank?
241
241
 
242
+ name = Symbol === key ? key.name : key.to_s
243
+ next if name.blank?
244
+
242
245
  type = TAG_TYPES[key]
243
246
  if type == :data && value.is_a?(Hash)
244
247
  value.each_pair do |k, v|
245
248
  next if k.blank? || v.nil?
246
249
 
250
+ nested_name = Symbol === k ? k.name : k.to_s
251
+ next if nested_name.blank?
252
+
247
253
  output << sep
248
- output << prefix_tag_option(key, k, v, escape)
254
+ output << prefix_tag_option(name, nested_name, v, escape)
249
255
  end
250
256
  elsif type == :aria && value.is_a?(Hash)
251
257
  value.each_pair do |k, v|
252
258
  next if k.blank? || v.nil?
253
259
 
260
+ nested_name = Symbol === k ? k.name : k.to_s
261
+ next if nested_name.blank?
262
+
254
263
  case v
255
264
  when Array, Hash
256
265
  tokens = TagHelper.build_tag_values(v)
@@ -262,16 +271,16 @@ module ActionView
262
271
  end
263
272
 
264
273
  output << sep
265
- output << prefix_tag_option(key, k, v, escape)
274
+ output << prefix_tag_option(name, nested_name, v, escape)
266
275
  end
267
276
  elsif type == :boolean
268
277
  if value
269
278
  output << sep
270
- output << boolean_tag_option(key)
279
+ output << boolean_tag_option(name)
271
280
  end
272
281
  elsif !value.nil?
273
282
  output << sep
274
- output << tag_option(key, value, escape)
283
+ output << tag_option(name, value, escape)
275
284
  end
276
285
  end
277
286
  output unless output.empty?
@@ -143,8 +143,15 @@ module ActionView
143
143
  #
144
144
  # [+:highlighter+]
145
145
  # The highlighter string. Uses <tt>\1</tt> as the placeholder for a
146
- # phrase, similar to +String#sub+. Defaults to <tt>"<mark>\1</mark>"</tt>.
147
- # This option is ignored if a block is specified.
146
+ # phrase. Defaults to <tt>"<mark>\1</mark>"</tt>. The numbered placeholders
147
+ # <tt>\0</tt> to <tt>\9</tt> are expanded; other +String#sub+ replacement escapes
148
+ # are not. The phrase is HTML escaped, quotes included. This option
149
+ # is ignored if a block is specified.
150
+ #
151
+ # WARNING: Put a placeholder only in element content or inside a
152
+ # quoted attribute value. HTML escaping does not make the phrase safe
153
+ # in an unquoted attribute value, in a URL, JavaScript or CSS
154
+ # context, or in an attribute whose value is HTML, such as +srcdoc+.
148
155
  #
149
156
  # [+:sanitize+]
150
157
  # Whether to sanitize +text+ before highlighting. Defaults to true.
@@ -163,8 +170,8 @@ module ActionView
163
170
  # highlight('You searched for: rails', ['for', 'rails'], highlighter: '<em>\1</em>')
164
171
  # # => "You searched <em>for</em>: <em>rails</em>"
165
172
  #
166
- # highlight('You searched for: rails', 'rails', highlighter: '<a href="search?q=\1">\1</a>')
167
- # # => "You searched for: <a href=\"search?q=rails\">rails</a>"
173
+ # highlight('You searched for: rails', 'rails', highlighter: '<mark title="\1">\1</mark>')
174
+ # # => "You searched for: <mark title=\"rails\">rails</mark>"
168
175
  #
169
176
  # highlight('You searched for: rails', 'rails') { |match| link_to(search_path(q: match)) }
170
177
  # # => "You searched for: <a href=\"search?q=rails\">rails</a>"
@@ -179,14 +186,23 @@ module ActionView
179
186
  else
180
187
  patterns = Array(phrases).map { |phrase| Regexp === phrase ? phrase : Regexp.escape(phrase) }
181
188
  pattern = /(#{patterns.join("|")})/i
189
+ # The text after a tag begins with the ">" that closes it. Leave it
190
+ # in the segment so phrases can see it as context, but keep it out
191
+ # of the match so the highlighter can't take the place of the ">".
192
+ pattern_after_tag = /(?!\A)#{pattern}/
182
193
  highlighter = options.fetch(:highlighter, '<mark>\1</mark>') unless block
183
194
 
184
- text.scan(/<[^>]*|[^<]+/).each do |segment|
195
+ text.scan(/<[^>]*|[^<]+/).each_with_index do |segment, index|
185
196
  if !segment.start_with?("<")
197
+ segment_pattern = index > 0 ? pattern_after_tag : pattern
198
+
186
199
  if block
187
- segment.gsub!(pattern, &block)
200
+ segment.gsub!(segment_pattern, &block)
188
201
  else
189
- segment.gsub!(pattern, highlighter)
202
+ segment.gsub!(segment_pattern) do
203
+ match = Regexp.last_match
204
+ highlighter.gsub(/\\(\d)/) { ERB::Util.html_escape_once(match[$1.to_i]) }
205
+ end
190
206
  end
191
207
  end
192
208
  end.join
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionview
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.1.4
4
+ version: 8.1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 8.1.4
18
+ version: 8.1.4.1
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 8.1.4
25
+ version: 8.1.4.1
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: builder
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -58,6 +58,9 @@ dependencies:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
60
  version: '1.6'
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 1.7.2
61
64
  type: :runtime
62
65
  prerelease: false
63
66
  version_requirements: !ruby/object:Gem::Requirement
@@ -65,6 +68,9 @@ dependencies:
65
68
  - - "~>"
66
69
  - !ruby/object:Gem::Version
67
70
  version: '1.6'
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: 1.7.2
68
74
  - !ruby/object:Gem::Dependency
69
75
  name: rails-dom-testing
70
76
  requirement: !ruby/object:Gem::Requirement
@@ -85,28 +91,28 @@ dependencies:
85
91
  requirements:
86
92
  - - '='
87
93
  - !ruby/object:Gem::Version
88
- version: 8.1.4
94
+ version: 8.1.4.1
89
95
  type: :development
90
96
  prerelease: false
91
97
  version_requirements: !ruby/object:Gem::Requirement
92
98
  requirements:
93
99
  - - '='
94
100
  - !ruby/object:Gem::Version
95
- version: 8.1.4
101
+ version: 8.1.4.1
96
102
  - !ruby/object:Gem::Dependency
97
103
  name: activemodel
98
104
  requirement: !ruby/object:Gem::Requirement
99
105
  requirements:
100
106
  - - '='
101
107
  - !ruby/object:Gem::Version
102
- version: 8.1.4
108
+ version: 8.1.4.1
103
109
  type: :development
104
110
  prerelease: false
105
111
  version_requirements: !ruby/object:Gem::Requirement
106
112
  requirements:
107
113
  - - '='
108
114
  - !ruby/object:Gem::Version
109
- version: 8.1.4
115
+ version: 8.1.4.1
110
116
  description: Simple, battle-tested conventions and helpers for building web pages.
111
117
  email: david@loudthinking.com
112
118
  executables: []
@@ -247,10 +253,10 @@ licenses:
247
253
  - MIT
248
254
  metadata:
249
255
  bug_tracker_uri: https://github.com/rails/rails/issues
250
- changelog_uri: https://github.com/rails/rails/blob/v8.1.4/actionview/CHANGELOG.md
251
- documentation_uri: https://api.rubyonrails.org/v8.1.4/
256
+ changelog_uri: https://github.com/rails/rails/blob/v8.1.4.1/actionview/CHANGELOG.md
257
+ documentation_uri: https://api.rubyonrails.org/v8.1.4.1/
252
258
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
253
- source_code_uri: https://github.com/rails/rails/tree/v8.1.4/actionview
259
+ source_code_uri: https://github.com/rails/rails/tree/v8.1.4.1/actionview
254
260
  rubygems_mfa_required: 'true'
255
261
  rdoc_options: []
256
262
  require_paths: