I'm working on review webmin's source code.
($wuser) = grep { $_->{'name'} eq $in{'user'} } &acl::list_users();
If we pass $in{'user'} like ?user=notexist, variable $wuser will be undef, isn't it?
The abstract code descript what happened below.
# $wuser is undef now.
#die Dumper($wuser);
if($wuser){die 'not die here';}
if ($wuser->{'pass'} eq 'x') {
#never reach here.
die 'not die in branch 1';
}
elsif ($wuser->{'pass'} eq '*LK*' ||
$wuser->{'pass'} =~ /^\!/) {
#never reach here too.
die 'not die in branch 2';
}
if($wuser){die 'so....why die here '.Dumper($wuser);}
# $wuser is {} now.
}
So...when and how an undef variable becomes {} without any define...
The problem here is a Perl feature called "autovivification". Basically, it means that if you treat an undefined Perl variable as a type of reference, then Perl will create a reference of that type and store it in your variable.
So your problem starts when you execute this statement:
if ($wuser->{'pass'} eq 'x')
Perl sees you treating $wuser as a hash reference, so it creates an empty hash and stores a reference to that hash in $wuser. It can then look up the "pass" key in that hash and find that it doesn't exist.
Usually, this is seen as a feature. You can run code like:
my $hash; # created as undef
$hash->{foo}{bar}{baz} = 1;
And Perl will create this data structure for you:
{
'foo' => {
'bar' => {
'baz' => 1
}
}
};
without you needing to go to the trouble of creating all the intermediate levels of the hash.
Of course, your code is rather artificial. You know that $wuser is false when you start looking for keys. All references are true, so a false reference can never contain keys.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With