@@ -108,6 +108,29 @@ static void frankenphp_destroy_super_globals() {
108108 zend_end_try ();
109109}
110110
111+ /*
112+ * free php_stream resources that are temporary (php_stream_temp_ops)
113+ * streams are globally registered in EG(regular_list), see zend_list.c
114+ * this fixes a leak when reading the body of a request
115+ */
116+ static void frankenphp_release_temporary_streams () {
117+ zend_resource * val ;
118+ int stream_type = php_file_le_stream ();
119+ ZEND_HASH_FOREACH_PTR (& EG (regular_list ), val ) {
120+ /* verify the resource is a stream */
121+ if (val -> type == stream_type ) {
122+ php_stream * stream = (php_stream * )val -> ptr ;
123+ if (stream != NULL && stream -> ops == & php_stream_temp_ops &&
124+ !stream -> is_persistent && stream -> __exposed == 0 &&
125+ GC_REFCOUNT (val ) == 1 ) {
126+ zend_list_close (val );
127+ zend_list_delete (val );
128+ }
129+ }
130+ }
131+ ZEND_HASH_FOREACH_END ();
132+ }
133+
111134/* Adapted from php_request_shutdown */
112135static void frankenphp_worker_request_shutdown () {
113136 /* Flush all output buffers */
@@ -135,23 +158,6 @@ static void frankenphp_worker_request_shutdown() {
135158 zend_end_try ();
136159
137160 zend_set_memory_limit (PG (memory_limit ));
138-
139- /*
140- * free any php_stream resources that are not php source files
141- * all resources are stored in EG(regular_list), see zend_list.c
142- */
143- zend_resource * val ;
144- ZEND_HASH_FOREACH_PTR (& EG (regular_list ), val ) {
145- /* verify the resource is a stream */
146- if (val -> type == php_file_le_stream ()) {
147- php_stream * stream = (php_stream * )val -> ptr ;
148- if (stream != NULL && stream -> ops != & php_stream_stdio_ops &&
149- !stream -> is_persistent && GC_REFCOUNT (val ) == 1 ) {
150- zend_list_delete (val );
151- }
152- }
153- }
154- ZEND_HASH_FOREACH_END ();
155161}
156162
157163PHPAPI void get_full_env (zval * track_vars_array ) {
@@ -179,6 +185,7 @@ static int frankenphp_worker_request_startup() {
179185
180186 zend_try {
181187 frankenphp_destroy_super_globals ();
188+ frankenphp_release_temporary_streams ();
182189 php_output_activate ();
183190
184191 /* initialize global variables */
0 commit comments