Skip to content

Commit aeb4c76

Browse files
committed
Fix phpGH-11956: PCRE regular expressions with JIT enabled gives different result
The code in the attached test used to work correctly in PHP 8.0, but not in 8.1+. This is because PHP 8.1+ uses a more modern version of pcre2 than PHP 8.0, and that pcre2 versions has a regression. While upgrading pcre2lib seems to be only done for the master branch, it is possible to backport upstream fixes to stable branches. This has been already done in the past in for JIT regressions [1], so it is not unprecedented. We backport the upstream pcre2 fix [2]. [1] php@788a701e222 [2] PCRE2Project/pcre2#135
1 parent b21df69 commit aeb4c76

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

ext/pcre/pcre2lib/pcre2_jit_compile.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11286,19 +11286,19 @@ if (exact > 1)
1128611286
}
1128711287
}
1128811288
else if (exact == 1)
11289-
{
1129011289
compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
1129111290

11292-
if (early_fail_type == type_fail_range)
11293-
{
11294-
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr);
11295-
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + (int)sizeof(sljit_sw));
11296-
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, TMP2, 0);
11297-
OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, TMP2, 0);
11298-
add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0));
11291+
if (early_fail_type == type_fail_range)
11292+
{
11293+
/* Range end first, followed by range start. */
11294+
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr);
11295+
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + (int)sizeof(sljit_sw));
11296+
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, TMP2, 0);
11297+
OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, TMP2, 0);
11298+
add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0));
1129911299

11300-
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + (int)sizeof(sljit_sw), STR_PTR, 0);
11301-
}
11300+
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0);
11301+
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + (int)sizeof(sljit_sw), STR_PTR, 0);
1130211302
}
1130311303

1130411304
switch(opcode)

ext/pcre/tests/gh11956.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
GH-11956 (PCRE regular expressions with JIT enabled gives different result)
3+
--INI--
4+
pcre.jit=1
5+
--FILE--
6+
<?php
7+
preg_match( '/<(\w+)[\s\w\-]+ id="S44_i89ew">/', '<br><div id="S44_i89ew">', $matches );
8+
var_dump($matches);
9+
?>
10+
--EXPECT--
11+
array(2) {
12+
[0]=>
13+
string(20) "<div id="S44_i89ew">"
14+
[1]=>
15+
string(2) "di"
16+
}

0 commit comments

Comments
 (0)