haml-edge 2.3.51 → 2.3.52

Sign up to get free protection for your applications and to get access to all the features.
data/EDGE_GEM_VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.51
1
+ 2.3.52
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.3.51
1
+ 2.3.52
data/lib/haml/buffer.rb CHANGED
@@ -130,6 +130,8 @@ module Haml
130
130
  Haml::Util.def_static_method(self, :format_script, [:result],
131
131
  :preserve_script, :in_tag, :preserve_tag, :escape_html,
132
132
  :nuke_inner_whitespace, :interpolated, :ugly, <<RUBY)
133
+ <% # Escape HTML here so that the safety of the string is preserved in Rails
134
+ result_name = escape_html ? "html_escape(result.to_s)" : "result.to_s" %>
133
135
  <% unless ugly %>
134
136
  # If we're interpolated,
135
137
  # then the custom tabulation is handled in #push_text.
@@ -140,13 +142,11 @@ module Haml
140
142
  <% end %>
141
143
 
142
144
  tabulation = @real_tabs
143
- result = result.to_s.<% if nuke_inner_whitespace %>strip<% else %>rstrip<% end %>
145
+ result = <%= result_name %>.<% if nuke_inner_whitespace %>strip<% else %>rstrip<% end %>
144
146
  <% else %>
145
- result = result.to_s<% if nuke_inner_whitespace %>.strip<% end %>
147
+ result = <%= result_name %><% if nuke_inner_whitespace %>.strip<% end %>
146
148
  <% end %>
147
149
 
148
- <% if escape_html %> result = html_escape(result) <% end %>
149
-
150
150
  <% if preserve_tag %>
151
151
  result = Haml::Helpers.preserve(result)
152
152
  <% elsif preserve_script %>
data/lib/haml/engine.rb CHANGED
@@ -288,6 +288,7 @@ module Haml
288
288
  :ugly => @options[:ugly],
289
289
  :format => @options[:format],
290
290
  :encoding => @options[:encoding],
291
+ :escape_html => @options[:escape_html],
291
292
  }
292
293
  end
293
294
 
@@ -35,6 +35,21 @@ module Haml
35
35
  controller.controller_name + " " + controller.action_name
36
36
  end
37
37
  alias_method :generate_content_class_names, :page_class
38
+
39
+ # Treats all input to \{Haml::Helpers#haml\_concat} within the block
40
+ # as being HTML safe for Rails' XSS protection.
41
+ # This is useful for wrapping blocks of code that concatenate HTML en masse.
42
+ #
43
+ # This has no effect if Rails' XSS protection isn't enabled.
44
+ #
45
+ # @yield A block in which all input to `#haml_concat` is treated as raw.
46
+ # @see Haml::Util#rails_xss_safe?
47
+ def with_raw_haml_concat
48
+ @_haml_concat_raw = true
49
+ yield
50
+ ensure
51
+ @_haml_concat_raw = false
52
+ end
38
53
  end
39
54
  end
40
55
  end
@@ -26,6 +26,7 @@ module ActionView
26
26
 
27
27
  def set_output_buffer_with_haml(new)
28
28
  if is_haml?
29
+ new = String.new(new) if Haml::Util.rails_xss_safe? && new.is_a?(ActionView::SafeBuffer)
29
30
  haml_buffer.buffer = new
30
31
  else
31
32
  set_output_buffer_without_haml new
