diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 888990416eb64967f09090c5921c82d5fca70725..c99f09f4785f6ba4decf80eb1011319d2f26704c 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,5 +1,9 @@ ## Rails 4.0.0 (unreleased) ## +* Decode URI encoded attributes on database connection URLs. + + *Shawn Veader* + * Add `find_or_create_by`, `find_or_create_by!` and `find_or_initialize_by` methods to `Relation`. @@ -38,7 +42,7 @@ *Jon Leighton* -* Fix bug with presence validation of associations. Would incorrectly add duplicated errors +* Fix bug with presence validation of associations. Would incorrectly add duplicated errors when the association was blank. Bug introduced in 1fab518c6a75dac5773654646eb724a59741bc13. *Scott Willson* diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb index b9a61f7d916ce7295a65f9353cf0bee5d593a023..09250d3c0171014f06efec0125b7f2f5c37ca6f0 100644 --- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb @@ -73,6 +73,8 @@ def connection_url_to_hash(url) # :nodoc: :database => config.path.sub(%r{^/},""), :host => config.host } spec.reject!{ |_,value| value.blank? } + uri_parser = URI::Parser.new + spec.map { |key,value| spec[key] = uri_parser.unescape(value) if value.is_a?(String) } if config.query options = Hash[config.query.split("&").map{ |pair| pair.split("=") }].symbolize_keys spec.merge!(options) diff --git a/activerecord/test/cases/connection_specification/resolver_test.rb b/activerecord/test/cases/connection_specification/resolver_test.rb index 434d2b7ba5cfd23c7d52f1373d71b27baea5ddc2..40c4dc94d142fcb172649f15305b0acb8f5bcfea 100644 --- a/activerecord/test/cases/connection_specification/resolver_test.rb +++ b/activerecord/test/cases/connection_specification/resolver_test.rb @@ -36,6 +36,14 @@ def test_url_port :host => "foo", :encoding => "utf8" }, spec) end + + def test_encoded_password + skip "only if mysql is available" unless defined?(MysqlAdapter) + password = 'am@z1ng_p@ssw0rd#!' + encoded_password = URI.encode_www_form_component(password) + spec = resolve "mysql://foo:#{encoded_password}@localhost/bar" + assert_equal password, spec[:password] + end end end end