|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
Patch __clone-2.patch for Reproducible crash Bug #64196Patch version 2013-02-12 20:03 UTC Return to Bug #64196 | Download this patchThis patch is obsolete Obsoleted by patches: Patch Revisions:Developer: krakjoe@php.net
--- zend_objects_old.c 2013-02-12 13:54:50.141982732 +0000
+++ zend_objects.c 2013-02-12 19:56:49.242652512 +0000
@@ -26,6 +26,9 @@
#include "zend_interfaces.h"
#include "zend_exceptions.h"
+#define ZEND_CLONE_GUARD_NAME "$__clone"
+#define ZEND_CLONE_GUARD_LENGTH sizeof(ZEND_CLONE_GUARD_NAME)
+
ZEND_API void zend_object_std_init(zend_object *object, zend_class_entry *ce TSRMLS_DC)
{
object->ce = ce;
@@ -217,18 +220,40 @@
ZEND_API zend_object_value zend_objects_clone_obj(zval *zobject TSRMLS_DC)
{
+ zend_uint guarded = 1;
zend_object_value new_obj_val;
zend_object *old_object;
zend_object *new_object;
zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
-
+
/* assume that create isn't overwritten, so when clone depends on the
* overwritten one then it must itself be overwritten */
old_object = zend_objects_get_address(zobject TSRMLS_CC);
+
+ if (old_object->guards) {
+ if (zend_hash_find(old_object->guards, ZEND_CLONE_GUARD_NAME, ZEND_CLONE_GUARD_LENGTH, (void **) &guarded) == SUCCESS) {
+ zend_error(E_ERROR, "recursion detected in __clone");
+ }
+ } else {
+ ALLOC_HASHTABLE(old_object->guards);
+ zend_hash_init(old_object->guards, 0, NULL, NULL, 0);
+ }
+
new_obj_val = zend_objects_new(&new_object, old_object->ce TSRMLS_CC);
+ if (!new_object->guards) {
+ ALLOC_HASHTABLE(new_object->guards);
+ zend_hash_init(new_object->guards, 0, NULL, NULL, 0);
+ }
+
+ zend_hash_update(old_object->guards, ZEND_CLONE_GUARD_NAME, ZEND_CLONE_GUARD_LENGTH, (void **) &guarded, sizeof(zend_uint), NULL);
+ zend_hash_update(new_object->guards, ZEND_CLONE_GUARD_NAME, ZEND_CLONE_GUARD_LENGTH, (void **) &guarded, sizeof(zend_uint), NULL);
+
zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC);
+ zend_hash_del(old_object->guards, ZEND_CLONE_GUARD_NAME, ZEND_CLONE_GUARD_LENGTH);
+ zend_hash_del(new_object->guards, ZEND_CLONE_GUARD_NAME, ZEND_CLONE_GUARD_LENGTH);
+
return new_obj_val;
}
|
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 13:00:02 2025 UTC |