activesupport 3.1.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (276) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +798 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +13 -7
  5. data/lib/active_support/array_inquirer.rb +44 -0
  6. data/lib/active_support/backtrace_cleaner.rb +38 -34
  7. data/lib/active_support/benchmarkable.rb +17 -28
  8. data/lib/active_support/cache/file_store.rb +85 -70
  9. data/lib/active_support/cache/mem_cache_store.rb +75 -66
  10. data/lib/active_support/cache/memory_store.rb +31 -23
  11. data/lib/active_support/cache/null_store.rb +41 -0
  12. data/lib/active_support/cache/strategy/local_cache.rb +73 -70
  13. data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
  14. data/lib/active_support/cache.rb +360 -294
  15. data/lib/active_support/callbacks.rb +563 -393
  16. data/lib/active_support/concern.rb +42 -34
  17. data/lib/active_support/concurrency/latch.rb +19 -0
  18. data/lib/active_support/concurrency/share_lock.rb +186 -0
  19. data/lib/active_support/configurable.rb +70 -12
  20. data/lib/active_support/core_ext/array/access.rb +53 -9
  21. data/lib/active_support/core_ext/array/conversions.rb +109 -62
  22. data/lib/active_support/core_ext/array/extract_options.rb +2 -2
  23. data/lib/active_support/core_ext/array/grouping.rb +39 -32
  24. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  25. data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
  26. data/lib/active_support/core_ext/array/wrap.rb +16 -18
  27. data/lib/active_support/core_ext/array.rb +2 -2
  28. data/lib/active_support/core_ext/benchmark.rb +7 -0
  29. data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -36
  30. data/lib/active_support/core_ext/class/attribute.rb +47 -34
  31. data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -79
  32. data/lib/active_support/core_ext/class/subclasses.rb +12 -7
  33. data/lib/active_support/core_ext/class.rb +0 -3
  34. data/lib/active_support/core_ext/date/blank.rb +12 -0
  35. data/lib/active_support/core_ext/date/calculations.rb +57 -167
  36. data/lib/active_support/core_ext/date/conversions.rb +31 -42
  37. data/lib/active_support/core_ext/date/zones.rb +2 -10
  38. data/lib/active_support/core_ext/date.rb +5 -0
  39. data/lib/active_support/core_ext/date_and_time/calculations.rb +335 -0
  40. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -0
  41. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  42. data/lib/active_support/core_ext/date_time/acts_like.rb +1 -0
  43. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  44. data/lib/active_support/core_ext/date_time/calculations.rb +132 -65
  45. data/lib/active_support/core_ext/date_time/compatibility.rb +5 -0
  46. data/lib/active_support/core_ext/date_time/conversions.rb +36 -34
  47. data/lib/active_support/core_ext/date_time.rb +5 -0
  48. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  49. data/lib/active_support/core_ext/enumerable.rb +81 -74
  50. data/lib/active_support/core_ext/file/atomic.rb +53 -26
  51. data/lib/active_support/core_ext/file.rb +0 -1
  52. data/lib/active_support/core_ext/hash/compact.rb +20 -0
  53. data/lib/active_support/core_ext/hash/conversions.rb +175 -70
  54. data/lib/active_support/core_ext/hash/deep_merge.rb +30 -8
  55. data/lib/active_support/core_ext/hash/except.rb +11 -12
  56. data/lib/active_support/core_ext/hash/indifferent_access.rb +7 -8
  57. data/lib/active_support/core_ext/hash/keys.rb +147 -24
  58. data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
  59. data/lib/active_support/core_ext/hash/slice.rb +22 -14
  60. data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
  61. data/lib/active_support/core_ext/hash.rb +2 -2
  62. data/lib/active_support/core_ext/integer/inflections.rb +13 -1
  63. data/lib/active_support/core_ext/integer/multiple.rb +4 -0
  64. data/lib/active_support/core_ext/integer/time.rb +12 -22
  65. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -2
  66. data/lib/active_support/core_ext/kernel/concern.rb +12 -0
  67. data/lib/active_support/core_ext/kernel/debugger.rb +2 -15
  68. data/lib/active_support/core_ext/kernel/reporting.rb +12 -62
  69. data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
  70. data/lib/active_support/core_ext/kernel.rb +2 -3
  71. data/lib/active_support/core_ext/load_error.rb +14 -7
  72. data/lib/active_support/core_ext/marshal.rb +22 -0
  73. data/lib/active_support/core_ext/module/aliasing.rb +16 -12
  74. data/lib/active_support/core_ext/module/anonymous.rb +12 -8
  75. data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
  76. data/lib/active_support/core_ext/module/attribute_accessors.rb +165 -13
  77. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  78. data/lib/active_support/core_ext/module/concerning.rb +135 -0
  79. data/lib/active_support/core_ext/module/delegation.rb +141 -68
  80. data/lib/active_support/core_ext/module/deprecation.rb +17 -3
  81. data/lib/active_support/core_ext/module/introspection.rb +9 -31
  82. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -0
  83. data/lib/active_support/core_ext/module/qualified_const.rb +70 -0
  84. data/lib/active_support/core_ext/module/reachable.rb +1 -3
  85. data/lib/active_support/core_ext/module/remove_method.rb +24 -5
  86. data/lib/active_support/core_ext/module.rb +3 -3
  87. data/lib/active_support/core_ext/name_error.rb +15 -2
  88. data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
  89. data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
  90. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  91. data/lib/active_support/core_ext/numeric/time.rb +31 -36
  92. data/lib/active_support/core_ext/numeric.rb +2 -0
  93. data/lib/active_support/core_ext/object/acts_like.rb +4 -4
  94. data/lib/active_support/core_ext/object/blank.rb +52 -18
  95. data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
  96. data/lib/active_support/core_ext/object/duplicable.rb +12 -20
  97. data/lib/active_support/core_ext/object/inclusion.rb +13 -1
  98. data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
  99. data/lib/active_support/core_ext/object/json.rb +205 -0
  100. data/lib/active_support/core_ext/object/to_param.rb +1 -55
  101. data/lib/active_support/core_ext/object/to_query.rb +66 -9
  102. data/lib/active_support/core_ext/object/try.rb +124 -33
  103. data/lib/active_support/core_ext/object/with_options.rb +37 -11
  104. data/lib/active_support/core_ext/object.rb +2 -1
  105. data/lib/active_support/core_ext/range/conversions.rb +17 -7
  106. data/lib/active_support/core_ext/range/each.rb +21 -0
  107. data/lib/active_support/core_ext/range/include_range.rb +20 -18
  108. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  109. data/lib/active_support/core_ext/range.rb +1 -2
  110. data/lib/active_support/core_ext/securerandom.rb +23 -0
  111. data/lib/active_support/core_ext/string/access.rb +95 -90
  112. data/lib/active_support/core_ext/string/behavior.rb +1 -1
  113. data/lib/active_support/core_ext/string/conversions.rb +41 -38
  114. data/lib/active_support/core_ext/string/exclude.rb +6 -1
  115. data/lib/active_support/core_ext/string/filters.rb +70 -17
  116. data/lib/active_support/core_ext/string/indent.rb +43 -0
  117. data/lib/active_support/core_ext/string/inflections.rb +139 -59
  118. data/lib/active_support/core_ext/string/inquiry.rb +2 -2
  119. data/lib/active_support/core_ext/string/multibyte.rb +46 -65
  120. data/lib/active_support/core_ext/string/output_safety.rb +153 -56
  121. data/lib/active_support/core_ext/string/strip.rb +3 -6
  122. data/lib/active_support/core_ext/string/zones.rb +14 -0
  123. data/lib/active_support/core_ext/string.rb +2 -3
  124. data/lib/active_support/core_ext/struct.rb +3 -0
  125. data/lib/active_support/core_ext/time/calculations.rb +173 -173
  126. data/lib/active_support/core_ext/time/compatibility.rb +5 -0
  127. data/lib/active_support/core_ext/time/conversions.rb +33 -29
  128. data/lib/active_support/core_ext/time/marshal.rb +2 -56
  129. data/lib/active_support/core_ext/time/zones.rb +57 -32
  130. data/lib/active_support/core_ext/time.rb +5 -0
  131. data/lib/active_support/core_ext/uri.rb +13 -19
  132. data/lib/active_support/core_ext.rb +3 -2
  133. data/lib/active_support/dependencies/autoload.rb +47 -20
  134. data/lib/active_support/dependencies/interlock.rb +51 -0
  135. data/lib/active_support/dependencies.rb +315 -265
  136. data/lib/active_support/deprecation/behaviors.rb +71 -30
  137. data/lib/active_support/deprecation/instance_delegator.rb +24 -0
  138. data/lib/active_support/deprecation/method_wrappers.rb +59 -18
  139. data/lib/active_support/deprecation/proxy_wrappers.rb +82 -14
  140. data/lib/active_support/deprecation/reporting.rb +61 -14
  141. data/lib/active_support/deprecation.rb +38 -13
  142. data/lib/active_support/descendants_tracker.rb +34 -19
  143. data/lib/active_support/duration/iso8601_parser.rb +122 -0
  144. data/lib/active_support/duration/iso8601_serializer.rb +51 -0
  145. data/lib/active_support/duration.rb +85 -14
  146. data/lib/active_support/evented_file_update_checker.rb +194 -0
  147. data/lib/active_support/execution_wrapper.rb +117 -0
  148. data/lib/active_support/executor.rb +6 -0
  149. data/lib/active_support/file_update_checker.rb +138 -17
  150. data/lib/active_support/gem_version.rb +15 -0
  151. data/lib/active_support/gzip.rb +11 -5
  152. data/lib/active_support/hash_with_indifferent_access.rb +199 -49
  153. data/lib/active_support/i18n.rb +6 -2
  154. data/lib/active_support/i18n_railtie.rb +40 -21
  155. data/lib/active_support/inflections.rb +22 -13
  156. data/lib/active_support/inflector/inflections.rb +175 -144
  157. data/lib/active_support/inflector/methods.rb +328 -91
  158. data/lib/active_support/inflector/transliterate.rb +51 -37
  159. data/lib/active_support/json/decoding.rb +31 -22
  160. data/lib/active_support/json/encoding.rb +88 -248
  161. data/lib/active_support/key_generator.rb +71 -0
  162. data/lib/active_support/lazy_load_hooks.rb +27 -25
  163. data/lib/active_support/locale/en.yml +102 -3
  164. data/lib/active_support/log_subscriber/test_helper.rb +24 -21
  165. data/lib/active_support/log_subscriber.rb +36 -49
  166. data/lib/active_support/logger.rb +106 -0
  167. data/lib/active_support/logger_silence.rb +28 -0
  168. data/lib/active_support/logger_thread_safe_level.rb +31 -0
  169. data/lib/active_support/message_encryptor.rb +72 -36
  170. data/lib/active_support/message_verifier.rb +96 -24
  171. data/lib/active_support/multibyte/chars.rb +88 -333
  172. data/lib/active_support/multibyte/unicode.rb +156 -136
  173. data/lib/active_support/multibyte.rb +5 -28
  174. data/lib/active_support/notifications/fanout.rb +115 -19
  175. data/lib/active_support/notifications/instrumenter.rb +52 -15
  176. data/lib/active_support/notifications.rb +168 -33
  177. data/lib/active_support/number_helper/number_converter.rb +182 -0
  178. data/lib/active_support/number_helper/number_to_currency_converter.rb +44 -0
  179. data/lib/active_support/number_helper/number_to_delimited_converter.rb +28 -0
  180. data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
  181. data/lib/active_support/number_helper/number_to_human_size_converter.rb +62 -0
  182. data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
  183. data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
  184. data/lib/active_support/number_helper/number_to_rounded_converter.rb +92 -0
  185. data/lib/active_support/number_helper.rb +368 -0
  186. data/lib/active_support/option_merger.rb +1 -1
  187. data/lib/active_support/ordered_hash.rb +18 -183
  188. data/lib/active_support/ordered_options.rb +44 -24
  189. data/lib/active_support/per_thread_registry.rb +58 -0
  190. data/lib/active_support/proxy_object.rb +13 -0
  191. data/lib/active_support/rails.rb +27 -0
  192. data/lib/active_support/railtie.rb +25 -34
  193. data/lib/active_support/reloader.rb +129 -0
  194. data/lib/active_support/rescuable.rb +98 -48
  195. data/lib/active_support/security_utils.rb +27 -0
  196. data/lib/active_support/string_inquirer.rb +14 -9
  197. data/lib/active_support/subscriber.rb +120 -0
  198. data/lib/active_support/tagged_logging.rb +78 -0
  199. data/lib/active_support/test_case.rb +69 -17
  200. data/lib/active_support/testing/assertions.rb +43 -41
  201. data/lib/active_support/testing/autorun.rb +12 -0
  202. data/lib/active_support/testing/constant_lookup.rb +50 -0
  203. data/lib/active_support/testing/declarative.rb +7 -21
  204. data/lib/active_support/testing/deprecation.rb +14 -33
  205. data/lib/active_support/testing/file_fixtures.rb +34 -0
  206. data/lib/active_support/testing/isolation.rb +53 -95
  207. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  208. data/lib/active_support/testing/setup_and_teardown.rb +21 -82
  209. data/lib/active_support/testing/stream.rb +42 -0
  210. data/lib/active_support/testing/tagged_logging.rb +25 -0
  211. data/lib/active_support/testing/time_helpers.rb +134 -0
  212. data/lib/active_support/time.rb +6 -23
  213. data/lib/active_support/time_with_zone.rb +239 -92
  214. data/lib/active_support/values/time_zone.rb +236 -160
  215. data/lib/active_support/values/unicode_tables.dat +0 -0
  216. data/lib/active_support/version.rb +5 -7
  217. data/lib/active_support/xml_mini/jdom.rb +19 -13
  218. data/lib/active_support/xml_mini/libxml.rb +3 -4
  219. data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
  220. data/lib/active_support/xml_mini/nokogiri.rb +3 -4
  221. data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
  222. data/lib/active_support/xml_mini/rexml.rb +8 -10
  223. data/lib/active_support/xml_mini.rb +66 -34
  224. data/lib/active_support.rb +40 -23
  225. metadata +185 -134
  226. data/CHANGELOG +0 -1534
  227. data/lib/active_support/base64.rb +0 -42
  228. data/lib/active_support/basic_object.rb +0 -21
  229. data/lib/active_support/buffered_logger.rb +0 -137
  230. data/lib/active_support/cache/compressed_mem_cache_store.rb +0 -13
  231. data/lib/active_support/cache/synchronized_memory_store.rb +0 -11
  232. data/lib/active_support/core_ext/array/random_access.rb +0 -30
  233. data/lib/active_support/core_ext/array/uniq_by.rb +0 -16
  234. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -44
  235. data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -178
  236. data/lib/active_support/core_ext/date/freeze.rb +0 -31
  237. data/lib/active_support/core_ext/date_time/zones.rb +0 -21
  238. data/lib/active_support/core_ext/exception.rb +0 -3
  239. data/lib/active_support/core_ext/file/path.rb +0 -5
  240. data/lib/active_support/core_ext/float/rounding.rb +0 -19
  241. data/lib/active_support/core_ext/float.rb +0 -1
  242. data/lib/active_support/core_ext/hash/deep_dup.rb +0 -11
  243. data/lib/active_support/core_ext/hash/diff.rb +0 -13
  244. data/lib/active_support/core_ext/kernel/requires.rb +0 -28
  245. data/lib/active_support/core_ext/logger.rb +0 -81
  246. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +0 -31
  247. data/lib/active_support/core_ext/module/method_names.rb +0 -14
  248. data/lib/active_support/core_ext/module/synchronization.rb +0 -43
  249. data/lib/active_support/core_ext/object/to_json.rb +0 -19
  250. data/lib/active_support/core_ext/proc.rb +0 -14
  251. data/lib/active_support/core_ext/process/daemon.rb +0 -23
  252. data/lib/active_support/core_ext/process.rb +0 -1
  253. data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
  254. data/lib/active_support/core_ext/range/cover.rb +0 -3
  255. data/lib/active_support/core_ext/rexml.rb +0 -46
  256. data/lib/active_support/core_ext/string/encoding.rb +0 -11
  257. data/lib/active_support/core_ext/string/interpolation.rb +0 -2
  258. data/lib/active_support/core_ext/string/xchar.rb +0 -18
  259. data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
  260. data/lib/active_support/file_watcher.rb +0 -36
  261. data/lib/active_support/json/variable.rb +0 -9
  262. data/lib/active_support/memoizable.rb +0 -105
  263. data/lib/active_support/multibyte/exceptions.rb +0 -8
  264. data/lib/active_support/multibyte/utils.rb +0 -60
  265. data/lib/active_support/ruby/shim.rb +0 -22
  266. data/lib/active_support/secure_random.rb +0 -6
  267. data/lib/active_support/testing/mochaing.rb +0 -7
  268. data/lib/active_support/testing/pending.rb +0 -52
  269. data/lib/active_support/testing/performance/jruby.rb +0 -115
  270. data/lib/active_support/testing/performance/rubinius.rb +0 -113
  271. data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
  272. data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
  273. data/lib/active_support/testing/performance/ruby.rb +0 -152
  274. data/lib/active_support/testing/performance.rb +0 -317
  275. data/lib/active_support/time/autoload.rb +0 -5
  276. data/lib/active_support/whiny_nil.rb +0 -60
