@@ -92,7 +92,7 @@ static MUTEX_T pcre_mt = NULL;
9292
9393ZEND_TLS HashTable char_tables ;
9494
95- static void free_subpats_table (zend_string * * subpat_names , uint32_t num_subpats , bool persistent );
95+ static void free_subpats_table (zend_string * * subpat_names , uint32_t num_subpats );
9696
9797static void php_pcre_free_char_table (zval * data )
9898{/*{{{*/
@@ -168,25 +168,13 @@ static void php_free_pcre_cache(zval *data) /* {{{ */
168168 pcre_cache_entry * pce = (pcre_cache_entry * ) Z_PTR_P (data );
169169 if (!pce ) return ;
170170 if (pce -> subpats_table ) {
171- free_subpats_table (pce -> subpats_table , pce -> capture_count + 1 , true );
171+ free_subpats_table (pce -> subpats_table , pce -> capture_count + 1 );
172172 }
173173 pcre2_code_free (pce -> re );
174174 free (pce );
175175}
176176/* }}} */
177177
178- static void php_efree_pcre_cache (zval * data ) /* {{{ */
179- {
180- pcre_cache_entry * pce = (pcre_cache_entry * ) Z_PTR_P (data );
181- if (!pce ) return ;
182- if (pce -> subpats_table ) {
183- free_subpats_table (pce -> subpats_table , pce -> capture_count + 1 , false);
184- }
185- pcre2_code_free (pce -> re );
186- efree (pce );
187- }
188- /* }}} */
189-
190178static void * php_pcre_malloc (PCRE2_SIZE size , void * data )
191179{
192180 return pemalloc (size , 1 );
@@ -303,12 +291,7 @@ static PHP_GINIT_FUNCTION(pcre) /* {{{ */
303291{
304292 php_pcre_mutex_alloc ();
305293
306- /* If we're on the CLI SAPI, there will only be one request, so we don't need the
307- * cache to survive after RSHUTDOWN. */
308- pcre_globals -> per_request_cache = strcmp (sapi_module .name , "cli" ) == 0 ;
309- if (!pcre_globals -> per_request_cache ) {
310- zend_hash_init (& pcre_globals -> pcre_cache , 0 , NULL , php_free_pcre_cache , 1 );
311- }
294+ zend_hash_init (& pcre_globals -> pcre_cache , 0 , NULL , php_free_pcre_cache , 1 );
312295
313296 pcre_globals -> backtrack_limit = 0 ;
314297 pcre_globals -> recursion_limit = 0 ;
@@ -326,9 +309,7 @@ static PHP_GINIT_FUNCTION(pcre) /* {{{ */
326309
327310static PHP_GSHUTDOWN_FUNCTION (pcre ) /* {{{ */
328311{
329- if (!pcre_globals -> per_request_cache ) {
330- zend_hash_destroy (& pcre_globals -> pcre_cache );
331- }
312+ zend_hash_destroy (& pcre_globals -> pcre_cache );
332313
333314 php_pcre_shutdown_pcre2 ();
334315 zend_hash_destroy (& char_tables );
@@ -491,10 +472,6 @@ static PHP_RINIT_FUNCTION(pcre)
491472 return FAILURE ;
492473 }
493474
494- if (PCRE_G (per_request_cache )) {
495- zend_hash_init (& PCRE_G (pcre_cache ), 0 , NULL , php_efree_pcre_cache , 0 );
496- }
497-
498475 return SUCCESS ;
499476}
500477/* }}} */
@@ -504,10 +481,6 @@ static PHP_RSHUTDOWN_FUNCTION(pcre)
504481 pcre2_general_context_free (PCRE_G (gctx_zmm ));
505482 PCRE_G (gctx_zmm ) = NULL ;
506483
507- if (PCRE_G (per_request_cache )) {
508- zend_hash_destroy (& PCRE_G (pcre_cache ));
509- }
510-
511484 zval_ptr_dtor (& PCRE_G (unmatched_null_pair ));
512485 zval_ptr_dtor (& PCRE_G (unmatched_empty_pair ));
513486 ZVAL_UNDEF (& PCRE_G (unmatched_null_pair ));
@@ -530,18 +503,18 @@ static int pcre_clean_cache(zval *data, void *arg)
530503}
531504/* }}} */
532505
533- static void free_subpats_table (zend_string * * subpat_names , uint32_t num_subpats , bool persistent ) {
506+ static void free_subpats_table (zend_string * * subpat_names , uint32_t num_subpats ) {
534507 uint32_t i ;
535508 for (i = 0 ; i < num_subpats ; i ++ ) {
536509 if (subpat_names [i ]) {
537- zend_string_release_ex (subpat_names [i ], persistent );
510+ zend_string_release_ex (subpat_names [i ], true );
538511 }
539512 }
540- pefree (subpat_names , persistent );
513+ pefree (subpat_names , true );
541514}
542515
543516/* {{{ static make_subpats_table */
544- static zend_string * * make_subpats_table (uint32_t name_cnt , pcre_cache_entry * pce , bool persistent )
517+ static zend_string * * make_subpats_table (uint32_t name_cnt , pcre_cache_entry * pce )
545518{
546519 uint32_t num_subpats = pce -> capture_count + 1 ;
547520 uint32_t name_size , ni = 0 ;
@@ -556,7 +529,7 @@ static zend_string **make_subpats_table(uint32_t name_cnt, pcre_cache_entry *pce
556529 return NULL ;
557530 }
558531
559- subpat_names = pecalloc (num_subpats , sizeof (zend_string * ), persistent );
532+ subpat_names = pecalloc (num_subpats , sizeof (zend_string * ), true );
560533 while (ni ++ < name_cnt ) {
561534 unsigned short name_idx = 0x100 * (unsigned char )name_table [0 ] + (unsigned char )name_table [1 ];
562535 const char * name = name_table + 2 ;
@@ -566,10 +539,8 @@ static zend_string **make_subpats_table(uint32_t name_cnt, pcre_cache_entry *pce
566539 * Although we will be storing them in user-exposed arrays, they cannot cause problems
567540 * because they only live in this thread and the last reference is deleted on shutdown
568541 * instead of by user code. */
569- subpat_names [name_idx ] = zend_string_init (name , strlen (name ), persistent );
570- if (persistent ) {
571- GC_MAKE_PERSISTENT_LOCAL (subpat_names [name_idx ]);
572- }
542+ subpat_names [name_idx ] = zend_string_init (name , strlen (name ), true);
543+ GC_MAKE_PERSISTENT_LOCAL (subpat_names [name_idx ]);
573544 name_table += name_size ;
574545 }
575546 return subpat_names ;
@@ -871,7 +842,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo
871842
872843 /* Compute and cache the subpattern table to avoid computing it again over and over. */
873844 if (name_count > 0 ) {
874- new_entry .subpats_table = make_subpats_table (name_count , & new_entry , ! PCRE_G ( per_request_cache ) );
845+ new_entry .subpats_table = make_subpats_table (name_count , & new_entry );
875846 if (!new_entry .subpats_table ) {
876847 if (key != regex ) {
877848 zend_string_release_ex (key , false);
@@ -892,7 +863,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo
892863 * as hash keys especually for this table.
893864 * See bug #63180
894865 */
895- if (!(GC_FLAGS (key ) & IS_STR_PERMANENT ) && ! PCRE_G ( per_request_cache ) ) {
866+ if (!(GC_FLAGS (key ) & IS_STR_PERMANENT )) {
896867 zend_string * str = zend_string_init (ZSTR_VAL (key ), ZSTR_LEN (key ), 1 );
897868 GC_MAKE_PERSISTENT_LOCAL (str );
898869
@@ -963,18 +934,18 @@ PHPAPI void php_pcre_free_match_data(pcre2_match_data *match_data)
963934 }
964935}/*}}}*/
965936
966- static void init_unmatched_null_pair (void ) {
937+ static void init_unmatched_null_pair (zval * pair ) {
967938 zval val1 , val2 ;
968939 ZVAL_NULL (& val1 );
969940 ZVAL_LONG (& val2 , -1 );
970- ZVAL_ARR (& PCRE_G ( unmatched_null_pair ) , zend_new_pair (& val1 , & val2 ));
941+ ZVAL_ARR (pair , zend_new_pair (& val1 , & val2 ));
971942}
972943
973- static void init_unmatched_empty_pair (void ) {
944+ static void init_unmatched_empty_pair (zval * pair ) {
974945 zval val1 , val2 ;
975946 ZVAL_EMPTY_STRING (& val1 );
976947 ZVAL_LONG (& val2 , -1 );
977- ZVAL_ARR (& PCRE_G ( unmatched_empty_pair ) , zend_new_pair (& val1 , & val2 ));
948+ ZVAL_ARR (pair , zend_new_pair (& val1 , & val2 ));
978949}
979950
980951static zend_always_inline void populate_match_value_str (
@@ -1020,15 +991,29 @@ static inline void add_offset_pair(
1020991 /* Add (match, offset) to the return value */
1021992 if (PCRE2_UNSET == start_offset ) {
1022993 if (unmatched_as_null ) {
1023- if (Z_ISUNDEF (PCRE_G (unmatched_null_pair ))) {
1024- init_unmatched_null_pair ();
1025- }
1026- ZVAL_COPY (& match_pair , & PCRE_G (unmatched_null_pair ));
994+ do {
995+ if (Z_ISUNDEF (PCRE_G (unmatched_null_pair ))) {
996+ if (UNEXPECTED (EG (flags ) & EG_FLAGS_IN_SHUTDOWN )) {
997+ init_unmatched_null_pair (& match_pair );
998+ break ;
999+ } else {
1000+ init_unmatched_null_pair (& PCRE_G (unmatched_null_pair ));
1001+ }
1002+ }
1003+ ZVAL_COPY (& match_pair , & PCRE_G (unmatched_null_pair ));
1004+ } while (0 );
10271005 } else {
1028- if (Z_ISUNDEF (PCRE_G (unmatched_empty_pair ))) {
1029- init_unmatched_empty_pair ();
1030- }
1031- ZVAL_COPY (& match_pair , & PCRE_G (unmatched_empty_pair ));
1006+ do {
1007+ if (Z_ISUNDEF (PCRE_G (unmatched_empty_pair ))) {
1008+ if (UNEXPECTED (EG (flags ) & EG_FLAGS_IN_SHUTDOWN )) {
1009+ init_unmatched_empty_pair (& match_pair );
1010+ break ;
1011+ } else {
1012+ init_unmatched_empty_pair (& PCRE_G (unmatched_empty_pair ));
1013+ }
1014+ }
1015+ ZVAL_COPY (& match_pair , & PCRE_G (unmatched_empty_pair ));
1016+ } while (0 );
10321017 }
10331018 } else {
10341019 zval val1 , val2 ;
0 commit comments