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

This commit is contained in:
Stanislav Malyshev 2012-08-07 22:59:12 -07:00
parent 01e414bb6f
commit 4db70fd406
2 changed files with 184 additions and 118 deletions

View File

@ -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==

View File

@ -281,6 +281,57 @@ typedef struct _php_userstream_data php_userstream_data_t;
}}} **/
static zval *user_stream_create_object(struct php_user_stream_wrapper *uwrap, php_stream_context *context TSRMLS_DC)
{
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 (context) {
add_property_resource(object, "context", context->rsrc_id);
zend_list_addref(context->rsrc_id);
} else {
add_property_null(object, "context");
}
if (uwrap->ce->constructor) {
zend_fcall_info fci;
zend_fcall_info_cache fcc;
zval *retval_ptr;
fci.size = sizeof(fci);
fci.function_table = &uwrap->ce->function_table;
fci.function_name = NULL;
fci.symbol_table = NULL;
fci.object_ptr = object;
fci.retval_ptr_ptr = &retval_ptr;
fci.param_count = 0;
fci.params = NULL;
fci.no_separation = 1;
fcc.initialized = 1;
fcc.function_handler = uwrap->ce->constructor;
fcc.calling_scope = EG(scope);
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(object);
FREE_ZVAL(object);
return NULL;
} else {
if (retval_ptr) {
zval_ptr_dtor(&retval_ptr);
}
}
}
return object;
}
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;
@ -312,53 +363,12 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, char *filena
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;
zval *retval_ptr;
fci.size = sizeof(fci);
fci.function_table = &uwrap->ce->function_table;
fci.function_name = NULL;
fci.symbol_table = NULL;
fci.object_ptr = us->object;
fci.retval_ptr_ptr = &retval_ptr;
fci.param_count = 0;
fci.params = NULL;
fci.no_separation = 1;
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;
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;
return NULL;
} else {
if (retval_ptr) {
zval_ptr_dtor(&retval_ptr);
}
}
}
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->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 */