Skip to content

Fix #5189: Restore pregMatch capture group extraction on PCRE2 - #5191

Merged
FileEX merged 2 commits into
multitheftauto:masterfrom
MohabCodeX:fix/pregmatch-capture-group
Aug 17, 2026
Merged

Fix #5189: Restore pregMatch capture group extraction on PCRE2#5191
FileEX merged 2 commits into
multitheftauto:masterfrom
MohabCodeX:fix/pregmatch-capture-group

Conversation

@MohabCodeX

Copy link
Copy Markdown
Contributor

Summary

Fix pregMatch regression where patterns with capturing groups return the full match instead of the first captured subpattern.

Motivation

FindAndConsume in Shared/pcrecpp_compat.h was reading ovector[0..1] (full match) instead of ovector[2..3] (capture group 1). This was introduced in PR #4939 during the PCRE1 → PCRE2 migration and broke all scripts relying on capture group extraction.

Fixes #5189.

The fix caches the capture group count at compile time via pcre2_pattern_info(PCRE2_INFO_CAPTURECOUNT) and selects the correct ovector range in FindAndConsume:

  • Pattern has capturing groups → returns group 1
  • Pattern has no capturing groups → returns the full match (graceful fallback)

Forward progress on zero-width matches is preserved by always consuming based on the full match end offset.

Test plan

pcre_test.zip

Results

PCRE2 & PREG Functions Test Results — 21/21 Passed
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] single capture group -> {"123"}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] repeated single group -> {"hello", "hello"}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] first group of two -> {"John"}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] multiple matches with capture -> {"10", "20", "30"}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] non-capturing prefix with capture -> {"100", "200", "300"}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] no parens returns words -> {"apple", "banana", "orange"}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] no parens returns digits -> {"123", "456", "789"}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] named capture group -> {"999"}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] nested groups returns outermost -> {"foo:123", "bar:456"}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] optional group present -> {"5"}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] optional group absent -> {""}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] unicode flag with multibyte text -> {"123", "456"}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] case-insensitive flag -> {"HELLO", "world"}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] maxResults limit -> {"a", "b", "c"}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] no match returns empty table -> {}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [CLIENT PASS] [pregMatch] empty subject returns empty table -> {}
[01:34:56] [debug] pcre_test\client_test.lua:52 - [pregFind] match found -> true
[01:34:56] [debug] pcre_test\client_test.lua:52 - [pregFind] match not found -> false
[01:34:56] [debug] pcre_test\client_test.lua:52 - [pregFind] unicode flag -> true
[01:34:56] [debug] pcre_test\client_test.lua:52 - [pregReplace] simple replace -> client pass
[01:34:56] [debug] pcre_test\client_test.lua:52 - [pregReplace] backslash in replacement -> a\b
[01:34:56] [debug] pcre_test\client_test.lua:63 - =====================================================================
[01:34:56] [debug] pcre_test\client_test.lua:64 -        MTA:SA CLIENT PCRE2 & PREG FUNCTIONS TEST REPORT
[01:34:56] [debug] pcre_test\client_test.lua:65 - =====================================================================
[01:34:56] [debug] pcre_test\client_test.lua:66 -   Total: 21 | Passed: 21 | Failed: 0 | Pass Rate: 100% (14 ms)
[01:34:56] [debug] pcre_test\client_test.lua:68 - =====================================================================
[01:34:56] [debug] pcre_test\client_test.lua:71 -   RESULT: SUCCESS - ALL CLIENT PCRE2 TESTS PASSED!
[01:34:56] [debug] pcre_test\client_test.lua:75 - =====================================================================

Checklist

  • Your code should follow the coding guidelines.
  • Smaller pull requests are easier to review. If your pull request is beefy, your pull request should be reviewable commit-by-commit.

@FileEX FileEX added the bugfix Solution to a bug of any kind label Aug 17, 2026
@FileEX FileEX added this to the 1.7 (Current) milestone Aug 17, 2026
@FileEX
FileEX merged commit 19eb8ca into multitheftauto:master Aug 17, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Solution to a bug of any kind

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression: pregMatch returns the whole match instead of the capture group on 1.7

2 participants