activesupport 5.0.7.1

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 (236) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1013 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +39 -0
  5. data/lib/active_support.rb +99 -0
  6. data/lib/active_support/all.rb +3 -0
  7. data/lib/active_support/array_inquirer.rb +44 -0
  8. data/lib/active_support/backtrace_cleaner.rb +103 -0
  9. data/lib/active_support/benchmarkable.rb +49 -0
  10. data/lib/active_support/builder.rb +6 -0
  11. data/lib/active_support/cache.rb +701 -0
  12. data/lib/active_support/cache/file_store.rb +204 -0
  13. data/lib/active_support/cache/mem_cache_store.rb +207 -0
  14. data/lib/active_support/cache/memory_store.rb +167 -0
  15. data/lib/active_support/cache/null_store.rb +41 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +172 -0
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
  18. data/lib/active_support/callbacks.rb +791 -0
  19. data/lib/active_support/concern.rb +142 -0
  20. data/lib/active_support/concurrency/latch.rb +26 -0
  21. data/lib/active_support/concurrency/share_lock.rb +226 -0
  22. data/lib/active_support/configurable.rb +148 -0
  23. data/lib/active_support/core_ext.rb +4 -0
  24. data/lib/active_support/core_ext/array.rb +7 -0
  25. data/lib/active_support/core_ext/array/access.rb +90 -0
  26. data/lib/active_support/core_ext/array/conversions.rb +211 -0
  27. data/lib/active_support/core_ext/array/extract_options.rb +29 -0
  28. data/lib/active_support/core_ext/array/grouping.rb +107 -0
  29. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  30. data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
  31. data/lib/active_support/core_ext/array/wrap.rb +46 -0
  32. data/lib/active_support/core_ext/benchmark.rb +14 -0
  33. data/lib/active_support/core_ext/big_decimal.rb +1 -0
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  35. data/lib/active_support/core_ext/class.rb +2 -0
  36. data/lib/active_support/core_ext/class/attribute.rb +128 -0
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -0
  38. data/lib/active_support/core_ext/class/subclasses.rb +41 -0
  39. data/lib/active_support/core_ext/date.rb +5 -0
  40. data/lib/active_support/core_ext/date/acts_like.rb +8 -0
  41. data/lib/active_support/core_ext/date/blank.rb +12 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +143 -0
  43. data/lib/active_support/core_ext/date/conversions.rb +95 -0
  44. data/lib/active_support/core_ext/date/zones.rb +6 -0
  45. data/lib/active_support/core_ext/date_and_time/calculations.rb +335 -0
  46. data/lib/active_support/core_ext/date_and_time/compatibility.rb +14 -0
  47. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  48. data/lib/active_support/core_ext/date_time.rb +5 -0
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +14 -0
  50. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +199 -0
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  53. data/lib/active_support/core_ext/date_time/conversions.rb +105 -0
  54. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  55. data/lib/active_support/core_ext/enumerable.rb +146 -0
  56. data/lib/active_support/core_ext/file.rb +1 -0
  57. data/lib/active_support/core_ext/file/atomic.rb +68 -0
  58. data/lib/active_support/core_ext/hash.rb +9 -0
  59. data/lib/active_support/core_ext/hash/compact.rb +24 -0
  60. data/lib/active_support/core_ext/hash/conversions.rb +262 -0
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +38 -0
  62. data/lib/active_support/core_ext/hash/except.rb +22 -0
  63. data/lib/active_support/core_ext/hash/indifferent_access.rb +23 -0
  64. data/lib/active_support/core_ext/hash/keys.rb +170 -0
  65. data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -0
  66. data/lib/active_support/core_ext/hash/slice.rb +48 -0
  67. data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
  68. data/lib/active_support/core_ext/integer.rb +3 -0
  69. data/lib/active_support/core_ext/integer/inflections.rb +29 -0
  70. data/lib/active_support/core_ext/integer/multiple.rb +10 -0
  71. data/lib/active_support/core_ext/integer/time.rb +29 -0
  72. data/lib/active_support/core_ext/kernel.rb +4 -0
  73. data/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
  74. data/lib/active_support/core_ext/kernel/concern.rb +12 -0
  75. data/lib/active_support/core_ext/kernel/debugger.rb +3 -0
  76. data/lib/active_support/core_ext/kernel/reporting.rb +43 -0
  77. data/lib/active_support/core_ext/kernel/singleton_class.rb +6 -0
  78. data/lib/active_support/core_ext/load_error.rb +31 -0
  79. data/lib/active_support/core_ext/marshal.rb +22 -0
  80. data/lib/active_support/core_ext/module.rb +12 -0
  81. data/lib/active_support/core_ext/module/aliasing.rb +74 -0
  82. data/lib/active_support/core_ext/module/anonymous.rb +28 -0
  83. data/lib/active_support/core_ext/module/attr_internal.rb +36 -0
  84. data/lib/active_support/core_ext/module/attribute_accessors.rb +212 -0
  85. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  86. data/lib/active_support/core_ext/module/concerning.rb +135 -0
  87. data/lib/active_support/core_ext/module/delegation.rb +216 -0
  88. data/lib/active_support/core_ext/module/deprecation.rb +23 -0
  89. data/lib/active_support/core_ext/module/introspection.rb +68 -0
  90. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -0
  91. data/lib/active_support/core_ext/module/qualified_const.rb +70 -0
  92. data/lib/active_support/core_ext/module/reachable.rb +8 -0
  93. data/lib/active_support/core_ext/module/remove_method.rb +35 -0
  94. data/lib/active_support/core_ext/name_error.rb +31 -0
  95. data/lib/active_support/core_ext/numeric.rb +4 -0
  96. data/lib/active_support/core_ext/numeric/bytes.rb +64 -0
  97. data/lib/active_support/core_ext/numeric/conversions.rb +144 -0
  98. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  99. data/lib/active_support/core_ext/numeric/time.rb +74 -0
  100. data/lib/active_support/core_ext/object.rb +14 -0
  101. data/lib/active_support/core_ext/object/acts_like.rb +10 -0
  102. data/lib/active_support/core_ext/object/blank.rb +143 -0
  103. data/lib/active_support/core_ext/object/conversions.rb +4 -0
  104. data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
  105. data/lib/active_support/core_ext/object/duplicable.rb +124 -0
  106. data/lib/active_support/core_ext/object/inclusion.rb +27 -0
  107. data/lib/active_support/core_ext/object/instance_variables.rb +28 -0
  108. data/lib/active_support/core_ext/object/json.rb +205 -0
  109. data/lib/active_support/core_ext/object/to_param.rb +1 -0
  110. data/lib/active_support/core_ext/object/to_query.rb +84 -0
  111. data/lib/active_support/core_ext/object/try.rb +146 -0
  112. data/lib/active_support/core_ext/object/with_options.rb +69 -0
  113. data/lib/active_support/core_ext/range.rb +4 -0
  114. data/lib/active_support/core_ext/range/conversions.rb +31 -0
  115. data/lib/active_support/core_ext/range/each.rb +21 -0
  116. data/lib/active_support/core_ext/range/include_range.rb +23 -0
  117. data/lib/active_support/core_ext/range/overlaps.rb +8 -0
  118. data/lib/active_support/core_ext/regexp.rb +5 -0
  119. data/lib/active_support/core_ext/securerandom.rb +23 -0
  120. data/lib/active_support/core_ext/string.rb +13 -0
  121. data/lib/active_support/core_ext/string/access.rb +104 -0
  122. data/lib/active_support/core_ext/string/behavior.rb +6 -0
  123. data/lib/active_support/core_ext/string/conversions.rb +57 -0
  124. data/lib/active_support/core_ext/string/exclude.rb +11 -0
  125. data/lib/active_support/core_ext/string/filters.rb +102 -0
  126. data/lib/active_support/core_ext/string/indent.rb +43 -0
  127. data/lib/active_support/core_ext/string/inflections.rb +244 -0
  128. data/lib/active_support/core_ext/string/inquiry.rb +13 -0
  129. data/lib/active_support/core_ext/string/multibyte.rb +53 -0
  130. data/lib/active_support/core_ext/string/output_safety.rb +260 -0
  131. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -0
  132. data/lib/active_support/core_ext/string/strip.rb +23 -0
  133. data/lib/active_support/core_ext/string/zones.rb +14 -0
  134. data/lib/active_support/core_ext/struct.rb +3 -0
  135. data/lib/active_support/core_ext/time.rb +5 -0
  136. data/lib/active_support/core_ext/time/acts_like.rb +8 -0
  137. data/lib/active_support/core_ext/time/calculations.rb +290 -0
  138. data/lib/active_support/core_ext/time/compatibility.rb +14 -0
  139. data/lib/active_support/core_ext/time/conversions.rb +67 -0
  140. data/lib/active_support/core_ext/time/marshal.rb +3 -0
  141. data/lib/active_support/core_ext/time/zones.rb +111 -0
  142. data/lib/active_support/core_ext/uri.rb +24 -0
  143. data/lib/active_support/dependencies.rb +755 -0
  144. data/lib/active_support/dependencies/autoload.rb +77 -0
  145. data/lib/active_support/dependencies/interlock.rb +55 -0
  146. data/lib/active_support/deprecation.rb +43 -0
  147. data/lib/active_support/deprecation/behaviors.rb +90 -0
  148. data/lib/active_support/deprecation/instance_delegator.rb +37 -0
  149. data/lib/active_support/deprecation/method_wrappers.rb +70 -0
  150. data/lib/active_support/deprecation/proxy_wrappers.rb +149 -0
  151. data/lib/active_support/deprecation/reporting.rb +112 -0
  152. data/lib/active_support/descendants_tracker.rb +60 -0
  153. data/lib/active_support/duration.rb +235 -0
  154. data/lib/active_support/duration/iso8601_parser.rb +122 -0
  155. data/lib/active_support/duration/iso8601_serializer.rb +51 -0
  156. data/lib/active_support/evented_file_update_checker.rb +199 -0
  157. data/lib/active_support/execution_wrapper.rb +126 -0
  158. data/lib/active_support/executor.rb +6 -0
  159. data/lib/active_support/file_update_checker.rb +157 -0
  160. data/lib/active_support/gem_version.rb +15 -0
  161. data/lib/active_support/gzip.rb +36 -0
  162. data/lib/active_support/hash_with_indifferent_access.rb +329 -0
  163. data/lib/active_support/i18n.rb +13 -0
  164. data/lib/active_support/i18n_railtie.rb +115 -0
  165. data/lib/active_support/inflections.rb +70 -0
  166. data/lib/active_support/inflector.rb +7 -0
  167. data/lib/active_support/inflector/inflections.rb +242 -0
  168. data/lib/active_support/inflector/methods.rb +390 -0
  169. data/lib/active_support/inflector/transliterate.rb +112 -0
  170. data/lib/active_support/json.rb +2 -0
  171. data/lib/active_support/json/decoding.rb +74 -0
  172. data/lib/active_support/json/encoding.rb +127 -0
  173. data/lib/active_support/key_generator.rb +71 -0
  174. data/lib/active_support/lazy_load_hooks.rb +76 -0
  175. data/lib/active_support/locale/en.yml +135 -0
  176. data/lib/active_support/log_subscriber.rb +109 -0
  177. data/lib/active_support/log_subscriber/test_helper.rb +104 -0
  178. data/lib/active_support/logger.rb +106 -0
  179. data/lib/active_support/logger_silence.rb +28 -0
  180. data/lib/active_support/logger_thread_safe_level.rb +31 -0
  181. data/lib/active_support/message_encryptor.rb +114 -0
  182. data/lib/active_support/message_verifier.rb +134 -0
  183. data/lib/active_support/multibyte.rb +21 -0
  184. data/lib/active_support/multibyte/chars.rb +231 -0
  185. data/lib/active_support/multibyte/unicode.rb +413 -0
  186. data/lib/active_support/notifications.rb +212 -0
  187. data/lib/active_support/notifications/fanout.rb +157 -0
  188. data/lib/active_support/notifications/instrumenter.rb +91 -0
  189. data/lib/active_support/number_helper.rb +368 -0
  190. data/lib/active_support/number_helper/number_converter.rb +182 -0
  191. data/lib/active_support/number_helper/number_to_currency_converter.rb +44 -0
  192. data/lib/active_support/number_helper/number_to_delimited_converter.rb +28 -0
  193. data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
  194. data/lib/active_support/number_helper/number_to_human_size_converter.rb +62 -0
  195. data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
  196. data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
  197. data/lib/active_support/number_helper/number_to_rounded_converter.rb +92 -0
  198. data/lib/active_support/option_merger.rb +25 -0
  199. data/lib/active_support/ordered_hash.rb +48 -0
  200. data/lib/active_support/ordered_options.rb +81 -0
  201. data/lib/active_support/per_thread_registry.rb +58 -0
  202. data/lib/active_support/proxy_object.rb +13 -0
  203. data/lib/active_support/rails.rb +27 -0
  204. data/lib/active_support/railtie.rb +51 -0
  205. data/lib/active_support/reloader.rb +129 -0
  206. data/lib/active_support/rescuable.rb +173 -0
  207. data/lib/active_support/security_utils.rb +27 -0
  208. data/lib/active_support/string_inquirer.rb +26 -0
  209. data/lib/active_support/subscriber.rb +120 -0
  210. data/lib/active_support/tagged_logging.rb +77 -0
  211. data/lib/active_support/test_case.rb +88 -0
  212. data/lib/active_support/testing/assertions.rb +99 -0
  213. data/lib/active_support/testing/autorun.rb +5 -0
  214. data/lib/active_support/testing/constant_lookup.rb +50 -0
  215. data/lib/active_support/testing/declarative.rb +26 -0
  216. data/lib/active_support/testing/deprecation.rb +36 -0
  217. data/lib/active_support/testing/file_fixtures.rb +34 -0
  218. data/lib/active_support/testing/isolation.rb +115 -0
  219. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  220. data/lib/active_support/testing/setup_and_teardown.rb +50 -0
  221. data/lib/active_support/testing/stream.rb +42 -0
  222. data/lib/active_support/testing/tagged_logging.rb +25 -0
  223. data/lib/active_support/testing/time_helpers.rb +136 -0
  224. data/lib/active_support/time.rb +18 -0
  225. data/lib/active_support/time_with_zone.rb +511 -0
  226. data/lib/active_support/values/time_zone.rb +484 -0
  227. data/lib/active_support/values/unicode_tables.dat +0 -0
  228. data/lib/active_support/version.rb +8 -0
  229. data/lib/active_support/xml_mini.rb +209 -0
  230. data/lib/active_support/xml_mini/jdom.rb +181 -0
  231. data/lib/active_support/xml_mini/libxml.rb +77 -0
  232. data/lib/active_support/xml_mini/libxmlsax.rb +82 -0
  233. data/lib/active_support/xml_mini/nokogiri.rb +81 -0
  234. data/lib/active_support/xml_mini/nokogirisax.rb +85 -0
  235. data/lib/active_support/xml_mini/rexml.rb +128 -0
  236. metadata +350 -0
