better_html 1.0.14 → 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 -9
  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 +35 -33
  32. data/lib/better_html/test_helper/safe_lodash_tester.rb +36 -34
  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 -13
  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 +43 -148
  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 -45
  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 -128
  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 -145
  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 -30
@@ -1,128 +0,0 @@
1
- require 'test_helper'
2
- require 'better_html/test_helper/safe_erb/no_statements'
3
-
4
- module BetterHtml
5
- module TestHelper
6
- module SafeErb
7
- class NoStatementsTest < 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 "<script> tag with non executable content type is ignored" do
16
- errors = validate(<<-EOF).errors
17
- <script type="text/html">
18
- <a onclick="<%= unsafe %>">
19
- </script>
20
- EOF
21
-
22
- assert_predicate errors, :empty?
23
- end
24
-
25
- test "statements not allowed in script tags" do
26
- errors = validate(<<-EOF).errors
27
- <script type="text/javascript">
28
- <% if foo? %>
29
- bla
30
- <% end %>
31
- </script>
32
- EOF
33
-
34
- assert_equal 1, errors.size
35
- assert_equal "<% if foo? %>", errors.first.location.source
36
- assert_equal "erb statement not allowed here; did you mean '<%=' ?", errors.first.message
37
- end
38
-
39
- test "statements not allowed in script without specified type" do
40
- errors = validate(<<-EOF).errors
41
- <script>
42
- <% if foo? %>
43
- bla
44
- <% end %>
45
- </script>
46
- EOF
47
-
48
- assert_equal 1, errors.size
49
- assert_equal "<% if foo? %>", errors.first.location.source
50
- assert_equal "erb statement not allowed here; did you mean '<%=' ?", errors.first.message
51
- end
52
-
53
- test "statements not allowed in javascript template" do
54
- errors = validate(<<-JS, template_language: :javascript).errors
55
- <% if foo %>
56
- bla
57
- <% end %>
58
- JS
59
-
60
- assert_equal 1, errors.size
61
- assert_equal "<% if foo %>", errors.first.location.source
62
- assert_equal "erb statement not allowed here; did you mean '<%=' ?", errors.first.message
63
- end
64
-
65
- test "erb comments allowed in scripts" do
66
- errors = validate(<<-EOF).errors
67
- <script type="text/javascript">
68
- <%# comment %>
69
- </script>
70
- EOF
71
-
72
- assert_predicate errors, :empty?
73
- end
74
-
75
- test "script tag without content" do
76
- errors = validate(<<-EOF).errors
77
- <script type="text/javascript"></script>
78
- EOF
79
-
80
- assert_predicate errors, :empty?
81
- end
82
-
83
- test "statement after script regression" do
84
- errors = validate(<<-EOF).errors
85
- <script type="text/javascript">
86
- foo()
87
- </script>
88
- <% if condition? %>
89
- EOF
90
-
91
- assert_predicate errors, :empty?
92
- end
93
-
94
- test "end statements are allowed in script tags" do
95
- errors = validate(<<-EOF).errors
96
- <script type="text/template">
97
- <%= ui_form do %>
98
- <div></div>
99
- <% end %>
100
- </script>
101
- EOF
102
-
103
- assert_predicate errors, :empty?
104
- end
105
-
106
- test "statements are allowed in text/html tags" do
107
- errors = validate(<<-EOF).errors
108
- <script type="text/html">
109
- <% if condition? %>
110
- <div></div>
111
- <% end %>
112
- </script>
113
- EOF
114
-
115
- assert_predicate errors, :empty?
116
- end
117
-
118
- private
119
- def validate(data, template_language: :html)
120
- parser = BetterHtml::Parser.new(buffer(data), template_language: template_language)
121
- tester = BetterHtml::TestHelper::SafeErb::NoStatements.new(parser, config: @config)
122
- tester.validate
123
- tester
124
- end
125
- end
126
- end
127
- end
128
- 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