Fix #78662: stream_write bad error detection

This commit is contained in:
Remi Collet 2019-10-11 13:36:16 +02:00 committed by Remi Collet
parent 8b8c226dbf
commit 5a024d2c5b
2 changed files with 40 additions and 7 deletions

View File

@ -0,0 +1,32 @@
--TEST--
Bug #78662 (stream_write bad error detection)
--FILE--
<?php
class FailedStream {
function stream_open($path, $mode, $options, &$opened_path)
{
return true;
}
function stream_read($count)
{
return false;
}
function stream_write($data)
{
return false;
}
function stream_stat()
{
return [];
}
}
stream_wrapper_register('fails', 'FailedStream');
$f=fopen('fails://foo', 'a+');
var_dump(fwrite($f, "bar"));
var_dump(fread($f, 100));
?>
Done
--EXPECTF--
bool(false)
bool(false)
Done

View File

@ -630,7 +630,7 @@ static ssize_t php_userstreamop_write(php_stream *stream, const char *buf, size_
}
/* don't allow strange buffer overruns due to bogus return */
if (didwrite > count) {
if (didwrite > 0 && didwrite > count) {
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_WRITE " wrote " ZEND_LONG_FMT " bytes more data than requested (" ZEND_LONG_FMT " written, " ZEND_LONG_FMT " max)",
us->wrapper->classname,
(zend_long)(didwrite - count), (zend_long)didwrite, (zend_long)count);
@ -686,13 +686,14 @@ static ssize_t php_userstreamop_read(php_stream *stream, char *buf, size_t count
}
didread = Z_STRLEN(retval);
if (didread > count) {
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_READ " - read " ZEND_LONG_FMT " bytes more data than requested (" ZEND_LONG_FMT " read, " ZEND_LONG_FMT " max) - excess data will be lost",
us->wrapper->classname, (zend_long)(didread - count), (zend_long)didread, (zend_long)count);
didread = count;
}
if (didread > 0)
if (didread > 0) {
if (didread > count) {
php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_READ " - read " ZEND_LONG_FMT " bytes more data than requested (" ZEND_LONG_FMT " read, " ZEND_LONG_FMT " max) - excess data will be lost",
us->wrapper->classname, (zend_long)(didread - count), (zend_long)didread, (zend_long)count);
didread = count;
}
memcpy(buf, Z_STRVAL(retval), didread);
}
zval_ptr_dtor(&retval);
ZVAL_UNDEF(&retval);