@@ -3,25 +3,21 @@ require 'active_support/core_ext/kernel/singleton_class'
3
3
 
4
4
  class ERB
5
5
  module Util
6
- HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;' }
7
- JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
6
+ HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#39;' }
7
+ JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003e', '<' => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' }
8
+ HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
9
+ JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
8
10
 
9
11
  # A utility method for escaping HTML tag characters.
10
12
  # This method is also aliased as <tt>h</tt>.
11
13
  #
12
14
  # In your ERB templates, use this method to escape any unsafe content. For example:
13
- # <%=h @person.name %>
15
+ # <%= h @person.name %>
14
16
  #
15
- # ==== Example:
16
- # puts html_escape("is a > 0 & a < 10?")
17
+ # puts html_escape('is a > 0 & a < 10?')
17
18
  # # => is a &gt; 0 &amp; a &lt; 10?
18
19
  def html_escape(s)
19
- s = s.to_s
20
- if s.html_safe?
21
- s
22
- else
23
- s.to_s.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;").html_safe
24
- end
20
+ unwrapped_html_escape(s).html_safe
25
21
  end
26
22
 
27
23
  # Aliasing twice issues a warning "discarding old...". Remove first to avoid it.
@@ -33,30 +29,92 @@ class ERB
33
29
  singleton_class.send(:remove_method, :html_escape)
