@@ -92,7 +92,7 @@ static MUTEX_T pcre_mt = NULL;
92
92
93
93
ZEND_TLS HashTable char_tables ;
94
94
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 );
96
96
97
97
static void php_pcre_free_char_table (zval * data )
98
98
{/*{{{*/
@@ -168,25 +168,13 @@ static void php_free_pcre_cache(zval *data) /* {{{ */
168
168
pcre_cache_entry * pce = (pcre_cache_entry * ) Z_PTR_P (data );
169
169
if (!pce ) return ;
170
170
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 );
172
172
}
173
173
pcre2_code_free (pce -> re );
174
174
free (pce );
175
175
}
176
176
/* }}} */
177
177
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
-
190
178
static void * php_pcre_malloc (PCRE2_SIZE size , void * data )
191
179
{
192
180
return pemalloc (size , 1 );
@@ -303,12 +291,7 @@ static PHP_GINIT_FUNCTION(pcre) /* {{{ */
303
291
{
304
292
php_pcre_mutex_alloc ();
305
293
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 );
312
295
313
296
pcre_globals -> backtrack_limit = 0 ;
314
297
pcre_globals -> recursion_limit = 0 ;
@@ -326,9 +309,7 @@ static PHP_GINIT_FUNCTION(pcre) /* {{{ */
326
309
327
310
static PHP_GSHUTDOWN_FUNCTION (pcre ) /* {{{ */
328
311
{
329
- if (!pcre_globals -> per_request_cache ) {
330
- zend_hash_destroy (& pcre_globals -> pcre_cache );
331
- }
312
+ zend_hash_destroy (& pcre_globals -> pcre_cache );
332
313
333
314
php_pcre_shutdown_pcre2 ();
334
315
zend_hash_destroy (& char_tables );
@@ -491,10 +472,6 @@ static PHP_RINIT_FUNCTION(pcre)
491
472
return FAILURE ;
492
473
}
493
474
494
- if (PCRE_G (per_request_cache )) {
495
- zend_hash_init (& PCRE_G (pcre_cache ), 0 , NULL , php_efree_pcre_cache , 0 );
496
- }
497
-
498
475
return SUCCESS ;
499
476
}
500
477
/* }}} */
@@ -504,10 +481,6 @@ static PHP_RSHUTDOWN_FUNCTION(pcre)
504
481
pcre2_general_context_free (PCRE_G (gctx_zmm ));
505
482
PCRE_G (gctx_zmm ) = NULL ;
506
483
507
- if (PCRE_G (per_request_cache )) {
508
- zend_hash_destroy (& PCRE_G (pcre_cache ));
509
- }
510
-
511
484
zval_ptr_dtor (& PCRE_G (unmatched_null_pair ));
512
485
zval_ptr_dtor (& PCRE_G (unmatched_empty_pair ));
513
486
ZVAL_UNDEF (& PCRE_G (unmatched_null_pair ));
@@ -530,18 +503,18 @@ static int pcre_clean_cache(zval *data, void *arg)
530
503
}
531
504
/* }}} */
532
505
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 ) {
534
507
uint32_t i ;
535
508
for (i = 0 ; i < num_subpats ; i ++ ) {
536
509
if (subpat_names [i ]) {
537
- zend_string_release_ex (subpat_names [i ], persistent );
510
+ zend_string_release_ex (subpat_names [i ], true );
538
511
}
539
512
}
540
- pefree (subpat_names , persistent );
513
+ pefree (subpat_names , true );
541
514
}
542
515
543
516
/* {{{ 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 )
545
518
{
546
519
uint32_t num_subpats = pce -> capture_count + 1 ;
547
520
uint32_t name_size , ni = 0 ;
@@ -556,7 +529,7 @@ static zend_string **make_subpats_table(uint32_t name_cnt, pcre_cache_entry *pce
556
529
return NULL ;
557
530
}
558
531
559
- subpat_names = pecalloc (num_subpats , sizeof (zend_string * ), persistent );
532
+ subpat_names = pecalloc (num_subpats , sizeof (zend_string * ), true );
560
533
while (ni ++ < name_cnt ) {
561
534
unsigned short name_idx = 0x100 * (unsigned char )name_table [0 ] + (unsigned char )name_table [1 ];
562
535
const char * name = name_table + 2 ;
@@ -566,10 +539,8 @@ static zend_string **make_subpats_table(uint32_t name_cnt, pcre_cache_entry *pce
566
539
* Although we will be storing them in user-exposed arrays, they cannot cause problems
567
540
* because they only live in this thread and the last reference is deleted on shutdown
568
541
* 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 ]);
573
544
name_table += name_size ;
574
545
}
575
546
return subpat_names ;
@@ -871,7 +842,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo
871
842
872
843
/* Compute and cache the subpattern table to avoid computing it again over and over. */
873
844
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 );
875
846
if (!new_entry .subpats_table ) {
876
847
if (key != regex ) {
877
848
zend_string_release_ex (key , false);
@@ -892,7 +863,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, bo
892
863
* as hash keys especually for this table.
893
864
* See bug #63180
894
865
*/
895
- if (!(GC_FLAGS (key ) & IS_STR_PERMANENT ) && ! PCRE_G ( per_request_cache ) ) {
866
+ if (!(GC_FLAGS (key ) & IS_STR_PERMANENT )) {
896
867
zend_string * str = zend_string_init (ZSTR_VAL (key ), ZSTR_LEN (key ), 1 );
897
868
GC_MAKE_PERSISTENT_LOCAL (str );
898
869
@@ -963,18 +934,18 @@ PHPAPI void php_pcre_free_match_data(pcre2_match_data *match_data)
963
934
}
964
935
}/*}}}*/
965
936
966
- static void init_unmatched_null_pair (void ) {
937
+ static void init_unmatched_null_pair (zval * pair ) {
967
938
zval val1 , val2 ;
968
939
ZVAL_NULL (& val1 );
969
940
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 ));
971
942
}
972
943
973
- static void init_unmatched_empty_pair (void ) {
944
+ static void init_unmatched_empty_pair (zval * pair ) {
974
945
zval val1 , val2 ;
975
946
ZVAL_EMPTY_STRING (& val1 );
976
947
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 ));
978
949
}
979
950
980
951
static zend_always_inline void populate_match_value_str (
@@ -1020,15 +991,29 @@ static inline void add_offset_pair(
1020
991
/* Add (match, offset) to the return value */
1021
992
if (PCRE2_UNSET == start_offset ) {
1022
993
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 );
1027
1005
} 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 );
1032
1017
}
1033
1018
} else {
1034
1019
zval val1 , val2 ;
0 commit comments