You can insert your program's STDIN filehandle into the compartment like this:
use strict;
use warnings;
use 5.012;
use Safe;
if($ARGV[0]) {
my $code = $ARGV[0];
my $compartment = Safe->new;
my $namespace_name = $compartment->root();
{
no strict;
*{$namespace_name . "::STDIN"} = *main::STDIN;
}
$compartment->deny_only(qw(chdir)); #<----CHECK THIS***
$compartment->reval($code);
if ($@) {
print "Unsafe code detected: $@";
}
}
--output:--
$ $ perl 2.pl '
print "Enter some stdin: ";
my $line = <STDIN>;
print "From STDIN: $line";
'
Enter some stdin: hello
From STDIN: hello
But I can't figure out how to permit_only() what is necessary for the line input operator(<$infile>) to work. I tried permit_only(qw{ print <> }), which produced the error:
Unknown operator prefix "<>"
And because perlop says:
<FILEHANDLE> may also be spelled readline(*FILEHANDLE).
I tried permit_only(qw{ print readline }), but that produced this error:
Unsafe code detected: 'private value' trapped by operation mask at (ev
+al 5) line 1.
use strict;
use warnings;
use 5.012;
use Safe;
if($ARGV[0]) {
my $code = $ARGV[0];
my $compartment = Safe->new;
my $namespace_name = $compartment->root();
{
no strict;
*{$namespace_name . "::STDIN"} = *main::STDIN;
}
$compartment->permit_only(qw(print readline));
$compartment->reval($code);
if ($@) {
print "Unsafe code detected: $@";
}
}
--output:--
$ perl 2.pl '
print "Enter some stdin: ";
my $line = readline *STDIN;
print "From STDIN: $line";
'
Unsafe code detected: 'private value' trapped by operation mask at (ev
+al 5) line 1.