1--TEST--
2Phar with unsafe object in metadata does not unserialize on reading a file.
3--EXTENSIONS--
4phar
5--INI--
6phar.require_hash=0
7phar.readonly=0
8--FILE--
9<?php
10class EchoesOnWakeup {
11    public function __wakeup() {
12        echo "In wakeup\n";
13    }
14}
15$fname = __DIR__ . '/' . basename(__FILE__, '.php') . '.phar.php';
16$pname = 'phar://' . $fname;
17$file = "<?php __HALT_COMPILER(); ?>";
18
19$files = array();
20$files['a'] = array('cont' => 'contents of file a');
21include 'files/phar_test.inc';
22
23echo "Reading file contents through stream wrapper\n";
24foreach($files as $name => $cont) {
25    var_dump(file_get_contents($pname.'/'.$name));
26}
27
28$phar = new Phar($fname);
29echo "Original metadata\n";
30var_dump($phar->getMetadata());
31$phar->setMetadata(new EchoesOnWakeup());
32unset($phar);
33// NOTE: Phar will use the cached value of metadata if setMetaData was called on that Phar path before.
34// Save the writes to the phar and use a different file path.
35$fname_new = "$fname.copy.php";
36copy($fname, $fname_new);
37$phar = new Phar($fname_new);
38echo "Calling getMetadata\n";
39var_dump($phar->getMetadata());
40echo "Calling getMetadata with no allowed_classes\n";
41var_dump($phar->getMetadata(['allowed_classes' => []]));
42echo "Calling getMetadata with EchoesOnWakeup allowed\n";
43var_dump($phar->getMetadata(['allowed_classes' => [EchoesOnWakeup::class]]));
44// Part of this is a test that there are no unexpected behaviors when both selMetadata and getMetadata are used
45$phar->setMetaData([new EchoesOnWakeup(), new stdClass()]);
46echo "Calling getMetadata with too low max_depth\n";
47var_dump($phar->getMetadata(['max_depth' => 1]));
48echo "Calling getMetadata with some allowed classes\n";
49var_dump($phar->getMetadata(['allowed_classes' => [EchoesOnWakeup::class]]));
50echo "Calling getMetadata with no options returns the original metadata value\n";
51var_dump($phar->getMetadata());
52unset($phar);
53
54?>
55--CLEAN--
56<?php
57unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.phar.php');
58unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.phar.php.copy.php');
59?>
60--EXPECTF--
61Reading file contents through stream wrapper
62string(18) "contents of file a"
63Original metadata
64NULL
65Calling getMetadata
66In wakeup
67object(EchoesOnWakeup)#2 (0) {
68}
69Calling getMetadata with no allowed_classes
70object(__PHP_Incomplete_Class)#2 (1) {
71  ["__PHP_Incomplete_Class_Name"]=>
72  string(14) "EchoesOnWakeup"
73}
74Calling getMetadata with EchoesOnWakeup allowed
75In wakeup
76object(EchoesOnWakeup)#2 (0) {
77}
78Calling getMetadata with too low max_depth
79
80Warning: Phar::getMetadata(): Maximum depth of 1 exceeded. The depth limit can be changed using the max_depth unserialize() option or the unserialize_max_depth ini setting in %sphar_metadata_write3.php on line 39
81
82Notice: Phar::getMetadata(): Error at offset 34 of 59 bytes in %sphar_metadata_write3.php on line 39
83bool(false)
84Calling getMetadata with some allowed classes
85In wakeup
86array(2) {
87  [0]=>
88  object(EchoesOnWakeup)#4 (0) {
89  }
90  [1]=>
91  object(__PHP_Incomplete_Class)#5 (1) {
92    ["__PHP_Incomplete_Class_Name"]=>
93    string(8) "stdClass"
94  }
95}
96Calling getMetadata with no options returns the original metadata value
97array(2) {
98  [0]=>
99  object(EchoesOnWakeup)#2 (0) {
100  }
101  [1]=>
102  object(stdClass)#3 (0) {
103  }
104}
105