@@ -0,0 +1,94 @@
1
+ module Haml
2
+ module Helpers
3
+ # This module overrides Haml helpers to work properly
4
+ # in the context of ActionView.
5
+ # Currently it's only used for modifying the helpers
6
+ # to work with Rails' XSS protection methods.
7
+ module XssMods
8
+ def self.included(base)
9
+ %w[html_escape find_and_preserve preserve list_of surround
10
+ precede succeed capture_haml haml_concat haml_indent
11
+ haml_tag escape_once].each do |name|
12
+ base.send(:alias_method, "#{name}_without_haml_xss", name)
13
+ base.send(:alias_method, name, "#{name}_with_haml_xss")
14
+ end
15
+ end
16
+
17
+ # Don't escape text that's already safe,
18
+ # output is always HTML safe
19
+ def html_escape_with_haml_xss(text)
20
+ return text if text.html_safe?
21
+ html_escape_without_haml_xss(text).html_safe!
22
+ end
23
+
24
+ # Output is always HTML safe
25
+ def find_and_preserve_with_haml_xss(*args, &block)
26
+ find_and_preserve_without_haml_xss(*args, &block).html_safe!
27
+ end
28
+
29
+ # Output is always HTML safe
30
+ def preserve_with_haml_xss(*args, &block)
31
+ preserve_without_haml_xss(*args, &block).html_safe!
32
+ end
33
+
34
+ # Output is always HTML safe
35
+ def list_of_with_haml_xss(*args, &block)
36
+ list_of_without_haml_xss(*args, &block).html_safe!
37
+ end
38
+
39
+ # Input is escaped, output is always HTML safe
40
+ def surround_with_haml_xss(front, back = front, &block)
41
+ surround_without_haml_xss(
42
+ haml_xss_html_escape(front),
43
+ haml_xss_html_escape(back),
44
+ &block).html_safe!
45
+ end
46
+
47
+ # Input is escaped, output is always HTML safe
48
+ def precede_with_haml_xss(str, &block)
49
+ precede_without_haml_xss(haml_xss_html_escape(str), &block).html_safe!
50
+ end
51
+
52
+ # Input is escaped, output is always HTML safe
53
+ def succeed_with_haml_xss(str, &block)
54
+ succeed_without_haml_xss(haml_xss_html_escape(str), &block).html_safe!
55
+ end
56
+
57
+ # Output is always HTML safe
58
+ def capture_haml_with_haml_xss(*args, &block)
59
+ capture_haml_without_haml_xss(*args, &block).html_safe!
60
+ end
61
+
62
+ # Input is escaped
63
+ def haml_concat_with_haml_xss(text = "")
64
+ haml_concat_without_haml_xss(@_haml_concat_raw ? text : haml_xss_html_escape(text))
65
+ end
66
+
67
+ # Output is always HTML safe
68
+ def haml_indent_with_haml_xss
69
+ haml_indent_without_haml_xss.html_safe!
70
+ end
71
+
72
+ # Input is escaped, haml_concat'ed output is always HTML safe
73
+ def haml_tag_with_haml_xss(name, *rest, &block)
74
+ name = haml_xss_html_escape(name.to_s)
75
+ rest.unshift(haml_xss_html_escape(rest.shift.to_s)) unless [Symbol, Hash, NilClass].any? {|t| rest.first.is_a? t}
76
+ with_raw_haml_concat {haml_tag_without_haml_xss(name, *rest, &block)}
77
+ end
78
+
79
+ # Output is always HTML safe
80
+ def escape_once_with_haml_xss(*args)
81
+ escape_once_without_haml_xss(*args).html_safe!
82
+ end
83
+
84
+ private
85
+
86
+ # Escapes the HTML in the text if and only if
87
+ # Rails XSS protection is enabled *and* the `:escape_html` option is set.
88
+ def haml_xss_html_escape(text)
89
+ return text unless Haml::Util.rails_xss_safe? && haml_buffer.options[:escape_html]
90
+ html_escape(text)
91
+ end
92
+ end
93
+ end
94
+ end
data/lib/haml/helpers.rb CHANGED
@@ -467,6 +467,10 @@ END
467
467
  # Returns a copy of `text` with ampersands, angle brackets and quotes
468
468
  # escaped into HTML entities.
469
469
  #
470
+ # Note that if ActionView is loaded and XSS protection is enabled
471
+ # (as is the default for Rails 3.0+, and optional for version 2.3.5+),
472
+ # this won't escape text declared as "safe".
473
+ #
470
474
  # @param text [String] The string to sanitize
471
475
  # @return [String] The sanitized string
472
476
  def html_escape(text)
data/lib/haml/template.rb CHANGED
@@ -27,6 +27,21 @@ else
27
27
  require 'haml/template/patch'
28
28
  end
29
29
 
30
+ if ActionView::Base.respond_to?(:xss_safe?) && ActionView::Base.xss_safe?
31
+ Haml::Template.options[:escape_html] = true
32
+
33
+ module Haml::Util
34
+ def rails_xss_safe?
35
+ true
36
+ end
37
+ end
38
+
39
+ require 'haml/helpers/xss_mods'
40
+ module Haml::Helpers
41
+ include XssMods
42
+ end
43
+ end
44
+
30
45
  if defined?(RAILS_ROOT)
31
46
  # Update init.rb to the current version
32
47
  # if it's out of date.
data/lib/haml/util.rb CHANGED
@@ -122,6 +122,26 @@ module Haml
122
122
  end
123
123
  end
124
124
 
125
+ ## Rails XSS Safety
126
+
127
+ # Whether or not ActionView's XSS protection is available and enabled,
128
+ # as is the default for Rails 3.0+, and optional for version 2.3.5+.
129
+ # Overridden in haml/template.rb if this is the case.
130
+ #
131
+ # @return [Boolean]
132
+ def rails_xss_safe?
133
+ false
134
+ end
135
+
136
+ # Assert that a given object (usually a String) is HTML safe
137
+ # according to Rails' XSS handling, if it's loaded.
138
+ #
139
+ # @param text [Object]
140
+ def assert_html_safe!(text)
141
+ return unless rails_xss_safe? && text && !text.to_s.html_safe?
142
+ raise Haml::Error.new("Expected #{text.inspect} to be HTML-safe.")
143
+ end
144
+
125
145
  ## Cross-Ruby-Version Compatibility
126
146
 
127
147
  # Whether or not this is running under Ruby 1.8 or lower.
@@ -85,6 +85,7 @@ class TemplateTest < Test::Unit::TestCase
85
85
  end
86
86
 
87
87
  def render(text, opts = {})
