http://www.perlmonks.org?node_id=308300


in reply to flattening a list-of-lists

1-level deep flattener which uses string eval.

sub flatten_stringeval { eval join ',', map {ref $_[$_] eq 'ARRAY' ? "\@\{\$_[$_]\}" : "\$_[$ +_]"} (0..$#_); }

This exemplifies the automatic flattening of arrays in perl list literals.

Replies are listed 'Best First'.
Re: Re: flattening a list-of-lists
by demerphq (Chancellor) on Nov 19, 2003 at 19:42 UTC

    This is an extremely scary solution. So scary that I can only assume you are joking. Please dont suggest things like this without a security disclaimer. A fresh newbie might think its a good plan then end up having their hard drive deleted or other nasty tings. And security issues aside its going to be many times slower than a subroutine based solution.

    Gee.
    Do I feel like merlyn is standing behind me or what? :-)


    ---
    demerphq

      First they ignore you, then they laugh at you, then they fight you, then you win.
      -- Gandhi


      Well, to be truly like merlyn, you would now need to post the following test case to catch people on defensive programming style too.

      my @a = \@a; flatten(\@a);

      Yes, merlyn got me on this one once in a similar thread :-)

       

      perl -le "print+unpack'N',pack'B32','00000000000000000000001010010000'"

      I wanted to make a point. Show what Perl does when you feed it code, by writing code that writes code and feeds it back to Perl, as if it were written by you :) . Of course, the obvious solution is to just take away recursion from broquaint's version:

      sub flatten { map { ref $_ eq 'ARRAY' ? @$_ : $_ } @_ }

      This is an extremely scary solution. So scary that I can only assume you are joking. Please dont suggest things like this without a security disclaimer. A fresh newbie might think its a good plan then end up having their hard drive deleted or other nasty tings.

      This sounds freaky. I'm curious, can you post an exploit against flatten_stringeval?. The only thing interpolated is $_, which iterates through (0..$#_). Everything else is quoted. Also, it checks for hard array ref before putting @{...}, so one can't play games with symbolic references (one doesn't need string eval for that, just no strict 'refs'). Maybe I'm missing something...

        This sounds freaky. I'm curious, can you post an exploit against flatten_stringeval?.

        No. Your code actually is safe. (I have to admit it took some time for me to convince myself of this.) However the point I make is valid. Using eval for things like this is an extremely dangerous thing. A very subtle error could open an exploit. (Have a hunt around the archives, merlyn has stung people a few times this way, as have others.)

        As you point out here, everything is quoted correctly, and you arent actually interpolating values in the eval. However only slight changes to your code, an omitted backslash, etc could cause huge problems. If you had said "Note particularly that we dont allow interpolation of raw data to avoid potential security problems" or something to that effect I wouldnt have said a thing. Sometimes its not necessarily sufficient to post something that is correct. If its dangerous but correct you should IMO explain how to do it safely. (And why you are posting it.)

        However I do feel I owe you an apology. This is the second time in a short time that I have misread one of your posts. I promise ill read your nodes more closely, but do you think you could be a little clearer? Even realizing that you have in fact avoided the eval trap I would have replied pointing out how thin the ice is in this area. (As you didnt.)

        Anyway, cheers. :-)


        ---
        demerphq

          First they ignore you, then they laugh at you, then they fight you, then you win.
          -- Gandhi