34
30
  module_function :html_escape
35
31
 
36
- # A utility method for escaping HTML entities in JSON strings
37
- # using \uXXXX JavaScript escape sequences for string literals:
32
+ # HTML escapes strings but doesn't wrap them with an ActiveSupport::SafeBuffer.
33
+ # This method is not for public consumption! Seriously!
34
+ def unwrapped_html_escape(s) # :nodoc:
35
+ s = s.to_s
36
+ if s.html_safe?
37
+ s
38
+ else
39
+ CGI.escapeHTML(ActiveSupport::Multibyte::Unicode.tidy_bytes(s))
40
+ end
41
+ end
42
+ module_function :unwrapped_html_escape
43
+
44
+ # A utility method for escaping HTML without affecting existing escaped entities.
45
+ #
46
+ # html_escape_once('1 < 2 &amp; 3')
47
+ # # => "1 &lt; 2 &amp; 3"
48
+ #
49
+ # html_escape_once('&lt;&lt; Accept & Checkout')
50
+ # # => "&lt;&lt; Accept &amp; Checkout"
51
+ def html_escape_once(s)
52
+ result = ActiveSupport::Multibyte::Unicode.tidy_bytes(s.to_s).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
53
+ s.html_safe? ? result.html_safe : result
54
+ end
55
+
56
+ module_function :html_escape_once
57
+
58
+ # A utility method for escaping HTML entities in JSON strings. Specifically, the
59
+ # &, > and < characters are replaced with their equivalent unicode escaped form -
60
+ # \u0026, \u003e, and \u003c. The Unicode sequences \u2028 and \u2029 are also
61
+ # escaped as they are treated as newline characters in some JavaScript engines.
62
+ # These sequences have identical meaning as the original characters inside the
63
+ # context of a JSON string, so assuming the input is a valid and well-formed
64
+ # JSON value, the output will have equivalent meaning when parsed:
65
+ #
66
+ # json = JSON.generate({ name: "</script><script>alert('PWNED!!!')</script>"})
67
+ # # => "{\"name\":\"</script><script>alert('PWNED!!!')</script>\"}"
68
+ #
69
+ # json_escape(json)
70
+ # # => "{\"name\":\"\\u003C/script\\u003E\\u003Cscript\\u003Ealert('PWNED!!!')\\u003C/script\\u003E\"}"
71
+ #
72
+ # JSON.parse(json) == JSON.parse(json_escape(json))
73
+ # # => true
74
+ #
75
+ # The intended use case for this method is to escape JSON strings before including
76
+ # them inside a script tag to avoid XSS vulnerability:
77
+ #
78
+ # <script>
79
+ # var currentUser = <%= raw json_escape(current_user.to_json) %>;
80
+ # </script>
81
+ #
82
+ # It is necessary to +raw+ the result of +json_escape+, so that quotation marks
83
+ # don't get converted to <tt>&quot;</tt> entities. +json_escape+ doesn't
84
+ # automatically flag the result as HTML safe, since the raw value is unsafe to
85
+ # use inside HTML attributes.
38
86
  #
