1--TEST-- 2GH-8548: stream_wrapper_unregister() leaks memory 3--FILE-- 4<?php 5 6class Wrapper 7{ 8 public $context; 9 10 public function stream_open(string $path, string $mode, int $options): bool 11 { 12 return true; 13 } 14 15 public function stream_eof(): bool 16 { 17 return true; 18 } 19} 20 21function test() { 22 if (!stream_wrapper_register('foo', \Wrapper::class)) { 23 throw new \Exception('Could not register stream wrapper'); 24 } 25 26 $file = fopen('foo://bar', 'r'); 27 28 if (!stream_wrapper_unregister('foo')) { 29 throw new \Exception('Could not unregister stream wrapper'); 30 } 31 32 $wrapper = stream_get_meta_data($file)['wrapper_data']; 33 if (!$wrapper instanceof Wrapper) { 34 throw new \Exception('Wrapper is not of expected type'); 35 } 36 37 fclose($file); 38 unset($file); 39} 40 41// The first iterations will allocate space for things like the resource list 42for ($i = 0; $i < 10; $i++) { 43 test(); 44} 45 46$before = memory_get_usage(); 47for ($i = 0; $i < 1000; $i++) { 48 test(); 49} 50$after = memory_get_usage(); 51 52var_dump($before === $after); 53 54?> 55--EXPECT-- 56bool(true) 57