Skip to content

PCRE regular expressions with JIT enabled gives different result #11956

Closed

Description

@antman3351

Description

Hi,
The fallowing regex preg_match( '/<(\w+)[\s\w\-]+ id="S44_i89ew">/', '<br><div id="S44_i89ew">', $matches ); in PHP >= 8.1 gives different results if PCRE JIT is enabled or not. ( Note, I tried to simplify the regex to isolate the problem, that's why it doesn't make much sense ).

I had this problem with PHP 7.3 where I found a bug report that sated the problem was the PCRE library and not PHP.
I've recently migrated the code the regex is used in to PHP 8.2 and found there's still an issue, so I tested it on 3v4l.org and it seems to be fixed in PHP <= 8.0 and broken in 8.1.

I noted the issue on the PCRE2 github but the author doesn't think the issue is with any changes in the PCRE library: PCRE2Project/pcre2#261 (comment)

Code example: https://3v4l.org/189jh

Thanks,
Antonio

PHP Version

8.2.7

Operating System

No response

Activity

  1. ndossche commented on Aug 13, 2023

    @ndossche
    Member

    I can reproduce this locally. I'll run a bisect. This will also reveal if the problem is in PHP or in PCRE.

  2. ndossche commented on Aug 13, 2023

    @ndossche
    Member

    Bisect finished.

    It points to 5d42900 and 79755ca.
    This is indeed a pcre2lib problem in 2.37. Given that the pcre2lib maintainer says it does not reproduce in their testings on 2.42, I'd say the solution here is updating PHP's bundled pcre2lib to the latest version.

    As a temporary workaround you can configure & build with the flag to use your system's pcre2lib, and hope that version is high enough to not contain the bug.

  3. hormus commented on Aug 21, 2023

    @hormus

    Or for compatibility

    $equal = preg_quote('=');
    $pattern = '/<(\\w+)[\\s\\w\\-]*id' . $equal . '"S44_i89ew">/';
    
    // or for other regex
    $equal = preg_quote('=');
    $pattern = '/<(\\w+)[\\s\\w\\-]*id' . $equal . '"S44_123">/';
    Pattern /<(\w+)[\s\w\-]+ id="S44_i89ew">/ not + but * and without white space id
    for subject  <br><div id="S44_i89ew">
    
  4. antman3351 commented on Aug 21, 2023

    @antman3351
    Author

    Or for compatibility

    $equal = preg_quote('=');
    $pattern = '/<(\\w+)[\\s\\w\\-]*id' . $equal . '"S44_i89ew">/';
    
    // or for other regex
    $equal = preg_quote('=');
    $pattern = '/<(\\w+)[\\s\\w\\-]*id' . $equal . '"S44_123">/';
    
    Pattern /<(\w+)[\s\w\-]+ id="S44_i89ew">/ not + but * and without white space id
    for subject  <br><div id="S44_i89ew">
    

    Your regex doesn't cause the issue where there is a difference between JIT and non JIT.

  5. self-assigned this
    on Sep 2, 2023
  6. added a commit that references this issue on Sep 2, 2023
    aeb4c76
  7. added a commit that references this issue on Sep 18, 2023
    d61efdf
  8. added 3 commits that reference this issue on Sep 18, 2023
    15bbae7
    1bed209
    55432bf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions