Commit 3cb85cc681a for php.net

commit 3cb85cc681ac5f1120773917c8f089c898739f98
Author: Ilija Tovilo <ilija.tovilo@me.com>
Date:   Tue Feb 3 21:47:27 2026 +0100

    Fix assign-op/inc/dec on untyped hooked property backing value

    Fixes OSS-Fuzz #478009707
    Closes GH-21124

diff --git a/NEWS b/NEWS
index 81d0a689972..dd9fd9a2686 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ PHP                                                                        NEWS
     by setRawValueWithoutLazyInitialization() and newLazyGhost()). (Arnaud)
   . Fixed bug GH-20504 (Assertion failure in zend_get_property_guard when
     accessing properties on Reflection LazyProxy via isset()). (Arnaud)
+  . Fixed OSS-Fuzz #478009707 (Borked assign-op/inc/dec on untyped hooked
+    property backing value). (ilutov)

 - Curl:
   . Fixed bug GH-21023 (CURLOPT_XFERINFOFUNCTION crash with a null callback).
diff --git a/Zend/tests/oss-fuzz-478009707.phpt b/Zend/tests/oss-fuzz-478009707.phpt
new file mode 100644
index 00000000000..02ba186a49e
--- /dev/null
+++ b/Zend/tests/oss-fuzz-478009707.phpt
@@ -0,0 +1,23 @@
+--TEST--
+OSS-Fuzz #478009707: Assign-op/inc/dec on untyped hooked property backing value
+--FILE--
+<?php
+
+class C {
+    public $prop {
+        set {
+            $this->prop = $value;
+            $this->prop += 1;
+            $this->prop++;
+            ++$this->prop;
+        }
+    }
+}
+
+$c = new C(1);
+$c->prop = 1;
+var_dump($c->prop);
+
+?>
+--EXPECT--
+int(4)
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 3e1026ef60e..4ecd80837b1 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -1070,7 +1070,7 @@ ZEND_VM_C_LABEL(assign_op_object):
 					}

 					prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-					if (prop_info) {
+					if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) {
 						/* special case for typed properties */
 						zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC);
 					} else {
@@ -1326,7 +1326,8 @@ ZEND_VM_C_LABEL(pre_incdec_object):
 				}
 			} else {
 				prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2);
-				zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_pre_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
@@ -1394,7 +1395,8 @@ ZEND_VM_C_LABEL(post_incdec_object):
 				ZVAL_NULL(EX_VAR(opline->result.var));
 			} else {
 				prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
-				zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC);
+				zend_post_incdec_property_zval(zptr,
+					prop_info && ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC);
 			}
 		} else {
 			zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC);
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 46c04bdd6d2..d7c14a7cf80 100644
Binary files a/Zend/zend_vm_execute.h and b/Zend/zend_vm_execute.h differ