25#define PREG_PATTERN_ORDER 1
26#define PREG_SET_ORDER 2
27#define PREG_OFFSET_CAPTURE (1<<8)
28#define PREG_UNMATCHED_AS_NULL (1<<9)
30#define PREG_SPLIT_NO_EMPTY (1<<0)
31#define PREG_SPLIT_DELIM_CAPTURE (1<<1)
32#define PREG_SPLIT_OFFSET_CAPTURE (1<<2)
34#define PREG_GREP_INVERT (1<<0)
36#define PREG_JIT (1<<3)
38#define PCRE_CACHE_SIZE 4096
40#ifdef HAVE_PCRE_JIT_SUPPORT
41#define PHP_PCRE_JIT_SUPPORT 1
43#define PHP_PCRE_JIT_SUPPORT 0
67#ifdef HAVE_PCRE_JIT_SUPPORT
68#define PCRE_JIT_STACK_MIN_SIZE (32 * 1024)
69#define PCRE_JIT_STACK_MAX_SIZE (192 * 1024)
82#if defined(ZTS) && defined(HAVE_PCRE_JIT_SUPPORT)
83static MUTEX_T pcre_mt =
NULL;
84#define php_pcre_mutex_alloc() \
85 if (tsrm_is_main_thread() && !pcre_mt) pcre_mt = tsrm_mutex_alloc();
86#define php_pcre_mutex_free() \
87 if (tsrm_is_main_thread() && pcre_mt) { tsrm_mutex_free(pcre_mt); pcre_mt = NULL; }
88#define php_pcre_mutex_lock() tsrm_mutex_lock(pcre_mt);
89#define php_pcre_mutex_unlock() tsrm_mutex_unlock(pcre_mt);
91#define php_pcre_mutex_alloc()
92#define php_pcre_mutex_free()
93#define php_pcre_mutex_lock()
94#define php_pcre_mutex_unlock()
99static void free_subpats_table(
zend_string **subpat_names, uint32_t num_subpats);
101static void php_pcre_free_char_table(
zval *
data)
107static void pcre_handle_exec_error(
int pcre_code)
124#ifdef HAVE_PCRE_JIT_SUPPORT
149 return "Internal error";
151 return "Malformed UTF-8 characters, possibly incorrectly encoded";
153 return "The offset did not correspond to the beginning of a valid UTF-8 code point";
155 return "Backtrack limit exhausted";
157 return "Recursion limit exhausted";
159#ifdef HAVE_PCRE_JIT_SUPPORT
161 return "JIT stack limit exhausted";
165 return "Unknown error";
170static void php_free_pcre_cache(
zval *
data)
187static void php_pcre_free(
void *block,
void *
data)
197static void php_pcre_efree(
void *block,
void *
data)
202#ifdef PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK
204#define PHP_PCRE_DEFAULT_EXTRA_COPTIONS PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK
206#define PHP_PCRE_DEFAULT_EXTRA_COPTIONS 0
209#define PHP_PCRE_PREALLOC_MDATA_SIZE 32
211static void php_pcre_init_pcre2(uint8_t jit)
239#ifdef HAVE_PCRE_JIT_SUPPORT
240 if (jit && !jit_stack) {
260static void php_pcre_shutdown_pcre2(
void)
277#ifdef HAVE_PCRE_JIT_SUPPORT
300 pcre_globals->backtrack_limit = 0;
301 pcre_globals->recursion_limit = 0;
303 ZVAL_UNDEF(&pcre_globals->unmatched_null_pair);
304 ZVAL_UNDEF(&pcre_globals->unmatched_empty_pair);
305#ifdef HAVE_PCRE_JIT_SUPPORT
306 pcre_globals->jit = 1;
309 php_pcre_init_pcre2(1);
318 php_pcre_shutdown_pcre2();
326 OnUpdateLong(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
336 OnUpdateLong(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
344#ifdef HAVE_PCRE_JIT_SUPPORT
347 OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
348 if (
PCRE_G(jit) && jit_stack) {
361#ifdef HAVE_PCRE_JIT_SUPPORT
366static
char *_pcre2_config_str(uint32_t what)
369 char *
ret = (
char *) malloc(
len + 1);
383#ifdef HAVE_PCRE_JIT_SUPPORT
397#ifdef HAVE_PCRE_JIT_SUPPORT
411#ifdef HAVE_PCRE_VALGRIND_SUPPORT
424#ifdef HAVE_PCRE_JIT_SUPPORT
427 php_pcre_init_pcre2(
PCRE_G(jit));
428 if (!pcre2_init_ok) {
438 register_php_pcre_symbols(module_number);
458#ifdef HAVE_PCRE_JIT_SUPPORT
462 php_pcre_init_pcre2(
PCRE_G(jit));
463 if (!pcre2_init_ok) {
507 int *num_clean = (
int *)
arg;
510 if (--(*num_clean) == 0) {
520static void free_subpats_table(
zend_string **subpat_names, uint32_t num_subpats) {
522 for (i = 0; i < num_subpats; i++) {
523 if (subpat_names[i]) {
534 uint32_t name_size, ni = 0;
541 if (rc1 < 0 || rc2 < 0) {
547 while (ni++ < name_cnt) {
548 unsigned short name_idx = 0x100 * (
unsigned char)name_table[0] + (
unsigned char)name_table[1];
549 const char *
name = name_table + 2;
550 subpat_names[name_idx] = zend_string_init(
name,
strlen(
name),
false);
551 name_table += name_size;
575 while ((*++
end & 0xC0) == 0x80);
588#if 10 == PCRE2_MAJOR && 37 == PCRE2_MINOR && !defined(HAVE_BUNDLED_PCRE)
591 uint32_t coptions = 0;
598 char start_delimiter;
603 uint32_t poptions = 0;
604 const uint8_t *tables =
NULL;
611 if (locale_aware &&
BG(ctype_string)) {
634 while (isspace((
int)*(
unsigned char *)
p))
p++;
647 if (isalnum((
int)*(
unsigned char *)&delimiter) || delimiter ==
'\\' || delimiter ==
'\0') {
656 start_delimiter = delimiter;
657 if ((pp =
strchr(
"([{< )]}> )]}>", delimiter)))
659 end_delimiter = delimiter;
663 if (start_delimiter == end_delimiter) {
668 if (*pp ==
'\\' && pp + 1 < end_p) pp++;
669 else if (*pp == delimiter)
681 if (*pp ==
'\\' && pp + 1 < end_p) pp++;
682 else if (*pp == end_delimiter && --brackets <= 0)
684 else if (*pp == start_delimiter)
694 if (start_delimiter == end_delimiter) {
704 pattern_len = pp -
p;
724#ifdef PCRE2_EXTRA_CASELESS_RESTRICT
762 tables = (uint8_t *)zend_hash_find_ptr(&char_tables,
BG(ctype_string));
775 zend_hash_add_ptr(&char_tables, _k, (
void *)tables);
776 zend_string_release(_k);
797#ifdef HAVE_PCRE_JIT_SUPPORT
808 "Allocation of JIT memory failed, PCRE JIT will be disabled. "
809 "This is likely caused by security restrictions. "
810 "Either grant PHP permission to allocate executable memory, or set pcre.jit=0");
871 zend_string_release(str);
900 return pce ? pce->
re :
NULL;
914 if (!capture_count) {
937static void init_unmatched_null_pair(
zval *pair) {
944static void init_unmatched_empty_pair(
zval *pair) {
958 bool unmatched_as_null) {
960 if (unmatched_as_null) {
966 populate_match_value_str(
val, subject, start_offset, end_offset);
970static inline void add_named(
987static inline void add_offset_pair(
995 if (unmatched_as_null) {
999 init_unmatched_null_pair(&match_pair);
1011 init_unmatched_empty_pair(&match_pair);
1022 populate_match_value_str(&val1, subject, start_offset, end_offset);
1034static void populate_subpat_array(
1043 if (offset_capture) {
1044 for (i = 0; i <
count; i++) {
1046 subpats_ht, subject, offsets[2*i], offsets[2*i+1],
1047 subpat_names[i], unmatched_as_null);
1049 if (unmatched_as_null) {
1050 for (i =
count; i < num_subpats; i++) {
1055 for (i = 0; i <
count; i++) {
1056 populate_match_value(
1057 &
val, subject, offsets[2*i], offsets[2*i+1], unmatched_as_null);
1058 if (subpat_names[i]) {
1059 add_named(subpats_ht, subpat_names[i], &
val, offsets[2*i] ==
PCRE2_UNSET);
1063 if (unmatched_as_null) {
1064 for (i =
count; i < num_subpats; i++) {
1066 if (subpat_names[i]) {
1074 if (offset_capture) {
1075 for (i = 0; i <
count; i++) {
1077 subpats_ht, subject, offsets[2*i], offsets[2*i+1],
NULL, unmatched_as_null);
1079 if (unmatched_as_null) {
1080 for (i =
count; i < num_subpats; i++) {
1085 for (i = 0; i <
count; i++) {
1086 populate_match_value(
1087 &
val, subject, offsets[2*i], offsets[2*i+1], unmatched_as_null);
1090 if (unmatched_as_null) {
1091 for (i =
count; i < num_subpats; i++) {
1134 global,
flags, start_offset);
1146 if (start_offset ==
ZSTR_LEN(subject_str)) {
1152 return (
ZSTR_VAL(subject_str)[start_offset] & 0xc0) != 0x80;
1165 uint32_t num_subpats;
1169 uint32_t subpats_order;
1170 uint32_t offset_capture;
1177 char *subject =
ZSTR_VAL(subject_str);
1178 size_t subject_len =
ZSTR_LEN(subject_str);
1181 if (subpats !=
NULL) {
1182 subpats = zend_try_array_init(subpats);
1199 subpats_order =
flags & 0xff;
1200 if ((global && (subpats_order < PREG_PATTERN_ORDER || subpats_order >
PREG_SET_ORDER)) ||
1201 (!global && subpats_order != 0)) {
1208 unmatched_as_null = 0;
1212 if (start_offset < 0) {
1213 if ((
PCRE2_SIZE)-start_offset <= subject_len) {
1214 start_offset2 = subject_len + start_offset;
1222 if (start_offset2 > subject_len) {
1234 subpat_names =
NULL;
1236 subpat_names = ensure_subpats_table(pce->
name_count, pce);
1258 for (i=0; i<num_subpats; i++) {
1266 orig_start_offset = start_offset2;
1272#ifdef HAVE_PCRE_JIT_SUPPORT
1287 count = num_subpats;
1294 if (subpats !=
NULL) {
1297 if (match_sets)
efree(match_sets);
1305 if (offset_capture) {
1306 for (i = 0; i <
count; i++) {
1308 match_sets[i], subject, offsets[2*i], offsets[2*i+1],
1309 NULL, unmatched_as_null);
1312 for (i = 0; i <
count; i++) {
1314 populate_match_value(
1315 &
val, subject, offsets[2*i], offsets[2*i+1], unmatched_as_null);
1334 if (
count < num_subpats) {
1335 for (
int i =
count; i < num_subpats; i++) {
1336 if (offset_capture) {
1339 NULL, unmatched_as_null);
1340 }
else if (unmatched_as_null) {
1355 populate_subpat_array(
1356 &result_set, subject, offsets, subpat_names,
1364 populate_subpat_array(
1365 subpats, subject, offsets, subpat_names, num_subpats,
count, mark,
flags);
1371 start_offset2 = offsets[1];
1377 if (start_offset2 == offsets[0]) {
1391 if (start_offset2 < subject_len) {
1392 size_t unit_len = calculate_unit_length(pce, subject + start_offset2);
1394 start_offset2 += unit_len;
1406 pcre_handle_exec_error(
count);
1415#ifdef HAVE_PCRE_JIT_SUPPORT
1417 if (start_offset2 > subject_len) {
1428 if (match_data != mdata) {
1435 for (i = 0; i < num_subpats; i++) {
1438 if (subpat_names[i]) {
1445 for (i = 0; i < num_subpats; i++) {
1483 zval regex_tmp, subject_tmp;
1513static int preg_get_backref(
char **str,
int *backref)
1521 if (*walk ==
'$' && walk[1] ==
'{') {
1527 if (*walk >=
'0' && *walk <=
'9') {
1528 *backref = *walk -
'0';
1533 if (*walk && *walk >=
'0' && *walk <=
'9') {
1534 *backref = *backref * 10 + *walk -
'0';
1558 populate_subpat_array(&
arg, subject, offsets, subpat_names, num_subpats,
count, mark,
flags);
1576 result_str = zend_string_init(&subject[offsets[0]], offsets[1] - offsets[0], 0);
1588 const char *subject,
size_t subject_len,
1590 size_t limit,
size_t *replace_count)
1606 limit, replace_count);
1618 uint32_t num_subpats;
1624 size_t last_end_offset;
1643 last_end_offset = 0;
1663#ifdef HAVE_PCRE_JIT_SUPPORT
1673 piece = subject + last_end_offset;
1675 if (
count >= 0 && limit > 0) {
1681 count = num_subpats;
1694 if (replace_count) {
1699 match = subject + offsets[0];
1701 new_len = result_len + offsets[0] - last_end_offset;
1704 replace_end = walk +
ZSTR_LEN(replace_str);
1707 while (walk < replace_end) {
1708 if (
'\\' == *walk ||
'$' == *walk) {
1710 if (walk_last ==
'\\') {
1715 if (preg_get_backref(&walk, &backref)) {
1716 if (backref <
count)
1717 new_len += offsets[(backref<<1)+1] - offsets[backref<<1];
1723 walk_last = walk[-1];
1726 if (new_len >= alloc_len) {
1729 result = zend_string_alloc(alloc_len, 0);
1735 if (
match-piece > 0) {
1738 result_len += (
match-piece);
1741 if (simple_string) {
1744 result_len +=
ZSTR_LEN(replace_str);
1751 while (walk < replace_end) {
1752 if (
'\\' == *walk ||
'$' == *walk) {
1753 if (walk_last ==
'\\') {
1754 *(walkbuf-1) = *walk++;
1758 if (preg_get_backref(&walk, &backref)) {
1759 if (backref <
count) {
1760 if (offsets[backref<<1] <
SIZE_MAX) {
1761 match_len = offsets[(backref<<1)+1] - offsets[backref<<1];
1762 walkbuf = zend_mempcpy(walkbuf, subject + offsets[backref << 1], match_len);
1768 *walkbuf++ = *walk++;
1769 walk_last = walk[-1];
1779 start_offset = last_end_offset = offsets[1];
1785 if (start_offset == offsets[0]) {
1789 piece = subject + start_offset;
1790 if (
count >= 0 && limit > 0) {
1797 if (start_offset < subject_len) {
1798 size_t unit_len = calculate_unit_length(pce, piece);
1799 start_offset += unit_len;
1810 if (!
result && subject_str) {
1811 result = zend_string_copy(subject_str);
1815 alloc_len = result_len + subject_len - last_end_offset;
1819 result = zend_string_alloc(alloc_len, 0);
1823 result_len += subject_len - last_end_offset;
1829 pcre_handle_exec_error(
count);
1837#ifdef HAVE_PCRE_JIT_SUPPORT
1846 if (match_data != mdata) {
1860 uint32_t num_subpats;
1864 size_t last_end_offset;
1871 bool old_mdata_used;
1876 subpat_names = ensure_subpats_table(pce->
name_count, pce);
1881 subpat_names =
NULL;
1890 last_end_offset = 0;
1894 old_mdata_used = mdata_used;
1902 mdata_used = old_mdata_used;
1913#ifdef HAVE_PCRE_JIT_SUPPORT
1923 piece = subject + last_end_offset;
1925 if (
count >= 0 && limit) {
1929 count = num_subpats;
1942 if (replace_count) {
1947 match = subject + offsets[0];
1949 new_len = result_len + offsets[0] - last_end_offset;
1952 eval_result = preg_do_repl_func(
1953 fci, fcc, subject, offsets, subpat_names, num_subpats,
count,
1958 if (new_len >= alloc_len) {
1961 result = zend_string_alloc(alloc_len, 0);
1967 if (
match-piece > 0) {
1970 result_len += (
match-piece);
1975 result_len +=
ZSTR_LEN(eval_result);
1981 start_offset = last_end_offset = offsets[1];
1987 if (start_offset == offsets[0]) {
1991 piece = subject + start_offset;
1992 if (
count >= 0 && limit) {
1999 if (start_offset < subject_len) {
2000 size_t unit_len = calculate_unit_length(pce, piece);
2001 start_offset += unit_len;
2012 if (!
result && subject_str) {
2013 result = zend_string_copy(subject_str);
2017 alloc_len = result_len + subject_len - last_end_offset;
2021 result = zend_string_alloc(alloc_len, 0);
2025 result_len += subject_len - last_end_offset;
2031 pcre_handle_exec_error(
count);
2038#ifdef HAVE_PCRE_JIT_SUPPORT
2047 if (match_data != mdata) {
2050 mdata_used = old_mdata_used;
2070 result = php_pcre_replace_func_impl(
2072 limit, replace_count,
flags);
2082 zend_string *subject_str,
size_t limit,
size_t *replace_count)
2087 zend_string_addref(subject_str);
2090 uint32_t replace_idx = 0;
2096 zend_string *regex_str = zval_get_tmp_string(regex_entry, &tmp_regex_str);
2097 zend_string *replace_entry_str, *tmp_replace_entry_str;
2102 if (replace_idx == replace_ht->
nNumUsed) {
2104 tmp_replace_entry_str =
NULL;
2110 replace_entry_str = zval_get_tmp_string(
zv, &tmp_replace_entry_str);
2118 ZSTR_LEN(subject_str), replace_entry_str, limit, replace_count);
2119 zend_tmp_string_release(tmp_replace_entry_str);
2120 zend_tmp_string_release(tmp_regex_str);
2135 zend_string *regex_str = zval_get_tmp_string(regex_entry, &tmp_regex_str);
2140 ZSTR_LEN(subject_str), replace_str, limit, replace_count);
2141 zend_tmp_string_release(tmp_regex_str);
2159 zend_string *subject,
size_t limit,
size_t *replace_count)
2166 replace_str, limit, replace_count);
2169 result = php_pcre_replace_array(regex_ht, replace_str, replace_ht, subject,
2170 limit, replace_count);
2184 result = php_pcre_replace_func(
2185 regex_str, subject, fci, fcc, limit, replace_count,
flags);
2193 zend_string_addref(subject);
2199 zend_string *regex_entry_str = zval_get_tmp_string(regex_entry, &tmp_regex_entry_str);
2203 result = php_pcre_replace_func(
2204 regex_entry_str, subject, fci, fcc, limit, replace_count,
flags);
2205 zend_tmp_string_release(tmp_regex_entry_str);
2206 zend_string_release(subject);
2225 size_t replace_count = 0;
2228 result = php_replace_in_subject_func(
2229 regex_str, regex_ht, fci, fcc, subject_str, limit_val, &replace_count,
flags);
2250 zend_string *subject_entry_str = zval_get_tmp_string(subject_entry, &tmp_subject_entry_str);
2252 result = php_replace_in_subject_func(
2253 regex_str, regex_ht, fci, fcc, subject_entry_str, limit_val, &replace_count,
flags);
2263 zend_tmp_string_release(tmp_subject_entry_str);
2267 return replace_count;
2271static void _preg_replace_common(
2280 size_t replace_count = 0;
2282 size_t old_replace_count;
2285 if (replace_ht && !regex_ht) {
2291 old_replace_count = replace_count;
2292 result = php_replace_in_subject(regex_str, regex_ht, replace_str, replace_ht,
2293 subject_str, limit, &replace_count);
2295 if (!is_filter || replace_count > old_replace_count) {
2318 old_replace_count = replace_count;
2320 zend_string *subject_entry_str = zval_get_tmp_string(subject_entry, &tmp_subject_entry_str);
2321 result = php_replace_in_subject(regex_str, regex_ht, replace_str, replace_ht,
2322 subject_entry_str, limit, &replace_count);
2325 if (!is_filter || replace_count > old_replace_count) {
2337 zend_tmp_string_release(tmp_subject_entry_str);
2349 zend_string *regex_str, *replace_str, *subject_str;
2350 HashTable *regex_ht, *replace_ht, *subject_ht;
2364 _preg_replace_common(
2366 regex_ht, regex_str,
2367 replace_ht, replace_str,
2368 subject_ht, subject_str,
2369 limit, zcount, is_filter);
2382 zend_string *regex_str, *replace_str, *subject_str;
2383 HashTable *regex_ht, *replace_ht, *subject_ht;
2384 zval regex_tmp, replace_tmp, subject_tmp;
2390 _preg_replace_common(
2392 regex_ht, regex_str,
2393 replace_ht, replace_str,
2394 subject_ht, subject_str,
2412 size_t replace_count;
2427 replace_count = preg_replace_func_impl(
return_value, regex_str, regex_ht,
2429 subject_str, subject_ht, limit,
flags);
2443 size_t replace_count = 0;
2457 fci.
size =
sizeof(fci);
2472 if (!str_idx_regex) {
2479 replace_count += preg_replace_func_impl(&
zv, str_idx_regex,
NULL, &fci, &fcc,
2480 subject_str, subject_ht, limit,
flags);
2484 zend_array_release(subject_ht);
2489 zend_string_release(subject_str);
2520 zend_array_release(subject_ht);
2522 zend_string_release(subject_str);
2572 uint32_t delim_capture;
2573 uint32_t offset_capture;
2574 uint32_t num_subpats;
2577 char *subject =
ZSTR_VAL(subject_str);
2592 last_match_offset = 0;
2595 if (limit_val == -1) {
2597 }
else if (limit_val == 0) {
2599 }
else if (limit_val <= 1) {
2619#ifdef HAVE_PCRE_JIT_SUPPORT
2634 count = num_subpats;
2643 if (!no_empty || offsets[0] != last_match_offset) {
2644 if (offset_capture) {
2647 return_value_ht, subject, last_match_offset, offsets[0],
2651 populate_match_value_str(&tmp, subject, last_match_offset, offsets[0]);
2656 if (limit_val != -1)
2660 if (delim_capture) {
2662 for (i = 1; i <
count; i++) {
2664 if (!no_empty || offsets[2*i] != offsets[2*i+1]) {
2665 if (offset_capture) {
2667 return_value_ht, subject, offsets[2*i], offsets[2*i+1],
NULL, 0);
2669 populate_match_value_str(&tmp, subject, offsets[2*i], offsets[2*i+1]);
2677 start_offset = last_match_offset = offsets[1];
2683 if (start_offset == offsets[0]) {
2685 if (limit_val != -1 && limit_val <= 1) {
2697 if (start_offset <
ZSTR_LEN(subject_str)) {
2698 start_offset += calculate_unit_length(pce, subject + start_offset);
2711 pcre_handle_exec_error(
count);
2716 if (limit_val != -1 && limit_val <= 1) {
2720#ifdef HAVE_PCRE_JIT_SUPPORT
2729 if (match_data != mdata) {
2739 start_offset = last_match_offset;
2741 if (!no_empty || start_offset <
ZSTR_LEN(subject_str)) {
2742 if (offset_capture) {
2744 add_offset_pair(return_value_ht, subject, start_offset,
ZSTR_LEN(subject_str),
NULL, 0);
2747 if (start_offset == 0) {
2750 populate_match_value_str(&tmp, subject, start_offset,
ZSTR_LEN(subject_str));
2785 in_str_end = in_str +
ZSTR_LEN(str);
2826 if (c == delim_char) {
2832 }
while (
p != in_str_end);
2834 if (extra_len == 0) {
2840 out_str = zend_string_safe_alloc(1,
ZSTR_LEN(str), extra_len, 0);
2880 if (c == delim_char) {
2887 }
while (
p != in_str_end);
2924 uint32_t num_subpats;
2958 zend_string *subject_str = zval_get_tmp_string(entry, &tmp_subject_str);
2961#ifdef HAVE_PCRE_JIT_SUPPORT
2998 pcre_handle_exec_error(
count);
2999 zend_tmp_string_release(tmp_subject_str);
3003 zend_tmp_string_release(tmp_subject_str);
3005 if (match_data != mdata) {
3048#ifdef COMPILE_DL_PCRE
count(Countable|array $value, int $mode=COUNT_NORMAL)
assert(mixed $assertion, Throwable|string|null $description=null)
strchr(string $haystack, string $needle, bool $before_needle=false)
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
#define PCRE2_INFO_CAPTURECOUNT
#define PCRE2_DOLLAR_ENDONLY
#define PCRE2_ERROR_RECURSIONLIMIT
#define pcre2_match_data_create
#define PCRE2_NOTEMPTY_ATSTART
#define pcre2_jit_stack_assign
#define pcre2_set_compile_extra_options
#define pcre2_general_context
#define PCRE2_INFO_NAMETABLE
#define PCRE2_ERROR_NOMATCH
#define PCRE2_ERROR_INTERNAL
#define PCRE2_ERROR_UTF8_ERR21
#define pcre2_get_error_message
#define pcre2_general_context_free
#define pcre2_match_context_free
#define pcre2_set_match_limit
#define pcre2_compile_context_free
#define pcre2_get_ovector_pointer
#define pcre2_jit_stack_free
#define PCRE2_ERROR_BADOFFSET
#define PCRE2_INFO_JITSIZE
#define pcre2_set_character_tables
#define pcre2_pattern_info
#define pcre2_set_depth_limit
#define pcre2_match_data_create_from_pattern
#define pcre2_general_context_create
#define pcre2_match_context
#define pcre2_match_data_free
#define PCRE2_ERROR_JIT_STACKLIMIT
#define PCRE2_CONFIG_UNICODE_VERSION
#define PCRE2_EXTRA_CASELESS_RESTRICT
#define PCRE2_ERROR_MATCHLIMIT
#define PCRE2_JIT_COMPLETE
#define PCRE2_INFO_NAMECOUNT
#define PCRE2_NO_AUTO_CAPTURE
#define pcre2_jit_stack_create
#define PCRE2_NO_UTF_CHECK
#define pcre2_match_context_create
#define PCRE2_NO_START_OPTIMIZE
#define pcre2_compile_context_create
#define pcre2_jit_compile
#define pcre2_compile_context
#define PCRE2_INFO_NAMEENTRYSIZE
#define PCRE2_CONFIG_VERSION
#define PCRE2_CONFIG_JITTARGET
#define PCRE2_ERROR_BADUTFOFFSET
#define PCRE2_ERROR_NOMEMORY
php_info_print_table_start()
php_info_print_table_row(2, "PDO Driver for Firebird", "enabled")
php_info_print_table_end()
#define PHP_MSHUTDOWN_FUNCTION
#define PHP_MINIT_FUNCTION
#define PHP_MINFO_FUNCTION
#define PHP_GINIT_FUNCTION
#define PHP_RINIT_FUNCTION
#define PHP_RSHUTDOWN_FUNCTION
#define PHP_GSHUTDOWN_FUNCTION
#define PHP_MODULE_GLOBALS
unsigned const char * end
#define STD_PHP_INI_ENTRY
#define STD_PHP_INI_BOOLEAN
PHP_JSON_API size_t int options
php_json_error_code error_code
#define PREG_OFFSET_CAPTURE
#define php_pcre_mutex_alloc()
#define PHP_PCRE_PREALLOC_MDATA_SIZE
PHPAPI pcre2_match_context * php_pcre_mctx(void)
PHPAPI pcre2_code * php_pcre_pce_re(pcre_cache_entry *pce)
PHPAPI zend_string * php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *subject_str, const char *subject, size_t subject_len, zend_string *replace_str, size_t limit, size_t *replace_count)
PHPAPI pcre2_compile_context * php_pcre_cctx(void)
PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return_value, zend_long flags)
PHPAPI pcre2_match_data * php_pcre_create_match_data(uint32_t capture_count, pcre2_code *re)
PHPAPI void php_pcre_pce_decref(pcre_cache_entry *pce)
#define PREG_UNMATCHED_AS_NULL
PHPAPI pcre2_code * pcre_get_compiled_regex(zend_string *regex, uint32_t *capture_count)
PHPAPI pcre_cache_entry * pcre_get_compiled_regex_cache_ex(zend_string *regex, bool locale_aware)
#define PHP_PCRE_DEFAULT_EXTRA_COPTIONS
#define PREG_SPLIT_DELIM_CAPTURE
PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str, zval *return_value, zval *subpats, bool global, zend_long flags, zend_off_t start_offset)
#define PREG_SPLIT_OFFSET_CAPTURE
PHPAPI void php_pcre_pce_incref(pcre_cache_entry *pce)
zend_module_entry pcre_module_entry
#define PREG_SPLIT_NO_EMPTY
#define php_pcre_mutex_unlock()
#define php_pcre_mutex_free()
#define php_pcre_mutex_lock()
#define PREG_PATTERN_ORDER
PHPAPI pcre_cache_entry * pcre_get_compiled_regex_cache(zend_string *regex)
PHPAPI void php_pcre_free_match_data(pcre2_match_data *match_data)
PHPAPI zend_string * php_pcre_replace(zend_string *regex, zend_string *subject_str, const char *subject, size_t subject_len, zend_string *replace_str, size_t limit, size_t *replace_count)
PHPAPI pcre2_general_context * php_pcre_gctx(void)
PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, zend_string *subject_str, zval *return_value, zend_long limit_val, zend_long flags)
@ PHP_PCRE_JIT_STACKLIMIT_ERROR
@ PHP_PCRE_BACKTRACK_LIMIT_ERROR
@ PHP_PCRE_RECURSION_LIMIT_ERROR
@ PHP_PCRE_BAD_UTF8_ERROR
@ PHP_PCRE_BAD_UTF8_OFFSET_ERROR
@ PHP_PCRE_INTERNAL_ERROR
pcre2_general_context * gctx_zmm
zend_long backtrack_limit
struct _pcre_cache_entry pcre_cache_entry
zval unmatched_empty_pair
zend_long recursion_limit
preg_replace(string|array $pattern, string|array $replacement, string|array $subject, int $limit=-1, &$count=null)
preg_replace_callback(string|array $pattern, callable $callback, string|array $subject, int $limit=-1, &$count=null, int $flags=0)
preg_match_all(string $pattern, string $subject, &$matches=null, int $flags=0, int $offset=0)
preg_quote(string $str, ?string $delimiter=null)
preg_grep(string $pattern, array $array, int $flags=0)
preg_replace_callback_array(array $pattern, string|array $subject, int $limit=-1, &$count=null, int $flags=0)
preg_split(string $pattern, string $subject, int $limit=-1, int $flags=0)
preg_filter(string|array $pattern, string|array $replacement, string|array $subject, int $limit=-1, &$count=null)
preg_match(string $pattern, string $subject, &$matches=null, int $flags=0, int $offset=0)
unsigned char key[REFLECTION_KEY_LEN]
file_private int match(struct magic_set *, struct magic *, size_t, const struct buffer *, size_t, int, int, int, uint16_t *, uint16_t *, int *, int *, int *, int *, int *)
zend_string ** subpats_table
#define INTERNAL_FUNCTION_PARAMETERS
#define INTERNAL_FUNCTION_PARAM_PASSTHRU
ZEND_API zend_result add_next_index_null(zval *arg)
ZEND_API void add_assoc_string_ex(zval *arg, const char *key, size_t key_len, const char *str)
ZEND_API bool zend_is_callable_ex(zval *callable, zend_object *object, uint32_t check_flags, zend_string **callable_name, zend_fcall_info_cache *fcc, char **error)
ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *format,...)
ZEND_API ZEND_COLD void zend_argument_type_error(uint32_t arg_num, const char *format,...)
#define Z_PARAM_FUNC(dest_fci, dest_fcc)
struct _zend_fcall_info_cache zend_fcall_info_cache
#define ZEND_PARSE_PARAMETERS_END()
#define Z_PARAM_STR_OR_NULL(dest)
#define ZEND_PARSE_PARAMETERS_NONE()
#define ZVAL_STRING(z, s)
#define ZEND_DECLARE_MODULE_GLOBALS(module_name)
#define array_init_size(arg, size)
#define ZEND_GET_MODULE(name)
#define Z_PARAM_STR(dest)
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
#define ZEND_TRY_ASSIGN_REF_LONG(zv, lval)
#define Z_PARAM_ARRAY_HT_OR_STR(dest_ht, dest_str)
#define Z_PARAM_LONG(dest)
#define RETURN_NEW_STR(s)
struct _zend_fcall_info zend_fcall_info
#define Z_PARAM_ARRAY_HT(dest)
#define RETURN_EMPTY_STRING()
#define Z_PARAM_ARRAY(dest)
#define Z_PARAM_ZVAL(dest)
#define ZVAL_STRINGL_FAST(z, s, l)
ZEND_API zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache)
#define RETURN_STR_COPY(s)
#define ZVAL_EMPTY_STRING(z)
#define estrndup(s, length)
#define ecalloc(nmemb, size)
#define pefree(ptr, persistent)
#define pemalloc(size, persistent)
#define safe_emalloc(nmemb, size, offset)
zend_string_release_ex(func->internal_function.function_name, 0)
#define Z_FLF_PARAM_STR(arg_num, dest, tmp)
#define ZEND_FRAMELESS_FUNCTION(name, arity)
#define Z_FLF_PARAM_ARRAY_HT_OR_STR(arg_num, dest_ht, dest_str, str_tmp)
#define Z_FLF_PARAM_FREE_STR(arg_num, tmp)
#define EG_FLAGS_IN_SHUTDOWN
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_next_index_insert_new(HashTable *ht, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add_new(HashTable *ht, zend_ulong h, zval *pData)
ZEND_API void ZEND_FASTCALL zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t apply_func, void *argument)
ZEND_API zval *ZEND_FASTCALL zend_hash_add_new(HashTable *ht, zend_string *key, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_update(HashTable *ht, zend_ulong h, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_str_update(HashTable *ht, const char *str, size_t len, zval *pData)
ZEND_API HashTable *ZEND_FASTCALL zend_new_pair(zval *val1, zval *val2)
ZEND_API zval *ZEND_FASTCALL zend_hash_update(HashTable *ht, zend_string *key, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key)
ZEND_API zval *ZEND_FASTCALL zend_hash_add(HashTable *ht, zend_string *key, zval *pData)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
#define ZEND_HASH_ELEMENT(__ht, _idx)
#define ZEND_HASH_APPLY_STOP
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
#define ZEND_HASH_APPLY_REMOVE
#define zend_new_array(size)
#define ZEND_HASH_APPLY_KEEP
#define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val)
#define ZEND_HASH_FOREACH_STR_KEY_VAL(ht, _key, _val)
#define ZEND_HASH_FOREACH_END()
#define ZEND_HASH_FOREACH_VAL(ht, _val)
#define UNREGISTER_INI_ENTRIES()
#define REGISTER_INI_ENTRIES()
#define DISPLAY_INI_ENTRIES()
struct _zend_string zend_string
#define STANDARD_MODULE_HEADER
struct _zend_module_entry zend_module_entry
#define STANDARD_MODULE_PROPERTIES_EX
ZEND_API zend_string *ZEND_FASTCALL zval_get_string_func(zval *op)
#define EXPECTED(condition)
#define zend_always_inline
#define EMPTY_SWITCH_DEFAULT_CASE()
#define UNEXPECTED(condition)
ZEND_API zend_string * zend_string_concat2(const char *str1, size_t str1_len, const char *str2, size_t str2_len)
#define ZSTR_IS_VALID_UTF8(s)
#define ZSTR_IS_INTERNED(s)
#define ZSTR_MAX_OVERHEAD
#define ZSTR_EMPTY_ALLOC()
#define Z_TRY_ADDREF_P(pz)
#define Z_ARRVAL_P(zval_p)
#define ZVAL_STR_COPY(z, s)
struct _zend_array HashTable
#define IS_STR_VALID_UTF8
#define GC_MAKE_PERSISTENT_LOCAL(p)
#define IS_ARRAY_IMMUTABLE
#define Z_TYPE_FLAGS_P(zval_p)
#define ZVAL_COPY_VALUE(z, v)
#define IS_STR_PERSISTENT
#define GC_ADD_FLAGS(p, flags)
ZEND_API void zval_ptr_dtor(zval *zval_ptr)