@@ -133,6 +133,33 @@ static void userfilter_dtor(php_stream_filter *thisfilter)
133133 zval_ptr_dtor (obj );
134134}
135135
136+ static zend_result userfilter_assign_stream (php_stream * stream , zval * obj , zend_string * * stream_name_p )
137+ {
138+ /* Give the userfilter class a hook back to the stream */
139+ const zend_class_entry * old_scope = EG (fake_scope );
140+ EG (fake_scope ) = Z_OBJCE_P (obj );
141+
142+ zend_string * stream_name = ZSTR_INIT_LITERAL ("stream" , 0 );
143+ bool stream_property_exists = Z_OBJ_HT_P (obj )-> has_property (Z_OBJ_P (obj ), stream_name , ZEND_PROPERTY_EXISTS , NULL );
144+ if (stream_property_exists ) {
145+ zval stream_zval ;
146+ php_stream_to_zval (stream , & stream_zval );
147+ zend_update_property_ex (Z_OBJCE_P (obj ), Z_OBJ_P (obj ), stream_name , & stream_zval );
148+ /* If property update threw an exception, skip filter execution */
149+ if (EG (exception )) {
150+ EG (fake_scope ) = old_scope ;
151+ zend_string_release (stream_name );
152+ return FAILURE ;
153+ }
154+ * stream_name_p = stream_name ;
155+ } else {
156+ zend_string_release (stream_name );
157+ }
158+ EG (fake_scope ) = old_scope ;
159+
160+ return SUCCESS ;
161+ }
162+
136163static php_stream_filter_status_t userfilter_filter (
137164 php_stream * stream ,
138165 php_stream_filter * thisfilter ,
@@ -158,31 +185,16 @@ static php_stream_filter_status_t userfilter_filter(
158185 uint32_t orig_no_fclose = stream -> flags & PHP_STREAM_FLAG_NO_FCLOSE ;
159186 stream -> flags |= PHP_STREAM_FLAG_NO_FCLOSE ;
160187
161- /* Give the userfilter class a hook back to the stream */
162- const zend_class_entry * old_scope = EG (fake_scope );
163- EG (fake_scope ) = Z_OBJCE_P (obj );
164-
165- zend_string * stream_name = ZSTR_INIT_LITERAL ("stream" , 0 );
166- bool stream_property_exists = Z_OBJ_HT_P (obj )-> has_property (Z_OBJ_P (obj ), stream_name , ZEND_PROPERTY_EXISTS , NULL );
167- if (stream_property_exists ) {
168- zval stream_zval ;
169- php_stream_to_zval (stream , & stream_zval );
170- zend_update_property_ex (Z_OBJCE_P (obj ), Z_OBJ_P (obj ), stream_name , & stream_zval );
171- /* If property update threw an exception, skip filter execution */
172- if (EG (exception )) {
173- EG (fake_scope ) = old_scope ;
174- if (buckets_in -> head ) {
175- php_error_docref (NULL , E_WARNING , "Unprocessed filter buckets remaining on input brigade" );
176- }
177- zend_string_release (stream_name );
178- stream -> flags &= ~PHP_STREAM_FLAG_NO_FCLOSE ;
179- stream -> flags |= orig_no_fclose ;
180- return PSFS_ERR_FATAL ;
188+ zend_string * stream_name = NULL ;
189+ if (userfilter_assign_stream (stream , obj , & stream_name ) == FAILURE ) {
190+ if (buckets_in -> head ) {
191+ php_error_docref (NULL , E_WARNING , "Unprocessed filter buckets remaining on input brigade" );
181192 }
193+ stream -> flags &= ~PHP_STREAM_FLAG_NO_FCLOSE ;
194+ stream -> flags |= orig_no_fclose ;
195+ return PSFS_ERR_FATAL ;
182196 }
183197
184- EG (fake_scope ) = old_scope ;
185-
186198 ZVAL_STRINGL (& func_name , "filter" , sizeof ("filter" )- 1 );
187199
188200 /* Setup calling arguments */
@@ -227,12 +239,11 @@ static php_stream_filter_status_t userfilter_filter(
227239 * Since the property accepted a resource assignment above, it must have
228240 * no type hint or be typed as mixed, so we can safely assign null.
229241 */
230- if (stream_property_exists ) {
242+ if (stream_name != NULL ) {
231243 zend_update_property_null (Z_OBJCE_P (obj ), Z_OBJ_P (obj ), ZSTR_VAL (stream_name ), ZSTR_LEN (stream_name ));
244+ zend_string_release (stream_name );
232245 }
233246
234- zend_string_release (stream_name );
235-
236247 zval_ptr_dtor (& args [3 ]);
237248 zval_ptr_dtor (& args [2 ]);
238249 zval_ptr_dtor (& args [1 ]);
@@ -269,21 +280,20 @@ static zend_result userfilter_seek(
269280 /* Method doesn't exist - consider this a successful seek for BC */
270281 return SUCCESS ;
271282 }
272- zend_string_release (method_name );
273283
274284 /* Make sure the stream is not closed while the filter callback executes. */
275285 uint32_t orig_no_fclose = stream -> flags & PHP_STREAM_FLAG_NO_FCLOSE ;
276286 stream -> flags |= PHP_STREAM_FLAG_NO_FCLOSE ;
277287
278- zval * stream_prop = zend_hash_str_find_ind ( Z_OBJPROP_P ( obj ), "stream" , sizeof ( "stream" ) - 1 ) ;
279- if (stream_prop ) {
280- /* Give the userfilter class a hook back to the stream */
281- zval_ptr_dtor ( stream_prop ) ;
282- php_stream_to_zval ( stream , stream_prop );
283- Z_ADDREF_P ( stream_prop ) ;
288+ zend_string * stream_name = NULL ;
289+ if (userfilter_assign_stream ( stream , obj , & stream_name ) == FAILURE ) {
290+ stream -> flags &= ~ PHP_STREAM_FLAG_NO_FCLOSE ;
291+ stream -> flags |= orig_no_fclose ;
292+ zend_string_release ( method_name );
293+ return FAILURE ;
284294 }
285295
286- ZVAL_STRINGL (& func_name , "seek" , sizeof ( "seek" ) - 1 );
296+ ZVAL_STR (& func_name , method_name );
287297
288298 /* Setup calling arguments */
289299 ZVAL_LONG (& args [0 ], offset );
@@ -308,13 +318,11 @@ static zend_result userfilter_seek(
308318 /* filter resources are cleaned up by the stream destructor,
309319 * keeping a reference to the stream resource here would prevent it
310320 * from being destroyed properly */
311- if (stream_prop ) {
312- convert_to_null (stream_prop );
321+ if (stream_name != NULL ) {
322+ zend_update_property_null (Z_OBJCE_P (obj ), Z_OBJ_P (obj ), ZSTR_VAL (stream_name ), ZSTR_LEN (stream_name ));
323+ zend_string_release (stream_name );
313324 }
314325
315- zval_ptr_dtor (& args [1 ]);
316- zval_ptr_dtor (& args [0 ]);
317-
318326 stream -> flags &= ~PHP_STREAM_FLAG_NO_FCLOSE ;
319327 stream -> flags |= orig_no_fclose ;
320328
@@ -392,8 +400,7 @@ static php_stream_filter *user_filter_factory_create(const char *filtername,
392400 return NULL ;
393401 }
394402
395- filter = php_stream_filter_alloc (& userfilter_ops , NULL , false,
396- PHP_STREAM_FILTER_SEEKABLE_CHECK );
403+ filter = php_stream_filter_alloc (& userfilter_ops , NULL , false, PSFS_SEEKABLE_CHECK );
397404
398405 /* filtername */
399406 add_property_string (& obj , "filtername" , filtername );
0 commit comments