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