39
- # json_escape("is a > 0 & a < 10?")
40
- # # => is a \u003E 0 \u0026 a \u003C 10?
87
+ # If your JSON is being used downstream for insertion into the DOM, be aware of
88
+ # whether or not it is being inserted via +html()+. Most jQuery plugins do this.
89
+ # If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated
90
+ # content returned by your JSON.
41
91
  #
42
- # Note that after this operation is performed the output is not
43
- # valid JSON. In particular double quotes are removed:
92
+ # If you need to output JSON elsewhere in your HTML, you can just do something
93
+ # like this, as any unsafe characters (including quotation marks) will be
94
+ # automatically escaped for you:
44
95
  #
45
- # json_escape('{"name":"john","created_at":"2010-04-28T01:39:31Z","id":1}')
46
- # # => {name:john,created_at:2010-04-28T01:39:31Z,id:1}
96
+ # <div data-user-info="<%= current_user.to_json %>">...</div>
47
97
  #
48
- # This method is also aliased as +j+, and available as a helper
49
- # in Rails templates:
98
+ # WARNING: this helper only works with valid JSON. Using this on non-JSON values
99
+ # will open up serious XSS vulnerabilities. For example, if you replace the
100
+ # +current_user.to_json+ in the example above with user input instead, the browser
101
+ # will happily eval() that string as JavaScript.
50
102
  #
