xref: /openbsd-src/gnu/usr.bin/perl/dist/Safe/t/safeops.t (revision e068048151d29f2562a32185e21a8ba885482260)
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