By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
437,708 Members | 2,080 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 437,708 IT Pros & Developers. It's quick & easy.

Puzzling bug in a very simple piece of code

P: 3
Hello,

I have the following snippet of code:
Expand|Select|Wrap|Line Numbers
  1.  
  2.  sub getPasswordStatus {
  3.  
  4.     my ($login, $password) = @_;
  5.         my$quotedLogin = quotemeta($login);
  6.  
  7.     my $Passwd;
  8.     if( $password && $password !~ /\?{7,7}/ ) {
  9.  
  10.         if ($password =~ m/^NO PASSWORD$/i){ # No password
  11.  
  12.             $Passwd = 'empty';
  13.  
  14.         } elsif ($password =~ /^PASSWORD$/i){
  15.  
  16.             $Passwd = 'password';
  17.  
  18.         } elsif ($password =~ /^$quotedLogin$/i){
  19.  
  20.             $Passwd = 'login';
  21.  
  22.         } else {
  23.  
  24.             $Passwd = 'weak';
  25.         }
  26.  
  27.  
  28.     } else {
  29.  
  30.         $Passwd = 'ok';
  31.  
  32.     }
  33.         return $Passwd;
  34.  
  35.  }
  36.  
  37.  
As you can see, this is not a very tricky piece of code. But I have a very weird behaviour though. For some passwords, I get the following message:

Use of uninitialized value in string eq at lib/Pwc/Policy.pm line 24.

It's worth noting that it always happens for the same passwords, which are always using the same scheme: an upper case letter, then a few lower case letters and finally some numbers (for example "Alcatel1"). But some other passwords _using this very same scheme_ don't produce the error (for example "Algerie1").

Even more interestingly, the error is only generated for the first test, not the others on line 26 and 28, although the passwords causing this error obviously don't match the first test and thus should go through the others.

I tried to change the test on line 23 to "if( defined $password && $password !~ /\?{7,7}/ )", but it doesn't change anything and it shouldn't actually because if $password is undefined, then "$password" is false, and we don't enter in the guilty block.

I've also tried to change the regular expression match to a simple "eq", but I have the exact same behaviour.

I'm really puzzled on this bug. My leaning goes toward a Perl bug... Any idea to prove me I'm wrong?

Thank you very much for you help.
Best regards,
Jul 31 '08 #1
Share this Question
Share on Google+
4 Replies


KevinADC
Expert 2.5K+
P: 4,059
You are passing two arguments to the script:

my ($login, $password) = @_;

I assume they are the same thing. When I run your code and send the two arguments that you posted your code seems to work
fine:

Expand|Select|Wrap|Line Numbers
  1. my @words = qw(Alcatel1 Algerie1);
  2.  
  3. foreach my $p (@words) {
  4.    print  getPasswordStatus($p,$p);
  5.     print "\n";
  6. }
  7. sub getPasswordStatus {
  8.  
  9.    my ($login, $password) = @_;
  10.    my $quotedLogin = quotemeta($login);
  11.    my $Passwd;
  12.     if( $password && $password !~ /\?{7,7}/ ) {
  13.  
  14.         if ($password =~ m/^NO PASSWORD$/i){ # No password
  15.  
  16.             $Passwd = 'empty';
  17.  
  18.         } elsif ($password =~ /^PASSWORD$/i){
  19.  
  20.             $Passwd = 'password';
  21.  
  22.         } elsif ($password =~ /^$quotedLogin$/i){
  23.  
  24.             $Passwd = 'login';
  25.  
  26.         } else {
  27.  
  28.             $Passwd = 'weak';
  29.         }
  30.  
  31.  
  32.     } else {
  33.  
  34.         $Passwd = 'ok';
  35.  
  36.     }
  37.         return $Passwd;
  38.  
  39.  }
  40.  
I am not sure what you want this regexp to check:

Expand|Select|Wrap|Line Numbers
  1. $password !~ /\?{7,7}/
but it is checking that $password does not match seven question marks in a row: ???????

The problem you are experiencing in your code must be cuased by something else in the code. There were a few versions of perl that you should not use, namely the 5.7 series, if you have one of those that might be the problem, but I doubt it.
Aug 1 '08 #2

P: 3
Dear Kevin,

Thank you for your reply.

You are passing two arguments to the script:

my ($login, $password) = @_;

I assume they are the same thing. When I run your code and send the two arguments that you posted your code seems to work
fine:

Expand|Select|Wrap|Line Numbers
  1. my @words = qw(Alcatel1 Algerie1);
  2.  
  3. foreach my $p (@words) {
  4.    print  getPasswordStatus($p,$p);
  5.     print "\n";
  6. }
  7. sub getPasswordStatus {
  8.  
  9.    my ($login, $password) = @_;
  10.    my $quotedLogin = quotemeta($login);
  11.    my $Passwd;
  12.     if( $password && $password !~ /\?{7,7}/ ) {
  13.  
  14.         if ($password =~ m/^NO PASSWORD$/i){ # No password
  15.  
  16.             $Passwd = 'empty';
  17.  
  18.         } elsif ($password =~ /^PASSWORD$/i){
  19.  
  20.             $Passwd = 'password';
  21.  
  22.         } elsif ($password =~ /^$quotedLogin$/i){
  23.  
  24.             $Passwd = 'login';
  25.  
  26.         } else {
  27.  
  28.             $Passwd = 'weak';
  29.         }
  30.  
  31.  
  32.     } else {
  33.  
  34.         $Passwd = 'ok';
  35.  
  36.     }
  37.         return $Passwd;
  38.  
  39.  }
  40.  
Yes indeed, it works most of the time. This piece of code is run for a large number of login/password couples but the error only happens for less than 10 cases among more than 20000. And as I said, the guilty passwords don't differ especially from the others.

I've even tried to dump passwords as hexadecimal to see whether there wouldn't be non-printable characters in the guilty passwords, without success.

I am not sure what you want this regexp to check:

Expand|Select|Wrap|Line Numbers
  1. $password !~ /\?{7,7}/
but it is checking that $password does not match seven question marks in a row: ???????
Yes, exactly. For the background, this applications tries to break passwords and those that have not been broken are marked with "???????".

The problem you are experiencing in your code must be cuased by something else in the code. There were a few versions of perl that you should not use, namely the 5.7 series, if you have one of those that might be the problem, but I doubt it.
I'm using ActivePerl on Windows:
perl, v5.8.8 built for MSWin32-x86-multi-thread

It's very rare to be hit by a bug from the interpreter, but the more I think about it, given the simplicity of the code, I'm more and more leaning toward an interpreter bug.

The most puzzling thing is that the passwords generating this warning don't match the first condition, so they go though the other tests without generating any warning although this is exactly the same statement with a different regexp. Note that I've also tried to replace the "=~" statement with an equivalent "eq" statement, but it din't change anything.

Best regards,
-- Jeremie
Aug 1 '08 #3

KevinADC
Expert 2.5K+
P: 4,059
Maybe take this question over to www.perlmonks.com I have no idea what the problem could be. I suspect there is a problem with file I/O somewhere else in the script but that is pure conjecture at this point.
Aug 1 '08 #4

P: 3
I've tried on PerlMonks, and got a reply. Basically, in a
Expand|Select|Wrap|Line Numbers
  1. if {} elsif {} else {}
construct, if the warning occurs in the "elsif" condition, the warning will be displayed on the "if" line because it's the same statement.

http://www.perlmonks.com/index.pl?node_id=702113

Thanks.
-- Jeremie
Aug 5 '08 #5

Post your reply

Sign in to post your reply or Sign up for a free account.