http://qs1969.pair.com?node_id=11137061


in reply to Re: loop iterator in a string
in thread loop iterator in a string

Oh that's brilliant Rolf! I totally forgot about eval. This is definitely good enough for my use case. Thank you!

Replies are listed 'Best First'.
Re^3: loop iterator in a string
by haukex (Archbishop) on Sep 27, 2021 at 18:54 UTC

    Please be aware that eval with anything other than a fixed, literal string (i.e. no variables interpolated in) has the potential to introduce security issues or other subtle bugs.

      I think rejecting any $str containing anything which isn't a cipher, comma or dot prior to eval $str should be good enough

      DB<53> $EVIL= ',@{[say "kill all kitties!"]}' DB<54> $str = "2,4..9" DB<55> p $str =~ m/[^0-9,.]/ # OK DB<56> $str .= $EVIL DB<57> p $str =~ m/[^0-9,.]/ # NOT OK 1 DB<58> eval $str kill all kitties!

      update

      in order to avoid syntax error you need to check $@ to see if the eval was successful. NB line 82, not all errors are caught tho

      DB<80> @list = eval ",1..3"; unless($@){say for @list } DB<81> @list = eval "1..3"; unless($@){say for @list } 1 2 3 DB<82> @list = eval "1.3"; unless($@){say for @list } 1.3

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        I think rejecting any $str containing anything which isn't a cipher, comma or dot prior to eval $str should be good enough

        Not quite, since it would also accept ",....," and other things like that (one of the things I meant with "other subtle bugs"). Personally I would suggest both a regex like /\A(\d+(?:\.\.\d+)?)(?:,(?1))*\z/ and checking eval for errors. And at that level, the complexity is high enough that something like* tybalt89's solution is probably better.

        * Update: By which I mean, something like tybalt89's solution with some added error checking ;-)