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
|