better_html 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/lib/better_html/ast/iterator.rb +3 -3
  3. data/lib/better_html/ast/node.rb +6 -2
  4. data/lib/better_html/errors.rb +2 -11
  5. data/lib/better_html/test_helper/ruby_node.rb +103 -0
  6. data/lib/better_html/test_helper/safe_erb/allowed_script_type.rb +29 -0
  7. data/lib/better_html/test_helper/safe_erb/base.rb +56 -0
  8. data/lib/better_html/test_helper/safe_erb/no_javascript_tag_helper.rb +34 -0
  9. data/lib/better_html/test_helper/safe_erb/no_statements.rb +40 -0
  10. data/lib/better_html/test_helper/safe_erb/script_interpolation.rb +65 -0
  11. data/lib/better_html/test_helper/safe_erb/tag_interpolation.rb +163 -0
  12. data/lib/better_html/test_helper/safe_erb_tester.rb +32 -285
  13. data/lib/better_html/tokenizer/location.rb +1 -1
  14. data/lib/better_html/version.rb +1 -1
  15. data/test/better_html/errors_test.rb +13 -0
  16. data/test/better_html/test_helper/ruby_node_test.rb +288 -0
  17. data/test/better_html/test_helper/safe_erb/allowed_script_type_test.rb +45 -0
  18. data/test/better_html/test_helper/safe_erb/no_javascript_tag_helper_test.rb +37 -0
  19. data/test/better_html/test_helper/safe_erb/no_statements_test.rb +128 -0
  20. data/test/better_html/test_helper/safe_erb/script_interpolation_test.rb +149 -0
  21. data/test/better_html/test_helper/safe_erb/tag_interpolation_test.rb +295 -0
  22. data/test/test_helper.rb +1 -0
  23. metadata +23 -7
  24. data/lib/better_html/test_helper/ruby_expr.rb +0 -117
  25. data/test/better_html/test_helper/ruby_expr_test.rb +0 -283
  26. data/test/better_html/test_helper/safe_erb_tester_test.rb +0 -450
