Subject: | 5.14-->5.18: Unexpected changes with Safe.pm and opcodes, esp. eq |
[Originally posted to the p5p mailing list: http://www.nntp.perl.org/group/perl.perl5.porters/2013/10/msg208561.html]
We're currently smoking one of our apps at work for a proposed move from
5.14.4 to 5.18.[01]
Some of the code uses Safe.pm.
One of our devs wrote a series of tests to ensure that this always behaved
in ways we expected. It transpires that it no longer does.
Below is some example output of a test case:
- running on 5.14, passing
- running on 5.18, failing
- running on 5.18 after allowing 'rv2gv' to the permit only list
As the test should only be performing an eq I'm not sure where the need for
rv2gv comes from.
[The rv2gv turns a reference to the filehandle FILE into a GV, so that
print can print to it, and the final child is the constant "hi\n". -
http://www.faqs.org/docs/perl5int/ops.html]
The opcodes appear to have changed slightly between 5.14 and 5.18 but the
meaning is beyong my current understanding:
e.g.
https://metacpan.org/source/FLORA/perl-5.14.2/regen/opcodes#L147
eq numeric eq (==) ck_null Iifs2 S S
https://metacpan.org/source/RJBS/perl-5.18.1/regen/opcodes#L149
eq numeric eq (==) ck_null Iifs2 S S<
That block has a few opcodes with 'S' --> 'S<'
Obviously we could allow rv2gv in our use of Safe.pm but it seems strange
that we'd need to and I'd prefer to know why before I do, or if there's a
bug, or if we've just done something really silly.
Thanks in advance,
Chisel
__DATA__
---- 5.14 passing ----
$ perl -v |grep This
This is perl 5, version 14, subversion 4 (v5.14.4) built for x86_64-linux
$ cat foo.pl
#!/opt/xt/xt-perl/bin/perl
use strict;
use warnings;
use Safe;
my $compartment = Safe->new();
$compartment->permit_only(
qw[ padany lineseq const leaveeval eq i_eq seq ]
);
my $result = $compartment->reval('1 eq 1');
die "safe compartment initialisation error: $@" if $@;
print "all OK\n";
$ perl foo.pl
all OK
$
---- 5.18, failing ----
$ perl -v |grep This
This is perl 5, version 18, subversion 0 (v5.18.0) built for x86_64-linux
$ cat foo.pl
#!/opt/xt/xt-perl/bin/perl
use strict;
use warnings;
use Safe;
my $compartment = Safe->new();
$compartment->permit_only(
qw[ padany lineseq const leaveeval eq i_eq seq ]
);
my $result = $compartment->reval('1 eq 1');
die "safe compartment initialisation error: $@" if $@;
print "all OK\n";
$ perl foo.pl
safe compartment initialisation error: 'ref-to-glob cast' trapped by
operation mask at (eval 5) line 1.
$
---- 5.18.0 failing ----
$ perl -v |grep This
This is perl 5, version 18, subversion 0 (v5.18.0) built for x86_64-linux
$ cat foo.pl
#!/opt/xt/xt-perl/bin/perl
use strict;
use warnings;
use Safe;
my $compartment = Safe->new();
$compartment->permit_only(
qw[ padany lineseq const leaveeval eq i_eq seq ]
);
my $result = $compartment->reval('1 eq 1');
die "safe compartment initialisation error: $@" if $@;
print "all OK\n";
$ perl foo.pl
safe compartment initialisation error: 'ref-to-glob cast' trapped by
operation mask at (eval 5) line 1.
$
---- 5.18.0, passing with rv2gv ----
$ diff -Nau foo{,-518}.pl
--- foo.pl 2013-10-11 18:31:27.000000000 +0100
+++ foo-518.pl 2013-10-11 18:38:05.000000000 +0100
@@ -6,7 +6,7 @@
my $compartment = Safe->new();
$compartment->permit_only(
- qw[ padany lineseq const leaveeval eq i_eq seq ]
+ qw[ padany lineseq const leaveeval eq i_eq seq rv2gv]
);
my $result = $compartment->reval('1 eq 1');
$ perl -v |grep This
This is perl 5, version 18, subversion 0 (v5.18.0) built for x86_64-linux
$ perl foo.pl
safe compartment initialisation error: 'ref-to-glob cast' trapped by
operation mask at (eval 5) line 1.
$ perl foo-518.pl
all OK
$
---- 5.18.1, same behaviour as 5.18.0 ----
$ diff -Nau foo{,-518}.pl
--- foo.pl 2013-10-11 18:39:43.000000000 +0100
+++ foo-518.pl 2013-10-11 18:39:43.000000000 +0100
@@ -6,7 +6,7 @@
my $compartment = Safe->new();
$compartment->permit_only(
- qw[ padany lineseq const leaveeval eq i_eq seq ]
+ qw[ padany lineseq const leaveeval eq i_eq seq rv2gv]
);
my $result = $compartment->reval('1 eq 1');
$ perl -v |grep This
This is perl 5, version 18, subversion 1 (v5.18.1) built for x86_64-linux
$ perl foo.pl
safe compartment initialisation error: 'ref-to-glob cast' trapped by
operation mask at (eval 5) line 1.
$ perl foo-518.pl
all OK
$