develooper Front page | perl.perl5.porters | Postings from October 2013

5.14-->5.18: Unexpected changes with Safe.pm and opcodes, esp. eq

Thread Next
From:
Chisel
Date:
October 11, 2013 17:44
Subject:
5.14-->5.18: Unexpected changes with Safe.pm and opcodes, esp. eq
Message ID:
CAKp-Mas-6ULv2yW6SaKq_HLFh3+_RAWU2sxb5aWauJyShWVBfA@mail.gmail.com
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
$

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About