Skip to content

Fix #10610 (Support for PCRE2) - #9003

Open
danmar wants to merge 3 commits into
cppcheck-opensource:mainfrom
cppchecksolutions:fix-10610
Open

danmar wants to merge 3 commits into
cppcheck-opensource:mainfrom
cppchecksolutions:fix-10610

Conversation

@danmar

@danmar danmar commented Nov 7, 2026

Copy link
Copy Markdown
Collaborator

Replace the discontinued PCRE library with PCRE2 for rules

PCRE (8.x) is end of life and is being removed from Linux distributions.

  • lib/regex.cpp: use the PCRE2 API (with JIT when available)
  • fix endless loop when a rule pattern matches an empty string
  • CMake, Makefile, dmake and Visual Studio project use PCRE2
  • CI installs/builds PCRE2 instead of PCRE
  • update documentation

Rule files and the "pcre" engine name are unchanged.

Replace the discontinued PCRE library with PCRE2 for rules

PCRE (8.x) is end of life and is being removed from Linux distributions.

- lib/regex.cpp: use the PCRE2 API (with JIT when available)
- fix endless loop when a rule pattern matches an empty string
- CMake, Makefile, dmake and Visual Studio project use PCRE2
- CI installs/builds PCRE2 instead of PCRE
- update documentation

Rule files and the "pcre" engine name are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@danmar danmar added the ai-assisted contains code which was written with the assistance of AI - please review extra carefully label Nov 7, 2026
@danmar

danmar commented Nov 7, 2026

Copy link
Copy Markdown
Collaborator Author

@fliiiix @andrew-aitchison @loqs @Harvester57 @pfultz2 @firewave
this PR replaces PCRE with PCRE2.
So it's more aggressive than #8382 .
I have implemented this with AI so any help with reviewing / testing it out would be appreciated.

The PCRE2 source archive contains an INSTALL file, so on the
case-insensitive Windows file system "install" cannot be used as
install prefix directory.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@dmcppcheck dmcppcheck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI review

I found no new problems. lib/regex.cpp now uses the PCRE2 API correctly. The match data is created on each call, so a Regex that several threads share is safe. A failed JIT compile falls back to the interpreter. The match loop steps forward one byte after an empty match, so patterns such as b* or ( x)? no longer loop forever. Error messages for patterns that do not compile are the same as before (\ at end of pattern, missing terminating ] for character class), so the existing expected strings in the tests still pass. Patterns that match an empty string now report a found '' finding at many positions. Cppcheck's de-duplication cuts that down to one per line, and the same behaviour lets zero-width rules such as (?= x) work, so I don't count it as a defect. I could not check the Windows/MSVC and CI changes (library names, install prefix) here.

Testing

Build: The container has the libpcre2-8 runtime (10.42, libpcre2-8.so.0) but no headers and no pcre2-config. To build anyway, I wrote a small pcre2.h that declares only the functions regex.cpp uses (they map to the _8 symbols), plus a fake pcre2-config (--cflags/--libs8). With those I built make -j8 HAVE_RULES=yes cppcheck testrunner in pr/, and it built without errors. Base was not built: PCRE1 is not available, so I could not compare against the old engine.

Unit tests: ./testrunner TestRegExPcre TestCmdlineParser TestCppcheck ran 406 tests with 0 failures, including the new emptymatch and the compile-error message checks in TestCmdlineParser.

Python tests: pytest rules_test.py gave 6 passed. pytest other_test.py helloworld_test.py inline-suppress-polyspace_test.py -k rule gave 6 passed.

Manual checks with cppcheck --rule=... on a small C file:

  • ( x)? (matches the empty string) finishes at once. It reports the empty matches, which are de-duplicated to one per line, as well as the real x matches.
  • (?= x) (zero-width lookahead) reports the right lines.
  • \bx\b gives correct results, so word boundaries work when matching starts partway into the string.
  • Running on 30 files with -j8 and an empty-matching rule finishes with stable output and no hang.
  • (?<=x gives failed to compile rule pattern '(?<=x' (missing closing parenthesis).
  • A pattern that recurses without end, (a|aa)*+(?:(?R)), gives the error JIT stack limit reached (pos: 0) [pcre_exec] instead of crashing or hanging.

Automated review of ab7764c by Claude. The pull request was built and tested locally.

@Harvester57

Copy link
Copy Markdown

Hi there,

Built and tested locally by cherry-picking the PR over v2.22.0, applies cleanly and works perfectly well, thank you very much !

Comment thread requirements.txt Resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-assisted contains code which was written with the assistance of AI - please review extra carefully

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants