* lib/net/imap.rb (flag_list): untaint strings to intern in the safe
level 1. * lib/net/imap.rb (max_flag_count=): new methods to set the max number of flags interned to symbols. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25860 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ffffc0ce7d
commit
718ceb5476
@ -270,6 +270,16 @@ module Net
|
|||||||
return @@debug = val
|
return @@debug = val
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns the max number of flags interned to symbols.
|
||||||
|
def self.max_flag_count
|
||||||
|
return @@max_flag_count
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sets the max number of flags interned to symbols.
|
||||||
|
def self.max_flag_count=(count)
|
||||||
|
@@max_flag_count = count
|
||||||
|
end
|
||||||
|
|
||||||
# Adds an authenticator for Net::IMAP#authenticate. +auth_type+
|
# Adds an authenticator for Net::IMAP#authenticate. +auth_type+
|
||||||
# is the type of authentication this authenticator supports
|
# is the type of authentication this authenticator supports
|
||||||
# (for instance, "LOGIN"). The +authenticator+ is an object
|
# (for instance, "LOGIN"). The +authenticator+ is an object
|
||||||
@ -929,6 +939,7 @@ module Net
|
|||||||
|
|
||||||
@@debug = false
|
@@debug = false
|
||||||
@@authenticators = {}
|
@@authenticators = {}
|
||||||
|
@@max_flag_count = 10000
|
||||||
|
|
||||||
# call-seq:
|
# call-seq:
|
||||||
# Net::IMAP.new(host, options = {})
|
# Net::IMAP.new(host, options = {})
|
||||||
@ -1929,6 +1940,14 @@ module Net
|
|||||||
end
|
end
|
||||||
|
|
||||||
class ResponseParser # :nodoc:
|
class ResponseParser # :nodoc:
|
||||||
|
def initialize
|
||||||
|
@str = nil
|
||||||
|
@pos = nil
|
||||||
|
@lex_state = nil
|
||||||
|
@token = nil
|
||||||
|
@flag_symbols = {}
|
||||||
|
end
|
||||||
|
|
||||||
def parse(str)
|
def parse(str)
|
||||||
@str = str
|
@str = str
|
||||||
@pos = 0
|
@pos = 0
|
||||||
@ -2939,7 +2958,16 @@ module Net
|
|||||||
if @str.index(/\(([^)]*)\)/ni, @pos)
|
if @str.index(/\(([^)]*)\)/ni, @pos)
|
||||||
@pos = $~.end(0)
|
@pos = $~.end(0)
|
||||||
return $1.scan(FLAG_REGEXP).collect { |flag, atom|
|
return $1.scan(FLAG_REGEXP).collect { |flag, atom|
|
||||||
atom || flag.capitalize.intern
|
if atom
|
||||||
|
atom
|
||||||
|
else
|
||||||
|
symbol = flag.capitalize.untaint.intern
|
||||||
|
@flag_symbols[symbol] = true
|
||||||
|
if @flag_symbols.length > IMAP.max_flag_count
|
||||||
|
raise FlagCountError, "number of flag symbols exceeded"
|
||||||
|
end
|
||||||
|
symbol
|
||||||
|
end
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
parse_error("invalid flag list")
|
parse_error("invalid flag list")
|
||||||
@ -3410,6 +3438,10 @@ module Net
|
|||||||
# out due to inactivity.
|
# out due to inactivity.
|
||||||
class ByeResponseError < ResponseError
|
class ByeResponseError < ResponseError
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Error raised when too many flags are interned to symbols.
|
||||||
|
class FlagCountError < Error
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
54
test/net/imap/test_imap_response_parser.rb
Normal file
54
test/net/imap/test_imap_response_parser.rb
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
require "net/imap"
|
||||||
|
require "test/unit"
|
||||||
|
|
||||||
|
class IMAPResponseParserTest < Test::Unit::TestCase
|
||||||
|
def setup
|
||||||
|
@do_not_reverse_lookup = Socket.do_not_reverse_lookup
|
||||||
|
Socket.do_not_reverse_lookup = true
|
||||||
|
@max_flag_count = Net::IMAP.max_flag_count
|
||||||
|
Net::IMAP.max_flag_count = 3
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
Socket.do_not_reverse_lookup = @do_not_reverse_lookup
|
||||||
|
Net::IMAP.max_flag_count = @max_flag_count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_flag_list_safe
|
||||||
|
parser = Net::IMAP::ResponseParser.new
|
||||||
|
response = lambda {
|
||||||
|
$SAFE = 1
|
||||||
|
parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
|
||||||
|
* LIST (\\HasChildren) "." "INBOX"
|
||||||
|
EOF
|
||||||
|
}.call
|
||||||
|
assert_equal [:Haschildren], response.data.attr
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_flag_list_too_many_flags
|
||||||
|
parser = Net::IMAP::ResponseParser.new
|
||||||
|
assert_nothing_raised do
|
||||||
|
3.times do |i|
|
||||||
|
parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
|
||||||
|
* LIST (\\Foo#{i}) "." "INBOX"
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assert_raise(Net::IMAP::FlagCountError) do
|
||||||
|
parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
|
||||||
|
* LIST (\\Foo3) "." "INBOX"
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_flag_list_many_same_flags
|
||||||
|
parser = Net::IMAP::ResponseParser.new
|
||||||
|
assert_nothing_raised do
|
||||||
|
100.times do
|
||||||
|
parser.parse(<<EOF.gsub(/\n/, "\r\n").taint)
|
||||||
|
* LIST (\\Foo) "." "INBOX"
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user