|
39 | 39 | #define PREG_GREP_INVERT (1<<0)
|
40 | 40 |
|
41 | 41 | #define PREG_JIT (1<<3)
|
| 42 | +/* Whether JIT compiling has been attempted. This is necessary to avoid retrying JIT compilation |
| 43 | + * repeatedly when compilation fails. */ |
| 44 | +#define PREG_JIT_ATTEMPTED (1<<4) |
42 | 45 |
|
43 | 46 | #define PCRE_CACHE_SIZE 4096
|
44 | 47 |
|
@@ -585,6 +588,28 @@ static zend_always_inline size_t calculate_unit_length(pcre_cache_entry *pce, co
|
585 | 588 | }
|
586 | 589 | /* }}} */
|
587 | 590 |
|
| 591 | +static uint32_t pcre_jit_compile_regex(pcre2_code *re) { |
| 592 | + int rc = pcre2_jit_compile(re, PCRE2_JIT_COMPLETE); |
| 593 | + if (EXPECTED(rc >= 0)) { |
| 594 | + size_t jit_size = 0; |
| 595 | + if (!pcre2_pattern_info(re, PCRE2_INFO_JITSIZE, &jit_size) && jit_size > 0) { |
| 596 | + return (PREG_JIT|PREG_JIT_ATTEMPTED); |
| 597 | + } |
| 598 | + } else if (rc == PCRE2_ERROR_NOMEMORY) { |
| 599 | + php_error_docref(NULL, E_WARNING, |
| 600 | + "Allocation of JIT memory failed, PCRE JIT will be disabled. " |
| 601 | + "This is likely caused by security restrictions. " |
| 602 | + "Either grant PHP permission to allocate executable memory, or set pcre.jit=0"); |
| 603 | + PCRE_G(jit) = 0; |
| 604 | + } else { |
| 605 | + PCRE2_UCHAR error[128]; |
| 606 | + pcre2_get_error_message(rc, error, sizeof(error)); |
| 607 | + php_error_docref(NULL, E_WARNING, "JIT compilation failed: %s", error); |
| 608 | + pcre_handle_exec_error(PCRE2_ERROR_INTERNAL); |
| 609 | + } |
| 610 | + return PREG_JIT_ATTEMPTED; |
| 611 | +} |
| 612 | + |
588 | 613 | /* {{{ pcre_get_compiled_regex_cache */
|
589 | 614 | PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, int locale_aware)
|
590 | 615 | {
|
@@ -626,7 +651,13 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in
|
626 | 651 | if (key != regex) {
|
627 | 652 | zend_string_release_ex(key, 0);
|
628 | 653 | }
|
629 |
| - return (pcre_cache_entry*)Z_PTR_P(zv); |
| 654 | + pcre_cache_entry *pce = (pcre_cache_entry*)Z_PTR_P(zv); |
| 655 | +#ifdef HAVE_PCRE_JIT_SUPPORT |
| 656 | + if (!(pce->preg_options & PREG_JIT_ATTEMPTED) && PCRE_G(jit)) { |
| 657 | + pce->preg_options |= pcre_jit_compile_regex(re); |
| 658 | + } |
| 659 | +#endif |
| 660 | + return pce; |
630 | 661 | }
|
631 | 662 |
|
632 | 663 | p = ZSTR_VAL(regex);
|
@@ -806,24 +837,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in
|
806 | 837 |
|
807 | 838 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
808 | 839 | if (PCRE_G(jit)) {
|
809 |
| - /* Enable PCRE JIT compiler */ |
810 |
| - rc = pcre2_jit_compile(re, PCRE2_JIT_COMPLETE); |
811 |
| - if (EXPECTED(rc >= 0)) { |
812 |
| - size_t jit_size = 0; |
813 |
| - if (!pcre2_pattern_info(re, PCRE2_INFO_JITSIZE, &jit_size) && jit_size > 0) { |
814 |
| - poptions |= PREG_JIT; |
815 |
| - } |
816 |
| - } else if (rc == PCRE2_ERROR_NOMEMORY) { |
817 |
| - php_error_docref(NULL, E_WARNING, |
818 |
| - "Allocation of JIT memory failed, PCRE JIT will be disabled. " |
819 |
| - "This is likely caused by security restrictions. " |
820 |
| - "Either grant PHP permission to allocate executable memory, or set pcre.jit=0"); |
821 |
| - PCRE_G(jit) = 0; |
822 |
| - } else { |
823 |
| - pcre2_get_error_message(rc, error, sizeof(error)); |
824 |
| - php_error_docref(NULL, E_WARNING, "JIT compilation failed: %s", error); |
825 |
| - pcre_handle_exec_error(PCRE2_ERROR_INTERNAL); |
826 |
| - } |
| 840 | + poptions |= pcre_jit_compile_regex(re); |
827 | 841 | }
|
828 | 842 | #endif
|
829 | 843 | efree(pattern);
|
@@ -1263,7 +1277,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str,
|
1263 | 1277 |
|
1264 | 1278 | /* Execute the regular expression. */
|
1265 | 1279 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
1266 |
| - if ((pce->preg_options & PREG_JIT) && options) { |
| 1280 | + if ((pce->preg_options & PREG_JIT) && options && PCRE_G(jit)) { |
1267 | 1281 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset2,
|
1268 | 1282 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
1269 | 1283 | } else
|
@@ -1405,7 +1419,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str,
|
1405 | 1419 |
|
1406 | 1420 | /* Execute the regular expression. */
|
1407 | 1421 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
1408 |
| - if ((pce->preg_options & PREG_JIT)) { |
| 1422 | + if ((pce->preg_options & PREG_JIT) && PCRE_G(jit)) { |
1409 | 1423 | if (PCRE2_UNSET == start_offset2 || start_offset2 > subject_len) {
|
1410 | 1424 | pcre_handle_exec_error(PCRE2_ERROR_BADOFFSET);
|
1411 | 1425 | break;
|
@@ -1625,7 +1639,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
|
1625 | 1639 |
|
1626 | 1640 | /* Execute the regular expression. */
|
1627 | 1641 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
1628 |
| - if ((pce->preg_options & PREG_JIT) && options) { |
| 1642 | + if ((pce->preg_options & PREG_JIT) && options && PCRE_G(jit)) { |
1629 | 1643 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset,
|
1630 | 1644 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
1631 | 1645 | } else
|
@@ -1800,7 +1814,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
|
1800 | 1814 | }
|
1801 | 1815 |
|
1802 | 1816 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
1803 |
| - if (pce->preg_options & PREG_JIT) { |
| 1817 | + if ((pce->preg_options & PREG_JIT) && PCRE_G(jit)) { |
1804 | 1818 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset,
|
1805 | 1819 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
1806 | 1820 | } else
|
@@ -1881,7 +1895,7 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
|
1881 | 1895 |
|
1882 | 1896 | /* Execute the regular expression. */
|
1883 | 1897 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
1884 |
| - if ((pce->preg_options & PREG_JIT) && options) { |
| 1898 | + if ((pce->preg_options & PREG_JIT) && options && PCRE_G(jit)) { |
1885 | 1899 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset,
|
1886 | 1900 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
1887 | 1901 | } else
|
@@ -2008,7 +2022,7 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
|
2008 | 2022 | break;
|
2009 | 2023 | }
|
2010 | 2024 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
2011 |
| - if ((pce->preg_options & PREG_JIT)) { |
| 2025 | + if ((pce->preg_options & PREG_JIT) && PCRE_G(jit)) { |
2012 | 2026 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset,
|
2013 | 2027 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
2014 | 2028 | } else
|
@@ -2551,7 +2565,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, zend_string *subject_str,
|
2551 | 2565 | options = (pce->compile_options & PCRE2_UTF) ? 0 : PCRE2_NO_UTF_CHECK;
|
2552 | 2566 |
|
2553 | 2567 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
2554 |
| - if ((pce->preg_options & PREG_JIT) && options) { |
| 2568 | + if ((pce->preg_options & PREG_JIT) && options && PCRE_G(jit)) { |
2555 | 2569 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, ZSTR_LEN(subject_str), start_offset,
|
2556 | 2570 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
2557 | 2571 | } else
|
@@ -2654,7 +2668,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, zend_string *subject_str,
|
2654 | 2668 | }
|
2655 | 2669 |
|
2656 | 2670 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
2657 |
| - if (pce->preg_options & PREG_JIT) { |
| 2671 | + if ((pce->preg_options & PREG_JIT) && PCRE_G(jit)) { |
2658 | 2672 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, ZSTR_LEN(subject_str), start_offset,
|
2659 | 2673 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
2660 | 2674 | } else
|
@@ -2894,7 +2908,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return
|
2894 | 2908 |
|
2895 | 2909 | /* Perform the match */
|
2896 | 2910 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
2897 |
| - if ((pce->preg_options & PREG_JIT) && options) { |
| 2911 | + if ((pce->preg_options & PREG_JIT) && options && PCRE_G(jit)) { |
2898 | 2912 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)ZSTR_VAL(subject_str), ZSTR_LEN(subject_str), 0,
|
2899 | 2913 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
2900 | 2914 | } else
|
|
0 commit comments