GitHub
CERT Secure Coding

DCL02-PL. Any modified punctuation variable should be declared local

Perl has a large number of punctuation variables. They control the behavior of various operations in the Perl interpreter. Although they are initially set to reasonable default values, any Perl code has the ability to change their values for its own internal purposes. If a program modifies one of these variables, it is obligated to reset the variable to its default value, lest it alter the behavior of subsequent unrelated code. The easiest way for a program to "clean up after itself" is to declare such variables local when modifying them.

Noncompliant Code Example

This noncompliant code example shows a subroutine that counts the number of virtual users on this platform. This value is deduced by the number of users in the /etc/passwd file that use the program /usr/bin/false as their shell.

Non-compliant code
sub count_virtual_users {
  my $result = 0;
  $/ = ":";
  open( PASSWD, "<", "/etc/passwd");
  while (<PASSWD>) {
    @items = split "\n";
    foreach (@items) {
      if ($_ eq "/usr/bin/false") {
        $result++;
      }
    }
  }
  $result;
}

This program produces the correct result, but it leaves the $/ variable set to an unusual value ( : ). Subsequent reads of any file will use this character as the end-of-line delimiter rather than the typical newline, which is the default value.

Compliant Solution

This compliant solution again produces the same result but localizes the punctuation variable. Consequently, when the subroutine returns, the $/ variable is restored to its original value, and subsequent file reads behave as expected.

Compliant code
sub count_virtual_users {
  my $result = 0;
  local $/ = ":";
  open( PASSWD, "<", "/etc/passwd");
  while (<PASSWD>) {
    @items = split "\n";
    foreach (@items) {
      if ($_ eq "/usr/bin/false") {
        $result++;
      }
    }
  }
  $result;
}

Exceptions

DCL02-PL-EX0 : The following global variables may be modified without being declared local :

$_$ARG
@_@ARG
$!$ERRNO$OS_ERROR
%ENV$ENV{expr}
%SIG$SIG{expr}
%INC

Risk Assessment

Modifying punctuation variables without declaring them local can corrupt data and create unexpected program behavior.

RecommendationSeverityLikelihoodRemediation CostPriorityLevel
DCL02-PLLowProbableMediumP4L3

Automated Detection

ToolDiagnostic
Perl::CriticVariables::RequireLocalizedPunctuationVars

Bibliography

[ CPAN ]Elliot Shank, Perl-Critic-1.116 Variables::RequireLocalizedPunctuationVars
[ Wall 2011 ]perlfunc , perlvar