Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Moose types & taint removal?

by pileofrogs (Priest)
on Aug 11, 2010 at 18:17 UTC ( [id://854474]=perlquestion: print w/replies, xml ) Need Help??

pileofrogs has asked for the wisdom of the Perl Monks concerning the following question:

Greetings Monks!

Is it possible to use the type constraint stuff in Moose to de-taint values?

For instance, I have a class with a few file paths. Pre-Moose I would have checked them individually with a regex to de-taint them. Now I have this cool Moose type checking system, but I don't see how to de-taint values with it.

For instance:

# old way sub logfile { my $self = shift; my $new_name = shift; if ( !defined($new_name) ) { return $self->{logfile}; } if ( $new_name !~ m{^([\w/_\-\.]{1,80})$} ) { croak "I don't trust logfile name '$new_name'"; } $self->{logfile} = $1; } # New Moose Way subtype 'FilePath' => as 'Str' => where { $_ =~ m{^([\w/_\-\.]{1,80})$} } => message { "I don't trust file name '$_'" }; has logfile => ( is => 'rw', isa => 'FilePath', default => '/var/log/walrus.log' );

Replies are listed 'Best First'.
Re: Moose types & taint removal?
by ikegami (Patriarch) on Aug 11, 2010 at 19:23 UTC

    The best way might be to have a Trait that removes the tainting on assignment.

    subtype 'FilePath' => as 'Str' => where { m{^[\w/_.-]{1,80}\z} } => message { "I don't trust file name '$_'" }; has logfile => ( traits => [qw( Untaint )], is => 'rw', isa => 'FilePath', default => '/var/log/walrus.log', );

    Or if you want to allow any untainted value:

    subtype 'FilePath' => as 'Str' => where { !tainted($_) || m{^[\w/_.-]{1,80}\z} } => message { "I don't trust file name '$_'" }; has logfile => ( traits => [qw( Untaint )], is => 'rw', isa => 'FilePath', default => '/var/log/walrus.log', );

    However, I don't see anything like that on CPAN, and writing it is bound to be a bit complex. Instead, you could use coercion.

    subtype 'FilePath' => as 'Str' => where { m{^[\w/_.-]{1,80}\z} } => message { "I don't trust file name '$_'" }; coerce 'FilePath' => from 'Str' => via { /(.*)/s; $1 }; # Will be validated soon. has logfile => ( is => 'rw', isa => 'FilePath', default => '/var/log/walrus.log', coerce => 1, );

    As you can see, it's a bit icky since the tainting has to be removed before the validation. Also, it prevents having a looser check when the value isn't tainted.

    Untested.

    Notes:

    • Removed useless captures from regex patterns for speed.
    • Substituted "\z" for "$" since "$" can allow a newline.
    • "\w" is includes a suprising number of characters. You may want to pick something stricter.
    • "_" is already included in "\w".
    • Removed useless escaping from character classes for readability.

      As I have no idea how to approach this with a Trait, I've gone the coerce route. Your example almost works, with the exception that your subtype needs to check for tainted-ness in order to untaint an acceptable string. It won't do coercion if the where clause is satisfied by the original string.

      You Rule!

Re: Moose types & taint removal?
by stvn (Monsignor) on Aug 11, 2010 at 18:24 UTC

    Moose type checks won't change the value of something, for that you need coercions. Although to be totally honest I have no idea if this will do what you want or not, I don't really worry about tainting too much in my work. That said, if it doesn't work please submit a bug and test case (and a patch if you feel so inclined).

    -stvn

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://854474]
Approved by ww
Front-paged by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (4)
As of 2024-03-19 03:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found