@@ -6005,9 +6005,7 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
60056005 SAVE_OPLINE ();
60066006 obj = GET_OP1_OBJ_ZVAL_PTR_UNDEF (BP_VAR_R );
60076007
6008- /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync.
6009- * The OPcode intentionally does not support a clone-with property list to keep it simple.
6010- */
6008+ /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. */
60116009
60126010 do {
60136011 if (OP1_TYPE == IS_CONST ||
@@ -6027,6 +6025,7 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
60276025 }
60286026 zend_type_error ("clone(): Argument #1 ($object) must be of type object, %s given" , zend_zval_value_name (obj ));
60296027 FREE_OP1 ();
6028+ FREE_OP2 ();
60306029 HANDLE_EXCEPTION ();
60316030 }
60326031 } while (0 );
@@ -6037,6 +6036,7 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
60376036 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,6 +6048,7 @@ 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_bad_method_call (clone , clone -> common .function_name , scope );
60506050 FREE_OP1 ();
6051+ FREE_OP2 ();
60516052 ZVAL_UNDEF (EX_VAR (opline -> result .var ));
60526053 HANDLE_EXCEPTION ();
60536054 }
@@ -6057,8 +6058,29 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
60576058 zend_object * cloned ;
60586059 if (zobj -> handlers -> clone_obj_with ) {
60596060 scope = EX (func )-> op_array .scope ;
6060- cloned = zobj -> handlers -> clone_obj_with (zobj , scope , & zend_empty_array );
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 , & zend_empty_array );
6074+ }
60616075 } else {
6076+ if (OP2_TYPE != IS_UNUSED ) {
6077+ zend_throw_error (NULL , "Trying to clone an object with updated properties that is not compatible %s" , ZSTR_VAL (ce -> name ));
6078+ FREE_OP1 ();
6079+ FREE_OP2 ();
6080+ ZVAL_UNDEF (EX_VAR (opline -> result .var ));
6081+ HANDLE_EXCEPTION ();
6082+ }
6083+
60626084 cloned = zobj -> handlers -> clone_obj (zobj );
60636085 }
60646086
@@ -6069,6 +6091,7 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
60696091 ZVAL_UNDEF (EX_VAR (opline -> result .var ));
60706092 }
60716093 FREE_OP1 ();
6094+ FREE_OP2 ();
60726095 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION ();
60736096}
60746097
0 commit comments