1--TEST-- 2GH-13071 (Copying large files using mmap-able source streams may exhaust available memory and fail) 3--FILE-- 4<?php 5 6class CustomStream { 7 public $context; 8 protected $file; 9 protected $seekable; 10 public static int $writes = 0; 11 12 public function stream_open($path, $mode, $options, &$opened_path) { 13 $path = $this->trim_path($path); 14 $this->file = fopen($path, $mode); 15 return true; 16 } 17 18 public function stream_close() { 19 fclose($this->file); 20 return true; 21 } 22 23 public function stream_write($data) { 24 self::$writes++; 25 return fwrite($this->file, $data); 26 } 27 28 public function url_stat($path, $flags) { 29 return false; 30 } 31 32 private function trim_path(string $path): string { 33 return substr($path, strlen("up://")); 34 } 35} 36 37file_put_contents(__DIR__ . "/gh13071.tmp", str_repeat("a", 1024 * 1024 * 8)); 38 39stream_wrapper_register("up", CustomStream::class, STREAM_IS_URL); 40 41$old_limit = ini_get("memory_limit"); 42ini_set("memory_limit", memory_get_usage(true) + 5 * 1024 * 1024); 43copy(__DIR__ . "/gh13071.tmp", "up://" . __DIR__ . "/gh13071.out.tmp"); 44ini_set("memory_limit", $old_limit); 45 46echo "Done ", CustomStream::$writes, " writes\n"; 47 48?> 49--CLEAN-- 50<?php 51@unlink(__DIR__ . "/gh13071.tmp"); 52@unlink(__DIR__ . "/gh13071.out.tmp"); 53?> 54--EXPECT-- 55Done 1024 writes 56