From a0b80a44101708b5d66cdd87f16c98277954a77c Mon Sep 17 00:00:00 2001 From: shugo Date: Sat, 6 Dec 2014 01:13:45 +0000 Subject: * lib/net/imap.rb: Fix undefined variable usage & refactor/DRY code. Patch by @aledovsky. [Fixes GH-770] * test/net/test_imap.rb: related test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48728 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 7 +++++++ lib/net/imap.rb | 45 +++++++++++++++++++++++++++++++++-------- test/net/imap/test_imap.rb | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 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 + + * 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 * 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 -- cgit v1.2.3