Skip to content

Commit 8278442

Browse files
Narrow backed-enum scalar cast to Enum / ?Enum only
Per @arnaudlb's review: the scalar→backed-enum coercion should not fire when the property type already accepts the scalar literally, e.g. `Suit|string|int`. In that case the caller opted into accepting the raw scalar and promoting it to an enum case would be a surprising silent conversion. Add `(ZEND_TYPE_PURE_MASK(pi->type) & ~MAY_BE_NULL) == 0` so the cast only runs for pure-enum types (`Enum`) and their nullable variant (`?Enum`). Union types get the engine's standard type check.
1 parent 25226d3 commit 8278442

1 file changed

Lines changed: 5 additions & 1 deletion

File tree

deepclone.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,11 @@ static bool dc_write_backed_property(zend_object *obj, zend_property_info *pi,
769769
bool enum_holder_used = false;
770770
if ((Z_TYPE_P(value) == IS_LONG || Z_TYPE_P(value) == IS_STRING)
771771
&& ZEND_TYPE_HAS_NAME(pi->type)
772-
&& !ZEND_TYPE_HAS_LIST(pi->type))
772+
&& !ZEND_TYPE_HAS_LIST(pi->type)
773+
/* Only cast for types of the form `Enum` or `?Enum` — unions like
774+
* `Enum|string|int` already accept the scalar literally, so casting
775+
* it to an enum case would be surprising. */
776+
&& (ZEND_TYPE_PURE_MASK(pi->type) & ~MAY_BE_NULL) == 0)
773777
{
774778
zend_class_entry *type_ce = zend_lookup_class_ex(
775779
ZEND_TYPE_NAME(pi->type), NULL, ZEND_FETCH_CLASS_NO_AUTOLOAD);

0 commit comments

Comments
 (0)