@@ -6005,9 +6005,7 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
6005
6005
SAVE_OPLINE ();
6006
6006
obj = GET_OP1_OBJ_ZVAL_PTR_UNDEF (BP_VAR_R );
6007
6007
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. */
6011
6009
6012
6010
do {
6013
6011
if (OP1_TYPE == IS_CONST ||
@@ -6027,6 +6025,7 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
6027
6025
}
6028
6026
zend_type_error ("clone(): Argument #1 ($object) must be of type object, %s given" , zend_zval_value_name (obj ));
6029
6027
FREE_OP1 ();
6028
+ FREE_OP2 ();
6030
6029
HANDLE_EXCEPTION ();
6031
6030
}
6032
6031
} while (0 );
@@ -6037,6 +6036,7 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
6037
6036
if (UNEXPECTED (zobj -> handlers -> clone_obj == NULL )) {
6038
6037
zend_throw_error (NULL , "Trying to clone an uncloneable object of class %s" , ZSTR_VAL (ce -> name ));
6039
6038
FREE_OP1 ();
6039
+ FREE_OP2 ();
6040
6040
ZVAL_UNDEF (EX_VAR (opline -> result .var ));
6041
6041
HANDLE_EXCEPTION ();
6042
6042
}
@@ -6048,6 +6048,7 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
6048
6048
|| UNEXPECTED (!zend_check_protected (zend_get_function_root_class (clone ), scope ))) {
6049
6049
zend_bad_method_call (clone , clone -> common .function_name , scope );
6050
6050
FREE_OP1 ();
6051
+ FREE_OP2 ();
6051
6052
ZVAL_UNDEF (EX_VAR (opline -> result .var ));
6052
6053
HANDLE_EXCEPTION ();
6053
6054
}
@@ -6057,8 +6058,29 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
6057
6058
zend_object * cloned ;
6058
6059
if (zobj -> handlers -> clone_obj_with ) {
6059
6060
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
+ }
6061
6075
} 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
+
6062
6084
cloned = zobj -> handlers -> clone_obj (zobj );
6063
6085
}
6064
6086
@@ -6069,6 +6091,7 @@ ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
6069
6091
ZVAL_UNDEF (EX_VAR (opline -> result .var ));
6070
6092
}
6071
6093
FREE_OP1 ();
6094
+ FREE_OP2 ();
6072
6095
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION ();
6073
6096
}
6074
6097
0 commit comments