diff options
| author | Gustavo André dos Santos Lopes <cataphract@php.net> | 2011-03-27 22:44:34 +0000 |
|---|---|---|
| committer | Gustavo André dos Santos Lopes <cataphract@php.net> | 2011-03-27 22:44:34 +0000 |
| commit | f7b7b6aa9eb43e5969dac9c8fcd92f0f2cb3e6d7 (patch) | |
| tree | d91751a1636f0ad1fea80c9d7ac59a140d72c679 /ext/spl/php_spl.c | |
| parent | 11efb7295e9a9889721c5ea0ebae7f5db157d950 (diff) | |
| download | php-git-f7b7b6aa9eb43e5969dac9c8fcd92f0f2cb3e6d7.tar.gz | |
- Improved upon r309729.
- Extented strategy to remaining the classes on spl_directory.c, even those that don't crash.
- UPGRADING.
- Better bug54384.phpt, with all the classes covered.
Diffstat (limited to 'ext/spl/php_spl.c')
| -rwxr-xr-x | ext/spl/php_spl.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index cd9a548d8f..de59a02c93 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -66,7 +66,7 @@ static PHP_GINIT_FUNCTION(spl) cwf->type = ZEND_INTERNAL_FUNCTION; cwf->common.function_name = "internal_construction_wrapper"; - cwf->common.scope = NULL; /* to be filled */ + cwf->common.scope = NULL; /* to be filled w/ object runtime class */ cwf->common.fn_flags = ZEND_ACC_PRIVATE; cwf->common.prototype = NULL; cwf->common.num_args = 0; /* not necessarily true but not enforced */ @@ -815,8 +815,18 @@ static void construction_wrapper(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ zval *retval_ptr = NULL; object_data = zend_object_store_get_object(this TSRMLS_CC); - zf = zend_get_std_object_handlers()->get_constructor(this TSRMLS_CC); this_ce = Z_OBJCE_P(this); + + /* The call of this internal function did not change the scope because + * zend_do_fcall_common_helper doesn't do that for internal instance + * function calls. So the visibility checks on zend_std_get_constructor + * will still work. Reflection refuses to instantiate classes whose + * constructor is not public so we're OK there too*/ + zf = zend_std_get_constructor(this TSRMLS_CC); + + if (zf == NULL) { + return; + } fci.size = sizeof(fci); fci.function_table = &this_ce->function_table; @@ -828,15 +838,17 @@ static void construction_wrapper(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ fci.params = emalloc(fci.param_count * sizeof *fci.params); if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), fci.params) == FAILURE) { zend_throw_exception(NULL, "Unexpected error fetching arguments", 0 TSRMLS_CC); - return; + goto cleanup; } } fci.object_ptr = this; fci.no_separation = 0; - + fci_cache.initialized = 1; - fci_cache.called_scope = EG(current_execute_data)->called_scope; - fci_cache.calling_scope = EG(current_execute_data)->current_scope; + fci_cache.called_scope = this_ce; /* set called scope to class of this */ + /* function->common.scope will replace it, except for + * ZEND_OVERLOADED_FUNCTION, which we won't get */ + fci_cache.calling_scope = EG(scope); fci_cache.function_handler = zf; fci_cache.object_ptr = this; @@ -852,6 +864,8 @@ static void construction_wrapper(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ "and its exceptions cannot be cleared", this_ce->name); cleanup: + /* no need to cleanup zf, zend_std_get_constructor never allocates a new + * function (so no ZEND_OVERLOADED_FUNCTION or call-via-handlers) */ if (fci.params != NULL) { efree(fci.params); } |
