summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2016-11-28 12:54:47 +0300
committerDmitry Stogov <dmitry@zend.com>2016-11-28 12:54:47 +0300
commit9a9ad56af0f80c69d363e8cfabe412da798c497d (patch)
tree58baa0d09b318fd5ab0595c16e7dd0c4c64553b2
parent970f21be97980a18153f13d653f4132cce676158 (diff)
downloadphp-git-9a9ad56af0f80c69d363e8cfabe412da798c497d.tar.gz
Fixed bug #73586 (php_user_filter::$stream is not set to the stream the filter is working on).
-rw-r--r--NEWS4
-rw-r--r--Zend/zend_hash.h10
-rw-r--r--ext/standard/tests/filters/bug73586.phpt45
-rw-r--r--ext/standard/user_filters.c2
4 files changed, 60 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 9226c51cb7..79ced5e62b 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,10 @@ PHP NEWS
- PCRE:
. Fixed bug #73612 (preg_*() may leak memory). (cmb)
+- Streams:
+ . Fixed bug #73586 (php_user_filter::$stream is not set to the stream the
+ filter is working on). (Dmitry)
+
08 Dec 2016 PHP 7.0.14
- Core:
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h
index f4c2c30fbc..1be68c7d63 100644
--- a/Zend/zend_hash.h
+++ b/Zend/zend_hash.h
@@ -301,6 +301,16 @@ static zend_always_inline zval *zend_hash_str_find_ind(const HashTable *ht, cons
}
+static zend_always_inline int zend_hash_str_exists_ind(const HashTable *ht, const char *str, size_t len)
+{
+ zval *zv;
+
+ zv = zend_hash_str_find(ht, str, len);
+ return zv && (Z_TYPE_P(zv) != IS_INDIRECT ||
+ Z_TYPE_P(Z_INDIRECT_P(zv)) != IS_UNDEF);
+}
+
+
static zend_always_inline zval *zend_symtable_update(HashTable *ht, zend_string *key, zval *pData)
{
zend_ulong idx;
diff --git a/ext/standard/tests/filters/bug73586.phpt b/ext/standard/tests/filters/bug73586.phpt
new file mode 100644
index 0000000000..3cae4662bf
--- /dev/null
+++ b/ext/standard/tests/filters/bug73586.phpt
@@ -0,0 +1,45 @@
+--TEST--
+Bug #73586 (php_user_filter::$stream is not set to the stream the filter is working on).
+--FILE--
+<?php
+class append_filter extends php_user_filter {
+ public $stream;
+ function filter($in, $out, &$consumed, $closing) {
+ while ($bucket = stream_bucket_make_writeable($in)) {
+ $consumed += $bucket->datalen;
+ stream_bucket_append($out, $bucket);
+ }
+ if ($closing) {
+ $bucket = stream_bucket_new($this->stream, "FooBar\n");
+ stream_bucket_append($out, $bucket);
+ }
+ return PSFS_PASS_ON;
+ }
+}
+stream_filter_register("append", "append_filter");
+$fin = fopen(__FILE__, 'rb');
+stream_filter_append($fin, 'append', STREAM_FILTER_READ);
+stream_copy_to_stream($fin, STDOUT);
+?>
+--EXPECT--
+<?php
+class append_filter extends php_user_filter {
+ public $stream;
+ function filter($in, $out, &$consumed, $closing) {
+ while ($bucket = stream_bucket_make_writeable($in)) {
+ $consumed += $bucket->datalen;
+ stream_bucket_append($out, $bucket);
+ }
+ if ($closing) {
+ $bucket = stream_bucket_new($this->stream, "FooBar\n");
+ stream_bucket_append($out, $bucket);
+ }
+ return PSFS_PASS_ON;
+ }
+}
+stream_filter_register("append", "append_filter");
+$fin = fopen(__FILE__, 'rb');
+stream_filter_append($fin, 'append', STREAM_FILTER_READ);
+stream_copy_to_stream($fin, STDOUT);
+?>
+FooBar
diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c
index 2da03cd276..19aff782fd 100644
--- a/ext/standard/user_filters.c
+++ b/ext/standard/user_filters.c
@@ -175,7 +175,7 @@ php_stream_filter_status_t userfilter_filter(
return ret;
}
- if (!zend_hash_str_exists(Z_OBJPROP_P(obj), "stream", sizeof("stream")-1)) {
+ if (!zend_hash_str_exists_ind(Z_OBJPROP_P(obj), "stream", sizeof("stream")-1)) {
zval tmp;
/* Give the userfilter class a hook back to the stream */