better_html 1.0.16 → 2.0.0

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.
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 +58 -54
  18. data/lib/better_html/config.rb +7 -4
  19. data/lib/better_html/errors.rb +4 -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 +21 -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 +33 -31
  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 +14 -10
  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