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-2024 The PHP Group All rights reserved. |
Last updated: Thu Nov 21 16:01:29 2024 UTC |