Puzzling bug in a very simple piece of code

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • jlhsgcib
    New Member
    • Jul 2008
    • 3

    Puzzling bug in a very simple piece of code

    Hello,

    I have the following snippet of code:
    Code:
     sub getPasswordStatus {
    
    	my ($login, $password) = @_;
            my$quotedLogin = quotemeta($login);
    
    	my $Passwd;
    	if( $password && $password !~ /\?{7,7}/ ) {
    
    		if ($password =~ m/^NO PASSWORD$/i){ # No password
    
    			$Passwd = 'empty';
    
    		} elsif ($password =~ /^PASSWORD$/i){
    
    			$Passwd = 'password';
    
    		} elsif ($password =~ /^$quotedLogin$/i){
    
    			$Passwd = 'login';
    
    		} else {
    
    			$Passwd = 'weak';
    		}
    
    
    	} else {
    
    		$Passwd = 'ok';
    
    	}
            return $Passwd;
    
     }
    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,
    Last edited by numberwhun; Jul 31 '08, 05:16 PM. Reason: Please use code tags
  • KevinADC
    Recognized Expert Specialist
    • Jan 2007
    • 4092

    #2
    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:

    Code:
    my @words = qw(Alcatel1 Algerie1);
    
    foreach my $p (@words) {
       print  getPasswordStatus($p,$p);
    	print "\n";
    }
    sub getPasswordStatus {
    
       my ($login, $password) = @_;
       my $quotedLogin = quotemeta($login);
       my $Passwd;
    	if( $password && $password !~ /\?{7,7}/ ) {
    
    		if ($password =~ m/^NO PASSWORD$/i){ # No password
    
    			$Passwd = 'empty';
    
    		} elsif ($password =~ /^PASSWORD$/i){
    
    			$Passwd = 'password';
    
    		} elsif ($password =~ /^$quotedLogin$/i){
    
    			$Passwd = 'login';
    
    		} else {
    
    			$Passwd = 'weak';
    		}
    
    
    	} else {
    
    		$Passwd = 'ok';
    
    	}
            return $Passwd;
    
     }
    I am not sure what you want this regexp to check:

    Code:
    $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.

    Comment

    • jlhsgcib
      New Member
      • Jul 2008
      • 3

      #3
      Dear Kevin,

      Thank you for your reply.

      Originally posted by KevinADC
      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:

      Code:
      my @words = qw(Alcatel1 Algerie1);
      
      foreach my $p (@words) {
         print  getPasswordStatus($p,$p);
      	print "\n";
      }
      sub getPasswordStatus {
      
         my ($login, $password) = @_;
         my $quotedLogin = quotemeta($login);
         my $Passwd;
      	if( $password && $password !~ /\?{7,7}/ ) {
      
      		if ($password =~ m/^NO PASSWORD$/i){ # No password
      
      			$Passwd = 'empty';
      
      		} elsif ($password =~ /^PASSWORD$/i){
      
      			$Passwd = 'password';
      
      		} elsif ($password =~ /^$quotedLogin$/i){
      
      			$Passwd = 'login';
      
      		} else {
      
      			$Passwd = 'weak';
      		}
      
      
      	} else {
      
      		$Passwd = 'ok';
      
      	}
              return $Passwd;
      
       }
      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:

      Code:
      $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

      Comment

      • KevinADC
        Recognized Expert Specialist
        • Jan 2007
        • 4092

        #4
        Maybe take this question over to www.perlmonks.c om 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.

        Comment

        • jlhsgcib
          New Member
          • Jul 2008
          • 3

          #5
          I've tried on PerlMonks, and got a reply. Basically, in a
          Code:
          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.



          Thanks.
          -- Jeremie

          Comment

          Working...