@@ -6001,7 +6001,6 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
60016001 zend_object * zobj ;
60026002 zend_class_entry * ce , * scope ;
60036003 zend_function * clone ;
6004- zend_object_clone_obj_t clone_call ;
60056004
60066005 SAVE_OPLINE ();
60076006 obj = GET_OP1_OBJ_ZVAL_PTR_UNDEF (BP_VAR_R );
@@ -6026,17 +6025,18 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
60266025 }
60276026 zend_type_error ("clone(): Argument #1 ($object) must be of type object, %s given" , zend_zval_value_name (obj ));
60286027 FREE_OP1 ();
6028+ FREE_OP2 ();
60296029 HANDLE_EXCEPTION ();
60306030 }
60316031 } while (0 );
60326032
60336033 zobj = Z_OBJ_P (obj );
60346034 ce = zobj -> ce ;
60356035 clone = ce -> clone ;
6036- clone_call = zobj -> handlers -> clone_obj ;
6037- if (UNEXPECTED (clone_call == NULL )) {
6036+ if (UNEXPECTED (zobj -> handlers -> clone_obj == NULL )) {
60386037 zend_throw_error (NULL , "Trying to clone an uncloneable object of class %s" , ZSTR_VAL (ce -> name ));
60396038 FREE_OP1 ();
6039+ FREE_OP2 ();
60406040 ZVAL_UNDEF (EX_VAR (opline -> result .var ));
60416041 HANDLE_EXCEPTION ();
60426042 }
@@ -6048,15 +6048,55 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
60486048 || UNEXPECTED (!zend_check_protected (zend_get_function_root_class (clone ), scope ))) {
60496049 zend_wrong_clone_call (clone , scope );
60506050 FREE_OP1 ();
6051+ FREE_OP2 ();
60516052 ZVAL_UNDEF (EX_VAR (opline -> result .var ));
60526053 HANDLE_EXCEPTION ();
60536054 }
60546055 }
60556056 }
60566057
6057- ZVAL_OBJ (EX_VAR (opline -> result .var ), clone_call (zobj ));
6058+ zend_object * cloned ;
6059+ if (zobj -> handlers -> clone_obj_with ) {
6060+ scope = EX (func )-> op_array .scope ;
6061+ if (OP2_TYPE != IS_UNUSED ) {
6062+ zval * properties = GET_OP2_ZVAL_PTR (BP_VAR_R );
6063+ if (Z_TYPE_P (properties ) != IS_ARRAY ) {
6064+ zend_type_error ("clone(): Argument #2 ($withProperties) must be of type array, %s given" , zend_zval_value_name (obj ));
6065+ FREE_OP1 ();
6066+ FREE_OP2 ();
6067+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
6068+ HANDLE_EXCEPTION ();
6069+ }
6070+
6071+ cloned = zobj -> handlers -> clone_obj_with (zobj , scope , Z_ARR_P (properties ));
6072+ } else {
6073+ cloned = zobj -> handlers -> clone_obj_with (zobj , scope , NULL );
6074+ }
6075+
6076+ if (UNEXPECTED (EG (exception ))) {
6077+ if (cloned ) {
6078+ OBJ_RELEASE (cloned );
6079+ }
6080+ FREE_OP1 ();
6081+ FREE_OP2 ();
6082+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
6083+ HANDLE_EXCEPTION ();
6084+ }
6085+ } else {
6086+ if (OP2_TYPE != IS_UNUSED ) {
6087+ zend_throw_error (NULL , "Trying to clone an object with updated properties that is not compatible %s" , ZSTR_VAL (ce -> name ));
6088+ FREE_OP1 ();
6089+ FREE_OP2 ();
6090+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
6091+ HANDLE_EXCEPTION ();
6092+ }
6093+
6094+ cloned = zobj -> handlers -> clone_obj (zobj );
6095+ }
60586096
6097+ ZVAL_OBJ (EX_VAR (opline -> result .var ), cloned );
60596098 FREE_OP1 ();
6099+ FREE_OP2 ();
60606100 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION ();
60616101}
60626102
0 commit comments