1b39c5158Smillert#!perl 2b39c5158Smillert# Tests that all ops can be trapped by a Safe compartment 3b39c5158Smillert 4b39c5158SmillertBEGIN { 5b39c5158Smillert unless ($ENV{PERL_CORE}) { 6b39c5158Smillert # this won't work outside of the core, so exit 7b39c5158Smillert print "1..0 # skipped: PERL_CORE unset\n"; exit 0; 8b39c5158Smillert } 9b39c5158Smillert} 10b39c5158Smillertuse Config; 11b39c5158SmillertBEGIN { 12b39c5158Smillert if ($Config{'extensions'} !~ /\bOpcode\b/ && $Config{'osname'} ne 'VMS') { 13b39c5158Smillert print "1..0\n"; exit 0; 14b39c5158Smillert } 15898184e3Ssthen 16898184e3Ssthen # We need test.pl for runperl(). Since this test script is only run in 17898184e3Ssthen # the perl core, this should be fine: 18898184e3Ssthen require '../../t/test.pl'; 19b39c5158Smillert} 20b39c5158Smillert 21b39c5158Smillertuse strict; 22b39c5158Smillertuse Safe; 23b39c5158Smillert 24b39c5158Smillert# Read the op names and descriptions directly from opcode.pl 25b39c5158Smillertmy @op; 26b39c5158Smillertmy %code; 27b39c5158Smillert 28b39c5158Smillertwhile (<DATA>) { 29b39c5158Smillert chomp; 30b39c5158Smillert die "Can't match $_" unless /^([a-z_0-9]+)\t+(.*)/; 31b39c5158Smillert $code{$1} = $2; 32b39c5158Smillert} 33b39c5158Smillert 34898184e3Ssthenopen my $fh, '<', '../../regen/opcodes' or die "Can't open opcodes: $!"; 35b39c5158Smillertwhile (<$fh>) { 36b39c5158Smillert chomp; 37b39c5158Smillert next if !$_ or /^#/; 38b39c5158Smillert my ($op, $opname) = split /\t+/; 39b39c5158Smillert push @op, [$op, $opname, $code{$op}]; 40b39c5158Smillert} 41b39c5158Smillertclose $fh; 42b39c5158Smillert 4391f110e0Safresh1plan(tests => scalar @op + 3); 44b39c5158Smillert 45b39c5158Smillertsub testop { 46b39c5158Smillert my ($op, $opname, $code) = @_; 47b39c5158Smillert pass("$op : skipped") and return if $code =~ /^SKIP/; 48b39c5158Smillert pass("$op : skipped") and return if $code =~ m://|~~: && $] < 5.010; 49b39c5158Smillert my $c = new Safe; 50b39c5158Smillert $c->deny_only($op); 51b39c5158Smillert $c->reval($code); 52b39c5158Smillert like($@, qr/'\Q$opname\E' trapped by operation mask/, $op); 53b39c5158Smillert} 54b39c5158Smillert 55b39c5158Smillertforeach (@op) { 56b39c5158Smillert if ($_->[2]) { 57b39c5158Smillert testop @$_; 58b39c5158Smillert } else { 59b8851fccSafresh1 local our $TODO = "No test yet for $_->[0] ($_->[1])"; 60b39c5158Smillert fail(); 61b39c5158Smillert } 62b39c5158Smillert} 63b39c5158Smillert 64898184e3Ssthen# Test also that the errors resulting from disallowed ops do not cause 65898184e3Ssthen# ‘Unbalanced’ warnings. 66898184e3Ssthen{ 67898184e3Ssthen local $ENV{PERL_DESTRUCT_LEVEL}=2; 68898184e3Ssthen unlike 69898184e3Ssthen runperl( 70898184e3Ssthen switches => [ '-MSafe', '-w' ], 71898184e3Ssthen prog => 'Safe->new->reval(q(use strict))', 72898184e3Ssthen stderr => 1, 73898184e3Ssthen ), 74898184e3Ssthen qr/Unbalanced/, 75898184e3Ssthen 'No Unbalanced warnings when disallowing ops'; 76898184e3Ssthen unlike 77898184e3Ssthen runperl( 78898184e3Ssthen switches => [ '-MSafe', '-w' ], 79898184e3Ssthen prog => 'Safe->new->reval(q(use strict), 1)', 80898184e3Ssthen stderr => 1, 81898184e3Ssthen ), 82898184e3Ssthen qr/Unbalanced/, 83898184e3Ssthen 'No Unbalanced warnings when disallowing ops'; 8491f110e0Safresh1 unlike 8591f110e0Safresh1 runperl( 8691f110e0Safresh1 switches => [ '-MSafe', '-w' ], 8791f110e0Safresh1 prog => 'Safe->new->reval(' 8891f110e0Safresh1 . 'q(BEGIN{$^H{foo}=bar};use strict), 0' 8991f110e0Safresh1 .')', 9091f110e0Safresh1 stderr => 1, 9191f110e0Safresh1 ), 9291f110e0Safresh1 qr/Unbalanced/, 9391f110e0Safresh1 'No Unbalanced warnings when disallowing ops with %^H set'; 94898184e3Ssthen} 95898184e3Ssthen 96b39c5158Smillert# things that begin with SKIP are skipped, for various reasons (notably 97b39c5158Smillert# optree modified by the optimizer -- Safe checks are done before the 98b39c5158Smillert# optimizer modifies the optree) 99b39c5158Smillert 100b39c5158Smillert__DATA__ 101b39c5158Smillertnull SKIP 102b39c5158Smillertstub SKIP 103b39c5158Smillertscalar scalar $x 104b39c5158Smillertpushmark print @x 105b39c5158Smillertwantarray wantarray 106b39c5158Smillertconst 42 107b39c5158Smillertgvsv SKIP (set by optimizer) $x 108b39c5158Smillertgv SKIP *x 109b39c5158Smillertgelem *x{SCALAR} 110b39c5158Smillertpadsv SKIP my $x 111b39c5158Smillertpadav SKIP my @x 112b39c5158Smillertpadhv SKIP my %x 113b39c5158Smillertpadany SKIP (not implemented) 114b39c5158Smillertrv2gv *x 115b39c5158Smillertrv2sv $x 116b39c5158Smillertav2arylen $#x 117b39c5158Smillertrv2cv f() 118b39c5158Smillertanoncode sub { } 119b39c5158Smillertprototype prototype 'foo' 120b39c5158Smillertrefgen \($x,$y) 121b39c5158Smillertsrefgen SKIP \$x 122b39c5158Smillertref ref 123b39c5158Smillertbless bless 124b39c5158Smillertbacktick qx/ls/ 125b39c5158Smillertglob <*.c> 126b39c5158Smillertreadline <FH> 127b39c5158Smillertrcatline SKIP (set by optimizer) $x .= <F> 128b39c5158Smillertregcmaybe SKIP (internal) 129b39c5158Smillertregcreset SKIP (internal) 130b39c5158Smillertregcomp SKIP (internal) 131b39c5158Smillertmatch /foo/ 132b39c5158Smillertqr qr/foo/ 133b39c5158Smillertsubst s/foo/bar/ 134b39c5158Smillertsubstcont SKIP (set by optimizer) 135b39c5158Smillerttrans y:z:t: 136b39c5158Smillertsassign $x = $y 137b39c5158Smillertaassign @x = @y 138b39c5158Smillertchop chop @foo 139b39c5158Smillertschop chop 140b39c5158Smillertchomp chomp @foo 141b39c5158Smillertschomp chomp 142b39c5158Smillertdefined defined 143b39c5158Smillertundef undef 144b39c5158Smillertstudy study 145b39c5158Smillertpos pos 146b39c5158Smillertpreinc ++$i 147b39c5158Smillerti_preinc SKIP (set by optimizer) 148b39c5158Smillertpredec --$i 149b39c5158Smillerti_predec SKIP (set by optimizer) 150b39c5158Smillertpostinc $i++ 151b39c5158Smillerti_postinc SKIP (set by optimizer) 152b39c5158Smillertpostdec $i-- 153b39c5158Smillerti_postdec SKIP (set by optimizer) 154b39c5158Smillertpow $x ** $y 155b39c5158Smillertmultiply $x * $y 156b39c5158Smillerti_multiply SKIP (set by optimizer) 157b39c5158Smillertdivide $x / $y 158b39c5158Smillerti_divide SKIP (set by optimizer) 159b39c5158Smillertmodulo $x % $y 160b39c5158Smillerti_modulo SKIP (set by optimizer) 161b39c5158Smillertrepeat $x x $y 162b39c5158Smillertadd $x + $y 163b39c5158Smillerti_add SKIP (set by optimizer) 164b39c5158Smillertsubtract $x - $y 165b39c5158Smillerti_subtract SKIP (set by optimizer) 166b39c5158Smillertconcat $x . $y 167b39c5158Smillertstringify "$x" 168b39c5158Smillertleft_shift $x << 1 169b39c5158Smillertright_shift $x >> 1 170b39c5158Smillertlt $x < $y 171b39c5158Smillerti_lt SKIP (set by optimizer) 172b39c5158Smillertgt $x > $y 173b39c5158Smillerti_gt SKIP (set by optimizer) 174b39c5158Smillertle $i <= $y 175b39c5158Smillerti_le SKIP (set by optimizer) 176b39c5158Smillertge $i >= $y 177b39c5158Smillerti_ge SKIP (set by optimizer) 178b39c5158Smillerteq $x == $y 179b39c5158Smillerti_eq SKIP (set by optimizer) 180b39c5158Smillertne $x != $y 181b39c5158Smillerti_ne SKIP (set by optimizer) 182b39c5158Smillertncmp $i <=> $y 183b39c5158Smillerti_ncmp SKIP (set by optimizer) 184b39c5158Smillertslt $x lt $y 185b39c5158Smillertsgt $x gt $y 186b39c5158Smillertsle $x le $y 187b39c5158Smillertsge $x ge $y 188b39c5158Smillertseq $x eq $y 189b39c5158Smillertsne $x ne $y 190b39c5158Smillertscmp $x cmp $y 191b39c5158Smillertbit_and $x & $y 192b39c5158Smillertbit_xor $x ^ $y 193b39c5158Smillertbit_or $x | $y 194b39c5158Smillertnegate -$x 195b39c5158Smillerti_negate SKIP (set by optimizer) 196b39c5158Smillertnot !$x 197b39c5158Smillertcomplement ~$x 198b39c5158Smillertatan2 atan2 1 199b39c5158Smillertsin sin 1 200b39c5158Smillertcos cos 1 201b39c5158Smillertrand rand 202b39c5158Smillertsrand srand 203b39c5158Smillertexp exp 1 204b39c5158Smillertlog log 1 205b39c5158Smillertsqrt sqrt 1 206b39c5158Smillertint int 207b39c5158Smillerthex hex 208b39c5158Smillertoct oct 209b39c5158Smillertabs abs 210b39c5158Smillertlength length 211b39c5158Smillertsubstr substr $x, 1 212b39c5158Smillertvec vec 213b39c5158Smillertindex index 214b39c5158Smillertrindex rindex 215b39c5158Smillertsprintf sprintf '%s', 'foo' 216b39c5158Smillertformline formline 217b39c5158Smillertord ord 218b39c5158Smillertchr chr 219b39c5158Smillertcrypt crypt 'foo','bar' 220b39c5158Smillertucfirst ucfirst 221b39c5158Smillertlcfirst lcfirst 222b39c5158Smillertuc uc 223b39c5158Smillertlc lc 224b39c5158Smillertquotemeta quotemeta 225b39c5158Smillertrv2av @a 226b39c5158Smillertaelemfast SKIP (set by optimizer) 227b39c5158Smillertaelem $a[1] 228b39c5158Smillertaslice @a[1,2] 229b39c5158Smillerteach each %h 230b39c5158Smillertvalues values %h 231b39c5158Smillertkeys keys %h 232b39c5158Smillertdelete delete $h{Key} 233b39c5158Smillertexists exists $h{Key} 234b39c5158Smillertrv2hv %h 235b39c5158Smillerthelem $h{kEy} 236b39c5158Smillerthslice @h{kEy} 2379f11ffb7Safresh1multiconcat SKIP (set by optimizer) 238b8851fccSafresh1multideref SKIP (set by optimizer) 239b39c5158Smillertunpack unpack 240b39c5158Smillertpack pack 241b39c5158Smillertsplit split /foo/ 242b39c5158Smillertjoin join $a, @b 243b39c5158Smillertlist @x = (1,2) 244b39c5158Smillertlslice SKIP @x[1,2] 245b39c5158Smillertanonlist [1,2] 246b39c5158Smillertanonhash { a => 1 } 247b39c5158Smillertsplice splice @x, 1, 2, 3 248b39c5158Smillertpush push @x, $x 249b39c5158Smillertpop pop @x 250b39c5158Smillertshift shift @x 251b39c5158Smillertunshift unshift @x 252b39c5158Smillertsort sort @x 253b39c5158Smillertreverse reverse @x 254b39c5158Smillertgrepstart grep { $_ eq 'foo' } @x 255b39c5158Smillertgrepwhile SKIP grep { $_ eq 'foo' } @x 256b39c5158Smillertmapstart map $_ + 1, @foo 257b39c5158Smillertmapwhile SKIP (set by optimizer) 258b39c5158Smillertrange SKIP 259b39c5158Smillertflip 1..2 260b39c5158Smillertflop 1..2 261b39c5158Smillertand $x && $y 262b39c5158Smillertor $x || $y 263b39c5158Smillertxor $x xor $y 264b39c5158Smillertcond_expr $x ? 1 : 0 265b39c5158Smillertandassign $x &&= $y 266b39c5158Smillertorassign $x ||= $y 267b39c5158Smillertmethod Foo->$x() 268b39c5158Smillertentersub f() 269b39c5158Smillertleavesub sub f{} f() 270b39c5158Smillertleavesublv sub f:lvalue{return $x} f() 271b39c5158Smillertcaller caller 272b39c5158Smillertwarn warn 273b39c5158Smillertdie die 274b39c5158Smillertreset reset 275b39c5158Smillertlineseq SKIP 276b39c5158Smillertnextstate SKIP 277b39c5158Smillertdbstate SKIP (needs debugger) 278b39c5158Smillertunstack while(0){} 279b39c5158Smillertenter SKIP 280b39c5158Smillertleave SKIP 281b39c5158Smillertscope SKIP 282b39c5158Smillertenteriter SKIP 283b39c5158Smillertiter SKIP 284b39c5158Smillertenterloop SKIP 285b39c5158Smillertleaveloop SKIP 286b39c5158Smillertreturn return 287b39c5158Smillertlast last 288b39c5158Smillertnext next 289b39c5158Smillertredo redo THIS 2909f11ffb7Safresh1dump CORE::dump 291b39c5158Smillertgoto goto THERE 292b39c5158Smillertexit exit 0 293b39c5158Smillertopen open FOO 294b39c5158Smillertclose close FOO 295b39c5158Smillertpipe_op pipe FOO,BAR 296b39c5158Smillertfileno fileno FOO 297b39c5158Smillertumask umask 0755, 'foo' 298b39c5158Smillertbinmode binmode FOO 299b39c5158Smillerttie tie 300b39c5158Smillertuntie untie 301b39c5158Smillerttied tied 302b39c5158Smillertdbmopen dbmopen 303b39c5158Smillertdbmclose dbmclose 304b39c5158Smillertsselect SKIP (set by optimizer) 305b39c5158Smillertselect select FOO 306b39c5158Smillertgetc getc FOO 307b39c5158Smillertread read FOO 308b39c5158Smillertenterwrite write 309b39c5158Smillertleavewrite SKIP 310b39c5158Smillertprtf printf 311b39c5158Smillertprint print 312b39c5158Smillertsysopen sysopen 313b39c5158Smillertsysseek sysseek 314b39c5158Smillertsysread sysread 315b39c5158Smillertsyswrite syswrite 316b39c5158Smillertsend send 317b39c5158Smillertrecv recv 318b39c5158Smillerteof eof FOO 319b39c5158Smillerttell tell 320b39c5158Smillertseek seek FH, $pos, $whence 321b39c5158Smillerttruncate truncate FOO, 42 322b39c5158Smillertfcntl fcntl 323b39c5158Smillertioctl ioctl 324b39c5158Smillertflock flock FOO, 1 325b39c5158Smillertsocket socket 326b39c5158Smillertsockpair socketpair 327b39c5158Smillertbind bind 328b39c5158Smillertconnect connect 329b39c5158Smillertlisten listen 330b39c5158Smillertaccept accept 331b39c5158Smillertshutdown shutdown 332b39c5158Smillertgsockopt getsockopt 333b39c5158Smillertssockopt setsockopt 334b39c5158Smillertgetsockname getsockname 335b39c5158Smillertgetpeername getpeername 336b39c5158Smillertlstat lstat FOO 337b39c5158Smillertstat stat FOO 338b39c5158Smillertftrread -R 339b39c5158Smillertftrwrite -W 340b39c5158Smillertftrexec -X 341b39c5158Smillertfteread -r 342b39c5158Smillertftewrite -w 343b39c5158Smillertfteexec -x 344b39c5158Smillertftis -e 345b39c5158Smillertfteowned SKIP -O 346b39c5158Smillertftrowned SKIP -o 347b39c5158Smillertftzero -z 348b39c5158Smillertftsize -s 349b39c5158Smillertftmtime -M 350b39c5158Smillertftatime -A 351b39c5158Smillertftctime -C 352b39c5158Smillertftsock -S 353b39c5158Smillertftchr -c 354b39c5158Smillertftblk -b 355b39c5158Smillertftfile -f 356b39c5158Smillertftdir -d 357b39c5158Smillertftpipe -p 358b39c5158Smillertftlink -l 359b39c5158Smillertftsuid -u 360b39c5158Smillertftsgid -g 361b39c5158Smillertftsvtx -k 362b39c5158Smillertfttty -t 363b39c5158Smillertfttext -T 364b39c5158Smillertftbinary -B 365b39c5158Smillertchdir chdir '/' 366b39c5158Smillertchown chown 367b39c5158Smillertchroot chroot 368b39c5158Smillertunlink unlink 'foo' 369b39c5158Smillertchmod chmod 511, 'foo' 370b39c5158Smillertutime utime 371b39c5158Smillertrename rename 'foo', 'bar' 372b39c5158Smillertlink link 'foo', 'bar' 373b39c5158Smillertsymlink symlink 'foo', 'bar' 374b39c5158Smillertreadlink readlink 'foo' 375b39c5158Smillertmkdir mkdir 'foo' 376b39c5158Smillertrmdir rmdir 'foo' 377b39c5158Smillertopen_dir opendir DIR 378b39c5158Smillertreaddir readdir DIR 379b39c5158Smillerttelldir telldir DIR 380b39c5158Smillertseekdir seekdir DIR, $pos 381b39c5158Smillertrewinddir rewinddir DIR 382b39c5158Smillertclosedir closedir DIR 383b39c5158Smillertfork fork 384b39c5158Smillertwait wait 385b39c5158Smillertwaitpid waitpid 386b39c5158Smillertsystem system 387b39c5158Smillertexec exec 388b39c5158Smillertkill kill 389b39c5158Smillertgetppid getppid 390b39c5158Smillertgetpgrp getpgrp 391b39c5158Smillertsetpgrp setpgrp 392b39c5158Smillertgetpriority getpriority 393b39c5158Smillertsetpriority setpriority 394b39c5158Smillerttime time 395b39c5158Smillerttms times 396b39c5158Smillertlocaltime localtime 397b39c5158Smillertgmtime gmtime 398b39c5158Smillertalarm alarm 399b39c5158Smillertsleep sleep 1 400b39c5158Smillertshmget shmget 401b39c5158Smillertshmctl shmctl 402b39c5158Smillertshmread shmread 403b39c5158Smillertshmwrite shmwrite 404b39c5158Smillertmsgget msgget 405b39c5158Smillertmsgctl msgctl 406b39c5158Smillertmsgsnd msgsnd 407b39c5158Smillertmsgrcv msgrcv 408b39c5158Smillertsemget semget 409b39c5158Smillertsemctl semctl 410b39c5158Smillertsemop semop 411b39c5158Smillertrequire use strict 412b39c5158Smillertdofile do 'file' 413b39c5158Smillertentereval eval "1+1" 414b39c5158Smillertleaveeval eval "1+1" 415b39c5158Smillertentertry SKIP eval { 1+1 } 416b39c5158Smillertleavetry SKIP eval { 1+1 } 417b39c5158Smillertghbyname gethostbyname 'foo' 418b39c5158Smillertghbyaddr gethostbyaddr 'foo' 419b39c5158Smillertghostent gethostent 420b39c5158Smillertgnbyname getnetbyname 'foo' 421b39c5158Smillertgnbyaddr getnetbyaddr 'foo' 422b39c5158Smillertgnetent getnetent 423b39c5158Smillertgpbyname getprotobyname 'foo' 424b39c5158Smillertgpbynumber getprotobynumber 42 425b39c5158Smillertgprotoent getprotoent 426b39c5158Smillertgsbyname getservbyname 'name', 'proto' 427b39c5158Smillertgsbyport getservbyport 'a', 'b' 428b39c5158Smillertgservent getservent 429b39c5158Smillertshostent sethostent 430b39c5158Smillertsnetent setnetent 431b39c5158Smillertsprotoent setprotoent 432b39c5158Smillertsservent setservent 433b39c5158Smillertehostent endhostent 434b39c5158Smillertenetent endnetent 435b39c5158Smillerteprotoent endprotoent 436b39c5158Smillerteservent endservent 437b39c5158Smillertgpwnam getpwnam 438b39c5158Smillertgpwuid getpwuid 439b39c5158Smillertgpwent getpwent 440b39c5158Smillertspwent setpwent 441b39c5158Smillertepwent endpwent 442b39c5158Smillertggrnam getgrnam 443b39c5158Smillertggrgid getgrgid 444b39c5158Smillertggrent getgrent 445b39c5158Smillertsgrent setgrent 446b39c5158Smillertegrent endgrent 447b39c5158Smillertgetlogin getlogin 448b39c5158Smillertsyscall syscall 449b39c5158Smillertlock SKIP 450b39c5158Smillertsetstate SKIP 451b39c5158Smillertmethod_named $x->y() 452b39c5158Smillertdor $x // $y 453b39c5158Smillertdorassign $x //= $y 454b39c5158Smillertonce SKIP {use feature 'state'; state $foo = 42;} 455b39c5158Smillertsay SKIP {use feature 'say'; say "foo";} 456*e0680481Safresh1smartmatch no warnings 'deprecated'; $x ~~ $y 457b39c5158Smillertaeach SKIP each @t 458b39c5158Smillertakeys SKIP keys @t 459b39c5158Smillertavalues SKIP values @t 460b39c5158Smillertcustom SKIP (no way) 461