Commit:    4db70fd406c805a296f4531088fe716a1ef67158
Author:    Stanislav Malyshev <s...@php.net>         Tue, 7 Aug 2012 22:59:12 
-0700
Parents:   01e414bb6fb1f1939df3b45d3cd64f140f91e440
Branches:  PHP-5.4 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=4db70fd406c805a296f4531088fe716a1ef67158

Log:
fix bug #40459 - make all stream funcs that create object call ctor

Bugs:
https://bugs.php.net/40459

Changed paths:
  A  ext/standard/tests/streams/bug40459.phpt
  M  main/streams/userspace.c

diff --git a/ext/standard/tests/streams/bug40459.phpt 
b/ext/standard/tests/streams/bug40459.phpt
new file mode 100644
index 0000000..8ee4363
--- /dev/null
+++ b/ext/standard/tests/streams/bug40459.phpt
@@ -0,0 +1,103 @@
+--TEST--
+bug 40459 - Test whether the constructor of the user-space stream wrapper is 
called when stream functions are called
+--FILE--
+<?php
+// Test whether the constructor of the user-space stream wrapper is called 
when stream functions are called
+class testwrapper {
+       private $constructorCalled = false;
+       function __construct() {
+               $this->constructorCalled = true;
+       }
+
+       function stream_open($path, $mode, $options, &$opened_path)
+       {
+               echo $this->constructorCalled ? 'yes' : 'no';
+               return true;
+       }
+
+       function url_stat($url, $flags)
+       {
+               echo $this->constructorCalled ? 'yes' : 'no';
+               return array();
+       }
+
+       function unlink($url)
+       {
+               echo $this->constructorCalled ? 'yes' : 'no';
+       }
+
+       function rename($from, $to)
+       {
+               echo $this->constructorCalled ? 'yes' : 'no';
+       }
+
+       function mkdir($dir, $mode, $options)
+       {
+               echo $this->constructorCalled ? 'yes' : 'no';
+       }
+
+       function rmdir($dir, $options)
+       {
+               echo $this->constructorCalled ? 'yes' : 'no';
+       }
+
+       function dir_opendir($url, $options)
+       {
+               echo $this->constructorCalled ? 'yes' : 'no';
+               return TRUE;
+       }
+       function stream_metadata() 
+       {
+               echo $this->constructorCalled ? 'yes' : 'no';
+               return TRUE;
+       }
+}
+
+stream_wrapper_register('test', 'testwrapper', STREAM_IS_URL);
+
+echo 'stream_open: ';
+fopen('test://test', 'r');
+echo "\n";
+
+echo 'url_stat: ';
+stat('test://test');
+echo "\n";
+
+echo 'dir_opendir: ';
+opendir('test://test');
+echo "\n";
+
+echo 'rmdir: ';
+rmdir('test://test');
+echo "\n";
+
+echo 'mkdir: ';
+mkdir('test://test');
+echo "\n";
+
+echo 'rename: ';
+rename('test://test', 'test://test2');
+echo "\n";
+
+echo 'unlink: ';
+unlink('test://test');
+echo "\n";
+
+echo 'touch: ';
+touch('test://test', time());
+echo "\n";
+
+
+
+?>
+==DONE==
+--EXPECT--
+stream_open: yes
+url_stat: yes
+dir_opendir: yes
+rmdir: yes
+mkdir: yes
+rename: yes
+unlink: yes
+touch: yes
+==DONE==
diff --git a/main/streams/userspace.c b/main/streams/userspace.c
index 96a5195..3b27716 100644
--- a/main/streams/userspace.c
+++ b/main/streams/userspace.c
@@ -281,43 +281,22 @@ typedef struct _php_userstream_data php_userstream_data_t;
 
        }}} **/
 
-static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char 
*filename, char *mode, int options, char **opened_path, php_stream_context 
*context STREAMS_DC TSRMLS_DC)
+static zval *user_stream_create_object(struct php_user_stream_wrapper *uwrap, 
php_stream_context *context TSRMLS_DC)
 {
-       struct php_user_stream_wrapper *uwrap = (struct 
php_user_stream_wrapper*)wrapper->abstract;
-       php_userstream_data_t *us;
-       zval *zfilename, *zmode, *zopened, *zoptions, *zretval = NULL, 
*zfuncname;
-       zval **args[4];
-       int call_result;
-       php_stream *stream = NULL;
-       zend_bool old_in_user_include;
-
-       /* Try to catch bad usage without preventing flexibility */
-       if (FG(user_stream_current_filename) != NULL && strcmp(filename, 
FG(user_stream_current_filename)) == 0) {
-               php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, 
"infinite recursion prevented");
-               return NULL;
-       }
-       FG(user_stream_current_filename) = filename;
+       zval *object;
+       /* create an instance of our class */
+       ALLOC_ZVAL(object);
+       object_init_ex(object, uwrap->ce);
+       Z_SET_REFCOUNT_P(object, 1);
+       Z_SET_ISREF_P(object);
 