51
- # <%=j @person.to_json %>
103
+ # The escaping performed in this method is identical to those performed in the
104
+ # Active Support JSON encoder when +ActiveSupport.escape_html_entities_in_json+ is
105
+ # set to true. Because this transformation is idempotent, this helper can be
106
+ # applied even if +ActiveSupport.escape_html_entities_in_json+ is already true.
52
107
  #
108
+ # Therefore, when you are unsure if +ActiveSupport.escape_html_entities_in_json+
109
+ # is enabled, or if you are unsure where your JSON string originated from, it
110
+ # is recommended that you always apply this helper (other libraries, such as the
111
+ # JSON gem, do not provide this kind of protection by default; also some gems
112
+ # might override +to_json+ to bypass Active Support's encoder).
53
113
  def json_escape(s)
54
- result = s.to_s.gsub(/[&"><]/) { |special| JSON_ESCAPE[special] }
114
+ result = s.to_s.gsub(JSON_ESCAPE_REGEXP, JSON_ESCAPE)
55
115
  s.html_safe? ? result.html_safe : result
56
116
  end
57
117
 
58
- alias j json_escape
59
- module_function :j
60
118
  module_function :json_escape
61
119
  end
62
120
  end
@@ -75,47 +133,84 @@ end
75
133
 
76
134
  module ActiveSupport #:nodoc:
77
135
  class SafeBuffer < String
78
- UNSAFE_STRING_METHODS = ["capitalize", "chomp", "chop", "delete", "downcase", "gsub", "lstrip", "next", "reverse", "rstrip", "slice", "squeeze", "strip", "sub", "succ", "swapcase", "tr", "tr_s", "upcase"].freeze
136
+ UNSAFE_STRING_METHODS = %w(
137
+ capitalize chomp chop delete downcase gsub lstrip next reverse rstrip
138
+ slice squeeze strip sub succ swapcase tr tr_s upcase
139
+ )
79
140
 
80
141
  alias_method :original_concat, :concat
81
142
  private :original_concat
82
143
 
144
+ # Raised when <tt>ActiveSupport::SafeBuffer#safe_concat</tt> is called on unsafe buffers.
83
145
  class SafeConcatError < StandardError
84
146
  def initialize
85
- super "Could not concatenate to the buffer because it is not html safe."
147
+ super 'Could not concatenate to the buffer because it is not html safe.'
148
+ end
149
+ end
150
+
151
+ def [](*args)
152
+ if args.size < 2
153
+ super
154
+ else
155
+ if html_safe?
156
+ new_safe_buffer = super
157
+
158
+ if new_safe_buffer
159
+ new_safe_buffer.instance_variable_set :@html_safe, true
160
+ end
161
+
162
+ new_safe_buffer
163
+ else
164
+ to_str[*args]
165
+ end
86
166
  end
87
167
  end
88
168
 
89
169
  def safe_concat(value)
90
- raise SafeConcatError if dirty?
170
+ raise SafeConcatError unless html_safe?
91
171
  original_concat(value)
92
172
  end
93
173
 
94
- def initialize(*)
95
- @dirty = false
174
+ def initialize(str = '')
175
+ @html_safe = true
96
176
  super
97
177
  end
98
178
 
99
179
  def initialize_copy(other)
100
180
  super
101
- @dirty = other.dirty?
181
+ @html_safe = other.html_safe?
182
+ end
183
+
184
+ def clone_empty
185
+ self[0, 0]
102
186
  end
103
187
 
104
188
  def concat(value)
105
- if dirty? || value.html_safe?
106
- super(value)
107
- else
108
- super(ERB::Util.h(value))
109
- end
189
+ super(html_escape_interpolated_argument(value))
110
190
  end
111
191
  alias << concat
112
192
 
193
+ def prepend(value)
194
+ super(html_escape_interpolated_argument(value))
195
+ end
196
+
113
197
  def +(other)
114
198
  dup.concat(other)
115
199
  end
116
200
 
201
+ def %(args)
202
+ case args
203
+ when Hash
204
+ escaped_args = Hash[args.map { |k,arg| [k, html_escape_interpolated_argument(arg)] }]
205
+ else
206
+ escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
207
+ end
208
+
209
+ self.class.new(super(escaped_args))
210
+ end
211
+
117
212
  def html_safe?
118
- !dirty?
213
+ defined?(@html_safe) && @html_safe
119
214
  end
120
215
 
121
216
  def to_s
@@ -127,36 +222,38 @@ module ActiveSupport #:nodoc:
127
222
  end
128
223
 
129
224
  def encode_with(coder)
130
- coder.represent_scalar nil, to_str
225
+ coder.represent_object nil, to_str
131
226
  end
132
227
 
133
- def to_yaml(*args)
134
- return super() if defined?(YAML::ENGINE) && !YAML::ENGINE.syck?
135
- to_str.to_yaml(*args)
136
- end
137
-
138
- for unsafe_method in UNSAFE_STRING_METHODS
139
- class_eval <<-EOT, __FILE__, __LINE__
140
- def #{unsafe_method}(*args)
141
- super.to_str
142
- end
228
+ UNSAFE_STRING_METHODS.each do |unsafe_method|
229
+ if unsafe_method.respond_to?(unsafe_method)
230
+ class_eval <<-EOT, __FILE__, __LINE__ + 1
231
+ def #{unsafe_method}(*args, &block) # def capitalize(*args, &block)
232
+ to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block)
233
+ end # end
143
234
 
144
- def #{unsafe_method}!(*args)
145
- @dirty = true
146
- super
147
- end
148
- EOT
235
+ def #{unsafe_method}!(*args) # def capitalize!(*args)
236
+ @html_safe = false # @html_safe = false
237
+ super # super
238
+ end # end
239
+ EOT
240
+ end
149
241
  end
150
242
 
151
- protected
243
+ private
152
244
 
153
- def dirty?
154
- @dirty
245
+ def html_escape_interpolated_argument(arg)
246
+ (!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
155
247
  end
156
248
  end
157
249
  end
158
250
 
159
251
  class String
252
+ # Marks a string as trusted safe. It will be inserted into HTML with no
253
+ # additional escaping performed. It is your responsibility to ensure that the
254
+ # string contains no malicious content. This method is equivalent to the
255
+ # `raw` helper in views. It is recommended that you use `sanitize` instead of
256
+ # this method. It should never be called on user input.
160
257
  def html_safe
161
258
  ActiveSupport::SafeBuffer.new(self)
162
259
  end
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/object/try'
2
-
3
1
  class String
4
2
  # Strips indentation in heredocs.
5
3
  #
@@ -17,10 +15,9 @@ class String
17
15
  #
18
16
  # the user would see the usage message aligned against the left margin.
19
17
  #
20
- # Technically, it looks for the least indented line in the whole string, and removes
21
- # that amount of leading whitespace.
18
+ # Technically, it looks for the least indented non-empty line
19
+ # in the whole string, and removes that amount of leading whitespace.
22
20
  def strip_heredoc
23
- indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0
24
- gsub(/^[ \t]{#{indent}}/, '')
21
+ gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, ''.freeze)
25
22
  end
26
23
  end
@@ -0,0 +1,14 @@
1
+ require 'active_support/core_ext/string/conversions'
2
+ require 'active_support/core_ext/time/zones'
3
+
4
+ class String
5
+ # Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default
6
+ # is set, otherwise converts String to a Time via String#to_time
7
+ def in_time_zone(zone = ::Time.zone)
8
+ if zone
9
+ ::Time.find_zone!(zone).parse(self)
10
+ else
11
+ to_time
12
+ end
13
+ end
14
+ end
@@ -4,11 +4,10 @@ require 'active_support/core_ext/string/multibyte'
4
4
  require 'active_support/core_ext/string/starts_ends_with'
5
5
  require 'active_support/core_ext/string/inflections'
6
6
  require 'active_support/core_ext/string/access'
7
- require 'active_support/core_ext/string/xchar'
8
7
  require 'active_support/core_ext/string/behavior'
9
- require 'active_support/core_ext/string/interpolation'
10
8
  require 'active_support/core_ext/string/output_safety'
11
9
  require 'active_support/core_ext/string/exclude'
12
- require 'active_support/core_ext/string/encoding'
13
10
  require 'active_support/core_ext/string/strip'
14
11
  require 'active_support/core_ext/string/inquiry'
12
+ require 'active_support/core_ext/string/indent'
13
+ require 'active_support/core_ext/string/zones'
@@ -0,0 +1,3 @@
1
+ require 'active_support/deprecation'
2
+
3
+ ActiveSupport::Deprecation.warn("This file is deprecated and will be removed in Rails 5.1 with no replacement.")