This works.
$ perl -T -wle 'my $hash = {}; use Taint::Util; taint($hash); print
tainted($hash);'
1
This doesn't.
$ perl -T -wle 'my %hash; use Taint::Util; taint(\%hash); print
tainted(\%hash);'
This might seem a bit esoteric, but I'm putting together a universal set
of taint methods for perl5i. When combined with autobox this becomes
important because $hash_ref->taint works but %hash->taint does not.

> of taint methods for perl5i. When combined with autobox this becomes
> important because $hash_ref->taint works but %hash->taint does not.

I think this happens because those two occurrences of \%hash aren't the
same thing internally. I.e. they're different scalars when seen by Perl.
If you use a temporary variable then you'd get true out of tainted():
v taint-util (master) $ perl -T -wle 'my %hash; use Taint::Util; my $t =
\%hash; taint(\%hash); print int tainted(\%hash);'
0
v taint-util (master) $ perl -T -wle 'my %hash; use Taint::Util; my $t =
\%hash; taint($t); print int tainted($t);'
1
But regardless I'm open to implementing whatever it is you want, I just
don't understand what that is. Taint::Util is just a dumb wrapper for
Perl's SvTAINTED_on() and SvTAINTED(sv), when you do
SvTAINTED_on(\%hash) Perl doesn't think another reference to the same
hash is tainted when you do SvTAINTED(\%hash) later.
Do you want the hash to be automatically de-referenced or something? And
if so isn't that magic that should be implemented at a higher level?

> But regardless I'm open to implementing whatever it is you want, I just
> don't understand what that is. Taint::Util is just a dumb wrapper for
> Perl's SvTAINTED_on() and SvTAINTED(sv), when you do
> SvTAINTED_on(\%hash) Perl doesn't think another reference to the same
> hash is tainted when you do SvTAINTED(\%hash) later.
>
> Do you want the hash to be automatically de-referenced or something? And
> if so isn't that magic that should be implemented at a higher level?

Ideally, I'd like it to just work with whatever XS voodoo is necessary.
Let me go into a bit more background.
What's happening is I've written a UNIVERSAL::taint and untaint methods and
I'm using autobox. So %hash->taint and %hash->untaint "work" but I suppose
autobox is using the equivalent of \%hash as the invocant so it doesn't work.
You can see the code for that here.
http://github.com/schwern/perl5i/commit/84037974901e81d09925f8f0ae3078b014981a82
I was actually surprised that you can set taint on a non-scalar at all. My
original plan was to just make $object->untaint() a no-op and $object->taint()
die. They'd only really work on autoboxed scalars. I'm not entirely sure
that the ability to taint and untaint non-scalars is useful.
So the alternative is to convince me (or make be convince myself) that being
able to taint non-scalars isn't worth the trouble.
--
44. I am not the atheist chaplain.
-- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army
http://skippyslist.com/list/

> > But regardless I'm open to implementing whatever it is you want, I

> just

> > don't understand what that is. Taint::Util is just a dumb wrapper

> for

> > Perl's SvTAINTED_on() and SvTAINTED(sv), when you do
> > SvTAINTED_on(\%hash) Perl doesn't think another reference to the

> same

> > hash is tainted when you do SvTAINTED(\%hash) later.
> >
> > Do you want the hash to be automatically de-referenced or something?

> And

> > if so isn't that magic that should be implemented at a higher level?

>
> Ideally, I'd like it to just work with whatever XS voodoo is
> necessary.
>
> Let me go into a bit more background.
>
> What's happening is I've written a UNIVERSAL::taint and untaint
> methods and
> I'm using autobox. So %hash->taint and %hash->untaint "work" but I
> suppose
> autobox is using the equivalent of \%hash as the invocant so it
> doesn't work.
>
> You can see the code for that here.
>

>
> I was actually surprised that you can set taint on a non-scalar at
> all. My
> original plan was to just make $object->untaint() a no-op and $object-

> >taint()

> die. They'd only really work on autoboxed scalars. I'm not entirely
> sure
> that the ability to taint and untaint non-scalars is useful.
>
> So the alternative is to convince me (or make be convince myself) that
> being
> able to taint non-scalars isn't worth the trouble.

I've never actually used tainting, I just wrote module to deal with it
because I thought being forced to use regexes to deal with tainted data
sucked.
Tainting in Perl was always meant to be used for potentially hostile
external data passed to the program. Perl is passed a soup of strings
from the outside but never complex datatypes. So %ENV would have tainted
strings, getting filehandles like <STDIN> would produce tainted strings
etc.
Internally the interpreter is careful about what gets marked tainted in
the first place and only a selected things can become tainted. E.g. some
manual checking in the ucfirst operator ensures that the result of
C<ucfirst $i'm_tainted> will be tainted as well.
But since Taint::Util is exposing some of perl's guts via things get
more complex. Tainting is implemented via perl's MAGIC facility and you
can attach magic to any scalar, but because perl would never do that
it's not there to back you up.
You can taint(*DATA) for example and tainted(*DATA) will subsequently be
true but if you read from the filehandle via <DATA> you'll get untainted
data.
See http://github.com/avar/taint-util/blob/master/t/usage.t for a bunch
of these odd edge cases.
If you step back and actually look at why you would even use tainting in
the first place in code like perl5i which is targeted at users it's
because when you taint a value perl will back you up when you use it,
e.g. it will slap your hand if you try to pass a tainted value to
system().
If you taint references perl doesn't offer that protection because it
doesn't know anything about tainted references because it would never
create one. The things that do work like the stringification of
C<taint($t = [])> (i.e. ARRAY(0x11a5d48)) being tainted only work
incidentally.
I think what you should do in your code is to die loudly of someone
tries to taint a reference, and I shouldn't do anything because I'd like
to offer module authors such as yourself the opportunity to shoot
yourselves in the foot if that's what you really want :)

> I think what you should do in your code is to die loudly of someone
> tries to taint a reference, and I shouldn't do anything because I'd like
> to offer module authors such as yourself the opportunity to shoot
> yourselves in the foot if that's what you really want :)

Yeah, you're right. That was the original plan, die if someone tries to taint
a reference. I got a little crazy with the cheez-whiz when I realized it Just
Worked.
Consider this bug dropped.
BTW Taint.pm has some code in it to prevent calling taint() on anything but a
scalar if you're interested in incorporating that feature.
--
Stabbing you in the face so you don't have to.

> > I think what you should do in your code is to die loudly of someone
> > tries to taint a reference, and I shouldn't do anything because I'd

> like

> > to offer module authors such as yourself the opportunity to shoot
> > yourselves in the foot if that's what you really want :)

>
> Yeah, you're right. That was the original plan, die if someone tries
> to taint
> a reference. I got a little crazy with the cheez-whiz when I realized
> it Just
> Worked.
>
> Consider this bug dropped.

Ok, marking it as such.
Show quoted text

> BTW Taint.pm has some code in it to prevent calling taint() on
> anything but a
> scalar if you're interested in incorporating that feature.

I'd rather just keep it as a dry interface to SvTAINTED*() especially
since the only people that use this module are doing Dark Magic and can
probably fend for themselves. I'm going to add some documentation though
to explain the sillyness of reference tainting.