The address of $this passed to drectly called internal constructor in execute_data->return_value.
Internal constructors should use ZEND_CTOR_MAKE_NULL() macro (insted of previous ZEND_NULL(EG(This))) to do the work.
This patch doesn't fix the problem for indirectly called constructors. e.g. parant::__construct().
} \
} while (0)
+/* May be used in internal constructors to make them return NULL */
+#if 1 // support for directly called constructors only ???
+#define ZEND_CTOR_MAKE_NULL() do { \
+ if (EG(current_execute_data)->return_value) { \
+ zval_ptr_dtor(EG(current_execute_data)->return_value); \
+ ZVAL_NULL(EG(current_execute_data)->return_value); \
+ } \
+ } while (0)
+#else // attempt to support calls to parent::__construct() ???
+#define ZEND_CTOR_MAKE_NULL() do { \
+ if (EG(current_execute_data)->return_value) { \
+ zval_ptr_dtor(EG(current_execute_data)->return_value); \
+ ZVAL_NULL(EG(current_execute_data)->return_value); \
+ } else if (EG(current_execute_data)->prev_execute_data && \
+ EG(current_execute_data)->prev_execute_data->object == \
+ EG(current_execute_data)->object) { \
+ EG(current_execute_data)->prev_execute_data->object = NULL; \
+ } \
+ } while (0)
+#endif
+
#define RETURN_ZVAL_FAST(z) { RETVAL_ZVAL_FAST(z); return; }
#define HASH_OF(p) (Z_TYPE_P(p)==IS_ARRAY ? Z_ARRVAL_P(p) : ((Z_TYPE_P(p)==IS_OBJECT ? Z_OBJ_HT_P(p)->get_properties((p) TSRMLS_CC) : NULL)))
EX(call) = zend_vm_stack_push_call_frame(
fbc, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
+
+ if (OP2_TYPE == IS_UNUSED) {
+ EX(call)->return_value = NULL;
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
+ EX(call)->return_value = EX_VAR(opline->result.var);
+ } else {
+ EX(call)->return_value = NULL;
}
CHECK_EXCEPTION();
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
+ EX(call)->return_value = EX_VAR(opline->result.var);
+ } else {
+ EX(call)->return_value = NULL;
}
CHECK_EXCEPTION();
EX(call) = zend_vm_stack_push_call_frame(
fbc, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
+ if (IS_CONST == IS_UNUSED) {
+ EX(call)->return_value = NULL;
+ }
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
EX(call) = zend_vm_stack_push_call_frame(
fbc, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
+ if (IS_TMP_VAR == IS_UNUSED) {
+ EX(call)->return_value = NULL;
+ }
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
EX(call) = zend_vm_stack_push_call_frame(
fbc, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
+ if (IS_VAR == IS_UNUSED) {
+ EX(call)->return_value = NULL;
+ }
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
EX(call) = zend_vm_stack_push_call_frame(
fbc, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
+ if (IS_UNUSED == IS_UNUSED) {
+ EX(call)->return_value = NULL;
+ }
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
EX(call) = zend_vm_stack_push_call_frame(
fbc, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
+ if (IS_CV == IS_UNUSED) {
+ EX(call)->return_value = NULL;
+ }
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
EX(call) = zend_vm_stack_push_call_frame(
fbc, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
+ if (IS_CONST == IS_UNUSED) {
+ EX(call)->return_value = NULL;
+ }
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
EX(call) = zend_vm_stack_push_call_frame(
fbc, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
+ if (IS_TMP_VAR == IS_UNUSED) {
+ EX(call)->return_value = NULL;
+ }
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
EX(call) = zend_vm_stack_push_call_frame(
fbc, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
+ if (IS_VAR == IS_UNUSED) {
+ EX(call)->return_value = NULL;
+ }
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
EX(call) = zend_vm_stack_push_call_frame(
fbc, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
+ if (IS_UNUSED == IS_UNUSED) {
+ EX(call)->return_value = NULL;
+ }
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
EX(call) = zend_vm_stack_push_call_frame(
fbc, opline->extended_value, 0, ce, object, EX(call) TSRMLS_CC);
+ if (IS_CV == IS_UNUSED) {
+ EX(call)->return_value = NULL;
+ }
+
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO!", &time_str, &time_str_len, &timezone_object, date_ce_timezone)) {
if (!php_date_initialize(Z_PHPDATE_P(getThis()), time_str, time_str_len, NULL, timezone_object, 1 TSRMLS_CC)) {
-//??? ZVAL_NULL(getThis());
+ ZEND_CTOR_MAKE_NULL();
}
}
zend_restore_error_handling(&error_handling TSRMLS_CC);
if (object) { \
zend_object_store_ctor_failed(Z_OBJ_P(object) TSRMLS_CC); \
Z_OBJ_P(object) = NULL; \
+ ZEND_CTOR_MAKE_NULL(); \
} \
} while (0)
if (Z_TYPE_P(return_value) == IS_OBJECT && Z_OBJ_P(return_value) == NULL) {
zend_object_store_ctor_failed(Z_OBJ(orig_this) TSRMLS_CC);
zval_dtor(&orig_this);
+ ZEND_CTOR_MAKE_NULL();
}
}
if (Z_TYPE_P(return_value) == IS_OBJECT && Z_OBJ_P(return_value) == NULL) {
zend_object_store_ctor_failed(Z_OBJ(orig_this) TSRMLS_CC);
+ zval_dtor(&orig_this);
+ ZEND_CTOR_MAKE_NULL();
}
}
*/
PHP_METHOD( Collator, __construct )
{
+ zval orig_this = *getThis();
+
return_value = getThis();
collator_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+
+ if (Z_TYPE_P(return_value) == IS_OBJECT && Z_OBJ_P(return_value) == NULL) {
+ zend_object_store_ctor_failed(Z_OBJ(orig_this) TSRMLS_CC);
+ zval_dtor(&orig_this);
+ ZEND_CTOR_MAKE_NULL();
+ }
}
/* }}} */
*/
U_CFUNC PHP_METHOD( IntlDateFormatter, __construct )
{
+ zval orig_this = *getThis();
+
/* return_value param is being changed, therefore we will always return
* NULL here */
return_value = getThis();
datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+
+ if (Z_TYPE_P(return_value) == IS_OBJECT && Z_OBJ_P(return_value) == NULL) {
+ zend_object_store_ctor_failed(Z_OBJ(orig_this) TSRMLS_CC);
+ zval_dtor(&orig_this);
+ ZEND_CTOR_MAKE_NULL();
+ }
}
/* }}} */
*/
PHP_METHOD( NumberFormatter, __construct )
{
+ zval orig_this = *getThis();
+
return_value = getThis();
numfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+
+ if (Z_TYPE_P(return_value) == IS_OBJECT && Z_OBJ_P(return_value) == NULL) {
+ zend_object_store_ctor_failed(Z_OBJ(orig_this) TSRMLS_CC);
+ zval_dtor(&orig_this);
+ ZEND_CTOR_MAKE_NULL();
+ }
}
/* }}} */
*/
PHP_METHOD( MessageFormatter, __construct )
{
+ zval orig_this = *getThis();
+
return_value = getThis();
msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+
+ if (Z_TYPE_P(return_value) == IS_OBJECT && Z_OBJ_P(return_value) == NULL) {
+ zend_object_store_ctor_failed(Z_OBJ(orig_this) TSRMLS_CC);
+ zval_dtor(&orig_this);
+ ZEND_CTOR_MAKE_NULL();
+ }
}
/* }}} */
*/
PHP_METHOD( ResourceBundle, __construct )
{
+ zval orig_this = *getThis();
+
return_value = getThis();
resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+
+ if (Z_TYPE_P(return_value) == IS_OBJECT && Z_OBJ_P(return_value) == NULL) {
+ zend_object_store_ctor_failed(Z_OBJ(orig_this) TSRMLS_CC);
+ zval_dtor(&orig_this);
+ ZEND_CTOR_MAKE_NULL();
+ }
}
/* }}} */
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!s!a!", &data_source, &data_source_len,
&username, &usernamelen, &password, &passwordlen, &options)) {
- Z_OBJ_P(object) = NULL;
+ ZEND_CTOR_MAKE_NULL();
return;
}
snprintf(alt_dsn, sizeof(alt_dsn), "pdo.dsn.%s", data_source);
if (FAILURE == cfg_get_string(alt_dsn, &ini_dsn)) {
zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "invalid data source name");
- Z_OBJ_P(object) = NULL;
+ ZEND_CTOR_MAKE_NULL();
return;
}
if (!colon) {
zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "invalid data source name (via INI: %s)", alt_dsn);
- Z_OBJ_P(object) = NULL;
+ ZEND_CTOR_MAKE_NULL();
return;
}
}
data_source = dsn_from_uri(data_source + sizeof("uri:")-1, alt_dsn, sizeof(alt_dsn) TSRMLS_CC);
if (!data_source) {
zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "invalid data source URI");
- Z_OBJ_P(object) = NULL;
+ ZEND_CTOR_MAKE_NULL();
return;
}
colon = strchr(data_source, ':');
if (!colon) {
zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "invalid data source name (via URI)");
- Z_OBJ_P(object) = NULL;
+ ZEND_CTOR_MAKE_NULL();
return;
}
}
/* NB: don't want to include the data_source in the error message as
* it might contain a password */
zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC, "could not find driver");
- Z_OBJ_P(object) = NULL;
+ ZEND_CTOR_MAKE_NULL();
return;
}
/* the connection failed; things will tidy up in free_storage */
/* XXX raise exception */
- Z_OBJ_P(object) = NULL;
+ ZEND_CTOR_MAKE_NULL();
}
/* }}} */
if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
Z_OBJ_P(object) = NULL;
+ ZEND_CTOR_MAKE_NULL();
object = NULL; /* marks failure */
} else if (!Z_ISUNDEF(retval)) {
zval_ptr_dtor(&retval);