This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #117941] Blessing into freed current stash
[perl5.git] / t / op / bless.t
CommitLineData
81689caa
HS
1#!./perl
2
81689caa
HS
3BEGIN {
4 chdir 't' if -d 't';
20822f61 5 @INC = '../lib';
4a32f131 6 require './test.pl';
81689caa
HS
7}
8
dcdfe746 9plan (110);
4a32f131 10
81689caa
HS
11sub expected {
12 my($object, $package, $type) = @_;
81689caa 13 print "# $object $package $type\n";
4a32f131
NC
14 is(ref($object), $package);
15 my $r = qr/^\Q$package\E=(\w+)\(0x([0-9a-f]+)\)$/;
16 like("$object", $r);
40ff300d
RGS
17 if ("$object" =~ $r) {
18 is($1, $type);
19 # in 64-bit platforms hex warns for 32+ -bit values
20 cmp_ok(do {no warnings 'portable'; hex($2)}, '==', $object);
21 }
22 else {
23 fail(); fail();
24 }
81689caa
HS
25}
26
27# test blessing simple types
28
29$a1 = bless {}, "A";
4a32f131 30expected($a1, "A", "HASH");
81689caa 31$b1 = bless [], "B";
4a32f131 32expected($b1, "B", "ARRAY");
81689caa 33$c1 = bless \(map "$_", "test"), "C";
4a32f131 34expected($c1, "C", "SCALAR");
016a42f3 35our $test = "foo"; $d1 = bless \*test, "D";
4a32f131 36expected($d1, "D", "GLOB");
81689caa 37$e1 = bless sub { 1 }, "E";
4a32f131 38expected($e1, "E", "CODE");
81689caa 39$f1 = bless \[], "F";
4a32f131 40expected($f1, "F", "REF");
81689caa 41$g1 = bless \substr("test", 1, 2), "G";
4a32f131 42expected($g1, "G", "LVALUE");
81689caa
HS
43
44# blessing ref to object doesn't modify object
45
4a32f131
NC
46expected(bless(\$a1, "F"), "F", "REF");
47expected($a1, "A", "HASH");
81689caa
HS
48
49# reblessing does modify object
50
016a42f3 51bless $a1, "A2";
4a32f131 52expected($a1, "A2", "HASH");
81689caa
HS
53
54# local and my
55{
56 local $a1 = bless $a1, "A3"; # should rebless outer $a1
57 local $b1 = bless [], "B3";
58 my $c1 = bless $c1, "C3"; # should rebless outer $c1
016a42f3 59 our $test2 = ""; my $d1 = bless \*test2, "D3";
4a32f131
NC
60 expected($a1, "A3", "HASH");
61 expected($b1, "B3", "ARRAY");
62 expected($c1, "C3", "SCALAR");
63 expected($d1, "D3", "GLOB");
81689caa 64}
4a32f131
NC
65expected($a1, "A3", "HASH");
66expected($b1, "B", "ARRAY");
67expected($c1, "C3", "SCALAR");
68expected($d1, "D", "GLOB");
81689caa
HS
69
70# class is magic
71"E" =~ /(.)/;
4a32f131 72expected(bless({}, $1), "E", "HASH");
81689caa
HS
73{
74 local $! = 1;
75 my $string = "$!";
76 $! = 2; # attempt to avoid cached string
77 $! = 1;
4a32f131 78 expected(bless({}, $!), $string, "HASH");
81689caa
HS
79
80# ref is ref to magic
81 {
82 {
83 package F;
4a32f131 84 sub test { main::is(${$_[0]}, $string) }
81689caa
HS
85 }
86 $! = 2;
87 $f1 = bless \$!, "F";
88 $! = 1;
89 $f1->test;
81689caa
HS
90 }
91}
92
93# ref is magic
94### example of magic variable that is a reference??
95
96# no class, or empty string (with a warning), or undef (with two)
4a32f131 97expected(bless([]), 'main', "ARRAY");
81689caa
HS
98{
99 local $SIG{__WARN__} = sub { push @w, join '', @_ };
43a954af 100 use warnings;
81689caa
HS
101
102 $m = bless [];
4a32f131
NC
103 expected($m, 'main', "ARRAY");
104 is (scalar @w, 0);
81689caa
HS
105
106 @w = ();
107 $m = bless [], '';
4a32f131
NC
108 expected($m, 'main', "ARRAY");
109 is (scalar @w, 1);
81689caa
HS
110
111 @w = ();
112 $m = bless [], undef;
4a32f131
NC
113 expected($m, 'main', "ARRAY");
114 is (scalar @w, 2);
81689caa
HS
115}
116
117# class is a ref
118$a1 = bless {}, "A4";
119$b1 = eval { bless {}, $a1 };
4a32f131 120isnt ($@, '', "class is a ref");
016a42f3
HS
121
122# class is an overloaded ref
123{
124 package H4;
125 use overload '""' => sub { "C4" };
126}
127$h1 = bless {}, "H4";
128$c4 = eval { bless \$test, $h1 };
4a32f131
NC
129is ($@, '', "class is an overloaded ref");
130expected($c4, 'C4', "SCALAR");
e0744413
NC
131
132{
133 my %h = 1..2;
134 my($k) = keys %h;
135 my $x=\$k;
136 bless $x, 'pam';
137 is(ref $x, 'pam');
138
139 my $a = bless \(keys %h), 'zap';
140 is(ref $a, 'zap');
141}
1a063a89
FC
142
143bless [], "main::";
144ok(1, 'blessing into main:: does not crash'); # [perl #87388]
dcdfe746
FC
145
146sub _117941 { package _117941; bless [] }
147delete $::{"_117941::"};
148eval { _117941() };
149like $@, qr/^Attempt to bless into a freed package at /,
150 'bless with one arg when current stash is freed';