mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add add_limit_offset! to adapters.
This commit is contained in:
parent
ed21f0c502
commit
e3a2fae05d
3 changed files with 56 additions and 0 deletions
|
@ -181,6 +181,29 @@ module ActiveRecord
|
||||||
# done if the transaction block raises an exception or returns false.
|
# done if the transaction block raises an exception or returns false.
|
||||||
def rollback_db_transaction() end
|
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)
|
def default_sequence_name(table, column)
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -375,6 +375,18 @@ module ActiveRecord
|
||||||
execute("RELEASE SAVEPOINT #{current_savepoint_name}")
|
execute("RELEASE SAVEPOINT #{current_savepoint_name}")
|
||||||
end
|
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 ========================================
|
# SCHEMA STATEMENTS ========================================
|
||||||
|
|
||||||
def structure_dump #:nodoc:
|
def structure_dump #:nodoc:
|
||||||
|
|
|
@ -142,4 +142,25 @@ class AdapterTest < ActiveRecord::TestCase
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
Loading…
Reference in a new issue