better_html 1.0.15 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -0
  3. data/Rakefile +19 -14
  4. data/ext/better_html_ext/better_html.h +1 -0
  5. data/ext/better_html_ext/extconf.rb +16 -0
  6. data/ext/better_html_ext/html_tokenizer.c +12 -0
  7. data/ext/better_html_ext/html_tokenizer.h +7 -0
  8. data/ext/better_html_ext/parser.c +793 -0
  9. data/ext/better_html_ext/parser.h +93 -0
  10. data/ext/better_html_ext/tokenizer.c +717 -0
  11. data/ext/better_html_ext/tokenizer.h +80 -0
  12. data/lib/better_html/ast/iterator.rb +14 -9
  13. data/lib/better_html/ast/node.rb +4 -2
  14. data/lib/better_html/better_erb/erubi_implementation.rb +43 -39
  15. data/lib/better_html/better_erb/runtime_checks.rb +140 -133
  16. data/lib/better_html/better_erb/validated_output_buffer.rb +30 -22
  17. data/lib/better_html/better_erb.rb +47 -56
  18. data/lib/better_html/config.rb +7 -4
  19. data/lib/better_html/errors.rb +15 -2
  20. data/lib/better_html/helpers.rb +7 -3
  21. data/lib/better_html/html_attributes.rb +6 -2
  22. data/lib/better_html/parser.rb +22 -14
  23. data/lib/better_html/railtie.rb +8 -4
  24. data/lib/better_html/test_helper/ruby_node.rb +15 -10
  25. data/lib/better_html/test_helper/safe_erb/allowed_script_type.rb +8 -4
  26. data/lib/better_html/test_helper/safe_erb/base.rb +12 -9
  27. data/lib/better_html/test_helper/safe_erb/no_javascript_tag_helper.rb +7 -3
  28. data/lib/better_html/test_helper/safe_erb/no_statements.rb +7 -3
  29. data/lib/better_html/test_helper/safe_erb/script_interpolation.rb +9 -4
  30. data/lib/better_html/test_helper/safe_erb/tag_interpolation.rb +23 -20
  31. data/lib/better_html/test_helper/safe_erb_tester.rb +34 -32
  32. data/lib/better_html/test_helper/safe_lodash_tester.rb +36 -35
  33. data/lib/better_html/test_helper/safety_error.rb +2 -0
  34. data/lib/better_html/tokenizer/base_erb.rb +19 -15
  35. data/lib/better_html/tokenizer/html_erb.rb +3 -2
  36. data/lib/better_html/tokenizer/html_lodash.rb +22 -14
  37. data/lib/better_html/tokenizer/javascript_erb.rb +3 -1
  38. data/lib/better_html/tokenizer/location.rb +17 -6
  39. data/lib/better_html/tokenizer/token.rb +2 -0
  40. data/lib/better_html/tokenizer/token_array.rb +8 -8
  41. data/lib/better_html/tree/attribute.rb +10 -6
  42. data/lib/better_html/tree/attributes_list.rb +9 -5
  43. data/lib/better_html/tree/tag.rb +10 -6
  44. data/lib/better_html/version.rb +3 -1
  45. data/lib/better_html.rb +19 -17
  46. data/lib/tasks/better_html_tasks.rake +1 -0
  47. metadata +39 -147
  48. data/lib/better_html/better_erb/erubis_implementation.rb +0 -44
  49. data/test/better_html/better_erb/implementation_test.rb +0 -406
  50. data/test/better_html/errors_test.rb +0 -13
  51. data/test/better_html/helpers_test.rb +0 -49
  52. data/test/better_html/parser_test.rb +0 -314
  53. data/test/better_html/test_helper/ruby_node_test.rb +0 -288
  54. data/test/better_html/test_helper/safe_erb/allowed_script_type_test.rb +0 -46
  55. data/test/better_html/test_helper/safe_erb/no_javascript_tag_helper_test.rb +0 -37
  56. data/test/better_html/test_helper/safe_erb/no_statements_test.rb +0 -129
  57. data/test/better_html/test_helper/safe_erb/script_interpolation_test.rb +0 -149
  58. data/test/better_html/test_helper/safe_erb/tag_interpolation_test.rb +0 -303
  59. data/test/better_html/test_helper/safe_lodash_tester_test.rb +0 -90
  60. data/test/better_html/tokenizer/html_erb_test.rb +0 -180
  61. data/test/better_html/tokenizer/html_lodash_test.rb +0 -98
  62. data/test/better_html/tokenizer/location_test.rb +0 -75
  63. data/test/better_html/tokenizer/token_array_test.rb +0 -146
  64. data/test/better_html/tokenizer/token_test.rb +0 -15
  65. data/test/dummy/README.rdoc +0 -28
  66. data/test/dummy/Rakefile +0 -6
  67. data/test/dummy/app/assets/javascripts/application.js +0 -13
  68. data/test/dummy/app/assets/stylesheets/application.css +0 -15
  69. data/test/dummy/app/controllers/application_controller.rb +0 -5
  70. data/test/dummy/app/helpers/application_helper.rb +0 -2
  71. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  72. data/test/dummy/bin/bundle +0 -3
  73. data/test/dummy/bin/rails +0 -4
  74. data/test/dummy/bin/rake +0 -4
  75. data/test/dummy/bin/setup +0 -29
  76. data/test/dummy/config/application.rb +0 -26
  77. data/test/dummy/config/boot.rb +0 -5
  78. data/test/dummy/config/database.yml +0 -25
  79. data/test/dummy/config/environment.rb +0 -5
  80. data/test/dummy/config/environments/development.rb +0 -41
  81. data/test/dummy/config/environments/production.rb +0 -79
  82. data/test/dummy/config/environments/test.rb +0 -42
  83. data/test/dummy/config/initializers/assets.rb +0 -11
  84. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  85. data/test/dummy/config/initializers/cookies_serializer.rb +0 -3
  86. data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  87. data/test/dummy/config/initializers/inflections.rb +0 -16
  88. data/test/dummy/config/initializers/mime_types.rb +0 -4
  89. data/test/dummy/config/initializers/session_store.rb +0 -3
  90. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  91. data/test/dummy/config/locales/en.yml +0 -23
  92. data/test/dummy/config/routes.rb +0 -56
  93. data/test/dummy/config/secrets.yml +0 -22
  94. data/test/dummy/config.ru +0 -4
  95. data/test/dummy/public/404.html +0 -67
  96. data/test/dummy/public/422.html +0 -67
  97. data/test/dummy/public/500.html +0 -66
  98. data/test/dummy/public/favicon.ico +0 -0
  99. data/test/test_helper.rb +0 -29
