/scalate-jruby/src/main/resources/haml-3.0.25/lib/haml/helpers/xss_mods.rb

http://github.com/scalate/scalate · Ruby · 165 lines · 124 code · 20 blank · 21 comment · 6 complexity · 4db05b747a4da564e8a624c3513b308d MD5 · raw file

  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. # Don't escape text that's already safe,
  17. # output is always HTML safe
  18. def html_escape_with_haml_xss(text)
  19. str = text.to_s
  20. return text if str.html_safe?
  21. Haml::Util.html_safe(html_escape_without_haml_xss(str))
  22. end
  23. # Output is always HTML safe
  24. def find_and_preserve_with_haml_xss(*args, &block)
  25. Haml::Util.html_safe(find_and_preserve_without_haml_xss(*args, &block))
  26. end
  27. # Output is always HTML safe
  28. def preserve_with_haml_xss(*args, &block)
  29. Haml::Util.html_safe(preserve_without_haml_xss(*args, &block))
  30. end
  31. # Output is always HTML safe
  32. def list_of_with_haml_xss(*args, &block)
  33. Haml::Util.html_safe(list_of_without_haml_xss(*args, &block))
  34. end
  35. # Input is escaped, output is always HTML safe
  36. def surround_with_haml_xss(front, back = front, &block)
  37. Haml::Util.html_safe(
  38. surround_without_haml_xss(
  39. haml_xss_html_escape(front),
  40. haml_xss_html_escape(back),
  41. &block))
  42. end
  43. # Input is escaped, output is always HTML safe
  44. def precede_with_haml_xss(str, &block)
  45. Haml::Util.html_safe(precede_without_haml_xss(haml_xss_html_escape(str), &block))
  46. end
  47. # Input is escaped, output is always HTML safe
  48. def succeed_with_haml_xss(str, &block)
  49. Haml::Util.html_safe(succeed_without_haml_xss(haml_xss_html_escape(str), &block))
  50. end
  51. # Output is always HTML safe
  52. def capture_haml_with_haml_xss(*args, &block)
  53. Haml::Util.html_safe(capture_haml_without_haml_xss(*args, &block))
  54. end
  55. # Input is escaped
  56. def haml_concat_with_haml_xss(text = "")
  57. haml_concat_without_haml_xss(@_haml_concat_raw ? text : haml_xss_html_escape(text))
  58. end
  59. # Output is always HTML safe
  60. def haml_indent_with_haml_xss
  61. Haml::Util.html_safe(haml_indent_without_haml_xss)
  62. end
  63. # Input is escaped, haml_concat'ed output is always HTML safe
  64. def haml_tag_with_haml_xss(name, *rest, &block)
  65. name = haml_xss_html_escape(name.to_s)
  66. rest.unshift(haml_xss_html_escape(rest.shift.to_s)) unless [Symbol, Hash, NilClass].any? {|t| rest.first.is_a? t}
  67. with_raw_haml_concat {haml_tag_without_haml_xss(name, *rest, &block)}
  68. end
  69. # Output is always HTML safe
  70. def escape_once_with_haml_xss(*args)
  71. Haml::Util.html_safe(escape_once_without_haml_xss(*args))
  72. end
  73. private
  74. # Escapes the HTML in the text if and only if
  75. # Rails XSS protection is enabled *and* the `:escape_html` option is set.
  76. def haml_xss_html_escape(text)
  77. return text unless Haml::Util.rails_xss_safe? && haml_buffer.options[:escape_html]
  78. html_escape(text)
  79. end
  80. end
  81. class ErrorReturn
  82. # Any attempt to treat ErrorReturn as a string should cause it to blow up.
  83. alias_method :html_safe, :to_s
  84. alias_method :html_safe?, :to_s
  85. alias_method :html_safe!, :to_s
  86. end
  87. end
  88. end
  89. module ActionView
  90. module Helpers
  91. module CaptureHelper
  92. def with_output_buffer_with_haml_xss(*args, &block)
  93. res = with_output_buffer_without_haml_xss(*args, &block)
  94. case res
  95. when Array; res.map {|s| Haml::Util.html_safe(s)}
  96. when String; Haml::Util.html_safe(res)
  97. else; res
  98. end
  99. end
  100. alias_method :with_output_buffer_without_haml_xss, :with_output_buffer
  101. alias_method :with_output_buffer, :with_output_buffer_with_haml_xss
  102. end
  103. module FormTagHelper
  104. def form_tag_with_haml_xss(*args, &block)
  105. res = form_tag_without_haml_xss(*args, &block)
  106. res = Haml::Util.html_safe(res) unless block_given?
  107. res
  108. end
  109. alias_method :form_tag_without_haml_xss, :form_tag
  110. alias_method :form_tag, :form_tag_with_haml_xss
  111. end
  112. module FormHelper
  113. def form_for_with_haml_xss(*args, &block)
  114. res = form_for_without_haml_xss(*args, &block)
  115. return Haml::Util.html_safe(res) if res.is_a?(String)
  116. return res
  117. end
  118. alias_method :form_for_without_haml_xss, :form_for
  119. alias_method :form_for, :form_for_with_haml_xss
  120. end
  121. module TextHelper
  122. def concat_with_haml_xss(string)
  123. if is_haml?
  124. haml_buffer.buffer.concat(haml_xss_html_escape(string))
  125. else
  126. concat_without_haml_xss(string)
  127. end
  128. end
  129. alias_method :concat_without_haml_xss, :concat
  130. alias_method :concat, :concat_with_haml_xss
  131. # safe_concat was introduced in Rails 3.0
  132. if Haml::Util.has?(:instance_method, self, :safe_concat)
  133. def safe_concat_with_haml_xss(string)
  134. if is_haml?
  135. haml_buffer.buffer.concat(string)
  136. else
  137. safe_concat_without_haml_xss(string)
  138. end
  139. end
  140. alias_method :safe_concat_without_haml_xss, :safe_concat
  141. alias_method :safe_concat, :safe_concat_with_haml_xss
  142. end
  143. end
  144. end
  145. end