@@ -169,7 +169,6 @@ php_stream_filter_status_t userfilter_filter(
169169 return PSFS_ERR_FATAL ;
170170 }
171171 }
172- zend_string_release (stream_name );
173172
174173 EG (fake_scope ) = old_scope ;
175174
@@ -213,22 +212,23 @@ php_stream_filter_status_t userfilter_filter(
213212
214213 /* filter resources are cleaned up by the stream destructor,
215214 * keeping a reference to the stream resource here would prevent it
216- * from being destroyed properly */
217- zend_property_info * prop_info = zend_hash_str_find_ptr (& Z_OBJCE_P (obj )-> properties_info , "stream" , sizeof ("stream" )- 1 );
218- zval * stream_prop = zend_hash_str_find (Z_OBJPROP_P (obj ), "stream" , sizeof ("stream" )- 1 );
219-
220- if (stream_prop ) {
221- if (prop_info ) {
222- /* Declared property: set to UNDEF to make it uninitialized */
223- zval_ptr_dtor (stream_prop );
224- ZVAL_UNDEF (stream_prop );
225- } else {
226- /* Dynamic property: set to null */
227- zval_ptr_dtor (stream_prop );
228- ZVAL_NULL (stream_prop );
229- }
215+ * from being destroyed properly.
216+ * Since the property accepted a resource assignment above, it must have
217+ * no type hint or be typed as mixed, so we can safely assign null.
218+ */
219+ old_scope = EG (fake_scope );
220+ EG (fake_scope ) = Z_OBJCE_P (obj );
221+
222+ if (Z_OBJ_HT_P (obj )-> has_property (Z_OBJ_P (obj ), stream_name , ZEND_PROPERTY_EXISTS , NULL )) {
223+ zval null_zval ;
224+ ZVAL_NULL (& null_zval );
225+ zend_update_property_ex (Z_OBJCE_P (obj ), Z_OBJ_P (obj ), stream_name , & null_zval );
230226 }
231227
228+ EG (fake_scope ) = old_scope ;
229+
230+ zend_string_release (stream_name );
231+
232232 zval_ptr_dtor (& args [3 ]);
233233 zval_ptr_dtor (& args [2 ]);
234234 zval_ptr_dtor (& args [1 ]);
0 commit comments