summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--lib/net/imap.rb45
-rw-r--r--test/net/imap/test_imap.rb50
3 files changed, 94 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 565ef688bd..9f75df1abe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sat Dec 6 10:05:08 2014 Shugo Maeda <shugo@ruby-lang.org>
+
+ * lib/net/imap.rb: Fix undefined variable usage & refactor/DRY
+ code. Patch by @aledovsky. [Fixes GH-770]
+
+ * test/net/test_imap.rb: related test.
+
Sat Dec 6 10:09:44 2014 Eric Wong <e@80x24.org>
* thread.c (do_select): rename parameters to avoid shadowing
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
index 27bbe60263..a772c464ef 100644
--- a/lib/net/imap.rb
+++ b/lib/net/imap.rb
@@ -1256,9 +1256,7 @@ module Net
when nil
when String
when Integer
- if data < 0 || data >= 4294967296
- raise DataFormatError, num.to_s
- end
+ NumValidator.ensure_number(data)
when Array
data.each do |i|
validate_data(i)
@@ -1572,7 +1570,7 @@ module Net
case data
when "*"
when Integer
- ensure_nz_number(data)
+ NumValidator.ensure_nz_number(data)
when Range
when Array
data.each do |i|
@@ -1586,11 +1584,42 @@ module Net
raise DataFormatError, data.inspect
end
end
+ end
+
+ # Common validators of number and nz_number types
+ module NumValidator # :nodoc
+ class << self
+ # Check is passed argument valid 'number' in RFC 3501 terminology
+ def valid_number?(num)
+ # [RFC 3501]
+ # number = 1*DIGIT
+ # ; Unsigned 32-bit integer
+ # ; (0 <= n < 4,294,967,296)
+ num >= 0 && num < 4294967296
+ end
+
+ # Check is passed argument valid 'nz_number' in RFC 3501 terminology
+ def valid_nz_number?(num)
+ # [RFC 3501]
+ # nz-number = digit-nz *DIGIT
+ # ; Non-zero unsigned 32-bit integer
+ # ; (0 < n < 4,294,967,296)
+ num != 0 && valid_number?(num)
+ end
+
+ # Ensure argument is 'number' or raise DataFormatError
+ def ensure_number(num)
+ return if valid_number?(num)
+
+ msg = "number must be unsigned 32-bit integer: #{num}"
+ raise DataFormatError, msg
+ end
+
+ # Ensure argument is 'nz_number' or raise DataFormatError
+ def ensure_nz_number(num)
+ return if valid_nz_number?(num)
- def ensure_nz_number(num)
- if num < -1 || num == 0 || num >= 4294967296
- msg = "nz_number must be non-zero unsigned 32-bit integer: " +
- num.inspect
+ msg = "nz_number must be non-zero unsigned 32-bit integer: #{num}"
raise DataFormatError, msg
end
end
diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb
index 42c5572632..f217971294 100644
--- a/test/net/imap/test_imap.rb
+++ b/test/net/imap/test_imap.rb
@@ -417,6 +417,56 @@ class IMAPTest < Test::Unit::TestCase
assert_equal(993, Net::IMAP.default_imaps_port)
end
+ def test_send_invalid_number
+ server = create_tcp_server
+ port = server.addr[1]
+ @threads << Thread.start do
+ sock = server.accept
+ begin
+ sock.print("* OK test server\r\n")
+ sock.gets
+ sock.print("RUBY0001 OK TEST completed\r\n")
+ sock.gets
+ sock.print("RUBY0002 OK TEST completed\r\n")
+ sock.gets
+ sock.print("RUBY0003 OK TEST completed\r\n")
+ sock.gets
+ sock.print("RUBY0004 OK TEST completed\r\n")
+ sock.gets
+ sock.print("* BYE terminating connection\r\n")
+ sock.print("RUBY0005 OK LOGOUT completed\r\n")
+ ensure
+ sock.close
+ server.close
+ end
+ end
+ begin
+ imap = Net::IMAP.new(SERVER_ADDR, :port => port)
+ assert_raise(Net::IMAP::DataFormatError) do
+ imap.send(:send_command, "TEST", -1)
+ end
+ imap.send(:send_command, "TEST", 0)
+ imap.send(:send_command, "TEST", 4294967295)
+ assert_raise(Net::IMAP::DataFormatError) do
+ imap.send(:send_command, "TEST", 4294967296)
+ end
+ assert_raise(Net::IMAP::DataFormatError) do
+ imap.send(:send_command, "TEST", Net::IMAP::MessageSet.new(-1))
+ end
+ assert_raise(Net::IMAP::DataFormatError) do
+ imap.send(:send_command, "TEST", Net::IMAP::MessageSet.new(0))
+ end
+ imap.send(:send_command, "TEST", Net::IMAP::MessageSet.new(1))
+ imap.send(:send_command, "TEST", Net::IMAP::MessageSet.new(4294967295))
+ assert_raise(Net::IMAP::DataFormatError) do
+ imap.send(:send_command, "TEST", Net::IMAP::MessageSet.new(4294967296))
+ end
+ imap.logout
+ ensure
+ imap.disconnect
+ end
+ end
+
private
def imaps_test