From 921a296a3390192a71abeec6d9a035cc6d1865c8 Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Thu, 7 Feb 2013 18:45:25 -0800 Subject: Merge pull request #9208 from dylanahsmith/3-2-mysql-quote-numeric [3.2] active_record: Quote numeric values compared to string columns. Conflicts: activerecord/CHANGELOG.md --- activerecord/CHANGELOG.md | 14 +++++++++++- .../connection_adapters/abstract/quoting.rb | 10 +++++++-- .../connection_adapters/abstract_mysql_adapter.rb | 2 -- .../active_record/relation/predicate_builder.rb | 4 ++++ activerecord/test/cases/quoting_test.rb | 14 ++++++------ activerecord/test/cases/relation/where_test.rb | 25 ++++++++++++++++++++++ activerecord/test/cases/relation_scoping_test.rb | 6 +++--- activerecord/test/schema/schema.rb | 2 ++ 8 files changed, 62 insertions(+), 15 deletions(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 6be0c273c8..93c5aba851 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,4 +1,16 @@ -## Rails 3.2.11 ## +## Rails 3.2.12 (unreleased) ## + +* Quote numeric values being compared to non-numeric columns. Otherwise, + in some database, the string column values will be coerced to a numeric + allowing 0, 0.0 or false to match any string starting with a non-digit. + + Example: + + App.where(apikey: 0) # => SELECT * FROM users WHERE apikey = '0' + + *Dylan Smith* + +## Rails 3.2.11 (Jan 8, 2013) ## * Fix querying with an empty hash *Damien Mathieu* [CVE-2013-0155] diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb index f93c7cd74a..fe0b1959f6 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb @@ -25,13 +25,19 @@ module ActiveRecord when true, false if column && column.type == :integer value ? '1' : '0' + elsif column && [:text, :string, :binary].include?(column.type) + value ? "'1'" : "'0'" else value ? quoted_true : quoted_false end # BigDecimals need to be put in a non-normalized form and quoted. when nil then "NULL" - when BigDecimal then value.to_s('F') - when Numeric then value.to_s + when Numeric, ActiveSupport::Duration + value = BigDecimal === value ? value.to_s('F') : value.to_s + if column && ![:integer, :float, :decimal].include?(column.type) + value = "'#{value}'" + end + value when Date, Time then "'#{quoted_date(value)}'" when Symbol then "'#{quote_string(value.to_s)}'" else diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index abccc3af24..61c5e8040e 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -199,8 +199,6 @@ module ActiveRecord if value.kind_of?(String) && column && column.type == :binary && column.class.respond_to?(:string_to_binary) s = column.class.string_to_binary(value).unpack("H*")[0] "x'#{s}'" - elsif value.kind_of?(BigDecimal) - value.to_s("F") else super end diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index b31fdfd981..5f311ed6d4 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -51,6 +51,10 @@ module ActiveRecord when Class # FIXME: I think we need to deprecate this behavior attribute.eq(value.name) + when Integer, ActiveSupport::Duration + # Arel treats integers as literals, but they should be quoted when compared with strings + column = engine.connection.schema_cache.columns_hash(table.name)[attribute.name.to_s] + attribute.eq(Arel::Nodes::SqlLiteral.new(engine.connection.quote(value, column))) else attribute.eq(value) end diff --git a/activerecord/test/cases/quoting_test.rb b/activerecord/test/cases/quoting_test.rb index 80ee74e41e..babeaec5f6 100644 --- a/activerecord/test/cases/quoting_test.rb +++ b/activerecord/test/cases/quoting_test.rb @@ -122,35 +122,35 @@ module ActiveRecord def test_quote_float float = 1.2 assert_equal float.to_s, @quoter.quote(float, nil) - assert_equal float.to_s, @quoter.quote(float, Object.new) + assert_equal float.to_s, @quoter.quote(float, FakeColumn.new(:float)) end def test_quote_fixnum fixnum = 1 assert_equal fixnum.to_s, @quoter.quote(fixnum, nil) - assert_equal fixnum.to_s, @quoter.quote(fixnum, Object.new) + assert_equal fixnum.to_s, @quoter.quote(fixnum, FakeColumn.new(:integer)) end def test_quote_bignum bignum = 1 << 100 assert_equal bignum.to_s, @quoter.quote(bignum, nil) - assert_equal bignum.to_s, @quoter.quote(bignum, Object.new) + assert_equal bignum.to_s, @quoter.quote(bignum, FakeColumn.new(:integer)) end def test_quote_bigdecimal bigdec = BigDecimal.new((1 << 100).to_s) assert_equal bigdec.to_s('F'), @quoter.quote(bigdec, nil) - assert_equal bigdec.to_s('F'), @quoter.quote(bigdec, Object.new) + assert_equal bigdec.to_s('F'), @quoter.quote(bigdec, FakeColumn.new(:decimal)) end def test_dates_and_times @quoter.extend(Module.new { def quoted_date(value) 'lol' end }) assert_equal "'lol'", @quoter.quote(Date.today, nil) - assert_equal "'lol'", @quoter.quote(Date.today, Object.new) + assert_equal "'lol'", @quoter.quote(Date.today, FakeColumn.new(:date)) assert_equal "'lol'", @quoter.quote(Time.now, nil) - assert_equal "'lol'", @quoter.quote(Time.now, Object.new) + assert_equal "'lol'", @quoter.quote(Time.now, FakeColumn.new(:time)) assert_equal "'lol'", @quoter.quote(DateTime.now, nil) - assert_equal "'lol'", @quoter.quote(DateTime.now, Object.new) + assert_equal "'lol'", @quoter.quote(DateTime.now, FakeColumn.new(:datetime)) end def test_crazy_object diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb index 80158332f9..0529945532 100644 --- a/activerecord/test/cases/relation/where_test.rb +++ b/activerecord/test/cases/relation/where_test.rb @@ -35,5 +35,30 @@ module ActiveRecord def test_where_with_empty_hash_and_no_foreign_key assert_equal 0, Edge.where(:sink => {}).count end + + def test_where_with_integer_for_string_column + count = Post.where(:title => 0).count + assert_equal 0, count + end + + def test_where_with_float_for_string_column + count = Post.where(:title => 0.0).count + assert_equal 0, count + end + + def test_where_with_boolean_for_string_column + count = Post.where(:title => false).count + assert_equal 0, count + end + + def test_where_with_decimal_for_string_column + count = Post.where(:title => BigDecimal.new(0)).count + assert_equal 0, count + end + + def test_where_with_duration_for_string_column + count = Post.where(:title => 0.seconds).count + assert_equal 0, count + end end end diff --git a/activerecord/test/cases/relation_scoping_test.rb b/activerecord/test/cases/relation_scoping_test.rb index f33e765c59..aec2487aee 100644 --- a/activerecord/test/cases/relation_scoping_test.rb +++ b/activerecord/test/cases/relation_scoping_test.rb @@ -380,19 +380,19 @@ class DefaultScopingTest < ActiveRecord::TestCase def test_default_scope_with_inheritance wheres = InheritedPoorDeveloperCalledJamis.scoped.where_values_hash assert_equal "Jamis", wheres[:name] - assert_equal 50000, wheres[:salary] + assert_equal Arel.sql("50000"), wheres[:salary] end def test_default_scope_with_module_includes wheres = ModuleIncludedPoorDeveloperCalledJamis.scoped.where_values_hash assert_equal "Jamis", wheres[:name] - assert_equal 50000, wheres[:salary] + assert_equal Arel.sql("50000"), wheres[:salary] end def test_default_scope_with_multiple_calls wheres = MultiplePoorDeveloperCalledJamis.scoped.where_values_hash assert_equal "Jamis", wheres[:name] - assert_equal 50000, wheres[:salary] + assert_equal Arel.sql("50000"), wheres[:salary] end def test_method_scope diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 8a3dfbb35a..f04dc72cdd 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -518,6 +518,8 @@ ActiveRecord::Schema.define do create_table :price_estimates, :force => true do |t| t.string :estimate_of_type t.integer :estimate_of_id + t.string :thing_type + t.integer :thing_id t.integer :price end -- cgit v1.2.3 From b00fe01d6e231c866509f9f99bbe1534527c7c58 Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Fri, 8 Feb 2013 07:11:37 -0800 Subject: Merge pull request #9224 from dylanahsmith/bigdecimal-takes-string [3.2] Fix test failure for ruby 1.8. --- activerecord/test/cases/relation/where_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/test/cases/relation/where_test.rb b/activerecord/test/cases/relation/where_test.rb index 0529945532..ba9df1651b 100644 --- a/activerecord/test/cases/relation/where_test.rb +++ b/activerecord/test/cases/relation/where_test.rb @@ -52,7 +52,7 @@ module ActiveRecord end def test_where_with_decimal_for_string_column - count = Post.where(:title => BigDecimal.new(0)).count + count = Post.where(:title => BigDecimal.new('0')).count assert_equal 0, count end -- cgit v1.2.3 From 638e24796013282735543823cb71e58c76819060 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 8 Feb 2013 17:54:25 -0200 Subject: Bump rack dependency to 1.4.5 Conflicts: actionpack/actionpack.gemspec --- actionpack/actionpack.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index ebd3c926eb..f01842575e 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -20,7 +20,7 @@ Gem::Specification.new do |s| s.add_dependency('activemodel', version) s.add_dependency('rack-cache', '~> 1.2') s.add_dependency('builder', '~> 3.0.0') - s.add_dependency('rack', '~> 1.4.0') + s.add_dependency('rack', '~> 1.4.5') s.add_dependency('rack-test', '~> 0.6.1') s.add_dependency('journey', '~> 1.0.4') s.add_dependency('sprockets', '~> 2.2.1') -- cgit v1.2.3 From 2f0ff7554dfc7c8b025822e5212065f256926734 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Sat, 9 Feb 2013 16:54:48 -0800 Subject: fixing call to columns hash. run the damn tests when you backport! --- activerecord/lib/active_record/relation/predicate_builder.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb index 5f311ed6d4..236fd5cdfd 100644 --- a/activerecord/lib/active_record/relation/predicate_builder.rb +++ b/activerecord/lib/active_record/relation/predicate_builder.rb @@ -53,7 +53,7 @@ module ActiveRecord attribute.eq(value.name) when Integer, ActiveSupport::Duration # Arel treats integers as literals, but they should be quoted when compared with strings - column = engine.connection.schema_cache.columns_hash(table.name)[attribute.name.to_s] + column = engine.connection.schema_cache.columns_hash[table.name][attribute.name.to_s] attribute.eq(Arel::Nodes::SqlLiteral.new(engine.connection.quote(value, column))) else attribute.eq(value) -- cgit v1.2.3 From 060bb7250b963609a0d8a5d0559e36b99d2402c6 Mon Sep 17 00:00:00 2001 From: joernchen of Phenoelit Date: Sat, 9 Feb 2013 15:46:44 -0800 Subject: Fix issue with attr_protected where malformed input could circumvent protection Fixes: CVE-2013-0276 --- activemodel/lib/active_model/attribute_methods.rb | 2 +- activemodel/lib/active_model/mass_assignment_security/permission_set.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index f033a94c02..96f2c82631 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -365,7 +365,7 @@ module ActiveModel end @prefix, @suffix = options[:prefix] || '', options[:suffix] || '' - @regex = /^(#{Regexp.escape(@prefix)})(.+?)(#{Regexp.escape(@suffix)})$/ + @regex = /\A(#{Regexp.escape(@prefix)})(.+?)(#{Regexp.escape(@suffix)})\z/ @method_missing_target = "#{@prefix}attribute#{@suffix}" @method_name = "#{prefix}%s#{suffix}" end diff --git a/activemodel/lib/active_model/mass_assignment_security/permission_set.rb b/activemodel/lib/active_model/mass_assignment_security/permission_set.rb index a1fcdf1a38..10faa29f31 100644 --- a/activemodel/lib/active_model/mass_assignment_security/permission_set.rb +++ b/activemodel/lib/active_model/mass_assignment_security/permission_set.rb @@ -19,7 +19,7 @@ module ActiveModel protected def remove_multiparameter_id(key) - key.to_s.gsub(/\(.+/, '') + key.to_s.gsub(/\(.+/m, '') end end -- cgit v1.2.3 From 9b9be489948c65a8c6aef7ac063f600da914750a Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Sun, 10 Feb 2013 19:02:55 -0800 Subject: remove ruby-prof --- Gemfile | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Gemfile b/Gemfile index 8c381e9c9e..f0aa19af5d 100644 --- a/Gemfile +++ b/Gemfile @@ -45,12 +45,6 @@ end # Add your own local bundler stuff instance_eval File.read '.Gemfile' if File.exists? '.Gemfile' -platforms :mri do - group :test do - gem 'ruby-prof', '~> 0.11.2' - end -end - platforms :ruby do gem 'yajl-ruby' gem 'nokogiri', '>= 1.4.5' -- cgit v1.2.3 From 1dccd44a5c74f20b0406ecc8d39373226f73af35 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Sun, 10 Feb 2013 19:05:41 -0800 Subject: bumping version --- RAILS_VERSION | 2 +- actionmailer/lib/action_mailer/version.rb | 2 +- actionpack/lib/action_pack/version.rb | 2 +- activemodel/lib/active_model/version.rb | 2 +- activerecord/lib/active_record/version.rb | 2 +- activeresource/lib/active_resource/version.rb | 2 +- activesupport/lib/active_support/version.rb | 2 +- railties/lib/rails/version.rb | 2 +- version.rb | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/RAILS_VERSION b/RAILS_VERSION index 17ce91803c..275e51e5e5 100644 --- a/RAILS_VERSION +++ b/RAILS_VERSION @@ -1 +1 @@ -3.2.11 +3.2.12 diff --git a/actionmailer/lib/action_mailer/version.rb b/actionmailer/lib/action_mailer/version.rb index 695ea004f7..6c361b306f 100644 --- a/actionmailer/lib/action_mailer/version.rb +++ b/actionmailer/lib/action_mailer/version.rb @@ -2,7 +2,7 @@ module ActionMailer module VERSION #:nodoc: MAJOR = 3 MINOR = 2 - TINY = 11 + TINY = 12 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') diff --git a/actionpack/lib/action_pack/version.rb b/actionpack/lib/action_pack/version.rb index 10832373e1..9236f257c2 100644 --- a/actionpack/lib/action_pack/version.rb +++ b/actionpack/lib/action_pack/version.rb @@ -2,7 +2,7 @@ module ActionPack module VERSION #:nodoc: MAJOR = 3 MINOR = 2 - TINY = 11 + TINY = 12 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') diff --git a/activemodel/lib/active_model/version.rb b/activemodel/lib/active_model/version.rb index 51a678d151..5f4fd126a6 100644 --- a/activemodel/lib/active_model/version.rb +++ b/activemodel/lib/active_model/version.rb @@ -2,7 +2,7 @@ module ActiveModel module VERSION #:nodoc: MAJOR = 3 MINOR = 2 - TINY = 11 + TINY = 12 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') diff --git a/activerecord/lib/active_record/version.rb b/activerecord/lib/active_record/version.rb index ff9fa279f4..a340cfaf7d 100644 --- a/activerecord/lib/active_record/version.rb +++ b/activerecord/lib/active_record/version.rb @@ -2,7 +2,7 @@ module ActiveRecord module VERSION #:nodoc: MAJOR = 3 MINOR = 2 - TINY = 11 + TINY = 12 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') diff --git a/activeresource/lib/active_resource/version.rb b/activeresource/lib/active_resource/version.rb index 500da6c137..0547dbe14d 100644 --- a/activeresource/lib/active_resource/version.rb +++ b/activeresource/lib/active_resource/version.rb @@ -2,7 +2,7 @@ module ActiveResource module VERSION #:nodoc: MAJOR = 3 MINOR = 2 - TINY = 11 + TINY = 12 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') diff --git a/activesupport/lib/active_support/version.rb b/activesupport/lib/active_support/version.rb index e928403dd2..2230c5b78e 100644 --- a/activesupport/lib/active_support/version.rb +++ b/activesupport/lib/active_support/version.rb @@ -2,7 +2,7 @@ module ActiveSupport module VERSION #:nodoc: MAJOR = 3 MINOR = 2 - TINY = 11 + TINY = 12 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') diff --git a/railties/lib/rails/version.rb b/railties/lib/rails/version.rb index 352ecf45c0..ec1335ad34 100644 --- a/railties/lib/rails/version.rb +++ b/railties/lib/rails/version.rb @@ -2,7 +2,7 @@ module Rails module VERSION #:nodoc: MAJOR = 3 MINOR = 2 - TINY = 11 + TINY = 12 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') diff --git a/version.rb b/version.rb index 352ecf45c0..ec1335ad34 100644 --- a/version.rb +++ b/version.rb @@ -2,7 +2,7 @@ module Rails module VERSION #:nodoc: MAJOR = 3 MINOR = 2 - TINY = 11 + TINY = 12 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') -- cgit v1.2.3