@@ -341,6 +341,8 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *
341341
342342 us = emalloc (sizeof (* us ));
343343 us -> wrapper = uwrap ;
344+ /* call_method_if_exists() may unregister the stream wrapper. Hold on to it. */
345+ GC_ADDREF (us -> wrapper -> resource );
344346
345347 user_stream_create_object (uwrap , context , & us -> object );
346348 if (Z_TYPE (us -> object ) == IS_UNDEF ) {
@@ -376,8 +378,6 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *
376378
377379 /* set wrapper data to be a reference to our object */
378380 ZVAL_COPY (& stream -> wrapperdata , & us -> object );
379-
380- GC_ADDREF (us -> wrapper -> resource );
381381 } else {
382382 php_stream_wrapper_log_error (wrapper , options , "\"%s::" USERSTREAM_OPEN "\" call failed" ,
383383 ZSTR_VAL (us -> wrapper -> ce -> name ));
@@ -387,6 +387,7 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *
387387 if (stream == NULL ) {
388388 zval_ptr_dtor (& us -> object );
389389 ZVAL_UNDEF (& us -> object );
390+ zend_list_delete (us -> wrapper -> resource );
390391 efree (us );
391392 }
392393 zval_ptr_dtor (& zretval );
@@ -429,6 +430,8 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char
429430
430431 us = emalloc (sizeof (* us ));
431432 us -> wrapper = uwrap ;
433+ /* call_method_if_exists() may unregister the stream wrapper. Hold on to it. */
434+ GC_ADDREF (us -> wrapper -> resource );
432435
433436 user_stream_create_object (uwrap , context , & us -> object );
434437 if (Z_TYPE (us -> object ) == IS_UNDEF ) {
@@ -451,8 +454,6 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char
451454
452455 /* set wrapper data to be a reference to our object */
453456 ZVAL_COPY (& stream -> wrapperdata , & us -> object );
454-
455- GC_ADDREF (us -> wrapper -> resource );
456457 } else {
457458 php_stream_wrapper_log_error (wrapper , options , "\"%s::" USERSTREAM_DIR_OPEN "\" call failed" ,
458459 ZSTR_VAL (us -> wrapper -> ce -> name ));
@@ -462,6 +463,7 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char
462463 if (stream == NULL ) {
463464 zval_ptr_dtor (& us -> object );
464465 ZVAL_UNDEF (& us -> object );
466+ zend_list_delete (us -> wrapper -> resource );
465467 efree (us );
466468 }
467469 zval_ptr_dtor (& zretval );
0 commit comments