Skip to content

Commit 5a024d2

Browse files
committed
Fix #78662: stream_write bad error detection
1 parent 8b8c226 commit 5a024d2

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
Bug #78662 (stream_write bad error detection)
3+
--FILE--
4+
<?php
5+
class FailedStream {
6+
function stream_open($path, $mode, $options, &$opened_path)
7+
{
8+
return true;
9+
}
10+
function stream_read($count)
11+
{
12+
return false;
13+
}
14+
function stream_write($data)
15+
{
16+
return false;
17+
}
18+
function stream_stat()
19+
{
20+
return [];
21+
}
22+
}
23+
stream_wrapper_register('fails', 'FailedStream');
24+
$f=fopen('fails://foo', 'a+');
25+
var_dump(fwrite($f, "bar"));
26+
var_dump(fread($f, 100));
27+
?>
28+
Done
29+
--EXPECTF--
30+
bool(false)
31+
bool(false)
32+
Done

main/streams/userspace.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ static ssize_t php_userstreamop_write(php_stream *stream, const char *buf, size_
630630
}
631631

632632
/* don't allow strange buffer overruns due to bogus return */
633-
if (didwrite > count) {
633+
if (didwrite > 0 && didwrite > count) {
634634
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)",
635635
us->wrapper->classname,
636636
(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
686686
}
687687

688688
didread = Z_STRLEN(retval);
689-
if (didread > count) {
690-
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",
691-
us->wrapper->classname, (zend_long)(didread - count), (zend_long)didread, (zend_long)count);
692-
didread = count;
693-
}
694-
if (didread > 0)
689+
if (didread > 0) {
690+
if (didread > count) {
691+
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",
692+
us->wrapper->classname, (zend_long)(didread - count), (zend_long)didread, (zend_long)count);
693+
didread = count;
694+
}
695695
memcpy(buf, Z_STRVAL(retval), didread);
696+
}
696697

697698
zval_ptr_dtor(&retval);
698699
ZVAL_UNDEF(&retval);

0 commit comments

Comments
 (0)