diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-09-11 10:27:32 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-09-11 10:27:32 +0200 |
commit | 11f3e24190fa45689c8ccaeea54a28db6752092e (patch) | |
tree | 4bc2ed82e2fc21f7dfcfe74fd11e4208a4d8b346 | |
parent | 0a24cd4e7c38d7565905152d4286ef0404d9d591 (diff) | |
download | php-git-11f3e24190fa45689c8ccaeea54a28db6752092e.tar.gz |
Fixed bug #78506
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | ext/standard/tests/streams/bug78506.phpt | 27 | ||||
-rw-r--r-- | main/streams/streams.c | 34 |
3 files changed, 47 insertions, 18 deletions
@@ -25,6 +25,10 @@ PHP NEWS . Fixed bug #78510 (Partially uninitialized buffer returned by sodium_crypto_generichash_init()). (Frank Denis, cmb) +- Standard: + . Fixed bug #78506 (Error in a php_user_filter::filter() is not reported). + (Nikita) + 05 Sep 2019, PHP 7.4.0RC1 - Core: diff --git a/ext/standard/tests/streams/bug78506.phpt b/ext/standard/tests/streams/bug78506.phpt new file mode 100644 index 0000000000..869fa2a8ff --- /dev/null +++ b/ext/standard/tests/streams/bug78506.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #78506: Error in a php_user_filter::filter() is not reported +--FILE-- +<?php + +class MyFilter extends php_user_filter { + public function filter($in, $out, &$consumed, $closing) + { + stream_bucket_make_writeable($in); + return PSFS_ERR_FATAL; + } + +} + +stream_filter_register('filtername', MyFilter::class); + +$source_resource = fopen('php://memory', 'rb+'); +fwrite($source_resource, 'Test data'); +rewind($source_resource); + +stream_filter_prepend($source_resource,'filtername',STREAM_FILTER_READ); + +var_dump(stream_copy_to_stream($source_resource, fopen('php://memory', 'wb'))); + +?> +--EXPECT-- +bool(false) diff --git a/main/streams/streams.c b/main/streams/streams.c index 566cdcde08..aef1ebe762 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1586,33 +1586,31 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size while(1) { size_t readchunk = sizeof(buf); ssize_t didread; + char *writeptr; if (maxlen && (maxlen - haveread) < readchunk) { readchunk = maxlen - haveread; } didread = php_stream_read(src, buf, readchunk); + if (didread <= 0) { + *len = haveread; + return didread < 0 ? FAILURE : SUCCESS; + } - if (didread > 0) { - /* extra paranoid */ - char *writeptr; - - towrite = didread; - writeptr = buf; - haveread += didread; - - while (towrite) { - ssize_t didwrite = php_stream_write(dest, writeptr, towrite); - if (didwrite <= 0) { - *len = haveread - (didread - towrite); - return FAILURE; - } + towrite = didread; + writeptr = buf; + haveread += didread; - towrite -= didwrite; - writeptr += didwrite; + while (towrite) { + ssize_t didwrite = php_stream_write(dest, writeptr, towrite); + if (didwrite <= 0) { + *len = haveread - (didread - towrite); + return FAILURE; } - } else { - break; + + towrite -= didwrite; + writeptr += didwrite; } if (maxlen - haveread == 0) { |