Permalink
Browse files

Add add_limit_offset! to adapters.

  • Loading branch information...
1 parent ed21f0c commit e3a2fae05dfce39bbac86780c28b102acc3aa68f @miloops miloops committed Mar 25, 2010
@@ -181,6 +181,29 @@ def commit_db_transaction() end
# 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 @@ def release_savepoint
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 @@ def test_foreign_key_violations_are_translated_to_specific_exception
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

0 comments on commit e3a2fae

Please sign in to comment.