mirror of https://github.com/rails/rails
Add add_limit_offset! to adapters.
This commit is contained in:
parent
ed21f0c502
commit
e3a2fae05d
|
@ -181,6 +181,29 @@ module ActiveRecord
|
|||
# done if the transaction block raises an exception or returns false.
|
||||
def rollback_db_transaction() end
|
||||
|
||||
# Appends +LIMIT+ and +OFFSET+ options to an SQL statement, or some SQL
|
||||
# fragment that has the same semantics as LIMIT and OFFSET.
|
||||
#
|
||||
# +options+ must be a Hash which contains a +:limit+ option
|
||||
# and an +:offset+ option.
|
||||
#
|
||||
# This method *modifies* the +sql+ parameter.
|
||||
#
|
||||
# ===== Examples
|
||||
# add_limit_offset!('SELECT * FROM suppliers', {:limit => 10, :offset => 50})
|
||||
# generates
|
||||
# SELECT * FROM suppliers LIMIT 10 OFFSET 50
|
||||
|
||||
def add_limit_offset!(sql, options)
|
||||
if limit = options[:limit]
|
||||
sql << " LIMIT #{sanitize_limit(limit)}"
|
||||
end
|
||||
if offset = options[:offset]
|
||||
sql << " OFFSET #{offset.to_i}"
|
||||
end
|
||||
sql
|
||||
end
|
||||
|
||||
def default_sequence_name(table, column)
|
||||
nil
|
||||
end
|
||||
|
|
|
@ -375,6 +375,18 @@ module ActiveRecord
|
|||
execute("RELEASE SAVEPOINT #{current_savepoint_name}")
|
||||
end
|
||||
|
||||
def add_limit_offset!(sql, options) #:nodoc:
|
||||
limit, offset = options[:limit], options[:offset]
|
||||
if limit && offset
|
||||
sql << " LIMIT #{offset.to_i}, #{sanitize_limit(limit)}"
|
||||
elsif limit
|
||||
sql << " LIMIT #{sanitize_limit(limit)}"
|
||||
elsif offset
|
||||
sql << " OFFSET #{offset.to_i}"
|
||||
end
|
||||
sql
|
||||
end
|
||||
|
||||
# SCHEMA STATEMENTS ========================================
|
||||
|
||||
def structure_dump #:nodoc:
|
||||
|
|
|
@ -142,4 +142,25 @@ class AdapterTest < ActiveRecord::TestCase
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_add_limit_offset_should_sanitize_sql_injection_for_limit_without_comas
|
||||
sql_inject = "1 select * from schema"
|
||||
assert_equal " LIMIT 1", @connection.add_limit_offset!("", :limit => sql_inject)
|
||||
if current_adapter?(:MysqlAdapter)
|
||||
assert_equal " LIMIT 7, 1", @connection.add_limit_offset!("", :limit => sql_inject, :offset => 7)
|
||||
else
|
||||
assert_equal " LIMIT 1 OFFSET 7", @connection.add_limit_offset!("", :limit => sql_inject, :offset => 7)
|
||||
end
|
||||
end
|
||||
|
||||
def test_add_limit_offset_should_sanitize_sql_injection_for_limit_with_comas
|
||||
sql_inject = "1, 7 procedure help()"
|
||||
if current_adapter?(:MysqlAdapter)
|
||||
assert_equal " LIMIT 1,7", @connection.add_limit_offset!("", :limit => sql_inject)
|
||||
assert_equal " LIMIT 7, 1", @connection.add_limit_offset!("", :limit => '1 ; DROP TABLE USERS', :offset => 7)
|
||||
else
|
||||
assert_equal " LIMIT 1,7", @connection.add_limit_offset!("", :limit => sql_inject)
|
||||
assert_equal " LIMIT 1,7 OFFSET 7", @connection.add_limit_offset!("", :limit => sql_inject, :offset => 7)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue