mirror of
https://github.com/php/php-src.git
synced 2024-09-22 10:27:25 +00:00
fix bug #40459 - make all stream funcs that create object call ctor
This commit is contained in:
parent
01e414bb6f
commit
4db70fd406
103
ext/standard/tests/streams/bug40459.phpt
Normal file
103
ext/standard/tests/streams/bug40459.phpt
Normal 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==
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user