diff options
Diffstat (limited to 'Zend')
| -rw-r--r-- | Zend/zend_API.c | 24 | ||||
| -rw-r--r-- | Zend/zend_API.h | 3 | ||||
| -rw-r--r-- | Zend/zend_exceptions.c | 32 |
3 files changed, 50 insertions, 9 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 8202b9a505..0757cc9261 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3776,6 +3776,30 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const } /* }}} */ +ZEND_API void zend_unset_property(zend_class_entry *scope, zval *object, const char *name, int name_length TSRMLS_DC) /* {{{ */ +{ + zval *property; + zend_class_entry *old_scope = EG(scope); + + EG(scope) = scope; + + if (!Z_OBJ_HT_P(object)->unset_property) { + const char *class_name; + zend_uint class_name_len; + + zend_get_object_classname(object, &class_name, &class_name_len TSRMLS_CC); + + zend_error(E_CORE_ERROR, "Property %s of class %s cannot be unset", name, class_name); + } + MAKE_STD_ZVAL(property); + ZVAL_STRINGL(property, name, name_length, 1); + Z_OBJ_HT_P(object)->unset_property(object, property, 0 TSRMLS_CC); + zval_ptr_dtor(&property); + + EG(scope) = old_scope; +} +/* }}} */ + ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, const char *name, int name_length TSRMLS_DC) /* {{{ */ { zval *tmp; diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 53c1a4cbb5..dadeaf5849 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -330,6 +330,7 @@ ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, c ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, const char *name, int name_length, double value TSRMLS_DC); ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, const char *name, int name_length, const char *value TSRMLS_DC); ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, const char *name, int name_length, const char *value, int value_length TSRMLS_DC); +ZEND_API void zend_unset_property(zend_class_entry *scope, zval *object, const char *name, int name_length TSRMLS_DC); ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *name, int name_length, zval *value TSRMLS_DC); ZEND_API int zend_update_static_property_null(zend_class_entry *scope, const char *name, int name_length TSRMLS_DC); @@ -664,7 +665,7 @@ END_EXTERN_C() } \ RETURN_FALSE; \ } \ - RETVAL_STRINGL((s), __len, (dup)); \ + RETVAL_STRINGL((s), (int)__len, (dup)); \ } while (0) diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 95d18f45fb..f219687335 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -229,13 +229,9 @@ ZEND_METHOD(exception, __construct) /* {{{ proto Exception::__wakeup() Exception unserialize checks */ #define CHECK_EXC_TYPE(name, type) \ - value = zend_read_property(default_exception_ce, object, name, sizeof(name)-1, 0 TSRMLS_CC); \ + value = zend_read_property(default_exception_ce, object, name, sizeof(name)-1, 1 TSRMLS_CC); \ if (value && Z_TYPE_P(value) != IS_NULL && Z_TYPE_P(value) != type) { \ - zval *tmp; \ - MAKE_STD_ZVAL(tmp); \ - ZVAL_STRINGL(tmp, name, sizeof(name)-1, 1); \ - Z_OBJ_HANDLER_P(object, unset_property)(object, tmp, 0 TSRMLS_CC); \ - zval_ptr_dtor(&tmp); \ + zend_unset_property(default_exception_ce, object, name, sizeof(name)-1 TSRMLS_CC); \ } ZEND_METHOD(exception, __wakeup) @@ -248,7 +244,12 @@ ZEND_METHOD(exception, __wakeup) CHECK_EXC_TYPE("file", IS_STRING); CHECK_EXC_TYPE("line", IS_LONG); CHECK_EXC_TYPE("trace", IS_ARRAY); - CHECK_EXC_TYPE("previous", IS_OBJECT); + value = zend_read_property(default_exception_ce, object, "previous", sizeof("previous")-1, 1 TSRMLS_CC); + if (value && Z_TYPE_P(value) != IS_NULL && (Z_TYPE_P(value) != IS_OBJECT || + !instanceof_function(Z_OBJCE_P(value), default_exception_ce TSRMLS_CC) || + value == object)) { + zend_unset_property(default_exception_ce, object, "previous", sizeof("previous")-1 TSRMLS_CC); + } } /* }}} */ @@ -727,7 +728,11 @@ ZEND_METHOD(exception, __toString) zval_dtor(&file); zval_dtor(&line); - exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 0 TSRMLS_CC); + Z_OBJPROP_P(exception)->nApplyCount++; + exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC); + if (exception && Z_TYPE_P(exception) == IS_OBJECT && Z_OBJPROP_P(exception)->nApplyCount > 0) { + exception = NULL; + } if (trace) { zval_ptr_dtor(&trace); @@ -736,6 +741,17 @@ ZEND_METHOD(exception, __toString) } zval_dtor(&fname); + /* Reset apply counts */ + exception = getThis(); + while (exception && Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), default_exception_ce TSRMLS_CC)) { + if(Z_OBJPROP_P(exception)->nApplyCount) { + Z_OBJPROP_P(exception)->nApplyCount--; + } else { + break; + } + exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC); + } + /* We store the result in the private property string so we can access * the result in uncaught exception handlers without memleaks. */ zend_update_property_string(default_exception_ce, getThis(), "string", sizeof("string")-1, str TSRMLS_CC); |
