|
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,30 @@ static zend_always_inline size_t calculate_unit_length(pcre_cache_entry *pce, co
|
585 | 588 | }
|
586 | 589 | /* }}} */
|
587 | 590 |
|
| 591 | +#ifdef HAVE_PCRE_JIT_SUPPORT |
| 592 | +static uint32_t pcre_jit_compile_regex(pcre2_code *re) { |
| 593 | + int rc = pcre2_jit_compile(re, PCRE2_JIT_COMPLETE); |
| 594 | + if (EXPECTED(rc >= 0)) { |
| 595 | + size_t jit_size = 0; |
| 596 | + if (!pcre2_pattern_info(re, PCRE2_INFO_JITSIZE, &jit_size) && jit_size > 0) { |
| 597 | + return (PREG_JIT|PREG_JIT_ATTEMPTED); |
| 598 | + } |
| 599 | + } else if (rc == PCRE2_ERROR_NOMEMORY) { |
| 600 | + php_error_docref(NULL, E_WARNING, |
| 601 | + "Allocation of JIT memory failed, PCRE JIT will be disabled. " |
| 602 | + "This is likely caused by security restrictions. " |
| 603 | + "Either grant PHP permission to allocate executable memory, or set pcre.jit=0"); |
| 604 | + PCRE_G(jit) = 0; |
| 605 | + } else { |
| 606 | + PCRE2_UCHAR error[128]; |
| 607 | + pcre2_get_error_message(rc, error, sizeof(error)); |
| 608 | + php_error_docref(NULL, E_WARNING, "JIT compilation failed: %s", error); |
| 609 | + pcre_handle_exec_error(PCRE2_ERROR_INTERNAL); |
| 610 | + } |
| 611 | + return PREG_JIT_ATTEMPTED; |
| 612 | +} |
| 613 | +#endif |
| 614 | + |
588 | 615 | /* {{{ pcre_get_compiled_regex_cache */
|
589 | 616 | PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, int locale_aware)
|
590 | 617 | {
|
@@ -626,7 +653,13 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in
|
626 | 653 | if (key != regex) {
|
627 | 654 | zend_string_release_ex(key, 0);
|
628 | 655 | }
|
629 |
| - return (pcre_cache_entry*)Z_PTR_P(zv); |
| 656 | + pcre_cache_entry *pce = (pcre_cache_entry*)Z_PTR_P(zv); |
| 657 | +#ifdef HAVE_PCRE_JIT_SUPPORT |
| 658 | + if (!(pce->preg_options & PREG_JIT_ATTEMPTED) && PCRE_G(jit)) { |
| 659 | + pce->preg_options |= pcre_jit_compile_regex(re); |
| 660 | + } |
| 661 | +#endif |
| 662 | + return pce; |
630 | 663 | }
|
631 | 664 |
|
632 | 665 | p = ZSTR_VAL(regex);
|
@@ -806,24 +839,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache_ex(zend_string *regex, in
|
806 | 839 |
|
807 | 840 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
808 | 841 | 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 |
| - } |
| 842 | + poptions |= pcre_jit_compile_regex(re); |
827 | 843 | }
|
828 | 844 | #endif
|
829 | 845 | efree(pattern);
|
@@ -1263,7 +1279,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str,
|
1263 | 1279 |
|
1264 | 1280 | /* Execute the regular expression. */
|
1265 | 1281 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
1266 |
| - if ((pce->preg_options & PREG_JIT) && options) { |
| 1282 | + if ((pce->preg_options & PREG_JIT) && options && PCRE_G(jit)) { |
1267 | 1283 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset2,
|
1268 | 1284 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
1269 | 1285 | } else
|
@@ -1405,7 +1421,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str,
|
1405 | 1421 |
|
1406 | 1422 | /* Execute the regular expression. */
|
1407 | 1423 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
1408 |
| - if ((pce->preg_options & PREG_JIT)) { |
| 1424 | + if ((pce->preg_options & PREG_JIT) && PCRE_G(jit)) { |
1409 | 1425 | if (PCRE2_UNSET == start_offset2 || start_offset2 > subject_len) {
|
1410 | 1426 | pcre_handle_exec_error(PCRE2_ERROR_BADOFFSET);
|
1411 | 1427 | break;
|
@@ -1625,7 +1641,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
|
1625 | 1641 |
|
1626 | 1642 | /* Execute the regular expression. */
|
1627 | 1643 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
1628 |
| - if ((pce->preg_options & PREG_JIT) && options) { |
| 1644 | + if ((pce->preg_options & PREG_JIT) && options && PCRE_G(jit)) { |
1629 | 1645 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset,
|
1630 | 1646 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
1631 | 1647 | } else
|
@@ -1800,7 +1816,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su
|
1800 | 1816 | }
|
1801 | 1817 |
|
1802 | 1818 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
1803 |
| - if (pce->preg_options & PREG_JIT) { |
| 1819 | + if ((pce->preg_options & PREG_JIT) && PCRE_G(jit)) { |
1804 | 1820 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset,
|
1805 | 1821 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
1806 | 1822 | } else
|
@@ -1881,7 +1897,7 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
|
1881 | 1897 |
|
1882 | 1898 | /* Execute the regular expression. */
|
1883 | 1899 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
1884 |
| - if ((pce->preg_options & PREG_JIT) && options) { |
| 1900 | + if ((pce->preg_options & PREG_JIT) && options && PCRE_G(jit)) { |
1885 | 1901 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset,
|
1886 | 1902 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
1887 | 1903 | } else
|
@@ -2008,7 +2024,7 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin
|
2008 | 2024 | break;
|
2009 | 2025 | }
|
2010 | 2026 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
2011 |
| - if ((pce->preg_options & PREG_JIT)) { |
| 2027 | + if ((pce->preg_options & PREG_JIT) && PCRE_G(jit)) { |
2012 | 2028 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, subject_len, start_offset,
|
2013 | 2029 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
2014 | 2030 | } else
|
@@ -2551,7 +2567,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, zend_string *subject_str,
|
2551 | 2567 | options = (pce->compile_options & PCRE2_UTF) ? 0 : PCRE2_NO_UTF_CHECK;
|
2552 | 2568 |
|
2553 | 2569 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
2554 |
| - if ((pce->preg_options & PREG_JIT) && options) { |
| 2570 | + if ((pce->preg_options & PREG_JIT) && options && PCRE_G(jit)) { |
2555 | 2571 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, ZSTR_LEN(subject_str), start_offset,
|
2556 | 2572 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
2557 | 2573 | } else
|
@@ -2654,7 +2670,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, zend_string *subject_str,
|
2654 | 2670 | }
|
2655 | 2671 |
|
2656 | 2672 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
2657 |
| - if (pce->preg_options & PREG_JIT) { |
| 2673 | + if ((pce->preg_options & PREG_JIT) && PCRE_G(jit)) { |
2658 | 2674 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)subject, ZSTR_LEN(subject_str), start_offset,
|
2659 | 2675 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
2660 | 2676 | } else
|
@@ -2894,7 +2910,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return
|
2894 | 2910 |
|
2895 | 2911 | /* Perform the match */
|
2896 | 2912 | #ifdef HAVE_PCRE_JIT_SUPPORT
|
2897 |
| - if ((pce->preg_options & PREG_JIT) && options) { |
| 2913 | + if ((pce->preg_options & PREG_JIT) && options && PCRE_G(jit)) { |
2898 | 2914 | count = pcre2_jit_match(pce->re, (PCRE2_SPTR)ZSTR_VAL(subject_str), ZSTR_LEN(subject_str), 0,
|
2899 | 2915 | PCRE2_NO_UTF_CHECK, match_data, mctx);
|
2900 | 2916 | } else
|
|
0 commit comments