in reply to Re: Passing taint checked scalars
in thread Passing taint checked scalars

Let's walk through the OP's code snippet then:

$filename =~ m{([\w./]+)}smx is a pattern match with capturing parentheses in list context, evaluating to a list of the captured strings on success, otherwise an empty list. ($filename) = ... is the list assignment that gives our pattern match its context (note the parentheses) and stores the result of the match back in $filename. If the match fails, an empty list is assigned and that way $filename becomes undefined.

Now this whole assignment is the left hand side of a low-precedence or operation. The right hand side only gets evaluated if the left hand side evaluates to boolean false. A list assignment evaluates to true if and only if the list of things ready to be assigned is not empty, which is the case here if the pattern match succeeded.

The last part, croak "Bah!" will thus only be called if the pattern match failed. On success, $filename is untainted and stripped of all extra characters outside the match. The first element of the matching list is exactly what also could have been accessed as $1. There you are.

By the way, although this was some way to perform a taint check, the regular expression used here is not very effective to avoid danger. A user-supplied filename like ../../../etc/passwd, for example, would pass the check with nobody the wiser.

Replies are listed 'Best First'.
Re^3: Passing taint checked scalars
by Anonymous Monk on Feb 07, 2006 at 00:26 UTC

    Assuming I'm wish to enforce canonical paths, I believe:

    ($filename) = $filename =~ m{\A (/ ([\w./]+) )}smx and $filename !~ m{\.{2}\/}smx or die 'Bad filename';

    Covers me. Correct? Is there a more elegant way to do this?