@@ -1,129 +0,0 @@
1
- require 'test_helper'
2
- require 'better_html/parser'
3
- require 'better_html/test_helper/safe_erb/no_statements'
4
-
5
- module BetterHtml
6
- module TestHelper
7
- module SafeErb
8
- class NoStatementsTest < ActiveSupport::TestCase
9
- setup do
10
- @config = BetterHtml::Config.new(
11
- javascript_safe_methods: ['j', 'escape_javascript', 'to_json'],
12
- javascript_attribute_names: [/\Aon/i, 'data-eval'],
13
- )
14
- end
15
-
16
- test "<script> tag with non executable content type is ignored" do
17
- errors = validate(<<-EOF).errors
18
- <script type="text/html">
19
- <a onclick="<%= unsafe %>">
20
- </script>
21
- EOF
22
-
23
- assert_predicate errors, :empty?
24
- end
25
-
26
- test "statements not allowed in script tags" do
27
- errors = validate(<<-EOF).errors
28
- <script type="text/javascript">
29
- <% if foo? %>
30
- bla
31
- <% end %>
32
- </script>
33
- EOF
34
-
35
- assert_equal 1, errors.size
36
- assert_equal "<% if foo? %>", errors.first.location.source
37
- assert_equal "erb statement not allowed here; did you mean '<%=' ?", errors.first.message
38
- end
39
-
40
- test "statements not allowed in script without specified type" do
41
- errors = validate(<<-EOF).errors
42
- <script>
43
- <% if foo? %>
44
- bla
45
- <% end %>
46
- </script>
47
- EOF
48
-
49
- assert_equal 1, errors.size
50
- assert_equal "<% if foo? %>", errors.first.location.source
51
- assert_equal "erb statement not allowed here; did you mean '<%=' ?", errors.first.message
52
- end
53
-
54
- test "statements not allowed in javascript template" do
55
- errors = validate(<<-JS, template_language: :javascript).errors
56
- <% if foo %>
57
- bla
58
- <% end %>
59
- JS
60
-
61
- assert_equal 1, errors.size
62
- assert_equal "<% if foo %>", errors.first.location.source
63
- assert_equal "erb statement not allowed here; did you mean '<%=' ?", errors.first.message
64
- end
65
-
66
- test "erb comments allowed in scripts" do
67
- errors = validate(<<-EOF).errors
68
- <script type="text/javascript">
69
- <%# comment %>
70
- </script>
71
- EOF
72
-
73
- assert_predicate errors, :empty?
74
- end
75
-
76
- test "script tag without content" do
77
- errors = validate(<<-EOF).errors
78
- <script type="text/javascript"></script>
79
- EOF
80
-
81
- assert_predicate errors, :empty?
82
- end
83
-
84
- test "statement after script regression" do
85
- errors = validate(<<-EOF).errors
86
- <script type="text/javascript">
87
- foo()
88
- </script>
89
- <% if condition? %>
90
- EOF
91
-
92
- assert_predicate errors, :empty?
93
- end
94
-
95
- test "end statements are allowed in script tags" do
96
- errors = validate(<<-EOF).errors
97
- <script type="text/template">
98
- <%= ui_form do %>
99
- <div></div>
100
- <% end %>
101
- </script>
102
- EOF
103
-
104
- assert_predicate errors, :empty?
105
- end
106
-
107
- test "statements are allowed in text/html tags" do
108
- errors = validate(<<-EOF).errors
109
- <script type="text/html">
110
- <% if condition? %>
111
- <div></div>
112
- <% end %>
113
- </script>
114
- EOF
115
-
116
- assert_predicate errors, :empty?
117
- end
118
-
119
- private
120
- def validate(data, template_language: :html)
121
- parser = BetterHtml::Parser.new(buffer(data), template_language: template_language)
122
- tester = BetterHtml::TestHelper::SafeErb::NoStatements.new(parser, config: @config)
123
- tester.validate
124
- tester
125
- end
126
- end
127
- end
128
- end
129
- end
@@ -1,149 +0,0 @@
1
- require 'test_helper'
2
- require 'better_html/test_helper/safe_erb/script_interpolation'
3
-
4
- module BetterHtml
5
- module TestHelper
6
- module SafeErb
7
- class ScriptInterpolationTest < ActiveSupport::TestCase
8
- setup do
9
- @config = BetterHtml::Config.new(
10
- javascript_safe_methods: ['j', 'escape_javascript', 'to_json'],
11
- javascript_attribute_names: [/\Aon/i, 'data-eval'],
12
- )
13
- end
14
-
15
- test "multi line erb comments in text" do
16
- errors = validate(<<-EOF).errors
17
- text
18
- <%#
19
- this is a nice comment
20
- !@\#{$%?&*()}
21
- %>
22
- EOF
23
-
24
- assert_predicate errors, :empty?
25
- end
26
-
27
- test "multi line erb comments in html attribute" do
28
- errors = validate(<<-EOF).errors
29
- <div title="
30
- <%#
31
- this is a comment right in the middle of an attribute for some reason
32
- %>
33
- ">
34
- EOF
35
-
36
- assert_predicate errors, :empty?
37
- end
38
-
39
- test "unsafe erb in <script> tag without type" do
40
- errors = validate(<<-EOF).errors
41
- <script>
42
- if (a < 1) { <%= unsafe %> }
43
- </script>
44
- EOF
45
-
46
- assert_equal 1, errors.size
47
- assert_equal '<%= unsafe %>', errors.first.location.source
48
- assert_equal "erb interpolation in javascript tag must call '(...).to_json'", errors.first.message
49
- end
50
-
51
- test "unsafe erb in javascript template" do
52
- errors = validate(<<-JS, template_language: :javascript).errors
53
- if (a < 1) { <%= unsafe %> }
54
- JS
55
-
56
- assert_equal 1, errors.size
57
- assert_equal '<%= unsafe %>', errors.first.location.source
58
- assert_equal "erb interpolation in javascript tag must call '(...).to_json'", errors.first.message
59
- end
60
-
61
- test "<script> tag without calls is unsafe" do
62
- errors = validate(<<-EOF).errors
63
- <script type="text/javascript">
64
- if (a < 1) { <%= "unsafe" %> }
65
- </script>
66
- EOF
67
-
68
- assert_equal 1, errors.size
69
- assert_equal '<%= "unsafe" %>', errors.first.location.source
70
- assert_equal "erb interpolation in javascript tag must call '(...).to_json'", errors.first.message
71
- end
72
-
73
- test "javascript template without calls is unsafe" do
74
- errors = validate(<<-JS, template_language: :javascript).errors
75
- if (a < 1) { <%= "unsafe" %> }
76
- JS
77
-
78
- assert_equal 1, errors.size
79
- assert_equal '<%= "unsafe" %>', errors.first.location.source
80
- assert_equal "erb interpolation in javascript tag must call '(...).to_json'", errors.first.message
81
- end
82
-
83
- test "unsafe erb in <script> tag with text/javascript content type" do
84
- errors = validate(<<-EOF).errors
85
- <script type="text/javascript">
86
- if (a < 1) { <%= unsafe %> }
87
- </script>
88
- EOF
89
-
90
- assert_equal 1, errors.size
91
- assert_equal '<%= unsafe %>', errors.first.location.source
92
- assert_equal "erb interpolation in javascript tag must call '(...).to_json'", errors.first.message
93
- end
94
-
95
- test "<script> with to_json is safe" do
96
- errors = validate(<<-EOF).errors
97
- <script type="text/javascript">
98
- <%= unsafe.to_json %>
99
- </script>
100
- EOF
101
-
102
- assert_predicate errors, :empty?
103
- end
104
-
105
- test "javascript template with to_json is safe" do
106
- errors = validate(<<-JS, template_language: :javascript).errors
107
- <%= unsafe.to_json %>
108
- JS
109
-
110
- assert_predicate errors, :empty?
111
- end
112
-
113
- test "<script> with raw and to_json is safe" do
114
- errors = validate(<<-EOF).errors
115
- <script type="text/javascript">
116
- <%= raw unsafe.to_json %>
117
- </script>
118
- EOF
119
-
120
- assert_predicate errors, :empty?
121
- end
122
-
123
- test "javascript template with raw and to_json is safe" do
124
- errors = validate(<<-JS, template_language: :javascript).errors
125
- <%= raw unsafe.to_json %>
126
- JS
127
-
128
- assert_predicate errors, :empty?
129
- end
130
-
131
- test "ivar missing .to_json is unsafe" do
132
- errors = validate('<script><%= @feature.html_safe %></script>').errors
133
-
134
- assert_equal 1, errors.size
135
- assert_equal "<%= @feature.html_safe %>", errors.first.location.source
136
- assert_equal "erb interpolation in javascript tag must call '(...).to_json'", errors.first.message
137
- end
138
-
139
- private
140
- def validate(data, template_language: :html)
141
- parser = BetterHtml::Parser.new(buffer(data), template_language: template_language)
142
- tester = BetterHtml::TestHelper::SafeErb::ScriptInterpolation.new(parser, config: @config)
143
- tester.validate
144
- tester
145
- end
146
- end
147
- end
148
- end
149
- end
@@ -1,303 +0,0 @@
1
- require 'test_helper'
2
- require 'better_html/test_helper/safe_erb/tag_interpolation'
3
-
4
- module BetterHtml
5
- module TestHelper
6
- module SafeErb
7
- class TagInterpolationTest < ActiveSupport::TestCase
8
- setup do
9
- @config = BetterHtml::Config.new(
10
- javascript_safe_methods: ['j', 'escape_javascript', 'to_json'],
11
- javascript_attribute_names: [/\Aon/i, 'data-eval'],
12
- )
13
- end
14
-
15
- test "raw in <script> tag" do
16
- errors = validate(<<-EOF).errors
17
- <script>var myData = <%= raw(foo.to_json) %>;</script>
18
- EOF
19
-
20
- assert_equal 0, errors.size
21
- end
22
-
23
- test "raw in <style> tag" do
24
- errors = validate(<<-EOF).errors
25
- <style>@import url(<%= raw url_for("all.css") %>);</style>
26
- EOF
27
-
28
- assert_equal 0, errors.size
29
- end
30
-
31
- test "html_safe in <script> tag" do
32
- errors = validate(<<-EOF).errors
33
- <script>var myData = <%= foo.to_json.html_safe %>;</script>
34
- EOF
35
-
36
- assert_equal 0, errors.size
37
- end
38
-
39
- test "<%== in <script> tag" do
40
- errors = validate(<<-EOF).errors
41
- <script>var myData = <%== foo.to_json %>;</script>
42
- EOF
43
-
44
- assert_equal 0, errors.size
45
- end
46
-
47
- test "string without interpolation is safe" do
48
- errors = validate(<<-EOF).errors
49
- <a onclick="alert('<%= "something" %>')">
50
- EOF
51
-
52
- assert_equal 0, errors.size
53
- end
54
-
55
- test "string with interpolation" do
56
- errors = validate(<<-EOF).errors
57
- <a onclick="<%= "hello \#{name}" %>">
58
- EOF
59
-
60
- assert_equal 1, errors.size
61
- assert_equal 'name', errors.first.location.source
62
- assert_equal "erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'", errors.first.message
63
- end
64
-
65
- test "string with interpolation and ternary" do
66
- errors = validate(<<-EOF).errors
67
- <a onclick="<%= "hello \#{foo ? bar : baz}" if bla? %>">
68
- EOF
69
-
70
- assert_equal 2, errors.size
71
-
72
- assert_equal 'bar', errors[0].location.source
73
- assert_equal "erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'", errors[0].message
74
-
75
- assert_equal 'baz', errors[1].location.source
76
- assert_equal "erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'", errors[1].message
77
- end
78
-
79
- test "plain erb tag in html attribute" do
80
- errors = validate(<<-EOF).errors
81
- <a onclick="method(<%= unsafe %>)">
82
- EOF
83
-
84
- assert_equal 1, errors.size
85
- assert_equal 'unsafe', errors.first.location.source
86
- assert_equal "erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'", errors.first.message
87
- end
88
-
89
- test "to_json is safe in html attribute" do
90
- errors = validate(<<-EOF).errors
91
- <a onclick="method(<%= unsafe.to_json %>)">
92
- EOF
93
- assert_predicate errors, :empty?
94
- end
95
-
96
- test "ternary with safe javascript escaping" do
97
- errors = validate(<<-EOF).errors
98
- <a onclick="method(<%= foo ? bar.to_json : j(baz) %>)">
99
- EOF
100
- assert_predicate errors, :empty?
101
- end
102
-
103
- test "ternary with unsafe javascript escaping" do
104
- errors = validate(<<-EOF).errors
105
- <a onclick="method(<%= foo ? bar : j(baz) %>)">
106
- EOF
107
-
108
- assert_equal 1, errors.size
109
- assert_equal 'bar', errors.first.location.source
110
- assert_equal "erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'", errors.first.message
111
- end
112
-
113
- test "j is safe in html attribute" do
114
- errors = validate(<<-EOF).errors
115
- <a onclick="method('<%= j unsafe %>')">
116
- EOF
117
- assert_predicate errors, :empty?
118
- end
119
-
120
- test "j() is safe in html attribute" do
121
- errors = validate(<<-EOF).errors
122
- <a onclick="method('<%= j(unsafe) %>')">
123
- EOF
124
- assert_predicate errors, :empty?
125
- end
126
-
127
- test "escape_javascript is safe in html attribute" do
128
- errors = validate(<<-EOF).errors
129
- <a onclick="method(<%= escape_javascript unsafe %>)">
130
- EOF
131
- assert_predicate errors, :empty?
132
- end
133
-
134
- test "escape_javascript() is safe in html attribute" do
135
- errors = validate(<<-EOF).errors
136
- <a onclick="method(<%= escape_javascript(unsafe) %>)">
137
- EOF
138
- assert_predicate errors, :empty?
139
- end
140
-
141
- test "html_safe is never safe in html attribute, even non javascript attributes like href" do
142
- errors = validate(<<-EOF).errors
143
- <a href="<%= unsafe.html_safe %>">
144
- EOF
145
-
146
- assert_equal 1, errors.size
147
- assert_equal 'unsafe.html_safe', errors.first.location.source
148
- assert_equal "erb interpolation with '<%= (...).html_safe %>' in this context is never safe", errors.first.message
149
- end
150
-
151
- test "html_safe is never safe in html attribute, even with to_json" do
152
- errors = validate(<<-EOF).errors
153
- <a onclick="method(<%= unsafe.to_json.html_safe %>)">
154
- EOF
155
-
156
- assert_equal 2, errors.size
157
- assert_equal 'unsafe.to_json.html_safe', errors[0].location.source
158
- assert_equal "erb interpolation with '<%= (...).html_safe %>' in this context is never safe", errors[0].message
159
- assert_equal 'unsafe.to_json.html_safe', errors[1].location.source
160
- assert_equal "erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'", errors[1].message
161
- end
162
-
163
- test "<%== is never safe in html attribute, even non javascript attributes like href" do
164
- errors = validate(<<-EOF).errors
165
- <a href="<%== unsafe %>">
166
- EOF
167
-
168
- assert_equal 1, errors.size
169
- assert_equal '<%== unsafe %>', errors.first.location.source
170
- assert_includes "erb interpolation with '<%==' inside html attribute is never safe", errors.first.message
171
- end
172
-
173
- test "<%== is never safe in html attribute, even with to_json" do
174
- errors = validate(<<-EOF).errors
175
- <a onclick="method(<%== unsafe.to_json %>)">
176
- EOF
177
-
178
- assert_equal 1, errors.size
179
- assert_equal '<%== unsafe.to_json %>', errors.first.location.source
180
- assert_includes "erb interpolation with '<%==' inside html attribute is never safe", errors.first.message
181
- end
182
-
183
- test "raw is never safe in html attribute, even non javascript attributes like href" do
184
- errors = validate(<<-EOF).errors
185
- <a href="<%= raw unsafe %>">
186
- EOF
187
-
188
- assert_equal 1, errors.size
189
- assert_equal 'raw unsafe', errors.first.location.source
190
- assert_equal "erb interpolation with '<%= raw(...) %>' in this context is never safe", errors.first.message
191
- end
192
-
193
- test "raw is never safe in html attribute, even with to_json" do
194
- errors = validate(<<-EOF).errors
195
- <a onclick="method(<%= raw unsafe.to_json %>)">
196
- EOF
197
-
198
- assert_equal 2, errors.size
199
- assert_equal 'raw unsafe.to_json', errors[0].location.source
200
- assert_equal "erb interpolation with '<%= raw(...) %>' in this context is never safe", errors[0].message
201
- assert_equal 'raw unsafe.to_json', errors[1].location.source
202
- assert_equal "erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'", errors[1].message
203
- end
204
-
205
- test "unsafe javascript methods in helper calls with new hash syntax" do
206
- errors = validate(<<-EOF).errors
207
- <%= ui_my_helper(:foo, onclick: "alert(\#{unsafe})", onmouseover: "alert(\#{unsafe.to_json})") %>
208
- EOF
209
-
210
- assert_equal 1, errors.size
211
- assert_equal "unsafe", errors[0].location.source
212
- assert_equal "erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'", errors[0].message
213
- end
214
-
215
- test "unsafe javascript methods in helper calls with old hash syntax" do
216
- errors = validate(<<-EOF).errors
217
- <%= ui_my_helper(:foo, :onclick => "alert(\#{unsafe})") %>
218
- EOF
219
-
220
- assert_equal 1, errors.size
221
- assert_equal "unsafe", errors.first.location.source
222
- assert_equal "erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'", errors.first.message
223
- end
224
-
225
- test "unsafe javascript methods in helper calls with more than one level of nested hash and :dstr" do
226
- errors = validate(<<-EOF).errors
227
- <%= ui_my_helper(:foo, inner_html: { onclick: "foo \#{unsafe}" }) %>
228
- EOF
229
-
230
- assert_equal 1, errors.size
231
- assert_equal "unsafe", errors.first.location.source
232
- assert_equal "erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'", errors.first.message
233
- end
234
-
235
- test "safe javascript methods in helper calls with more than one level of nested hash and :dstr" do
236
- errors = validate(<<-EOF).errors
237
- <%= ui_my_helper(:foo, inner_html: { onclick: "foo \#{unsafe.to_json}" }) %>
238
- EOF
239
-
240
- assert_equal 0, errors.size
241
- end
242
-
243
- test "unsafe javascript methods in helper calls with string as key" do
244
- errors = validate(<<-EOF).errors
245
- <%= ui_my_helper(:foo, 'data-eval' => "alert(\#{unsafe})") %>
246
- EOF
247
-
248
- assert_equal 1, errors.size
249
- assert_equal "unsafe", errors.first.location.source
250
- assert_equal "erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'", errors.first.message
251
- end
252
-
253
- test "unsafe javascript methods in helper calls with nested data key" do
254
- errors = validate(<<-EOF).errors
255
- <%= ui_my_helper(:foo, data: { eval: "alert(\#{unsafe})" }) %>
256
- EOF
257
-
258
- assert_equal 1, errors.size
259
- assert_equal "unsafe", errors.first.location.source
260
- assert_equal "erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'", errors.first.message
261
- end
262
-
263
- test "unsafe javascript methods in helper calls with more than one level of nested data key" do
264
- errors = validate(<<-EOF).errors
265
- <%= ui_my_helper(:foo, inner_html: { data: { eval: "alert(\#{unsafe})" } }) %>
266
- EOF
267
-
268
- assert_equal 1, errors.size
269
- assert_equal "unsafe", errors.first.location.source
270
- assert_equal "erb interpolation in javascript attribute must be wrapped in safe helper such as '(...).to_json'", errors.first.message
271
- end
272
-
273
- test "using raw anywhere in helpers" do
274
- errors = validate(<<-EOF).errors
275
- <%= ui_my_helper(:foo, help_text: raw("foo")) %>
276
- EOF
277
-
278
- assert_equal 1, errors.size
279
- assert_equal "ui_my_helper(:foo, help_text: raw(\"foo\"))", errors.first.location.source
280
- assert_equal "erb interpolation with '<%= raw(...) %>' in this context is never safe", errors.first.message
281
- end
282
-
283
- test "using raw anywhere in html tags" do
284
- errors = validate(<<-EOF).errors
285
- <a "<%= raw("hello") %>">
286
- EOF
287
-
288
- assert_equal 1, errors.size
289
- assert_equal "raw(\"hello\")", errors.first.location.source
290
- assert_equal "erb interpolation with '<%= raw(...) %>' in this context is never safe", errors.first.message
291
- end
292
-
293
- private
294
- def validate(data, template_language: :html)
295
- parser = BetterHtml::Parser.new(buffer(data), template_language: template_language)
296
- tester = BetterHtml::TestHelper::SafeErb::TagInterpolation.new(parser, config: @config)
297
- tester.validate
298
- tester
299
- end
300
- end
301
- end
302
- end
303
- end
@@ -1,90 +0,0 @@
1
- require 'test_helper'
2
- require 'better_html/test_helper/safe_lodash_tester'
3
-
4
- module BetterHtml
5
- module TestHelper
6
- class SafeLodashTesterTest < ActiveSupport::TestCase
7
- test "interpolate in attribute not allowed" do
8
- errors = parse(<<-EOF).errors
9
- <div class="[%! foo %]">
10
- EOF
11
-
12
- assert_equal 1, errors.size
13
- assert_equal '[%! foo %]', errors.first.location.source
14
- assert_equal "lodash interpolation with '[%!' inside html attribute is never safe", errors.first.message
15
- end
16
-
17
- test "escape in attribute is allowed" do
18
- errors = parse(<<-EOF).errors
19
- <div class="[%= foo %]">
20
- EOF
21
-
22
- assert_predicate errors, :empty?
23
- end
24
-
25
- test "escape in javascript attribute not allowed" do
26
- errors = parse(<<-EOF).errors
27
- <div onclick="[%= foo %]">
28
- EOF
29
-
30
- assert_equal 1, errors.size
31
- assert_equal '[%= foo %]', errors.first.location.source
32
- assert_equal "lodash interpolation in javascript attribute `onclick` must call `JSON.stringify(foo)`", errors.first.message
33
- end
34
-
35
- test "escape in javascript attribute with JSON.stringify is allowed" do
36
- errors = parse(<<-EOF).errors
37
- <div onclick="[%= JSON.stringify(foo) %]">
38
- EOF
39
-
40
- assert_predicate errors, :empty?
41
- end
42
-
43
- test "script tag is not allowed" do
44
- errors = parse(<<-EOF).errors
45
- <script type="text/javascript"></script>
46
- EOF
47
-
48
- assert_equal 1, errors.size
49
- assert_equal '<script type="text/javascript">', errors.first.location.source
50
- assert_equal "No script tags allowed nested in lodash templates", errors.first.message
51
- end
52
-
53
- test "script tag names are unescaped" do
54
- errors = parse(<<-EOF).errors
55
- <script type="text/j&#x61;v&#x61;script"></script>
56
- EOF
57
-
58
- assert_equal 1, errors.size
59
- assert_equal '<script type="text/j&#x61;v&#x61;script">', errors.first.location.source
60
- assert_equal "No script tags allowed nested in lodash templates", errors.first.message
61
- end
62
-
63
- test "statement not allowed in attribute name" do
64
- errors = parse(<<-EOF).errors
65
- <div class[% if (foo) %]="foo">
66
- EOF
67
-
68
- assert_equal 1, errors.size
69
- assert_equal '[% if (foo) %]', errors.first.location.source
70
- assert_equal "javascript statement not allowed here; did you mean '[%=' ?", errors.first.message
71
- end
72
-
73
- test "statement not allowed in attribute value" do
74
- errors = parse(<<-EOF).errors
75
- <div class="foo[% if (foo) %]">
76
- EOF
77
-
78
- assert_equal 1, errors.size
79
- assert_equal '[% if (foo) %]', errors.first.location.source
80
- assert_equal "javascript statement not allowed here; did you mean '[%=' ?", errors.first.message
81
- end
82
-
83
- private
84
-
85
- def parse(data)
86
- SafeLodashTester::Tester.new(buffer(data))
87
- end
88
- end
89
- end
90
- end