@@ -1,450 +0,0 @@
1
- require 'test_helper'
2
- require 'better_html/test_helper/safe_erb_tester'
3
-
4
- module BetterHtml
5
- module TestHelper
6
- class SafeErbTesterTest < ActiveSupport::TestCase
7
- setup do
8
- @config = BetterHtml::Config.new(
9
- javascript_safe_methods: ['j', 'escape_javascript', 'to_json'],
10
- javascript_attribute_names: [/\Aon/i, 'data-eval'],
11
- )
12
- end
13
-
14
- test "multi line erb comments in text" do
15
- errors = parse(<<-EOF).errors
16
- text
17
- <%#
18
- this is a nice comment
19
- !@\#{$%?&*()}
20
- %>
21
- EOF
22
-
23
- assert_predicate errors, :empty?
24
- end
25
-
26
- test "multi line erb comments in html attribute" do
27
- errors = parse(<<-EOF).errors
28
- <div title="
29
- <%#
30
- this is a comment right in the middle of an attribute for some reason
31
- %>
32
- ">
33
- EOF
34
-
35
- assert_predicate errors, :empty?
36
- end
37
-
38
- test "string without interpolation is safe" do
39
- errors = parse(<<-EOF).errors
40
- <a onclick="alert('<%= "something" %>')">
41
- EOF
42
-
43
- assert_equal 0, errors.size
44
- end
45
-
46
- test "string with interpolation" do
47
- errors = parse(<<-EOF).errors
48
- <a onclick="<%= "hello \#{name}" %>">
49
- EOF
50
-
51
- assert_equal 1, errors.size
52
- assert_equal '"hello #{name}"', errors.first.location.source
53
- assert_equal "erb interpolation in javascript attribute must call '(...).to_json'", errors.first.message
54
- end
55
-
56
- test "string with interpolation and ternary" do
57
- errors = parse(<<-EOF).errors
58
- <a onclick="<%= "hello \#{foo ? bar : baz}" if bla? %>">
59
- EOF
60
-
61
- assert_equal 2, errors.size
62
-
63
- assert_equal '"hello #{foo ? bar : baz}" if bla?', errors.first.location.source
64
- assert_equal "erb interpolation in javascript attribute must call '(...).to_json'", errors.first.message
65
-
66
- assert_equal '"hello #{foo ? bar : baz}" if bla?', errors.first.location.source
67
- assert_equal "erb interpolation in javascript attribute must call '(...).to_json'", errors.first.message
68
- end
69
-
70
- test "plain erb tag in html attribute" do
71
- errors = parse(<<-EOF).errors
72
- <a onclick="method(<%= unsafe %>)">
73
- EOF
74
-
75
- assert_equal 1, errors.size
76
- assert_equal 'unsafe', errors.first.location.source
77
- assert_equal "erb interpolation in javascript attribute must call '(...).to_json'", errors.first.message
78
- end
79
-
80
- test "to_json is safe in html attribute" do
81
- errors = parse(<<-EOF).errors
82
- <a onclick="method(<%= unsafe.to_json %>)">
83
- EOF
84
- assert_predicate errors, :empty?
85
- end
86
-
87
- test "ternary with safe javascript escaping" do
88
- errors = parse(<<-EOF).errors
89
- <a onclick="method(<%= foo ? bar.to_json : j(baz) %>)">
90
- EOF
91
- assert_predicate errors, :empty?
92
- end
93
-
94
- test "ternary with unsafe javascript escaping" do
95
- errors = parse(<<-EOF).errors
96
- <a onclick="method(<%= foo ? bar : j(baz) %>)">
97
- EOF
98
-
99
- assert_equal 1, errors.size
100
- assert_equal 'foo ? bar : j(baz)', errors.first.location.source
101
- assert_equal "erb interpolation in javascript attribute must call '(...).to_json'", errors.first.message
102
- end
103
-
104
- test "j is safe in html attribute" do
105
- errors = parse(<<-EOF).errors
106
- <a onclick="method('<%= j unsafe %>')">
107
- EOF
108
- assert_predicate errors, :empty?
109
- end
110
-
111
- test "j() is safe in html attribute" do
112
- errors = parse(<<-EOF).errors
113
- <a onclick="method('<%= j(unsafe) %>')">
114
- EOF
115
- assert_predicate errors, :empty?
116
- end
117
-
118
- test "escape_javascript is safe in html attribute" do
119
- errors = parse(<<-EOF).errors
120
- <a onclick="method(<%= escape_javascript unsafe %>)">
121
- EOF
122
- assert_predicate errors, :empty?
123
- end
124
-
125
- test "escape_javascript() is safe in html attribute" do
126
- errors = parse(<<-EOF).errors
127
- <a onclick="method(<%= escape_javascript(unsafe) %>)">
128
- EOF
129
- assert_predicate errors, :empty?
130
- end
131
-
132
- test "html_safe is never safe in html attribute, even non javascript attributes like href" do
133
- errors = parse(<<-EOF).errors
134
- <a href="<%= unsafe.html_safe %>">
135
- EOF
136
-
137
- assert_equal 1, errors.size
138
- assert_equal 'unsafe.html_safe', errors.first.location.source
139
- assert_equal "erb interpolation with '<%= (...).html_safe %>' inside html attribute is never safe", errors.first.message
140
- end
141
-
142
- test "html_safe is never safe in html attribute, even with to_json" do
143
- errors = parse(<<-EOF).errors
144
- <a onclick="method(<%= unsafe.to_json.html_safe %>)">
145
- EOF
146
-
147
- assert_equal 1, errors.size
148
- assert_equal 'unsafe.to_json.html_safe', errors.first.location.source
149
- assert_equal "erb interpolation with '<%= (...).html_safe %>' inside html attribute is never safe", errors.first.message
150
- end
151
-
152
- test "<%== is never safe in html attribute, even non javascript attributes like href" do
153
- errors = parse(<<-EOF).errors
154
- <a href="<%== unsafe %>">
155
- EOF
156
-
157
- assert_equal 1, errors.size
158
- assert_equal '<%== unsafe %>', errors.first.location.source
159
- assert_includes "erb interpolation with '<%==' inside html attribute is never safe", errors.first.message
160
- end
161
-
162
- test "<%== is never safe in html attribute, even with to_json" do
163
- errors = parse(<<-EOF).errors
164
- <a onclick="method(<%== unsafe.to_json %>)">
165
- EOF
166
-
167
- assert_equal 1, errors.size
168
- assert_equal '<%== unsafe.to_json %>', errors.first.location.source
169
- assert_includes "erb interpolation with '<%==' inside html attribute is never safe", errors.first.message
170
- end
171
-
172
- test "raw is never safe in html attribute, even non javascript attributes like href" do
173
- errors = parse(<<-EOF).errors
174
- <a href="<%= raw unsafe %>">
175
- EOF
176
-
177
- assert_equal 1, errors.size
178
- assert_equal 'raw unsafe', errors.first.location.source
179
- assert_equal "erb interpolation with '<%= raw(...) %>' inside html attribute is never safe", errors.first.message
180
- end
181
-
182
- test "raw is never safe in html attribute, even with to_json" do
183
- errors = parse(<<-EOF).errors
184
- <a onclick="method(<%= raw unsafe.to_json %>)">
185
- EOF
186
-
187
- assert_equal 1, errors.size
188
- assert_equal 'raw unsafe.to_json', errors.first.location.source
189
- assert_equal "erb interpolation with '<%= raw(...) %>' inside html attribute is never safe", errors.first.message
190
- end
191
-
192
- test "unsafe erb in <script> tag without type" do
193
- errors = parse(<<-EOF).errors
194
- <script>
195
- if (a < 1) { <%= unsafe %> }
196
- </script>
197
- EOF
198
-
199
- assert_equal 1, errors.size
200
- assert_equal '<%= unsafe %>', errors.first.location.source
201
- assert_equal "erb interpolation in javascript tag must call '(...).to_json'", errors.first.message
202
- end
203
-
204
- test "unsafe erb in javascript template" do
205
- errors = parse(<<-JS, template_language: :javascript).errors
206
- if (a < 1) { <%= unsafe %> }
207
- JS
208
-
209
- assert_equal 1, errors.size
210
- assert_equal '<%= unsafe %>', errors.first.location.source
211
- assert_equal "erb interpolation in javascript tag must call '(...).to_json'", errors.first.message
212
- end
213
-
214
- test "<script> tag without calls is unsafe" do
215
- errors = parse(<<-EOF).errors
216
- <script type="text/javascript">
217
- if (a < 1) { <%= "unsafe" %> }
218
- </script>
219
- EOF
220
-
221
- assert_equal 1, errors.size
222
- assert_equal '<%= "unsafe" %>', errors.first.location.source
223
- assert_equal "erb interpolation in javascript tag must call '(...).to_json'", errors.first.message
224
- end
225
-
226
- test "javascript template without calls is unsafe" do
227
- errors = parse(<<-JS, template_language: :javascript).errors
228
- if (a < 1) { <%= "unsafe" %> }
229
- JS
230
-
231
- assert_equal 1, errors.size
232
- assert_equal '<%= "unsafe" %>', errors.first.location.source
233
- assert_equal "erb interpolation in javascript tag must call '(...).to_json'", errors.first.message
234
- end
235
-
236
- test "unsafe erb in javascript_tag" do
237
- errors = parse(<<-EOF).errors
238
- <%= javascript_tag do %>
239
- if (a < 1) { <%= unsafe %> }
240
- <% end %>
241
- EOF
242
-
243
- assert_equal 1, errors.size
244
- assert_equal '<%= javascript_tag do %>', errors.first.location.source
245
- assert_includes "'javascript_tag do' syntax is deprecated; use inline <script> instead", errors.first.message
246
- end
247
-
248
- test "unsafe erb in <script> tag with text/javascript content type" do
249
- errors = parse(<<-EOF).errors
250
- <script type="text/javascript">
251
- if (a < 1) { <%= unsafe %> }
252
- </script>
253
- EOF
254
-
255
- assert_equal 1, errors.size
256
- assert_equal '<%= unsafe %>', errors.first.location.source
257
- assert_equal "erb interpolation in javascript tag must call '(...).to_json'", errors.first.message
258
- end
259
-
260
- test "<script> tag with non executable content type is ignored" do
261
- errors = parse(<<-EOF).errors
262
- <script type="text/html">
263
- <a onclick="<%= unsafe %>">
264
- </script>
265
- EOF
266
-
267
- assert_predicate errors, :empty?
268
- end
269
-
270
- test "statements not allowed in script tags" do
271
- errors = parse(<<-EOF).errors
272
- <script type="text/javascript">
273
- <% if foo? %>
274
- bla
275
- <% end %>
276
- </script>
277
- EOF
278
-
279
- assert_equal 1, errors.size
280
- assert_equal "<% if foo? %>", errors.first.location.source
281
- assert_equal "erb statement not allowed here; did you mean '<%=' ?", errors.first.message
282
- end
283
-
284
- test "disallowed script types" do
285
- errors = parse(<<-EOF).errors
286
- <script type="text/bogus">
287
- </script>
288
- EOF
289
-
290
- assert_equal 1, errors.size
291
- assert_equal 'type="text/bogus"', errors.first.location.source
292
- assert_equal "text/bogus is not a valid type, valid types are text/javascript, text/template, text/html", errors.first.message
293
- end
294
-
295
- test "statements not allowed in javascript template" do
296
- errors = parse(<<-JS, template_language: :javascript).errors
297
- <% if foo %>
298
- bla
299
- <% end %>
300
- JS
301
-
302
- assert_equal 1, errors.size
303
- assert_equal "<% if foo %>", errors.first.location.source
304
- assert_equal "erb statement not allowed here; did you mean '<%=' ?", errors.first.message
305
- end
306
-
307
- test "erb comments allowed in scripts" do
308
- errors = parse(<<-EOF).errors
309
- <script type="text/javascript">
310
- <%# comment %>
311
- </script>
312
- EOF
313
-
314
- assert_predicate errors, :empty?
315
- end
316
-
317
- test "script tag without content" do
318
- errors = parse(<<-EOF).errors
319
- <script type="text/javascript"></script>
320
- EOF
321
-
322
- assert_predicate errors, :empty?
323
- end
324
-
325
- test "statement after script regression" do
326
- errors = parse(<<-EOF).errors
327
- <script type="text/javascript">
328
- foo()
329
- </script>
330
- <% if condition? %>
331
- EOF
332
-
333
- assert_predicate errors, :empty?
334
- end
335
-
336
- test "<script> with to_json is safe" do
337
- errors = parse(<<-EOF).errors
338
- <script type="text/javascript">
339
- <%= unsafe.to_json %>
340
- </script>
341
- EOF
342
-
343
- assert_predicate errors, :empty?
344
- end
345
-
346
- test "javascript template with to_json is safe" do
347
- errors = parse(<<-JS, template_language: :javascript).errors
348
- <%= unsafe.to_json %>
349
- JS
350
-
351
- assert_predicate errors, :empty?
352
- end
353
-
354
- test "<script> with raw and to_json is safe" do
355
- errors = parse(<<-EOF).errors
356
- <script type="text/javascript">
357
- <%= raw unsafe.to_json %>
358
- </script>
359
- EOF
360
-
361
- assert_predicate errors, :empty?
362
- end
363
-
364
- test "javascript template with raw and to_json is safe" do
365
- errors = parse(<<-JS, template_language: :javascript).errors
366
- <%= raw unsafe.to_json %>
367
- JS
368
-
369
- assert_predicate errors, :empty?
370
- end
371
-
372
- test "end statements are allowed in script tags" do
373
- errors = parse(<<-EOF).errors
374
- <script type="text/template">
375
- <%= ui_form do %>
376
- <div></div>
377
- <% end %>
378
- </script>
379
- EOF
380
-
381
- assert_predicate errors, :empty?
382
- end
383
-
384
- test "statements are allowed in text/html tags" do
385
- errors = parse(<<-EOF).errors
386
- <script type="text/html">
387
- <% if condition? %>
388
- <div></div>
389
- <% end %>
390
- </script>
391
- EOF
392
-
393
- assert_predicate errors, :empty?
394
- end
395
-
396
- test "unsafe javascript methods in helper calls with new hash syntax" do
397
- errors = parse(<<-EOF).errors
398
- <%= ui_my_helper(:foo, onclick: "alert(\#{unsafe})", onmouseover: "alert(\#{unsafe.to_json})") %>
399
- EOF
400
-
401
- assert_equal 1, errors.size
402
- assert_equal "\#{unsafe}", errors[0].location.source
403
- assert_equal "erb interpolation in javascript attribute must call '(...).to_json'", errors[0].message
404
- end
405
-
406
- test "unsafe javascript methods in helper calls with old hash syntax" do
407
- errors = parse(<<-EOF).errors
408
- <%= ui_my_helper(:foo, :onclick => "alert(\#{unsafe})") %>
409
- EOF
410
-
411
- assert_equal 1, errors.size
412
- assert_equal "\#{unsafe}", errors.first.location.source
413
- assert_equal "erb interpolation in javascript attribute must call '(...).to_json'", errors.first.message
414
- end
415
-
416
- test "unsafe javascript methods in helper calls with string as key" do
417
- errors = parse(<<-EOF).errors
418
- <%= ui_my_helper(:foo, 'data-eval' => "alert(\#{unsafe})") %>
419
- EOF
420
-
421
- assert_equal 1, errors.size
422
- assert_equal "\#{unsafe}", errors.first.location.source
423
- assert_equal "erb interpolation in javascript attribute must call '(...).to_json'", errors.first.message
424
- end
425
-
426
- test "unsafe javascript methods in helper calls with nested data key" do
427
- errors = parse(<<-EOF).errors
428
- <%= ui_my_helper(:foo, data: { eval: "alert(\#{unsafe})" }) %>
429
- EOF
430
-
431
- assert_equal 1, errors.size
432
- assert_equal "\#{unsafe}", errors.first.location.source
433
- assert_equal "erb interpolation in javascript attribute must call '(...).to_json'", errors.first.message
434
- end
435
-
436
- test "ivar missing .to_json is unsafe" do
437
- errors = parse('<script><%= @feature.html_safe %></script>').errors
438
-
439
- assert_equal 1, errors.size
440
- assert_equal "<%= @feature.html_safe %>", errors.first.location.source
441
- assert_equal "erb interpolation in javascript tag must call '(...).to_json'", errors.first.message
442
- end
443
-
444
- private
445
- def parse(data, template_language: :html)
446
- SafeErbTester::Tester.new(data, config: @config, template_language: template_language)
447
- end
448
- end
449
- end
450
- end