88
+ return @base.render(:inline => text, :type => :haml) if opts == :action_view
88
89
  Haml::Engine.new(text, opts).to_html(@base)
89
90
  end
90
91
 
@@ -95,6 +96,8 @@ class TemplateTest < Test::Unit::TestCase
95
96
  end
96
97
 
97
98
  def assert_renders_correctly(name, &render_method)
99
+ old_options = Haml::Template.options.dup
100
+ Haml::Template.options[:escape_html] = false
98
101
  if ActionPack::VERSION::MAJOR < 2 ||
99
102
  (ActionPack::VERSION::MAJOR == 2 && ActionPack::VERSION::MINOR < 2)
100
103
  render_method ||= proc { |name| @base.render(name) }
@@ -112,6 +115,8 @@ class TemplateTest < Test::Unit::TestCase
112
115
  else
113
116
  raise e
114
117
  end
118
+ ensure
119
+ Haml::Template.options = old_options
115
120
  end
116
121
 
117
122
  def test_empty_render_should_remain_empty
@@ -176,12 +181,13 @@ class TemplateTest < Test::Unit::TestCase
176
181
  end
177
182
 
178
183
  def test_haml_options
179
- Haml::Template.options = { :suppress_eval => true }
180
- assert_equal({ :suppress_eval => true }, Haml::Template.options)
184
+ old_options = Haml::Template.options.dup
185
+ Haml::Template.options[:suppress_eval] = true
181
186
  old_base, @base = @base, create_base
182
187
  assert_renders_correctly("eval_suppressed")
188
+ ensure
183
189
  @base = old_base
184
- Haml::Template.options = {}
190
+ Haml::Template.options = old_options
185
191
  end
186
192
 
187
193
  def test_with_output_buffer_with_ugly
@@ -231,5 +237,41 @@ END
231
237
  else
232
238
  assert false
233
239
  end
234
- end
240
+ end
241
+
242
+ ## XSS Protection Tests
243
+
244
+ if Haml::Util.rails_xss_safe?
245
+ def test_escape_html_option_set
246
+ assert Haml::Template.options[:escape_html]
247
+ end
248
+
249
+ def test_xss_protection
250
+ assert_equal("Foo &amp; Bar\n", render('= "Foo & Bar"', :action_view))
251
+ end
252
+
253
+ def test_xss_protection_with_safe_strings
254
+ assert_equal("Foo & Bar\n", render('= "Foo & Bar".html_safe!', :action_view))
255
+ end
256
+
257
+ def test_xss_protection_with_bang
258
+ assert_equal("Foo & Bar\n", render('!= "Foo & Bar"', :action_view))
259
+ end
260
+
261
+ def test_xss_protection_in_interpolation
262
+ assert_equal("Foo &amp; Bar\n", render('Foo #{"&"} Bar', :action_view))
263
+ end
264
+
265
+ def test_xss_protection_with_bang_in_interpolation
266
+ assert_equal("Foo & Bar\n", render('! Foo #{"&"} Bar', :action_view))
267
+ end
268
+
269
+ def test_xss_protection_with_safe_strings_in_interpolation
270
+ assert_equal("Foo & Bar\n", render('Foo #{"&".html_safe!} Bar', :action_view))
271
+ end
272
+
273
+ def test_xss_protection_with_mixed_strings_in_interpolation
274
+ assert_equal("Foo & Bar &amp; Baz\n", render('Foo #{"&".html_safe!} Bar #{"&"} Baz', :action_view))
275
+ end
276
+ end
235
277
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml-edge
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.51
4
+ version: 2.3.52
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Weizenbaum
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-10-16 00:00:00 -04:00
13
+ date: 2009-10-17 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -63,6 +63,7 @@ files:
63
63
  - lib/haml/helpers
64
64
  - lib/haml/helpers/action_view_extensions.rb
65
65
  - lib/haml/helpers/action_view_mods.rb
66
+ - lib/haml/helpers/xss_mods.rb
66
67
  - lib/haml/html.rb
67
68
  - lib/haml/precompiler.rb
68
69
  - lib/haml/shared.rb
@@ -152,8 +153,8 @@ files:
152
153
  - test/haml/rhtml/action_view.rhtml
153
154
  - test/haml/rhtml/standard.rhtml
154
155
  - test/haml/spec
155
- - test/haml/spec_test.rb
156
156
  - test/haml/template_test.rb
157
+ - test/haml/spec_test.rb
157
158
  - test/haml/templates
158
159
  - test/haml/templates/_av_partial_1.haml
159
160
  - test/haml/templates/_av_partial_1_ugly.haml
@@ -300,8 +301,8 @@ test_files:
300
301
  - test/haml/engine_test.rb
301
302
  - test/haml/helper_test.rb
302
303
  - test/haml/html2haml_test.rb
303
- - test/haml/spec_test.rb
304
304
  - test/haml/template_test.rb
305
+ - test/haml/spec_test.rb
305
306
  - test/haml/util_test.rb
306
307
  - test/sass/css2sass_test.rb
307
308
  - test/sass/engine_test.rb