@@ -7,6 +7,8 @@ class TagHelperTest < ActionView::TestCase
7
7
8
8
tests ActionView ::Helpers ::TagHelper
9
9
10
+ COMMON_DANGEROUS_CHARS = "&<>\" ' %*+,/;=^|"
11
+
10
12
def test_tag
11
13
assert_equal "<br />" , tag ( "br" )
12
14
assert_equal "<br clear=\" left\" />" , tag ( :br , clear : "left" )
@@ -111,6 +113,77 @@ def test_tag_builder_do_not_modify_html_safe_options
111
113
assert html_safe_str . html_safe?
112
114
end
113
115
116
+ def test_tag_with_dangerous_name
117
+ assert_equal "<#{ "_" * COMMON_DANGEROUS_CHARS . size } />" ,
118
+ tag ( COMMON_DANGEROUS_CHARS )
119
+
120
+ assert_equal "<#{ COMMON_DANGEROUS_CHARS } />" ,
121
+ tag ( COMMON_DANGEROUS_CHARS , nil , false , false )
122
+ end
123
+
124
+ def test_tag_builder_with_dangerous_name
125
+ escaped_dangerous_chars = "_" * COMMON_DANGEROUS_CHARS . size
126
+ assert_equal "<#{ escaped_dangerous_chars } ></#{ escaped_dangerous_chars } >" ,
127
+ tag . public_send ( COMMON_DANGEROUS_CHARS . to_sym )
128
+
129
+ assert_equal "<#{ COMMON_DANGEROUS_CHARS } ></#{ COMMON_DANGEROUS_CHARS } >" ,
130
+ tag . public_send ( COMMON_DANGEROUS_CHARS . to_sym , nil , escape : false )
131
+ end
132
+
133
+ def test_tag_with_dangerous_aria_attribute_name
134
+ escaped_dangerous_chars = "_" * COMMON_DANGEROUS_CHARS . size
135
+ assert_equal "<the-name aria-#{ escaped_dangerous_chars } =\" the value\" />" ,
136
+ tag ( "the-name" , aria : { COMMON_DANGEROUS_CHARS => "the value" } )
137
+
138
+ assert_equal "<the-name aria-#{ COMMON_DANGEROUS_CHARS } =\" the value\" />" ,
139
+ tag ( "the-name" , { aria : { COMMON_DANGEROUS_CHARS => "the value" } } , false , false )
140
+ end
141
+
142
+ def test_tag_builder_with_dangerous_aria_attribute_name
143
+ escaped_dangerous_chars = "_" * COMMON_DANGEROUS_CHARS . size
144
+ assert_equal "<the-name aria-#{ escaped_dangerous_chars } =\" the value\" ></the-name>" ,
145
+ tag . public_send ( :"the-name" , aria : { COMMON_DANGEROUS_CHARS => "the value" } )
146
+
147
+ assert_equal "<the-name aria-#{ COMMON_DANGEROUS_CHARS } =\" the value\" ></the-name>" ,
148
+ tag . public_send ( :"the-name" , aria : { COMMON_DANGEROUS_CHARS => "the value" } , escape : false )
149
+ end
150
+
151
+ def test_tag_with_dangerous_data_attribute_name
152
+ escaped_dangerous_chars = "_" * COMMON_DANGEROUS_CHARS . size
153
+ assert_equal "<the-name data-#{ escaped_dangerous_chars } =\" the value\" />" ,
154
+ tag ( "the-name" , data : { COMMON_DANGEROUS_CHARS => "the value" } )
155
+
156
+ assert_equal "<the-name data-#{ COMMON_DANGEROUS_CHARS } =\" the value\" />" ,
157
+ tag ( "the-name" , { data : { COMMON_DANGEROUS_CHARS => "the value" } } , false , false )
158
+ end
159
+
160
+ def test_tag_builder_with_dangerous_data_attribute_name
161
+ escaped_dangerous_chars = "_" * COMMON_DANGEROUS_CHARS . size
162
+ assert_equal "<the-name data-#{ escaped_dangerous_chars } =\" the value\" ></the-name>" ,
163
+ tag . public_send ( :"the-name" , data : { COMMON_DANGEROUS_CHARS => "the value" } )
164
+
165
+ assert_equal "<the-name data-#{ COMMON_DANGEROUS_CHARS } =\" the value\" ></the-name>" ,
166
+ tag . public_send ( :"the-name" , data : { COMMON_DANGEROUS_CHARS => "the value" } , escape : false )
167
+ end
168
+
169
+ def test_tag_with_dangerous_unknown_attribute_name
170
+ escaped_dangerous_chars = "_" * COMMON_DANGEROUS_CHARS . size
171
+ assert_equal "<the-name #{ escaped_dangerous_chars } =\" the value\" />" ,
172
+ tag ( "the-name" , COMMON_DANGEROUS_CHARS => "the value" )
173
+
174
+ assert_equal "<the-name #{ COMMON_DANGEROUS_CHARS } =\" the value\" />" ,
175
+ tag ( "the-name" , { COMMON_DANGEROUS_CHARS => "the value" } , false , false )
176
+ end
177
+
178
+ def test_tag_builder_with_dangerous_unknown_attribute_name
179
+ escaped_dangerous_chars = "_" * COMMON_DANGEROUS_CHARS . size
180
+ assert_equal "<the-name #{ escaped_dangerous_chars } =\" the value\" ></the-name>" ,
181
+ tag . public_send ( :"the-name" , COMMON_DANGEROUS_CHARS => "the value" )
182
+
183
+ assert_equal "<the-name #{ COMMON_DANGEROUS_CHARS } =\" the value\" ></the-name>" ,
184
+ tag . public_send ( :"the-name" , COMMON_DANGEROUS_CHARS => "the value" , escape : false )
185
+ end
186
+
114
187
def test_content_tag
115
188
assert_equal "<a href=\" create\" >Create</a>" , content_tag ( "a" , "Create" , "href" => "create" )
116
189
assert_predicate content_tag ( "a" , "Create" , "href" => "create" ) , :html_safe?
@@ -130,10 +203,54 @@ def test_tag_builder_with_content
130
203
assert_equal "<p><script>evil_js</script></p>" ,
131
204
tag . p ( "<script>evil_js</script>" )
132
205
assert_equal "<p><script>evil_js</script></p>" ,
133
- tag . p ( "<script>evil_js</script>" , escape_attributes : false )
206
+ tag . p ( "<script>evil_js</script>" , escape : false )
134
207
assert_equal '<input pattern="\w+">' , tag . input ( pattern : /\w +/ )
135
208
end
136
209
210
+ def test_deprecated_option_escape_attributes
211
+ raw_content = "<script>evil_js</script>"
212
+ escaped_content = "<script>evil_js</script>"
213
+
214
+ expected_deprecation_warning = <<~MSG
215
+ Use of the option :escape_attributes is deprecated. It currently \
216
+ escapes both names and values of tags and attributes and it is \
217
+ equivalent to :escape. If any of them are enabled, the escaping \
218
+ is fully enabled.
219
+ MSG
220
+
221
+ assert_equal "<p>#{ escaped_content } </p>" ,
222
+ tag . p ( raw_content )
223
+ assert_equal "<p>#{ escaped_content } </p>" ,
224
+ tag . p ( raw_content , escape : true )
225
+ assert_equal "<p>#{ raw_content } </p>" ,
226
+ tag . p ( raw_content , escape : false )
227
+
228
+ assert_deprecated ( expected_deprecation_warning ) do
229
+ assert_equal "<p>#{ escaped_content } </p>" ,
230
+ tag . p ( raw_content , escape_attributes : true )
231
+ end
232
+ assert_deprecated ( expected_deprecation_warning ) do
233
+ assert_equal "<p>#{ raw_content } </p>" ,
234
+ tag . p ( raw_content , escape_attributes : false )
235
+ end
236
+ assert_deprecated ( expected_deprecation_warning ) do
237
+ assert_equal "<p>#{ escaped_content } </p>" ,
238
+ tag . p ( raw_content , escape_attributes : true , escape : true )
239
+ end
240
+ assert_deprecated ( expected_deprecation_warning ) do
241
+ assert_equal "<p>#{ raw_content } </p>" ,
242
+ tag . p ( raw_content , escape_attributes : false , escape : false )
243
+ end
244
+ assert_deprecated ( expected_deprecation_warning ) do
245
+ assert_equal "<p>#{ escaped_content } </p>" ,
246
+ tag . p ( raw_content , escape_attributes : true , escape : false )
247
+ end
248
+ assert_deprecated ( expected_deprecation_warning ) do
249
+ assert_equal "<p>#{ escaped_content } </p>" ,
250
+ tag . p ( raw_content , escape_attributes : false , escape : true )
251
+ end
252
+ end
253
+
137
254
def test_tag_builder_nested
138
255
assert_equal "<div>content</div>" ,
139
256
tag . div { "content" }
@@ -246,10 +363,10 @@ def test_content_tag_with_unescaped_array_class
246
363
end
247
364
248
365
def test_tag_builder_with_unescaped_array_class
249
- str = tag . p "limelight" , class : [ "song" , "play>" ] , escape_attributes : false
366
+ str = tag . p "limelight" , class : [ "song" , "play>" ] , escape : false
250
367
assert_equal "<p class=\" song play>\" >limelight</p>" , str
251
368
252
- str = tag . p "limelight" , class : [ "song" , [ "play>" ] ] , escape_attributes : false
369
+ str = tag . p "limelight" , class : [ "song" , [ "play>" ] ] , escape : false
253
370
assert_equal "<p class=\" song play>\" >limelight</p>" , str
254
371
end
255
372
@@ -268,7 +385,7 @@ def test_content_tag_with_unescaped_empty_array_class
268
385
end
269
386
270
387
def test_tag_builder_with_unescaped_empty_array_class
271
- str = tag . p "limelight" , class : [ ] , escape_attributes : false
388
+ str = tag . p "limelight" , class : [ ] , escape : false
272
389
assert_equal '<p class="">limelight</p>' , str
273
390
end
274
391
@@ -339,10 +456,10 @@ def test_content_tag_with_unescaped_conditional_hash_classes
339
456
end
340
457
341
458
def test_tag_builder_with_unescaped_conditional_hash_classes
342
- str = tag . p "limelight" , class : { "song" : true , "play>" : true } , escape_attributes : false
459
+ str = tag . p "limelight" , class : { "song" : true , "play>" : true } , escape : false
343
460
assert_equal "<p class=\" song play>\" >limelight</p>" , str
344
461
345
- str = tag . p "limelight" , class : [ "song" , { "play>" : true } ] , escape_attributes : false
462
+ str = tag . p "limelight" , class : [ "song" , { "play>" : true } ] , escape : false
346
463
assert_equal "<p class=\" song play>\" >limelight</p>" , str
347
464
end
348
465
@@ -456,11 +573,11 @@ def test_disable_escaping
456
573
end
457
574
458
575
def test_tag_builder_disable_escaping
459
- assert_equal '<a href="&"></a>' , tag . a ( href : "&" , escape_attributes : false )
460
- assert_equal '<a href="&">cnt</a>' , tag . a ( href : "&" , escape_attributes : false ) { "cnt" }
461
- assert_equal '<br data-hidden="&">' , tag . br ( "data-hidden" : "&" , escape_attributes : false )
462
- assert_equal '<a href="&">content</a>' , tag . a ( "content" , href : "&" , escape_attributes : false )
463
- assert_equal '<a href="&">content</a>' , tag . a ( href : "&" , escape_attributes : false ) { "content" }
576
+ assert_equal '<a href="&"></a>' , tag . a ( href : "&" , escape : false )
577
+ assert_equal '<a href="&">cnt</a>' , tag . a ( href : "&" , escape : false ) { "cnt" }
578
+ assert_equal '<br data-hidden="&">' , tag . br ( "data-hidden" : "&" , escape : false )
579
+ assert_equal '<a href="&">content</a>' , tag . a ( "content" , href : "&" , escape : false )
580
+ assert_equal '<a href="&">content</a>' , tag . a ( href : "&" , escape : false ) { "content" }
464
581
end
465
582
466
583
def test_data_attributes
0 commit comments