diff options
-rw-r--r-- | actionpack/CHANGELOG.md | 9 | ||||
-rw-r--r-- | actionpack/lib/action_controller/test_case.rb | 30 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/journey/router/utils.rb | 12 | ||||
-rw-r--r-- | actionpack/test/journey/router/utils_test.rb | 5 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/tag_helper.rb | 1 | ||||
-rw-r--r-- | guides/source/getting_started.md | 3 | ||||
-rw-r--r-- | guides/source/upgrading_ruby_on_rails.md | 14 |
7 files changed, 48 insertions, 26 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 8c6374eeb9..fb36396167 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -3,6 +3,15 @@ *Greg Campbell* +* Because URI paths may contain non US-ASCII characters we need to force + the encoding of any unescaped URIs to UTF-8 if they are US-ASCII. + This essentially replicates the functionality of the monkey patch to + URI.parser.unescape in active_support/core_ext/uri.rb. + + Fixes #16104. + + *Karl Entwistle* + * Generate shallow paths for all children of shallow resources. Fixes #15783. diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 8fd11d7cf2..a18c35e3e9 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -30,25 +30,21 @@ module ActionController end @_subscribers << ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload| - path = payload[:virtual_path] - next unless path - partial = path =~ /^.*\/_[^\/]*$/ + if virtual_path = payload[:virtual_path] + partial = virtual_path =~ /^.*\/_[^\/]*$/ - if partial - @_partials[path] += 1 - @_partials[path.split("/").last] += 1 - end - - @_templates[path] += 1 - end - - @_subscribers << ActiveSupport::Notifications.subscribe("!render_template.action_view") do |_name, _start, _finish, _id, payload| - next if payload[:virtual_path] # files don't have virtual path + if partial + @_partials[virtual_path] += 1 + @_partials[virtual_path.split("/").last] += 1 + end - path = payload[:identifier] - if path - @_files[path] += 1 - @_files[path.split("/").last] += 1 + @_templates[virtual_path] += 1 + else + path = payload[:identifier] + if path + @_files[path] += 1 + @_files[path.split("/").last] += 1 + end end end end diff --git a/actionpack/lib/action_dispatch/journey/router/utils.rb b/actionpack/lib/action_dispatch/journey/router/utils.rb index ac4ecb1e65..2b0a6575d4 100644 --- a/actionpack/lib/action_dispatch/journey/router/utils.rb +++ b/actionpack/lib/action_dispatch/journey/router/utils.rb @@ -25,9 +25,10 @@ module ActionDispatch # http://tools.ietf.org/html/rfc3986 class UriEncoder # :nodoc: ENCODE = "%%%02X".freeze - ENCODING = Encoding::US_ASCII - EMPTY = "".force_encoding(ENCODING).freeze - DEC2HEX = (0..255).to_a.map{ |i| ENCODE % i }.map{ |s| s.force_encoding(ENCODING) } + US_ASCII = Encoding::US_ASCII + UTF_8 = Encoding::UTF_8 + EMPTY = "".force_encoding(US_ASCII).freeze + DEC2HEX = (0..255).to_a.map{ |i| ENCODE % i }.map{ |s| s.force_encoding(US_ASCII) } ALPHA = "a-zA-Z".freeze DIGIT = "0-9".freeze @@ -53,12 +54,13 @@ module ActionDispatch end def unescape_uri(uri) - uri.gsub(ESCAPED) { [$&[1, 2].hex].pack('C') }.force_encoding(uri.encoding) + encoding = uri.encoding == US_ASCII ? UTF_8 : uri.encoding + uri.gsub(ESCAPED) { [$&[1, 2].hex].pack('C') }.force_encoding(encoding) end protected def escape(component, pattern) - component.gsub(pattern){ |unsafe| percent_encode(unsafe) }.force_encoding(ENCODING) + component.gsub(pattern){ |unsafe| percent_encode(unsafe) }.force_encoding(US_ASCII) end def percent_encode(unsafe) diff --git a/actionpack/test/journey/router/utils_test.rb b/actionpack/test/journey/router/utils_test.rb index 584fd56a5c..9b2b85ec73 100644 --- a/actionpack/test/journey/router/utils_test.rb +++ b/actionpack/test/journey/router/utils_test.rb @@ -1,3 +1,4 @@ +# coding: utf-8 require 'abstract_unit' module ActionDispatch @@ -20,6 +21,10 @@ module ActionDispatch assert_equal "a/b c+d", Utils.unescape_uri("a%2Fb%20c+d") end + def test_uri_unescape_with_utf8_string + assert_equal "Šašinková", Utils.unescape_uri("%C5%A0a%C5%A1inkov%C3%A1".force_encoding(Encoding::US_ASCII)) + end + def test_normalize_path_not_greedy assert_equal "/foo%20bar%20baz", Utils.normalize_path("/foo%20bar%20baz") end diff --git a/actionview/lib/action_view/helpers/tag_helper.rb b/actionview/lib/action_view/helpers/tag_helper.rb index 35444bcfb4..268558669e 100644 --- a/actionview/lib/action_view/helpers/tag_helper.rb +++ b/actionview/lib/action_view/helpers/tag_helper.rb @@ -9,6 +9,7 @@ module ActionView module TagHelper extend ActiveSupport::Concern include CaptureHelper + include OutputSafetyHelper BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer autoplay controls loop selected hidden scoped async diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md index 0e121b6f75..ef97cda3bc 100644 --- a/guides/source/getting_started.md +++ b/guides/source/getting_started.md @@ -749,8 +749,7 @@ to create an article. Try it! You should get an error that looks like this: (images/getting_started/forbidden_attributes_for_new_article.png) Rails has several security features that help you write secure applications, -and you're running into one of them now. This one is called `[strong_parameters] -(http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters)`, +and you're running into one of them now. This one is called [strong parameters](http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters), which requires us to tell Rails exactly which parameters are allowed into our controller actions. diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md index 1e752b449d..36cd505977 100644 --- a/guides/source/upgrading_ruby_on_rails.md +++ b/guides/source/upgrading_ruby_on_rails.md @@ -241,6 +241,16 @@ If your application depends on one of these features, you can get them back by adding the [`activesupport-json_encoder`](https://github.com/rails/activesupport-json_encoder) gem to your Gemfile. +#### JSON representation of Time objects + +`#as_json` for objects with time component (`Time`, `DateTime`, `ActiveSupport::TimeWithZone`) +now returns millisecond precision by default. If you need to keep old behavior with no millisecond +precision, set the following in an initializer: + +``` +ActiveSupport::JSON::Encoding.time_precision = 0 +``` + ### Usage of `return` within inline callback blocks Previously, Rails allowed inline callback blocks to use `return` this way: @@ -434,8 +444,8 @@ string keys consistently. ### Explicit block use for `ActiveSupport::Callbacks` -Rails 4.1 now expects an explicit block to be passed when calling -`ActiveSupport::Callbacks.set_callback`. This change stems from +Rails 4.1 now expects an explicit block to be passed when calling +`ActiveSupport::Callbacks.set_callback`. This change stems from `ActiveSupport::Callbacks` being largely rewritten for the 4.1 release. ```ruby |