From 285d02877f1d38019e5acd82898f29ea3bd8def9 Mon Sep 17 00:00:00 2001 From: Ken Collins Date: Wed, 9 Feb 2011 11:07:25 -0500 Subject: [PATCH] Allow limit values to accept an ARel SQL literal. --- .../abstract/database_statements.rb | 10 +++++++--- activerecord/test/cases/base_test.rb | 10 ++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb index a1b1531..2750ca0 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -253,13 +253,17 @@ module ActiveRecord # Sanitizes the given LIMIT parameter in order to prevent SQL injection. # - # +limit+ may be anything that can evaluate to a string via #to_s. It - # should look like an integer, or a comma-delimited list of integers. + # The +limit+ may be anything that can evaluate to a string via #to_s. It + # should look like an integer, or a comma-delimited list of integers, or + # an Arel SQL literal. # + # Returns Integer and Arel::Nodes::SqlLiteral limits as is. # Returns the sanitized limit parameter, either as an integer, or as a # string which contains a comma-delimited list of integers. def sanitize_limit(limit) - if limit.to_s =~ /,/ + if limit.is_a?(Integer) || limit.is_a?(Arel::Nodes::SqlLiteral) + limit + elsif limit.to_s =~ /,/ Arel.sql limit.to_s.split(',').map{ |i| Integer(i) }.join(',') else Integer(limit) diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 559ef79..c378c5e 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -48,7 +48,7 @@ class Boolean < ActiveRecord::Base; end class BasicsTest < ActiveRecord::TestCase fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, 'warehouse-things', :authors, :categorizations, :categories, :posts - unless current_adapter?(:PostgreSQLAdapter) || current_adapter?(:OracleAdapter) + unless current_adapter?(:PostgreSQLAdapter,:OracleAdapter,:SQLServerAdapter) def test_limit_with_comma assert_nothing_raised do Topic.limit("1,2").all @@ -83,7 +83,13 @@ class BasicsTest < ActiveRecord::TestCase Topic.limit("1, 7 procedure help()").all end end - + + unless current_adapter?(:MysqlAdapter) + def test_limit_should_allow_sql_literal + assert_equal 1, Topic.limit(Arel.sql('2-1')).all.length + end + end + def test_select_symbol topic_ids = Topic.select(:id).map(&:id).sort assert_equal Topic.find(:all).map(&:id).sort, topic_ids -- 1.7.2.2