]> granicus.if.org Git - php/commitdiff
Fixed bug #73586 (php_user_filter::$stream is not set to the stream the filter is...
authorDmitry Stogov <dmitry@zend.com>
Mon, 28 Nov 2016 09:54:47 +0000 (12:54 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 28 Nov 2016 09:54:47 +0000 (12:54 +0300)
NEWS
Zend/zend_hash.h
ext/standard/tests/filters/bug73586.phpt [new file with mode: 0644]
ext/standard/user_filters.c

diff --git a/NEWS b/NEWS
index 9226c51cb7a54551e70a5dd08a0d785cc4a4a380..79ced5e62bfb33421985397a1588775f38e6d399 100644 (file)
--- 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:
index f4c2c30fbcae0427e56f55b8cf241352c5a8c75f..1be68c7d638eab59ffbc72a8227ae00d26a5b62a 100644 (file)
@@ -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 (file)
index 0000000..3cae466
--- /dev/null
@@ -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
index 2da03cd2766622a26cde3c710d77e0314bbc7599..19aff782fda277b8b6c0c185803ce5a1ae9d61ce 100644 (file)
@@ -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 */