Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Untainting a blessed hash member with or without the delete

Tags:

hash

perl

taint

I saw this line of code in some sources

( $self->{arg} ) = ( ( delete $self->{arg} ) =~ /(.*)/s ) if ${^TAINT}; 

I understand the untainting. I also known delete

My question is, in what circumstances is it necessary or preferred to use the delete, and isn't it enough to use the simpler

( $self->{arg} ) = ( ( $self->{arg} ) =~ /(.*)/s ) if ${^TAINT};

For example

#!/usr/bin/env perl -T

use 5.014;
use warnings;

package Some {
    use Moose;
    has 'arg' => (is => 'rw', isa => 'Str');
    sub doit {
        my $self = shift;
        #( $self->{arg} ) = ( ( delete $self->{arg} ) =~ /(.*)/s ) if ${^TAINT};
        ( $self->{arg} ) = ( ( $self->{arg} ) =~ /(.*)/s ) if ${^TAINT};
    }
};

my $some = Some->new( arg => 'some text' );
$some->doit();
say $some->arg;
like image 889
jm666 Avatar asked Nov 15 '15 09:11

jm666


1 Answers

With a normal hash deleting the value and reinserting will give the same result as modifying it in place.

The commit does not give any information about why he deletes it just that he copies the functionality from Mason 1. But if you look at the source of HTML::Mason::Lexer, you will find this comment:

We need to untaint the component or else the regexes will fail to a Perl bug. The delete is important because we need to create an entirely new scalar, not just modify the existing one.

($current->{comp_source}) = (delete $current->{comp_source}) =~ /(.*)/s if taint_is_on;

So the reason of doing it this way is to have a new scalar, although he does not do that for the other place where he is untainting: Mason::Interp, so my guess is an earlier Perl bug, when untainting.

So the difference is that with delete will give you a new scalar, although this will seldom have a practical application. (Delete and insert is also a slower operation of course.)

use strict;
my $hash->{test} = 'test';
print \($hash->{test}),"\n";
( $hash->{test} ) = ( ( $hash->{test} ) =~ /(.*)/s );
print \($hash->{test}),"\n";
( $hash->{test} ) = ( ( delete $hash->{test} ) =~ /(.*)/s );
print \($hash->{test}),"\n";

gives

SCALAR(0x7f84d10047e8)
SCALAR(0x7f84d10047e8)
SCALAR(0x7f84d1029230)
like image 181
bolav Avatar answered Oct 20 '22 02:10

bolav