mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Fixed bug #78340
Even if we know the file size, we still need to read in a loop in case the read call returns an incomplete result. This was less of an issue previously because we did not use the "one large read" approach for non-plain stream wrappers.
This commit is contained in:
parent
fec71e3f25
commit
9bfda013d3
3 changed files with 69 additions and 9 deletions
4
NEWS
4
NEWS
|
@ -2,6 +2,10 @@ PHP NEWS
|
||||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||
?? ??? ????, PHP 7.4.0beta2
|
?? ??? ????, PHP 7.4.0beta2
|
||||||
|
|
||||||
|
- Core:
|
||||||
|
. Fixed bug #78340 (Include of stream wrapper not reading whole file).
|
||||||
|
(Nikita)
|
||||||
|
|
||||||
- Iconv:
|
- Iconv:
|
||||||
. Fixed bug #78342 (Bus error in configure test for iconv //IGNORE). (Rainer
|
. Fixed bug #78342 (Bus error in configure test for iconv //IGNORE). (Rainer
|
||||||
Jung)
|
Jung)
|
||||||
|
|
54
Zend/tests/bug78340.phpt
Normal file
54
Zend/tests/bug78340.phpt
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #78340: Include of stream wrapper not reading whole file
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class lib {
|
||||||
|
public static $files= [];
|
||||||
|
|
||||||
|
private $bytes, $pos;
|
||||||
|
|
||||||
|
function stream_open($path, $mode, $options, $opened_path) {
|
||||||
|
$this->bytes= self::$files[$path];
|
||||||
|
$this->pos= 0;
|
||||||
|
$this->ino= crc32($path);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stream_read($count) {
|
||||||
|
$chunk= substr($this->bytes, $this->pos, $count);
|
||||||
|
$this->pos+= strlen($chunk);
|
||||||
|
return $chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stream_eof() {
|
||||||
|
return $this->pos >= strlen($this->bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
function stream_close() {
|
||||||
|
$this->bytes= null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stream_stat() {
|
||||||
|
return [
|
||||||
|
'dev' => 3632233996,
|
||||||
|
'size' => strlen($this->bytes),
|
||||||
|
'ino' => $this->ino
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function stream_set_option($option, $arg1, $arg2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$fill = str_repeat('.', 8192);
|
||||||
|
lib::$files['lib://test.php']= '<?php /* '.$fill.' */ function test() { echo "Works!\n"; }';
|
||||||
|
stream_wrapper_register('lib', lib::class);
|
||||||
|
|
||||||
|
include('lib://test.php');
|
||||||
|
test();
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
Works!
|
|
@ -115,7 +115,7 @@ static ssize_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_t
|
||||||
|
|
||||||
ZEND_API int zend_stream_fixup(zend_file_handle *file_handle, char **buf, size_t *len) /* {{{ */
|
ZEND_API int zend_stream_fixup(zend_file_handle *file_handle, char **buf, size_t *len) /* {{{ */
|
||||||
{
|
{
|
||||||
size_t size;
|
size_t file_size;
|
||||||
|
|
||||||
if (file_handle->buf) {
|
if (file_handle->buf) {
|
||||||
*buf = file_handle->buf;
|
*buf = file_handle->buf;
|
||||||
|
@ -142,26 +142,28 @@ ZEND_API int zend_stream_fixup(zend_file_handle *file_handle, char **buf, size_t
|
||||||
file_handle->handle.stream.fsizer = (zend_stream_fsizer_t)zend_stream_stdio_fsizer;
|
file_handle->handle.stream.fsizer = (zend_stream_fsizer_t)zend_stream_stdio_fsizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = zend_stream_fsize(file_handle);
|
file_size = zend_stream_fsize(file_handle);
|
||||||
if (size == (size_t)-1) {
|
if (file_size == (size_t)-1) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size) {
|
if (file_size) {
|
||||||
ssize_t read;
|
ssize_t read;
|
||||||
*buf = safe_emalloc(1, size, ZEND_MMAP_AHEAD);
|
size_t size = 0;
|
||||||
read = zend_stream_read(file_handle, *buf, size);
|
*buf = safe_emalloc(1, file_size, ZEND_MMAP_AHEAD);
|
||||||
|
while ((read = zend_stream_read(file_handle, *buf + size, file_size - size)) > 0) {
|
||||||
|
size += read;
|
||||||
|
}
|
||||||
if (read < 0) {
|
if (read < 0) {
|
||||||
efree(*buf);
|
efree(*buf);
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
file_handle->buf = *buf;
|
file_handle->buf = *buf;
|
||||||
file_handle->len = read;
|
file_handle->len = size;
|
||||||
} else {
|
} else {
|
||||||
size_t remain = 4*1024;
|
size_t size = 0, remain = 4*1024;
|
||||||
ssize_t read;
|
ssize_t read;
|
||||||
*buf = emalloc(remain);
|
*buf = emalloc(remain);
|
||||||
size = 0;
|
|
||||||
|
|
||||||
while ((read = zend_stream_read(file_handle, *buf + size, remain)) > 0) {
|
while ((read = zend_stream_read(file_handle, *buf + size, remain)) > 0) {
|
||||||
size += read;
|
size += read;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue