3 # Copyright (c) 2002 Slaven Rezic
5 # You may redistribute only under the same terms as Perl 5, as specified
6 # in the README file that comes with the distribution.
12 @INC = ('.', '../lib');
16 require Config; import Config;
17 if ($ENV{PERL_CORE} and $Config{'extensions'} !~ /\bStorable\b/) {
18 print "1..0 # Skip: Storable was not built\n";
31 print "1..0 # skip: tests only work with B::Deparse 0.61 and at least perl 5.6.0\n";
35 if ($File::Spec::VERSION < 0.8) {
36 print "1..0 # Skip: newer File::Spec needed\n";
41 BEGIN { plan tests => 49 }
43 use Storable qw(retrieve store nstore freeze nfreeze thaw dclone);
46 #$Storable::DEBUGME = 1;
48 use vars qw($freezed $thawed @obj @res $blessed_code);
50 $blessed_code = bless sub { "blessed" }, "Some::Package";
51 { package Another::Package; sub foo { __PACKAGE__ } }
54 no strict; # to make the life for Safe->reval easier
59 ([\&code, # code reference
61 $blessed_code, # blessed code reference
62 \&Another::Package::foo, # code in another package
63 sub ($$;$) { 0 }, # prototypes
64 sub { print "test\n" },
65 \&Test::ok, # large scalar
68 {"a" => sub { "srt" }, "b" => \&code},
70 sub { ord("a")-ord("7") },
74 \&dclone, # XS function
76 sub { open FOO, "/" },
79 $Storable::Deparse = 1;
82 ######################################################################
85 $freezed = freeze $obj[0];
86 $thawed = thaw $freezed;
88 ok($thawed->[0]->(), "JAPH");
89 ok($thawed->[1]->(), 42);
90 ok($thawed->[2]->(), "blessed");
91 ok($thawed->[3]->(), "Another::Package");
92 ok(prototype($thawed->[4]), prototype($obj[0]->[4]));
94 ######################################################################
96 $freezed = freeze $obj[1];
97 $thawed = thaw $freezed;
99 ok($thawed->{"a"}->(), "srt");
100 ok($thawed->{"b"}->(), "JAPH");
102 ######################################################################
104 $freezed = freeze $obj[2];
105 $thawed = thaw $freezed;
109 ######################################################################
111 $freezed = freeze $obj[3];
112 $thawed = thaw $freezed;
114 ok($thawed->(), "JAPH");
116 ######################################################################
118 eval { $freezed = freeze $obj[4] };
119 ok($@ =~ /The result of B::Deparse::coderef2text was empty/);
121 ######################################################################
124 my $new_sub = dclone($obj[2]);
125 ok($new_sub->(), $obj[2]->());
127 ######################################################################
128 # Test retrieve & store
130 store $obj[0], 'store';
131 $thawed = retrieve 'store';
133 ok($thawed->[0]->(), "JAPH");
134 ok($thawed->[1]->(), 42);
135 ok($thawed->[2]->(), "blessed");
136 ok($thawed->[3]->(), "Another::Package");
137 ok(prototype($thawed->[4]), prototype($obj[0]->[4]));
139 ######################################################################
141 nstore $obj[0], 'store';
142 $thawed = retrieve 'store';
145 ok($thawed->[0]->(), "JAPH");
146 ok($thawed->[1]->(), 42);
147 ok($thawed->[2]->(), "blessed");
148 ok($thawed->[3]->(), "Another::Package");
149 ok(prototype($thawed->[4]), prototype($obj[0]->[4]));
151 ######################################################################
157 local $Storable::Eval = 0;
160 $freezed = freeze $obj[$i];
162 eval { $thawed = thaw $freezed };
163 ok($@ =~ /Can\'t eval/);
169 local $Storable::Deparse = 0;
172 eval { $freezed = freeze $obj[$i] };
173 ok($@ =~ /Can\'t store CODE items/);
178 local $Storable::Eval = 0;
179 local $Storable::forgive_me = 1;
181 $freezed = freeze $obj[0]->[$i];
183 eval { $thawed = thaw $freezed };
185 ok($$thawed =~ /^sub/);
190 local $Storable::Deparse = 0;
191 local $Storable::forgive_me = 1;
193 my $devnull = File::Spec->devnull;
195 open(SAVEERR, ">&STDERR");
196 open(STDERR, ">$devnull") or
197 ( print SAVEERR "Unable to redirect STDERR: $!\n" and exit(1) );
199 eval { $freezed = freeze $obj[0]->[0] };
201 open(STDERR, ">&SAVEERR");
209 local $Storable::Eval = sub { $safe->reval(shift) };
211 $freezed = freeze $obj[0]->[0];
213 eval { $thawed = thaw $freezed };
215 ok($thawed->(), "JAPH");
217 $freezed = freeze $obj[0]->[6];
218 eval { $thawed = thaw $freezed };
222 # Disable or fix this test if the internal representation of Storable
224 skip("no malicious storable file check", 1);
226 # Construct malicious storable code
227 $freezed = nfreeze $obj[0]->[0];
228 my $bad_code = ';open FOO, "/badfile"';
229 # 5th byte is (short) length of scalar
230 my $len = ord(substr($freezed, 4, 1));
231 substr($freezed, 4, 1, chr($len+length($bad_code)));
232 substr($freezed, -1, 0, $bad_code);
234 eval { $thawed = thaw $freezed };
241 # because of opcodes used in "use strict":
242 $safe->permit(qw(:default require));
243 local $Storable::Eval = sub { $safe->reval(shift) };
245 $freezed = freeze $obj[0]->[1];
247 eval { $thawed = thaw $freezed };
255 sub new { bless {}, shift }
258 # Here you can apply some nifty regexpes to ensure the
259 # safeness of the source code.
260 my $coderef = eval $source;
265 my $safe = new MySafe;
266 local $Storable::Eval = sub { $safe->reval($_[0]) };
268 $freezed = freeze $obj[0];
269 eval { $thawed = thaw $freezed };
275 ok($thawed->[0]->(), "JAPH");
276 ok($thawed->[1]->(), 42);
277 ok($thawed->[2]->(), "blessed");
278 ok($thawed->[3]->(), "Another::Package");
279 ok(prototype($thawed->[4]), prototype($obj[0]->[4]));