Skip to content

Commit 219e585

Browse files
snowblinkh-lame
authored andcommitted
Fixing limit test in adapter, which raised on a blank options[:limit]. Updated offset_and_limit_test to not run if shoulda gem is not installed.
1 parent 892857f commit 219e585

File tree

2 files changed

+72
-62
lines changed

2 files changed

+72
-62
lines changed

lib/active_record/connection_adapters/sqlserver_adapter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ def add_limit_offset!(sql, options)
422422
end
423423
end
424424

425-
unless options[:limit].kind_of?Integer
425+
if options[:limit] && !(options[:limit].kind_of?Integer)
426426
# is it just a string which should be an integer?
427427
if options[:limit] =~ /^\d+$/
428428
options[:limit] = options[:limit].to_i
Lines changed: 71 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,85 @@
11
require 'cases/helper'
22
# require File.dirname(__FILE__) + '/../../lib/shoulda'
3-
require 'rubygems'
4-
require 'shoulda'
53

6-
class OffsetAndLimitTest < ActiveRecord::TestCase
7-
def setup
8-
@connection = ActiveRecord::Base.connection
4+
def uses_shoulda(&blk)
5+
begin
6+
require 'rubygems'
7+
require 'shoulda'
8+
yield
9+
rescue Gem::LoadError
10+
$stderr.puts "Sorry, you need to install shoulda to run these tests: `gem install shoulda`"
911
end
12+
end
1013

11-
context "selecting with limit" do
12-
setup do
13-
@select_sql = 'SELECT * FROM schema'
14+
uses_shoulda do
15+
class OffsetAndLimitTest < ActiveRecord::TestCase
16+
def setup
17+
@connection = ActiveRecord::Base.connection
1418
end
1519

16-
should "alter SQL to limit number of records returned" do
17-
options = { :limit => 10 }
18-
assert_equal('SELECT TOP 10 * FROM schema', @connection.add_limit_offset!(@select_sql, options))
19-
end
20-
21-
should "only allow integers for limit" do
22-
options = { :limit => 'ten' }
23-
assert_raise(ArgumentError) {@connection.add_limit_offset!(@select_sql, options) }
24-
end
20+
context "selecting with limit" do
21+
setup do
22+
@select_sql = 'SELECT * FROM schema'
23+
end
2524

26-
should "convert strings which look like integers to integers" do
27-
options = { :limit => '42' }
28-
assert_nothing_raised(ArgumentError) {@connection.add_limit_offset!(@select_sql, options)}
29-
end
25+
should "alter SQL to limit number of records returned" do
26+
options = { :limit => 10 }
27+
assert_equal('SELECT TOP 10 * FROM schema', @connection.add_limit_offset!(@select_sql, options))
28+
end
3029

31-
should "not allow sql injection via limit" do
32-
options = { :limit => '1 * FROM schema; DELETE * FROM table; SELECT TOP 10 *'}
33-
assert_raise(ArgumentError) { @connection.add_limit_offset!(@select_sql, options) }
34-
end
35-
end
36-
37-
context "selecting with limit and offset" do
38-
setup do
39-
# we have to use a real table as we need the counts
40-
@select_sql = 'SELECT * FROM accounts'
41-
class Account < ActiveRecord::Base; end
42-
43-
# create 10 Accounts
44-
(1..10).each {|i| Account.create!}
45-
end
46-
47-
should "have limit if offset is passed" do
48-
options = { :offset => 1 }
49-
assert_raise(ArgumentError) { @connection.add_limit_offset!(@select_sql, options) }
50-
end
51-
52-
should "only allow integers for offset" do
53-
options = { :limit => 10, :offset => 'five' }
54-
assert_raise(ArgumentError) { @connection.add_limit_offset!(@select_sql, options)}
55-
end
56-
57-
should "convert strings which look like integers to integers" do
58-
options = { :limit => 10, :offset => '5' }
59-
assert_nothing_raised(ArgumentError) {@connection.add_limit_offset!(@select_sql, options)}
60-
end
61-
62-
should "alter SQL to limit number of records returned offset by specified amount" do
63-
options = { :limit => 3, :offset => 5 }
64-
expected_sql = %&SELECT * FROM (SELECT TOP 3 * FROM (SELECT TOP 8 * FROM accounts) AS tmp1) AS tmp2&
65-
assert_equal(expected_sql, @connection.add_limit_offset!(@select_sql, options))
30+
should "only allow integers for limit" do
31+
options = { :limit => 'ten' }
32+
assert_raise(ArgumentError) {@connection.add_limit_offset!(@select_sql, options) }
33+
end
34+
35+
should "convert strings which look like integers to integers" do
36+
options = { :limit => '42' }
37+
assert_nothing_raised(ArgumentError) {@connection.add_limit_offset!(@select_sql, options)}
38+
end
39+
40+
should "not allow sql injection via limit" do
41+
options = { :limit => '1 * FROM schema; DELETE * FROM table; SELECT TOP 10 *'}
42+
assert_raise(ArgumentError) { @connection.add_limit_offset!(@select_sql, options) }
43+
end
6644
end
6745

68-
# Not really sure what an offset sql injection might look like
69-
should "not allow sql injection via offset" do
70-
options = { :limit => 10, :offset => '1 * FROM schema; DELETE * FROM table; SELECT TOP 10 *'}
71-
assert_raise(ArgumentError) { @connection.add_limit_offset!(@select_sql, options) }
46+
context "selecting with limit and offset" do
47+
setup do
48+
# we have to use a real table as we need the counts
49+
@select_sql = 'SELECT * FROM accounts'
50+
class Account < ActiveRecord::Base; end
51+
52+
# create 10 Accounts
53+
(1..10).each {|i| Account.create!}
54+
end
55+
56+
should "have limit if offset is passed" do
57+
options = { :offset => 1 }
58+
assert_raise(ArgumentError) { @connection.add_limit_offset!(@select_sql, options) }
59+
end
60+
61+
should "only allow integers for offset" do
62+
options = { :limit => 10, :offset => 'five' }
63+
assert_raise(ArgumentError) { @connection.add_limit_offset!(@select_sql, options)}
64+
end
65+
66+
should "convert strings which look like integers to integers" do
67+
options = { :limit => 10, :offset => '5' }
68+
assert_nothing_raised(ArgumentError) {@connection.add_limit_offset!(@select_sql, options)}
69+
end
70+
71+
should "alter SQL to limit number of records returned offset by specified amount" do
72+
options = { :limit => 3, :offset => 5 }
73+
expected_sql = %&SELECT * FROM (SELECT TOP 3 * FROM (SELECT TOP 8 * FROM accounts) AS tmp1) AS tmp2&
74+
assert_equal(expected_sql, @connection.add_limit_offset!(@select_sql, options))
75+
end
76+
77+
# Not really sure what an offset sql injection might look like
78+
should "not allow sql injection via offset" do
79+
options = { :limit => 10, :offset => '1 * FROM schema; DELETE * FROM table; SELECT TOP 10 *'}
80+
assert_raise(ArgumentError) { @connection.add_limit_offset!(@select_sql, options) }
81+
end
7282
end
73-
end
7483

84+
end
7585
end

0 commit comments

Comments
 (0)