Remove :base_io from the set of default "safe" opcodes.
[p5sagit/p5-mst-13.2.git] / ext / Safe / t / safe2.t
1 #!./perl -w
2 $|=1;
3 BEGIN {
4     if($ENV{PERL_CORE}) {
5         chdir 't' if -d 't';
6         @INC = '../lib';
7     } 
8     require Config; import Config;
9     if ($Config{'extensions'} !~ /\bOpcode\b/ && $Config{'osname'} ne 'VMS') {
10         print "1..0\n";
11         exit 0;
12     }
13 }
14
15 # Tests Todo:
16 #       'main' as root
17
18 use vars qw($bar);
19
20 use Opcode 1.00, qw(opdesc opset opset_to_ops opset_to_hex
21         opmask_add full_opset empty_opset opcodes opmask define_optag);
22
23 use Safe 1.00;
24
25 my $last_test; # initalised at end
26 print "1..$last_test\n";
27
28 # Set up a package namespace of things to be visible to the unsafe code
29 $Root::foo = "visible";
30 $bar = "invisible";
31
32 # Stop perl from moaning about identifies which are apparently only used once
33 $Root::foo .= "";
34
35 my $cpt;
36 # create and destroy a couple of automatic Safe compartments first
37 $cpt = new Safe or die;
38 $cpt = new Safe or die;
39
40 $cpt = new Safe "Root";
41
42 $cpt->permit(qw(:base_io));
43
44 $cpt->reval(q{ system("echo not ok 1"); });
45 if ($@ =~ /^'?system'? trapped by operation mask/) {
46     print "ok 1\n";
47 } else {
48     print "#$@" if $@;
49     print "not ok 1\n";
50 }
51
52 $cpt->reval(q{
53     print $foo eq 'visible'             ? "ok 2\n" : "not ok 2\n";
54     print $main::foo  eq 'visible'      ? "ok 3\n" : "not ok 3\n";
55     print defined($bar)                 ? "not ok 4\n" : "ok 4\n";
56     print defined($::bar)               ? "not ok 5\n" : "ok 5\n";
57     print defined($main::bar)           ? "not ok 6\n" : "ok 6\n";
58 });
59 print $@ ? "not ok 7\n#$@" : "ok 7\n";
60
61 $foo = "ok 8\n";
62 %bar = (key => "ok 9\n");
63 @baz = (); push(@baz, "o", "10"); $" = 'k ';
64 $glob = "ok 11\n";
65 @glob = qw(not ok 16);
66
67 sub sayok { print "ok @_\n" }
68
69 $cpt->share(qw($foo %bar @baz *glob sayok));
70 $cpt->share('$"') unless $Config{use5005threads};
71
72 $cpt->reval(q{
73     package other;
74     sub other_sayok { print "ok @_\n" }
75     package main;
76     print $foo ? $foo : "not ok 8\n";
77     print $bar{key} ? $bar{key} : "not ok 9\n";
78     (@baz) ? print "@baz\n" : print "not ok 10\n";
79     print $glob;
80     other::other_sayok(12);
81     $foo =~ s/8/14/;
82     $bar{new} = "ok 15\n";
83     @glob = qw(ok 16);
84 });
85 print $@ ? "not ok 13\n#$@" : "ok 13\n";
86 $" = ' ';
87 print $foo, $bar{new}, "@glob\n";
88
89 $Root::foo = "not ok 17";
90 @{$cpt->varglob('bar')} = qw(not ok 18);
91 ${$cpt->varglob('foo')} = "ok 17";
92 @Root::bar = "ok";
93 push(@Root::bar, "18"); # Two steps to prevent "Identifier used only once..."
94
95 print "$Root::foo\n";
96 print "@{$cpt->varglob('bar')}\n";
97
98 use strict;
99
100 print 1 ? "ok 19\n" : "not ok 19\n";
101 print 1 ? "ok 20\n" : "not ok 20\n";
102
103 my $m1 = $cpt->mask;
104 $cpt->trap("negate");
105 my $m2 = $cpt->mask;
106 my @masked = opset_to_ops($m1);
107 print $m2 eq opset("negate", @masked) ? "ok 21\n" : "not ok 21\n";
108
109 print eval { $cpt->mask("a bad mask") } ? "not ok 22\n" : "ok 22\n";
110
111 print $cpt->reval("2 + 2") == 4 ? "ok 23\n" : "not ok 23\n";
112
113 $cpt->mask(empty_opset);
114 my $t_scalar = $cpt->reval('print wantarray ? "not ok 24\n" : "ok 24\n"');
115 print $cpt->reval('@ary=(6,7,8);@ary') == 3 ? "ok 25\n" : "not ok 25\n";
116 my @t_array  = $cpt->reval('print wantarray ? "ok 26\n" : "not ok 26\n"; (2,3,4)');
117 print $t_array[2] == 4 ? "ok 27\n" : "not ok 27\n";
118
119 my $t_scalar2 = $cpt->reval('die "foo bar"; 1');
120 print defined $t_scalar2 ? "not ok 28\n" : "ok 28\n";
121 print $@ =~ /foo bar/ ? "ok 29\n" : "not ok 29\n";
122
123 # --- rdo
124   
125 my $t = 30;
126 $! = 0;
127 my $nosuch = '/non/existant/file.name';
128 open(NOSUCH, $nosuch);
129 if ($@) {
130     my $errno  = $!;
131     die "Eek! Attempting to open $nosuch failed, but \$! is still 0" unless $!;
132     $! = 0;
133     $cpt->rdo($nosuch);
134     print $! == $errno ? "ok $t\n" : sprintf "not ok $t # \"$!\" is %d (expected %d)\n", $!, $errno; $t++;
135 } else {
136     die "Eek! Didn't expect $nosuch to be there.";
137 }
138 close(NOSUCH);
139
140 # test #31 is gone.
141 print "ok $t\n"; $t++;
142   
143 #my $rdo_file = "tmp_rdo.tpl";
144 #if (open X,">$rdo_file") {
145 #    print X "999\n";
146 #    close X;
147 #    $cpt->permit_only('const', 'leaveeval');
148 #    print  $cpt->rdo($rdo_file) == 999 ? "ok $t\n" : "not ok $t\n"; $t++;
149 #    unlink $rdo_file;
150 #}
151 #else {
152 #    print "# test $t skipped, can't open file: $!\nok $t\n"; $t++;
153 #}
154
155
156 print "ok $last_test\n";
157 BEGIN { $last_test = 32 }