GitHub
CERT Secure Coding

EXP35-PL. Use the correct operator type for comparing values

Perl provides two sets of comparison operators: one set for working with numbers and one set for working with strings.

NumbersStrings
==eq
!=ne
<lt
<=le
>gt
>=ge
<=>cmp

Do not use the number comparison operators on nonnumeric strings. Likewise, do not use the string comparison operators on numbers.

Noncompliant Code Example (Numbers)

This noncompliant code example improperly uses eq to test two numbers for equality.

Non-compliant code
my $num = 2;
print "Enter a number\n";
my $user_num = <STDIN>;
chomp $user_num;
if ($num eq $user_num) {print "true\n"} else {print "false\n"};

This code will print true if the user enters 2 , but false if the user enters 02 ,

Compliant Solution (Numbers)

This compliant solution uses == , which interprets its arguments as numbers. This code therefore prints true even if the right argument to == is initialized to some different string like 02 .

Compliant code
my $num = 2;
print "Enter a number\n";
my $user_num = <STDIN>;
chomp $user_num;
if ($num == $user_num) {print "true\n"} else {print "false\n"};

Noncompliant Code Example (Strings)

This noncompliant code example improperly uses == to test two strings for equality.

Non-compliant code
sub check_password {
  my $correct = shift;
  my $password = shift;
  # encrypt password
  if ($password == $correct) {
    return true;
  } else {
    return false;
  }
}

The == operator first converts its arguments into numbers by extracting digits from the front of each argument (along with a preceding + or - ). Nonnumeric data in an argument is ignored, and the number consists of whatever digits were extracted. A string such as "goodpass" has no leading digits, so it is converted to the numeral 0. Consequently, unless either $password or $correct contains leading digits, they will both be converted to 0 and will be considered equivalent.

Compliant Solution (Strings)

This compliant solution uses eq , which interprets its arguments as strings.

Compliant code
sub check_password {
  my $correct = shift;
  my $password = shift;
  # encrypt password
  if ($password eq $correct) {
    return true;
  } else {
    return false;
  }
}

Risk Assessment

Confusing the string comparison operators with numeric comparison operators can lead to incorrect program behavior or incorrect program data.

Rule Severity Likelihood Detectable Repairable Priority Level
EXP35-PL Low Likely Yes No P6 L2

Automated Detection

ToolDiagnostic
Perl::CriticValuesAndExpressions::ProhibitMismatchedOperators
Security Reviewer - Static ReviewerDoubledPrefix

Bibliography

[ CPAN ]Elliot Shank, Perl-Critic-1.116 ProhibitMismatchedOperators
[ Wall 2011 ]perlop