php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #64196
Patch __clone-2.patch revision 2013-02-12 23:12 UTC by krakjoe@php.net
revision 2013-02-12 20:03 UTC by krakjoe@php.net
Patch __clone.patch revision 2013-02-12 14:29 UTC by pthreads at pthreads dot org

Patch __clone.patch for Reproducible crash Bug #64196

Patch version 2013-02-12 14:29 UTC

Return to Bug #64196 | Download this patch
Patch Revisions:

Developer: pthreads@pthreads.org

--- zend_objects_old.c	2013-02-12 13:54:50.141982732 +0000
+++ zend_objects.c	2013-02-12 14:05:47.343379861 +0000
@@ -217,6 +217,7 @@
 
 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;
@@ -225,10 +226,39 @@
 	/* 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) {
+		ALLOC_HASHTABLE(old_object->guards);
+		zend_hash_init(old_object->guards, 0, NULL, NULL, 0);
+
+		zend_hash_update(
+			old_object->guards, 
+			ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME), 
+			(void **) &guarded, sizeof(zend_uint), NULL
+		);
+
+	} else if (zend_hash_find(old_object->guards, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME), (void **) &guarded) == SUCCESS) {
+		zend_error(E_ERROR, "recursion detected in __clone");
+	}	
+
 	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(
+			new_object->guards, 
+			ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME), 
+			(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_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME));
+	zend_hash_del(new_object->guards, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME));		
+	
 	return new_obj_val;
 }
 
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Sun Apr 11 22:01:23 2021 UTC