@@ -0,0 +1,112 @@
1
+ require 'active_support/core_ext/string/multibyte'
2
+ require 'active_support/i18n'
3
+
4
+ module ActiveSupport
5
+ module Inflector
6
+
7
+ # Replaces non-ASCII characters with an ASCII approximation, or if none
8
+ # exists, a replacement character which defaults to "?".
9
+ #
10
+ # transliterate('Ærøskøbing')
11
+ # # => "AEroskobing"
12
+ #
13
+ # Default approximations are provided for Western/Latin characters,
14
+ # e.g, "ø", "ñ", "é", "ß", etc.
15
+ #
16
+ # This method is I18n aware, so you can set up custom approximations for a
17
+ # locale. This can be useful, for example, to transliterate German's "ü"
18
+ # and "ö" to "ue" and "oe", or to add support for transliterating Russian
19
+ # to ASCII.
20
+ #
21
+ # In order to make your custom transliterations available, you must set
22
+ # them as the <tt>i18n.transliterate.rule</tt> i18n key:
23
+ #
24
+ # # Store the transliterations in locales/de.yml
25
+ # i18n:
26
+ # transliterate:
27
+ # rule:
28
+ # ü: "ue"
29
+ # ö: "oe"
30
+ #
31
+ # # Or set them using Ruby
32
+ # I18n.backend.store_translations(:de, i18n: {
33
+ # transliterate: {
34
+ # rule: {
35
+ # 'ü' => 'ue',
36
+ # 'ö' => 'oe'
37
+ # }
38
+ # }
39
+ # })
40
+ #
41
+ # The value for <tt>i18n.transliterate.rule</tt> can be a simple Hash that
42
+ # maps characters to ASCII approximations as shown above, or, for more
43
+ # complex requirements, a Proc:
44
+ #
45
+ # I18n.backend.store_translations(:de, i18n: {
46
+ # transliterate: {
47
+ # rule: ->(string) { MyTransliterator.transliterate(string) }
48
+ # }
49
+ # })
50
+ #
51
+ # Now you can have different transliterations for each locale:
52
+ #
53
+ # I18n.locale = :en
54
+ # transliterate('Jürgen')
55
+ # # => "Jurgen"
56
+ #
57
+ # I18n.locale = :de
58
+ # transliterate('Jürgen')
59
+ # # => "Juergen"
60
+ def transliterate(string, replacement = "?".freeze)
61
+ I18n.transliterate(ActiveSupport::Multibyte::Unicode.normalize(
62
+ ActiveSupport::Multibyte::Unicode.tidy_bytes(string), :c),
63
+ :replacement => replacement)
64
+ end
65
+
66
+ # Replaces special characters in a string so that it may be used as part of
67
+ # a 'pretty' URL.
68
+ #
69
+ # parameterize("Donald E. Knuth") # => "donald-e-knuth"
70
+ # parameterize("^trés|Jolie-- ") # => "tres-jolie"
71
+ #
72
+ # To use a custom separator, override the `separator` argument.
73
+ #
74
+ # parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
75
+ # parameterize("^trés|Jolie-- ", separator: '_') # => "tres_jolie"
76
+ #
77
+ # To preserve the case of the characters in a string, use the `preserve_case` argument.
78
+ #
79
+ # parameterize("Donald E. Knuth", preserve_case: true) # => "Donald-E-Knuth"
80
+ # parameterize("^trés|Jolie-- ", preserve_case: true) # => "tres-Jolie"
81
+ #
82
+ def parameterize(string, sep = :unused, separator: '-', preserve_case: false)
83
+ unless sep == :unused
84
+ ActiveSupport::Deprecation.warn("Passing the separator argument as a positional parameter is deprecated and will soon be removed. Use `separator: '#{sep}'` instead.")
85
+ separator = sep
86
+ end
87
+ # Replace accented chars with their ASCII equivalents.
88
+ parameterized_string = transliterate(string)
89
+
90
+ # Turn unwanted chars into the separator.
91
+ parameterized_string.gsub!(/[^a-z0-9\-_]+/i, separator)
92
+
93
+ unless separator.nil? || separator.empty?
94
+ if separator == "-".freeze
95
+ re_duplicate_separator = /-{2,}/
96
+ re_leading_trailing_separator = /^-|-$/i
97
+ else
98
+ re_sep = Regexp.escape(separator)
99
+ re_duplicate_separator = /#{re_sep}{2,}/
100
+ re_leading_trailing_separator = /^#{re_sep}|#{re_sep}$/i
101
+ end
102
+ # No more than one of the separator in a row.
103
+ parameterized_string.gsub!(re_duplicate_separator, separator)
104
+ # Remove leading/trailing separator.
105
+ parameterized_string.gsub!(re_leading_trailing_separator, ''.freeze)
106
+ end
107
+
108
+ parameterized_string.downcase! unless preserve_case
109
+ parameterized_string
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,2 @@
1
+ require 'active_support/json/decoding'
2
+ require 'active_support/json/encoding'
@@ -0,0 +1,74 @@
1
+ require 'active_support/core_ext/module/attribute_accessors'
2
+ require 'active_support/core_ext/module/delegation'
3
+ require 'json'
4
+
5
+ module ActiveSupport
6
+ # Look for and parse json strings that look like ISO 8601 times.
7
+ mattr_accessor :parse_json_times
8
+
9
+ module JSON
10
+ # matches YAML-formatted dates
11
+ DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/
12
+ DATETIME_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?)$/
13
+
14
+ class << self
15
+ # Parses a JSON string (JavaScript Object Notation) into a hash.
16
+ # See http://www.json.org for more info.
17
+ #
18
+ # ActiveSupport::JSON.decode("{\"team\":\"rails\",\"players\":\"36\"}")
19
+ # => {"team" => "rails", "players" => "36"}
20
+ def decode(json)
21
+ data = ::JSON.parse(json, quirks_mode: true)
22
+
23
+ if ActiveSupport.parse_json_times
24
+ convert_dates_from(data)
25
+ else
26
+ data
27
+ end
28
+ end
29
+
30
+ # Returns the class of the error that will be raised when there is an
31
+ # error in decoding JSON. Using this method means you won't directly
32
+ # depend on the ActiveSupport's JSON implementation, in case it changes
33
+ # in the future.
34
+ #
35
+ # begin
36
+ # obj = ActiveSupport::JSON.decode(some_string)
37
+ # rescue ActiveSupport::JSON.parse_error
38
+ # Rails.logger.warn("Attempted to decode invalid JSON: #{some_string}")
39
+ # end
40
+ def parse_error
41
+ ::JSON::ParserError
42
+ end
43
+
44
+ private
45
+
46
+ def convert_dates_from(data)
47
+ case data
48
+ when nil
49
+ nil
50
+ when DATE_REGEX
51
+ begin
52
+ Date.parse(data)
53
+ rescue ArgumentError
54
+ data
55
+ end
56
+ when DATETIME_REGEX
57
+ begin
58
+ Time.zone.parse(data)
59
+ rescue ArgumentError
60
+ data
61
+ end
62
+ when Array
63
+ data.map! { |d| convert_dates_from(d) }
64
+ when Hash
65
+ data.each do |key, value|
66
+ data[key] = convert_dates_from(value)
67
+ end
68
+ else
69
+ data
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,127 @@
1
+ require 'active_support/core_ext/object/json'
2
+ require 'active_support/core_ext/module/delegation'
3
+
4
+ module ActiveSupport
5
+ class << self
6
+ delegate :use_standard_json_time_format, :use_standard_json_time_format=,
7
+ :time_precision, :time_precision=,
8
+ :escape_html_entities_in_json, :escape_html_entities_in_json=,
9
+ :json_encoder, :json_encoder=,
10
+ :to => :'ActiveSupport::JSON::Encoding'
11
+ end
12
+
13
+ module JSON
14
+ # Dumps objects in JSON (JavaScript Object Notation).
15
+ # See http://www.json.org for more info.
16
+ #
17
+ # ActiveSupport::JSON.encode({ team: 'rails', players: '36' })
18
+ # # => "{\"team\":\"rails\",\"players\":\"36\"}"
19
+ def self.encode(value, options = nil)
20
+ Encoding.json_encoder.new(options).encode(value)
21
+ end
22
+
23
+ module Encoding #:nodoc:
24
+ class JSONGemEncoder #:nodoc:
25
+ attr_reader :options
26
+
27
+ def initialize(options = nil)
28
+ @options = options || {}
29
+ end
30
+
31
+ # Encode the given object into a JSON string
32
+ def encode(value)
33
+ stringify jsonify value.as_json(options.dup)
34
+ end
35
+
36
+ private
37
+ # Rails does more escaping than the JSON gem natively does (we
38
+ # escape \u2028 and \u2029 and optionally >, <, & to work around
39
+ # certain browser problems).
40
+ ESCAPED_CHARS = {
41
+ "\u2028" => '\u2028',
42
+ "\u2029" => '\u2029',
43
+ '>' => '\u003e',
44
+ '<' => '\u003c',
45
+ '&' => '\u0026',
46
+ }
47
+
48
+ ESCAPE_REGEX_WITH_HTML_ENTITIES = /[\u2028\u2029><&]/u
49
+ ESCAPE_REGEX_WITHOUT_HTML_ENTITIES = /[\u2028\u2029]/u
50
+
51
+ # This class wraps all the strings we see and does the extra escaping
52
+ class EscapedString < String #:nodoc:
53
+ def to_json(*)
54
+ if Encoding.escape_html_entities_in_json
55
+ super.gsub ESCAPE_REGEX_WITH_HTML_ENTITIES, ESCAPED_CHARS
56
+ else
57
+ super.gsub ESCAPE_REGEX_WITHOUT_HTML_ENTITIES, ESCAPED_CHARS
58
+ end
59
+ end
60
+
61
+ def to_s
62
+ self
63
+ end
64
+ end
65
+
66
+ # Mark these as private so we don't leak encoding-specific constructs
67
+ private_constant :ESCAPED_CHARS, :ESCAPE_REGEX_WITH_HTML_ENTITIES,
68
+ :ESCAPE_REGEX_WITHOUT_HTML_ENTITIES, :EscapedString
69
+
70
+ # Convert an object into a "JSON-ready" representation composed of
71
+ # primitives like Hash, Array, String, Numeric, and true/false/nil.
72
+ # Recursively calls #as_json to the object to recursively build a
73
+ # fully JSON-ready object.
74
+ #
75
+ # This allows developers to implement #as_json without having to
76
+ # worry about what base types of objects they are allowed to return
77
+ # or having to remember to call #as_json recursively.
78
+ #
79
+ # Note: the +options+ hash passed to +object.to_json+ is only passed
80
+ # to +object.as_json+, not any of this method's recursive +#as_json+
81
+ # calls.
82
+ def jsonify(value)
83
+ case value
84
+ when String
85
+ EscapedString.new(value)
86
+ when Numeric, NilClass, TrueClass, FalseClass
87
+ value.as_json
88
+ when Hash
89
+ Hash[value.map { |k, v| [jsonify(k), jsonify(v)] }]
90
+ when Array
91
+ value.map { |v| jsonify(v) }
92
+ else
93
+ jsonify value.as_json
94
+ end
95
+ end
96
+
97
+ # Encode a "jsonified" Ruby data structure using the JSON gem
98
+ def stringify(jsonified)
99
+ ::JSON.generate(jsonified, quirks_mode: true, max_nesting: false)
100
+ end
101
+ end
102
+
103
+ class << self
104
+ # If true, use ISO 8601 format for dates and times. Otherwise, fall back
105
+ # to the Active Support legacy format.
106
+ attr_accessor :use_standard_json_time_format
107
+
108
+ # If true, encode >, <, & as escaped unicode sequences (e.g. > as \u003e)
109
+ # as a safety measure.
110
+ attr_accessor :escape_html_entities_in_json
111
+
112
+ # Sets the precision of encoded time values.
113
+ # Defaults to 3 (equivalent to millisecond precision)
114
+ attr_accessor :time_precision
115
+
116
+ # Sets the encoder used by Rails to encode Ruby objects into JSON strings
117
+ # in +Object#to_json+ and +ActiveSupport::JSON.encode+.
118
+ attr_accessor :json_encoder
119
+ end
120
+
121
+ self.use_standard_json_time_format = true
122
+ self.escape_html_entities_in_json = true
123
+ self.json_encoder = JSONGemEncoder
124
+ self.time_precision = 3
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,71 @@
1
+ require 'concurrent/map'
2
+ require 'openssl'
3
+
4
+ module ActiveSupport
5
+ # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2.
6
+ # It can be used to derive a number of keys for various purposes from a given secret.
7
+ # This lets Rails applications have a single secure secret, but avoid reusing that
8
+ # key in multiple incompatible contexts.
9
+ class KeyGenerator
10
+ def initialize(secret, options = {})
11
+ @secret = secret
12
+ # The default iterations are higher than required for our key derivation uses
13
+ # on the off chance someone uses this for password storage
14
+ @iterations = options[:iterations] || 2**16
15
+ end
16
+
17
+ # Returns a derived key suitable for use. The default key_size is chosen
18
+ # to be compatible with the default settings of ActiveSupport::MessageVerifier.
19
+ # i.e. OpenSSL::Digest::SHA1#block_length
20
+ def generate_key(salt, key_size=64)
21
+ OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size)
22
+ end
23
+ end
24
+
25
+ # CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid
26
+ # re-executing the key generation process when it's called using the same salt and
27
+ # key_size.
28
+ class CachingKeyGenerator
29
+ def initialize(key_generator)
30
+ @key_generator = key_generator
31
+ @cache_keys = Concurrent::Map.new
32
+ end
33
+
34
+ # Returns a derived key suitable for use.
35
+ def generate_key(*args)
36
+ @cache_keys[args.join] ||= @key_generator.generate_key(*args)
37
+ end
38
+ end
39
+
40
+ class LegacyKeyGenerator # :nodoc:
41
+ SECRET_MIN_LENGTH = 30 # Characters
42
+
43
+ def initialize(secret)
44
+ ensure_secret_secure(secret)
45
+ @secret = secret
46
+ end
47
+
48
+ def generate_key(salt)
49
+ @secret
50
+ end
51
+
52
+ private
53
+
54
+ # To prevent users from using something insecure like "Password" we make sure that the
55
+ # secret they've provided is at least 30 characters in length.
56
+ def ensure_secret_secure(secret)
57
+ if secret.blank?
58
+ raise ArgumentError, "A secret is required to generate an integrity hash " \
59
+ "for cookie session data. Set a secret_key_base of at least " \
60
+ "#{SECRET_MIN_LENGTH} characters in config/secrets.yml."
61
+ end
62
+
63
+ if secret.length < SECRET_MIN_LENGTH
64
+ raise ArgumentError, "Secret should be something secure, " \
65
+ "like \"#{SecureRandom.hex(16)}\". The value you " \
66
+ "provided, \"#{secret}\", is shorter than the minimum length " \
67
+ "of #{SECRET_MIN_LENGTH} characters."
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,76 @@
1
+ module ActiveSupport
2
+ # lazy_load_hooks allows Rails to lazily load a lot of components and thus
3
+ # making the app boot faster. Because of this feature now there is no need to
4
+ # require <tt>ActiveRecord::Base</tt> at boot time purely to apply
5
+ # configuration. Instead a hook is registered that applies configuration once
6
+ # <tt>ActiveRecord::Base</tt> is loaded. Here <tt>ActiveRecord::Base</tt> is
7
+ # used as example but this feature can be applied elsewhere too.
8
+ #
9
+ # Here is an example where +on_load+ method is called to register a hook.
10
+ #
11
+ # initializer 'active_record.initialize_timezone' do
12
+ # ActiveSupport.on_load(:active_record) do
13
+ # self.time_zone_aware_attributes = true
14
+ # self.default_timezone = :utc
15
+ # end
16
+ # end
17
+ #
18
+ # When the entirety of +activerecord/lib/active_record/base.rb+ has been
19
+ # evaluated then +run_load_hooks+ is invoked. The very last line of
20
+ # +activerecord/lib/active_record/base.rb+ is:
21
+ #
22
+ # ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
23
+ module LazyLoadHooks
24
+ def self.extended(base) # :nodoc:
25
+ base.class_eval do
26
+ @load_hooks = Hash.new { |h, k| h[k] = [] }
27
+ @loaded = Hash.new { |h, k| h[k] = [] }
28
+ @run_once = Hash.new { |h, k| h[k] = [] }
29
+ end
30
+ end
31
+
32
+ # Declares a block that will be executed when a Rails component is fully
33
+ # loaded.
34
+ #
35
+ # Options:
36
+ #
37
+ # * <tt>:yield</tt> - Yields the object that run_load_hooks to +block+.
38
+ # * <tt>:run_once</tt> - Given +block+ will run only once.
39
+ def on_load(name, options = {}, &block)
40
+ @loaded[name].each do |base|
41
+ execute_hook(name, base, options, block)
42
+ end
43
+
44
+ @load_hooks[name] << [block, options]
45
+ end
46
+
47
+ def run_load_hooks(name, base = Object)
48
+ @loaded[name] << base
49
+ @load_hooks[name].each do |hook, options|
50
+ execute_hook(name, base, options, hook)
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def with_execution_control(name, block, once)
57
+ unless @run_once[name].include?(block)
58
+ @run_once[name] << block if once
59
+
60
+ yield
61
+ end
62
+ end
63
+
64
+ def execute_hook(name, base, options, block)
65
+ with_execution_control(name, block, options[:run_once]) do
66
+ if options[:yield]
67
+ block.call(base)
68
+ else
69
+ base.instance_eval(&block)
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ extend LazyLoadHooks
76
+ end