-       /* if the user stream was registered as local and we are in include 
context,
-               we add allow_url_include restrictions to allow_url_fopen ones */
-       /* we need only is_url == 0 here since if is_url == 1 and remote 
wrappers
-               were restricted we wouldn't get here */
-       old_in_user_include = PG(in_user_include);
-       if(uwrap->wrapper.is_url == 0 &&
-               (options & STREAM_OPEN_FOR_INCLUDE) &&
-               !PG(allow_url_include)) {
-               PG(in_user_include) = 1;
+       if (context) {
+               add_property_resource(object, "context", context->rsrc_id);
+               zend_list_addref(context->rsrc_id);
+       } else {
+               add_property_null(object, "context");
        }
 
-       us = emalloc(sizeof(*us));
-       us->wrapper = uwrap;
-
-       /* create an instance of our class */
-       ALLOC_ZVAL(us->object);
-       object_init_ex(us->object, uwrap->ce);
-       Z_SET_REFCOUNT_P(us->object, 1);
-       Z_SET_ISREF_P(us->object);
-
        if (uwrap->ce->constructor) {
                zend_fcall_info fci;
                zend_fcall_info_cache fcc;
@@ -327,7 +306,7 @@ static php_stream *user_wrapper_opener(php_stream_wrapper 
*wrapper, char *filena
                fci.function_table = &uwrap->ce->function_table;
                fci.function_name = NULL;
                fci.symbol_table = NULL;
-               fci.object_ptr = us->object;
+               fci.object_ptr = object;
                fci.retval_ptr_ptr = &retval_ptr;
                fci.param_count = 0;
                fci.params = NULL;
@@ -336,16 +315,13 @@ static php_stream *user_wrapper_opener(php_stream_wrapper 
*wrapper, char *filena
                fcc.initialized = 1;
                fcc.function_handler = uwrap->ce->constructor;
                fcc.calling_scope = EG(scope);
-               fcc.called_scope = Z_OBJCE_P(us->object);
-               fcc.object_ptr = us->object;
+               fcc.called_scope = Z_OBJCE_P(object);
+               fcc.object_ptr = object;
 
                if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not 
execute %s::%s()", uwrap->ce->name, 
uwrap->ce->constructor->common.function_name);
-                       zval_dtor(us->object);
-                       FREE_ZVAL(us->object);
-                       efree(us);
-                       FG(user_stream_current_filename) = NULL;
-                       PG(in_user_include) = old_in_user_include;
+                       zval_dtor(object);
+                       FREE_ZVAL(object);
                        return NULL;
                } else {
                        if (retval_ptr) {
@@ -353,12 +329,46 @@ static php_stream *user_wrapper_opener(php_stream_wrapper 
*wrapper, char *filena
                        }
                }
        }
+       return object;
+}
 
-       if (context) {
-               add_property_resource(us->object, "context", context->rsrc_id);
-               zend_list_addref(context->rsrc_id);
-       } else {
-               add_property_null(us->object, "context");
+static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char 
*filename, char *mode, int options, char **opened_path, php_stream_context 
*context STREAMS_DC TSRMLS_DC)
+{
+       struct php_user_stream_wrapper *uwrap = (struct 
php_user_stream_wrapper*)wrapper->abstract;
+       php_userstream_data_t *us;
+       zval *zfilename, *zmode, *zopened, *zoptions, *zretval = NULL, 
*zfuncname;
+       zval **args[4];
+       int call_result;
+       php_stream *stream = NULL;
+       zend_bool old_in_user_include;
+
+       /* Try to catch bad usage without preventing flexibility */
+       if (FG(user_stream_current_filename) != NULL && strcmp(filename, 
FG(user_stream_current_filename)) == 0) {
+               php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, 
"infinite recursion prevented");
+               return NULL;
+       }
+       FG(user_stream_current_filename) = filename;
+
+       /* if the user stream was registered as local and we are in include 
context,
+               we add allow_url_include restrictions to allow_url_fopen ones */
+       /* we need only is_url == 0 here since if is_url == 1 and remote 
wrappers
+               were restricted we wouldn't get here */
+       old_in_user_include = PG(in_user_include);
+       if(uwrap->wrapper.is_url == 0 &&
+               (options & STREAM_OPEN_FOR_INCLUDE) &&
+               !PG(allow_url_include)) {
+               PG(in_user_include) = 1;
+       }
+
+       us = emalloc(sizeof(*us));
+       us->wrapper = uwrap;
+
+       us->object = user_stream_create_object(uwrap, context TSRMLS_CC);
+       if(us->object == NULL) {
+               FG(user_stream_current_filename) = NULL;
+               PG(in_user_include) = old_in_user_include;
+               efree(us);
+               return NULL;
        }
 
        /* call it's stream_open method - set up params first */
@@ -447,17 +457,11 @@ static php_stream 
*user_wrapper_opendir(php_stream_wrapper *wrapper, char *filen
        us = emalloc(sizeof(*us));
        us->wrapper = uwrap;
 
-       /* create an instance of our class */
-       ALLOC_ZVAL(us->object);
-       object_init_ex(us->object, uwrap->ce);
-       Z_SET_REFCOUNT_P(us->object, 1);
-       Z_SET_ISREF_P(us->object);
-
-       if (context) {
-               add_property_resource(us->object, "context", context->rsrc_id);
-               zend_list_addref(context->rsrc_id);
-       } else {
-               add_property_null(us->object, "context");
+       us->object = user_stream_create_object(uwrap, context TSRMLS_CC);
+       if(us == NULL) {
+               FG(user_stream_current_filename) = NULL;
+               efree(us);
+               return NULL;
        }
 
        /* call it's dir_open method - set up params first */
@@ -1157,16 +1161,9 @@ static int user_wrapper_unlink(php_stream_wrapper 
*wrapper, char *url, int optio
        int ret = 0;
 
        /* create an instance of our class */
-       ALLOC_ZVAL(object);
-       object_init_ex(object, uwrap->ce);
-       Z_SET_REFCOUNT_P(object, 1);
-       Z_SET_ISREF_P(object);
-
-       if (context) {
-               add_property_resource(object, "context", context->rsrc_id);
-               zend_list_addref(context->rsrc_id);
-       } else {
-               add_property_null(object, "context");
+       object = user_stream_create_object(uwrap, context TSRMLS_CC);
+       if(object == NULL) {
+               return ret;
        }
 
        /* call the unlink method */
@@ -1211,16 +1208,9 @@ static int user_wrapper_rename(php_stream_wrapper 
*wrapper, char *url_from, char
        int ret = 0;
 
        /* create an instance of our class */
-       ALLOC_ZVAL(object);
-       object_init_ex(object, uwrap->ce);
-       Z_SET_REFCOUNT_P(object, 1);
-       Z_SET_ISREF_P(object);
-
-       if (context) {
-               add_property_resource(object, "context", context->rsrc_id);
-               zend_list_addref(context->rsrc_id);
-       } else {
-               add_property_null(object, "context");
+       object = user_stream_create_object(uwrap, context TSRMLS_CC);   
+       if(object == NULL) {
+               return ret;
        }
 
        /* call the rename method */
@@ -1270,16 +1260,9 @@ static int user_wrapper_mkdir(php_stream_wrapper 
*wrapper, char *url, int mode,
        int ret = 0;
 
        /* create an instance of our class */
-       ALLOC_ZVAL(object);
-       object_init_ex(object, uwrap->ce);
-       Z_SET_REFCOUNT_P(object, 1);
-       Z_SET_ISREF_P(object);
-
-       if (context) {
-               add_property_resource(object, "context", context->rsrc_id);
-               zend_list_addref(context->rsrc_id);
-       } else {
-               add_property_null(object, "context");
+       object = user_stream_create_object(uwrap, context TSRMLS_CC);   
+       if(object == NULL) {
+               return ret;
        }
 
        /* call the mkdir method */
@@ -1335,16 +1318,9 @@ static int user_wrapper_rmdir(php_stream_wrapper 
*wrapper, char *url, int option
        int ret = 0;
 
        /* create an instance of our class */
-       ALLOC_ZVAL(object);
-       object_init_ex(object, uwrap->ce);
-       Z_SET_REFCOUNT_P(object, 1);
-       Z_SET_ISREF_P(object);
-
-       if (context) {
-               add_property_resource(object, "context", context->rsrc_id);
-               zend_list_addref(context->rsrc_id);
-       } else {
-               add_property_null(object, "context");
+       object = user_stream_create_object(uwrap, context TSRMLS_CC);   
+       if(object == NULL) {
+               return ret;
        }
 
        /* call the rmdir method */
@@ -1420,16 +1396,10 @@ static int user_wrapper_metadata(php_stream_wrapper 
*wrapper, char *url, int opt
        }
 
        /* create an instance of our class */
-       ALLOC_ZVAL(object);
-       object_init_ex(object, uwrap->ce);
-       Z_SET_REFCOUNT_P(object, 1);
-       Z_SET_ISREF_P(object);
-
-       if (context) {
-               add_property_resource(object, "context", context->rsrc_id);
-               zend_list_addref(context->rsrc_id);
-       } else {
-               add_property_null(object, "context");
+       object = user_stream_create_object(uwrap, context TSRMLS_CC);   
+       if(object == NULL) {
+               zval_ptr_dtor(&zvalue);
+               return ret;
        }
 
        /* call the mkdir method */
@@ -1484,16 +1454,9 @@ static int user_wrapper_stat_url(php_stream_wrapper 
*wrapper, char *url, int fla
        int ret = -1;
 
        /* create an instance of our class */
-       ALLOC_ZVAL(object);
-       object_init_ex(object, uwrap->ce);
-       Z_SET_REFCOUNT_P(object, 1);
-       Z_SET_ISREF_P(object);
-
-       if (context) {
-               add_property_resource(object, "context", context->rsrc_id);
-               zend_list_addref(context->rsrc_id);
-       } else {
-               add_property_null(object, "context");
+       object = user_stream_create_object(uwrap, context TSRMLS_CC);   
+       if(object == NULL) {
+               return ret;
        }
 
        /* call it's stat_url method - set up params first */
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to