Subject: | Infinite loop when whois server can't be contacted |
When one of the servers in the %IANA hash can't be contacted, the
source_connect method goes into an infinite loop and never exits. This
can be demonstrated as follows:
1) modify IANA.pm and change one of the hostnames to an invalid
hostname. For example: change whois.apnic.net to whois.apnicxxxxxx.net
2) create a test script that simply creates a Net::Whois::IANA object and
calls whois_query on it.
The result is that you will get an error message about not being able to
connect to whois.apnicxxxxxx.net, followed by the following four lines:
Use of uninitialized value in concatenation (.) or string at
/usr/local/share/perl/5.8.8/Net/Whois/IANA.pm line 96.
Use of uninitialized value in concatenation (.) or string at
/usr/local/share/perl/5.8.8/Net/Whois/IANA.pm line 96.
Cannot connect to at port at ./test.pl line 10
IO::Socket::INET: Cannot determine remote port at ./test.pl line 10
These 4 lines of output will then repeat forever at a rate of once per
second.
The problem exists in the following block of code:
do {
$sock = whois_connect($self->{source}{$source_name}[$i]);
$self->{query_sub} =
ref $self->{source}{$source_name}[$i][3] &&
ref $self->{source}{$source_name}[$i][3] eq 'CODE' ?
$self->{source}{$source_name}[$i][3] : \&default_query;
$i++;
$self->{whois_host} = $self->{source}{$source_name}[$i][0];
} until ($sock || !defined $self->{source}{$source_name}[$i]);
In the last 2 lines of the loop, you increment $i, and then use $i to
reference the whois_host. Then when the 'until' line hits, it tries to
check if element $i exists. However, after incrementing $i, the next
line actually created a new dummy array at element $i, thus you will
never get to a situation where element $i doesn't exist.
The solution is to swap the order of those 2 lines, so that $i++ is the
last line of the loop (just before the 'until' line).