You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

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

Numbers

Strings

==

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. Counterintuitively, this code prints false.

my $num = 02;
# ...
if ($num eq "02") {print "true\n"} else {print "false\n"};

The counterintuitive result arises because $num is interpreted as a number. When it is initialized, the 02 string is converted to its numeric representation, which is 2. When it is compared, it is converted back to a string, but this time it has the value 2, so the string comparison fails.

Compliant Solution (Numbers)

This compliant solution uses ==, which interprets its arguments as numbers. This code therefore prints true even though the right argument to == is explicitly provided as a string.

my $num = 02;
# ...
if ($num == "02") {print "true\n"} else {print "false\n"};

Noncompliant Code Example (Strings)

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

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 extract. A string such as "goodpass" has no leading digits and is thus 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.

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.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

EXP35-PL

low

likely

low

P9

L2

Automated Detection

Tool

Diagnostic

Perl::Critic

ValuesAndExpressions::ProhibitMismatchedOperators

Bibliography

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


EXP11-C. Do not apply operators expecting one type to data of an incompatible type      03. Expressions (EXP)      EXP13-C. Treat relational and equality operators as if they were nonassociative

  • No labels