Subject: | Random errors... |
In Perl, the syntax:
my $foo = bar if $cond
results in $foo containing random data if $cond is false.
The same is true for any statement modifier (e.g. unless, while, until, foreach).
There was quite some discussion about this on the Perl list a while ago, but the bottom line is that $foo can contain anything from undef, to a prior value, to something else. The language lawyers say 'don't do that'.
The usual intent is:
my $foo;
$foo = bar if $cond; # Otherwise, $foo is undef/@foo is empty, etc.
And this syntax must be used for deterministic results.
Unfortunately, MOST of the time the bad syntax produces the intended results. But I (and others) have been burned by random results. A statement that 'works' can start producing random results due to a change anywhere in the script. This is a real problem.
While debugging another issue, I noticed that Net::DNS contains the bad syntax.
I did a quick scan of Net::DNS and found the following instances of if and unless modifiers that need to be corrected:
find /usr/lib/perl5/site_perl/5.8.8/i686-linux-thread-multi/Net/DNS/ -name '*.pm' -exec grep -HniP 'my\s.*\s(if|unless|while|until|foreach)\s' {} \;
Net/DNS/RR.pm:381: my $name = $self->name if COMPATIBLE;
Net/DNS/RR.pm:794: my $method = $1 if $AUTOLOAD =~ m/^.*::(.*)$/;
Net/DNS/RR/OPT.pm:124: my $mods = shift || return if scalar @_;
Net/DNS/RR/TSIG.pm:274: my $packet = $data if $data->isa('Net::DNS::Packet');
Net/DNS/RR/LOC.pm:175: my $neg = pop(@ang) =~ /[SWsw]/ if scalar @ang;
Net/DNS/Text.pm:57:my $ascii = Encode::find_encoding('ascii') if ASCII; # Osborn's Law:
Net/DNS/Text.pm:58:my $utf8 = Encode::find_encoding('utf8') if UTF8; # Variables won't; constants aren't.
Net/DNS/ZoneFile.pm:551: my @discipline = ( join ':', '<', PerlIO::get_layers $self->{handle} ) if PERLIO;
Net/DNS/Packet.pm:42:my @dummy_header = ( header => {} ) if Net::DNS::RR->COMPATIBLE;
Net/DNS/Resolver/Base.pm:157: my %args = @_ unless scalar(@_) % 2;
Net/DNS/Resolver/Base.pm:354: my @address = cname_addr( [@names], $packet ) if defined $packet;
Net/DNS/Resolver/Base.pm:375: my @ns4 = @{$self->{nameserver4}} unless $self->force_v6;
Net/DNS/Resolver/Base.pm:376: my @ns6 = @{$self->{nameserver6}} if $has_inet6 && !$self->force_v4;
Net/DNS/Resolver/Base.pm:449: my $defdomain = $self->{domain} if $self->{defnames};
Net/DNS/Resolver/Base.pm:450: my @searchlist = @{$self->{'searchlist'}} if $self->{dnsrch};
Net/DNS/Resolver/Base.pm:486: my @suffix = ( $self->{domain} || () ) if $name !~ m/[:.]/ and $self->{defnames};
Net/DNS/Resolver/Base.pm:658: my $stop_time = time + $self->{'udp_timeout'} if $self->{'udp_timeout'};
Net/DNS/Resolver/Base.pm:1127: my $verfy = $reply->verify($query) || croak $reply->verifyerr if $query->sigrr;
Net/DNS/Domain.pm:63:my $ascii = Encode::find_encoding('ascii') if ASCII; # Osborn's Law:
Net/DNS/Domain.pm:64:my $utf8 = Encode::find_encoding('utf8') if UTF8; # Variables won't; constants aren't.
Net/DNS/Nameserver.pm:415: my $max_len = $query->edns->size if $query && $self->{Truncate};
I don't claim that this is an exhaustive list.
Please:
Update your coding standards/reviews to ensure that the bad syntax is not used.
Fix these errors.
Check for any that my quick scan missed, and fix them.