35
35
static int le_protocols ;
36
36
37
37
struct php_user_stream_wrapper {
38
+ php_stream_wrapper wrapper ;
38
39
char * protoname ;
39
40
zend_class_entry * ce ;
40
- php_stream_wrapper wrapper ;
41
+ zend_resource * resource ;
41
42
};
42
43
43
44
static php_stream * user_wrapper_opener (php_stream_wrapper * wrapper , const char * filename , const char * mode , int options , zend_string * * opened_path , php_stream_context * context STREAMS_DC );
@@ -481,10 +482,12 @@ PHP_FUNCTION(stream_wrapper_register)
481
482
uwrap -> wrapper .wops = & user_stream_wops ;
482
483
uwrap -> wrapper .abstract = uwrap ;
483
484
uwrap -> wrapper .is_url = ((flags & PHP_STREAM_IS_URL ) != 0 );
485
+ uwrap -> resource = NULL ;
484
486
485
487
rsrc = zend_register_resource (uwrap , le_protocols );
486
488
487
489
if (php_register_url_stream_wrapper_volatile (protocol , & uwrap -> wrapper ) == SUCCESS ) {
490
+ uwrap -> resource = rsrc ;
488
491
RETURN_TRUE ;
489
492
}
490
493
@@ -510,12 +513,23 @@ PHP_FUNCTION(stream_wrapper_unregister)
510
513
RETURN_THROWS ();
511
514
}
512
515
516
+ php_stream_wrapper * wrapper = zend_hash_find_ptr (php_stream_get_url_stream_wrappers_hash (), protocol );
513
517
if (php_unregister_url_stream_wrapper_volatile (protocol ) == FAILURE ) {
514
518
/* We failed */
515
519
php_error_docref (NULL , E_WARNING , "Unable to unregister protocol %s://" , ZSTR_VAL (protocol ));
516
520
RETURN_FALSE ;
517
521
}
518
522
523
+ ZEND_ASSERT (wrapper != NULL );
524
+ if (wrapper -> wops == & user_stream_wops ) {
525
+ struct php_user_stream_wrapper * uwrap = (struct php_user_stream_wrapper * )wrapper ;
526
+ zend_resource * resource = uwrap -> resource ;
527
+ uint32_t refcount = GC_DELREF (resource );
528
+ ZEND_ASSERT (refcount == 0 );
529
+ // uwrap will be released by resource destructor
530
+ rc_dtor_func ((zend_refcounted * )resource );
531
+ }
532
+
519
533
RETURN_TRUE ;
520
534
}
521
535
/* }}} */
0 commit comments