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

Fellow monks,

I've run into a wall again with my Tk programming.

Given the following code:

my $canvas = $frame2 ->Canvas( -bg=>COLOR, -height=>$height, -width=>$width, )->pack();

I've set $height and $width prior to it ever seeing that, so why does that keep giving me this error:

Arg 5 to `.frame1.canvas' (300) is tainted at C:/Perl/site/lib/Tk/Widget.pm line 196.

If I go in and physically set the canvas dimension, it all works just fine, but I want to have a dynamic canvas - if possible.

Any help would be appreciated!

Edit ar0n -- title change

Replies are listed 'Best First'.
Re: Another day, another Tk question
by samtregar (Abbot) on Apr 29, 2002 at 21:46 UTC
    Ok, I'll bite: $width is tainted. That means it came from an external source - a file, a socket, an environment variable, something. If you put this code above that call I bet it will work again:

    $width = 100; $height = 100;

    Now, as for why $width is tainted, I can't tell. You didn't post the code that sets $width so I can only guess.

    -sam

      Yes it does work if I hard code the variables.

      The code to get $height and $width is:

      sub getfilesize{ my @spec=(); open FH, $file; for (0..9){$spec[$_] = getc(FH);} close FH; my $tmp1 = unpack("H2",$spec[7]).unpack("H2",$spec[6]); my $tmp2 = unpack("H2",$spec[9]).unpack("H2",$spec[8]); $width = unpack('s',pack('s',hex($tmp2))); $height = unpack('s',pack('s',hex($tmp1))); }

      I know it's a bit screwy, but I just need to get the filesize out of a gif, no other format, so I thought writing the quick bit would be easier than plugging in a whole module.

      Given that, can you tell me why it's tainted? I'm lost on that one.

      Thanks!

        Given that, can you tell me why it's tainted?

        Short answer: read perlsec.

        Long answer: @spec comes from file so it gets tainted. $tmp1 and $tmp2 are derived from @spec so they become tainted too. And $width with $height become tainted because they are derived from $tmp1 and $tmp2.

        If you want to unaint $width and $height your code should look like:

        sub getfilesize{ my @spec=(); open FH, $file; for (0..9){$spec[$_] = getc(FH);} close FH; my $tmp1 = unpack("H2",$spec[7]).unpack("H2",$spec[6]); my $tmp2 = unpack("H2",$spec[9]).unpack("H2",$spec[8]); $width = unpack('s',pack('s',hex($tmp2))); ($width) = $width =~ /(\d+)/; $height = unpack('s',pack('s',hex($tmp1))); ($height) = $height =~ /(\d+)/; }

        BTW if you are looking for simplicity just use Image::Size:

        use Image::Size; my ($width, $height) = imgsize($file); ($width) = $width =~ /(\d+)/; ($height) = $height =~ /(\d+)/;

        P.S. It is unrelated to your question but you are using bad coding practices in your code. You are using global variables without need: to pass parameters to sub ($file) and to return data from the sub ($width and $height). It is better to rewrite you sub this way:

        sub getfilesize{ my $file = shift; my @spec=(); open FH, $file; for (0..9){$spec[$_] = getc(FH);} close FH; my $tmp1 = unpack("H2",$spec[7]).unpack("H2",$spec[6]); my $tmp2 = unpack("H2",$spec[9]).unpack("H2",$spec[8]); my $width = unpack('s',pack('s',hex($tmp2))); ($width) = $width =~ /(\d+)/; my $height = unpack('s',pack('s',hex($tmp1))); ($height) = $height =~ /(\d+)/; return ($width, $height); } # example of sub call my ($width, $height) = getfilesize('/path/to/file.gif');

        --
        Ilya Martynov (http://martynov.org/)

        You need to read perlsec. After that it should be obvious why $width and $height are tainted. The short version: data coming from external sources is always tainted and will cause errors when running under -T.

        -sam

Re: Another day, another Tk question
by Popcorn Dave (Abbot) on Apr 29, 2002 at 23:27 UTC
    Thanks for all the help!

    For whatever reason, this is the first time that I've run in to this error.

    I'm off to read perlsec right now!!

    Thanks again!