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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +798 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +13 -7
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +38 -34
- data/lib/active_support/benchmarkable.rb +17 -28
- data/lib/active_support/cache/file_store.rb +85 -70
- data/lib/active_support/cache/mem_cache_store.rb +75 -66
- data/lib/active_support/cache/memory_store.rb +31 -23
- data/lib/active_support/cache/null_store.rb +41 -0
- data/lib/active_support/cache/strategy/local_cache.rb +73 -70
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
- data/lib/active_support/cache.rb +360 -294
- data/lib/active_support/callbacks.rb +563 -393
- data/lib/active_support/concern.rb +42 -34
- data/lib/active_support/concurrency/latch.rb +19 -0
- data/lib/active_support/concurrency/share_lock.rb +186 -0
- data/lib/active_support/configurable.rb +70 -12
- data/lib/active_support/core_ext/array/access.rb +53 -9
- data/lib/active_support/core_ext/array/conversions.rb +109 -62
- data/lib/active_support/core_ext/array/extract_options.rb +2 -2
- data/lib/active_support/core_ext/array/grouping.rb +39 -32
- data/lib/active_support/core_ext/array/inquiry.rb +17 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
- data/lib/active_support/core_ext/array/wrap.rb +16 -18
- data/lib/active_support/core_ext/array.rb +2 -2
- data/lib/active_support/core_ext/benchmark.rb +7 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -36
- data/lib/active_support/core_ext/class/attribute.rb +47 -34
- data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -79
- data/lib/active_support/core_ext/class/subclasses.rb +12 -7
- data/lib/active_support/core_ext/class.rb +0 -3
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +57 -167
- data/lib/active_support/core_ext/date/conversions.rb +31 -42
- data/lib/active_support/core_ext/date/zones.rb +2 -10
- data/lib/active_support/core_ext/date.rb +5 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +335 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +1 -0
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +132 -65
- data/lib/active_support/core_ext/date_time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +36 -34
- data/lib/active_support/core_ext/date_time.rb +5 -0
- data/lib/active_support/core_ext/digest/uuid.rb +51 -0
- data/lib/active_support/core_ext/enumerable.rb +81 -74
- data/lib/active_support/core_ext/file/atomic.rb +53 -26
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/hash/compact.rb +20 -0
- data/lib/active_support/core_ext/hash/conversions.rb +175 -70
- data/lib/active_support/core_ext/hash/deep_merge.rb +30 -8
- data/lib/active_support/core_ext/hash/except.rb +11 -12
- data/lib/active_support/core_ext/hash/indifferent_access.rb +7 -8
- data/lib/active_support/core_ext/hash/keys.rb +147 -24
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
- data/lib/active_support/core_ext/hash/slice.rb +22 -14
- data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
- data/lib/active_support/core_ext/hash.rb +2 -2
- data/lib/active_support/core_ext/integer/inflections.rb +13 -1
- data/lib/active_support/core_ext/integer/multiple.rb +4 -0
- data/lib/active_support/core_ext/integer/time.rb +12 -22
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -2
- data/lib/active_support/core_ext/kernel/concern.rb +12 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -15
- data/lib/active_support/core_ext/kernel/reporting.rb +12 -62
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
- data/lib/active_support/core_ext/kernel.rb +2 -3
- data/lib/active_support/core_ext/load_error.rb +14 -7
- data/lib/active_support/core_ext/marshal.rb +22 -0
- data/lib/active_support/core_ext/module/aliasing.rb +16 -12
- data/lib/active_support/core_ext/module/anonymous.rb +12 -8
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +165 -13
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
- data/lib/active_support/core_ext/module/concerning.rb +135 -0
- data/lib/active_support/core_ext/module/delegation.rb +141 -68
- data/lib/active_support/core_ext/module/deprecation.rb +17 -3
- data/lib/active_support/core_ext/module/introspection.rb +9 -31
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -0
- data/lib/active_support/core_ext/module/qualified_const.rb +70 -0
- data/lib/active_support/core_ext/module/reachable.rb +1 -3
- data/lib/active_support/core_ext/module/remove_method.rb +24 -5
- data/lib/active_support/core_ext/module.rb +3 -3
- data/lib/active_support/core_ext/name_error.rb +15 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +31 -36
- data/lib/active_support/core_ext/numeric.rb +2 -0
- data/lib/active_support/core_ext/object/acts_like.rb +4 -4
- data/lib/active_support/core_ext/object/blank.rb +52 -18
- data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
- data/lib/active_support/core_ext/object/duplicable.rb +12 -20
- data/lib/active_support/core_ext/object/inclusion.rb +13 -1
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
- data/lib/active_support/core_ext/object/json.rb +205 -0
- data/lib/active_support/core_ext/object/to_param.rb +1 -55
- data/lib/active_support/core_ext/object/to_query.rb +66 -9
- data/lib/active_support/core_ext/object/try.rb +124 -33
- data/lib/active_support/core_ext/object/with_options.rb +37 -11
- data/lib/active_support/core_ext/object.rb +2 -1
- data/lib/active_support/core_ext/range/conversions.rb +17 -7
- data/lib/active_support/core_ext/range/each.rb +21 -0
- data/lib/active_support/core_ext/range/include_range.rb +20 -18
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -2
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +41 -38
- data/lib/active_support/core_ext/string/exclude.rb +6 -1
- data/lib/active_support/core_ext/string/filters.rb +70 -17
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +139 -59
- data/lib/active_support/core_ext/string/inquiry.rb +2 -2
- data/lib/active_support/core_ext/string/multibyte.rb +46 -65
- data/lib/active_support/core_ext/string/output_safety.rb +153 -56
- data/lib/active_support/core_ext/string/strip.rb +3 -6
- data/lib/active_support/core_ext/string/zones.rb +14 -0
- data/lib/active_support/core_ext/string.rb +2 -3
- data/lib/active_support/core_ext/struct.rb +3 -0
- data/lib/active_support/core_ext/time/calculations.rb +173 -173
- data/lib/active_support/core_ext/time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/time/conversions.rb +33 -29
- data/lib/active_support/core_ext/time/marshal.rb +2 -56
- data/lib/active_support/core_ext/time/zones.rb +57 -32
- data/lib/active_support/core_ext/time.rb +5 -0
- data/lib/active_support/core_ext/uri.rb +13 -19
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/dependencies/interlock.rb +51 -0
- data/lib/active_support/dependencies.rb +315 -265
- data/lib/active_support/deprecation/behaviors.rb +71 -30
- data/lib/active_support/deprecation/instance_delegator.rb +24 -0
- data/lib/active_support/deprecation/method_wrappers.rb +59 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +82 -14
- data/lib/active_support/deprecation/reporting.rb +61 -14
- data/lib/active_support/deprecation.rb +38 -13
- data/lib/active_support/descendants_tracker.rb +34 -19
- data/lib/active_support/duration/iso8601_parser.rb +122 -0
- data/lib/active_support/duration/iso8601_serializer.rb +51 -0
- data/lib/active_support/duration.rb +85 -14
- data/lib/active_support/evented_file_update_checker.rb +194 -0
- data/lib/active_support/execution_wrapper.rb +117 -0
- data/lib/active_support/executor.rb +6 -0
- data/lib/active_support/file_update_checker.rb +138 -17
- data/lib/active_support/gem_version.rb +15 -0
- data/lib/active_support/gzip.rb +11 -5
- data/lib/active_support/hash_with_indifferent_access.rb +199 -49
- data/lib/active_support/i18n.rb +6 -2
- data/lib/active_support/i18n_railtie.rb +40 -21
- data/lib/active_support/inflections.rb +22 -13
- data/lib/active_support/inflector/inflections.rb +175 -144
- data/lib/active_support/inflector/methods.rb +328 -91
- data/lib/active_support/inflector/transliterate.rb +51 -37
- data/lib/active_support/json/decoding.rb +31 -22
- data/lib/active_support/json/encoding.rb +88 -248
- data/lib/active_support/key_generator.rb +71 -0
- data/lib/active_support/lazy_load_hooks.rb +27 -25
- data/lib/active_support/locale/en.yml +102 -3
- data/lib/active_support/log_subscriber/test_helper.rb +24 -21
- data/lib/active_support/log_subscriber.rb +36 -49
- data/lib/active_support/logger.rb +106 -0
- data/lib/active_support/logger_silence.rb +28 -0
- data/lib/active_support/logger_thread_safe_level.rb +31 -0
- data/lib/active_support/message_encryptor.rb +72 -36
- data/lib/active_support/message_verifier.rb +96 -24
- data/lib/active_support/multibyte/chars.rb +88 -333
- data/lib/active_support/multibyte/unicode.rb +156 -136
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/notifications/fanout.rb +115 -19
- data/lib/active_support/notifications/instrumenter.rb +52 -15
- data/lib/active_support/notifications.rb +168 -33
- data/lib/active_support/number_helper/number_converter.rb +182 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +44 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +28 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +62 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +92 -0
- data/lib/active_support/number_helper.rb +368 -0
- data/lib/active_support/option_merger.rb +1 -1
- data/lib/active_support/ordered_hash.rb +18 -183
- data/lib/active_support/ordered_options.rb +44 -24
- data/lib/active_support/per_thread_registry.rb +58 -0
- data/lib/active_support/proxy_object.rb +13 -0
- data/lib/active_support/rails.rb +27 -0
- data/lib/active_support/railtie.rb +25 -34
- data/lib/active_support/reloader.rb +129 -0
- data/lib/active_support/rescuable.rb +98 -48
- data/lib/active_support/security_utils.rb +27 -0
- data/lib/active_support/string_inquirer.rb +14 -9
- data/lib/active_support/subscriber.rb +120 -0
- data/lib/active_support/tagged_logging.rb +78 -0
- data/lib/active_support/test_case.rb +69 -17
- data/lib/active_support/testing/assertions.rb +43 -41
- data/lib/active_support/testing/autorun.rb +12 -0
- data/lib/active_support/testing/constant_lookup.rb +50 -0
- data/lib/active_support/testing/declarative.rb +7 -21
- data/lib/active_support/testing/deprecation.rb +14 -33
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +53 -95
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/setup_and_teardown.rb +21 -82
- data/lib/active_support/testing/stream.rb +42 -0
- data/lib/active_support/testing/tagged_logging.rb +25 -0
- data/lib/active_support/testing/time_helpers.rb +134 -0
- data/lib/active_support/time.rb +6 -23
- data/lib/active_support/time_with_zone.rb +239 -92
- data/lib/active_support/values/time_zone.rb +236 -160
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +5 -7
- data/lib/active_support/xml_mini/jdom.rb +19 -13
- data/lib/active_support/xml_mini/libxml.rb +3 -4
- data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
- data/lib/active_support/xml_mini/nokogiri.rb +3 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
- data/lib/active_support/xml_mini/rexml.rb +8 -10
- data/lib/active_support/xml_mini.rb +66 -34
- data/lib/active_support.rb +40 -23
- metadata +185 -134
- data/CHANGELOG +0 -1534
- data/lib/active_support/base64.rb +0 -42
- data/lib/active_support/basic_object.rb +0 -21
- data/lib/active_support/buffered_logger.rb +0 -137
- data/lib/active_support/cache/compressed_mem_cache_store.rb +0 -13
- data/lib/active_support/cache/synchronized_memory_store.rb +0 -11
- data/lib/active_support/core_ext/array/random_access.rb +0 -30
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -44
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -178
- data/lib/active_support/core_ext/date/freeze.rb +0 -31
- data/lib/active_support/core_ext/date_time/zones.rb +0 -21
- data/lib/active_support/core_ext/exception.rb +0 -3
- data/lib/active_support/core_ext/file/path.rb +0 -5
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- data/lib/active_support/core_ext/float.rb +0 -1
- data/lib/active_support/core_ext/hash/deep_dup.rb +0 -11
- data/lib/active_support/core_ext/hash/diff.rb +0 -13
- data/lib/active_support/core_ext/kernel/requires.rb +0 -28
- data/lib/active_support/core_ext/logger.rb +0 -81
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +0 -31
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/synchronization.rb +0 -43
- data/lib/active_support/core_ext/object/to_json.rb +0 -19
- data/lib/active_support/core_ext/proc.rb +0 -14
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- data/lib/active_support/core_ext/process.rb +0 -1
- data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
- data/lib/active_support/core_ext/range/cover.rb +0 -3
- data/lib/active_support/core_ext/rexml.rb +0 -46
- data/lib/active_support/core_ext/string/encoding.rb +0 -11
- data/lib/active_support/core_ext/string/interpolation.rb +0 -2
- data/lib/active_support/core_ext/string/xchar.rb +0 -18
- data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
- data/lib/active_support/file_watcher.rb +0 -36
- data/lib/active_support/json/variable.rb +0 -9
- data/lib/active_support/memoizable.rb +0 -105
- data/lib/active_support/multibyte/exceptions.rb +0 -8
- data/lib/active_support/multibyte/utils.rb +0 -60
- data/lib/active_support/ruby/shim.rb +0 -22
- data/lib/active_support/secure_random.rb +0 -6
- data/lib/active_support/testing/mochaing.rb +0 -7
- data/lib/active_support/testing/pending.rb +0 -52
- data/lib/active_support/testing/performance/jruby.rb +0 -115
- data/lib/active_support/testing/performance/rubinius.rb +0 -113
- data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
- data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
- data/lib/active_support/testing/performance/ruby.rb +0 -152
- data/lib/active_support/testing/performance.rb +0 -317
- data/lib/active_support/time/autoload.rb +0 -5
- 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 = { '&' => '&', '>' => '>', '<' => '<', '"' => '"' }
|
7
|
-
JSON_ESCAPE = { '&' => '\u0026', '>' => '\
|
6
|
+
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''' }
|
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
|
-
#
|
16
|
-
# puts html_escape("is a > 0 & a < 10?")
|
17
|
+
# puts html_escape('is a > 0 & a < 10?')
|
17
18
|
# # => is a > 0 & a < 10?
|
18
19
|
def html_escape(s)
|
19
|
-
s
|
20
|
-
if s.html_safe?
|
21
|
-
s
|
22
|
-
else
|
23
|
-
s.to_s.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/</, "<").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
|
-
#
|
37
|
-
#
|
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 & 3')
|
47
|
+
# # => "1 < 2 & 3"
|
48
|
+
#
|
49
|
+
# html_escape_once('<< Accept & Checkout')
|
50
|
+
# # => "<< Accept & 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>"</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
|
-
#
|
40
|
-
#
|
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
|
-
#
|
43
|
-
#
|
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
|
-
#
|
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
|
-
#
|
49
|
-
#
|
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
|
-
#
|
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(
|
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 =
|
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
|
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
|
170
|
+
raise SafeConcatError unless html_safe?
|
91
171
|
original_concat(value)
|
92
172
|
end
|
93
173
|
|
94
|
-
def initialize(
|
95
|
-
@
|
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
|
-
@
|
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
|
-
|
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
|
-
|
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.
|
225
|
+
coder.represent_object nil, to_str
|
131
226
|
end
|
132
227
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
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
|
-
|
243
|
+
private
|
152
244
|
|
153
|
-
def
|
154
|
-
|
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
|
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
|
-
|
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'
|