Skip to content

Check match error before nametable scan in substring byname functions - #1052

Open
akashdeshmukh-git wants to merge 3 commits into
PCRE2Project:mainfrom
akashdeshmukh-git:fix-byname-early-failure
Open

akashdeshmukh-git wants to merge 3 commits into
PCRE2Project:mainfrom
akashdeshmukh-git:fix-byname-early-failure

Conversation

@akashdeshmukh-git

Copy link
Copy Markdown

What was wrong

When pcre2_match() fails early (e.g. PCRE2_ERROR_BADOFFSET, UTF validation failure), match_data->code is not assigned. Calling pcre2_substring_length_byname(), pcre2_substring_copy_byname(), or pcre2_substring_get_byname() subsequently dereferences a NULL code pointer in pcre2_substring_nametable_scan(), causing a segmentation fault or assertion failure.

How to reproduce

  1. Call pcre2_match() with arguments causing an early error return (such as start_offset > length).
  2. Call pcre2_substring_length_byname() with the resulting match data block.
  3. Observe segmentation fault in pcre2_substring_nametable_scan().

What changed

In pcre2_substring_copy_byname(), pcre2_substring_get_byname(), and pcre2_substring_length_byname(), check match_data->rc < 0 before scanning the nametable and return the match error code immediately, matching the behavior of the �ynumber functions. If match_data->code is NULL, return PCRE2_ERROR_NULL.

How it was tested

Added unit test in src/pcre2test_inc.h asserting that calling copy_byname, get_byname, and length_byname after an early match failure returns PCRE2_ERROR_BADOFFSET without crashing.

Fixes #1049

@NWilson

NWilson commented Oct 23, 2026

Copy link
Copy Markdown
Member

Thanks for opening a PR!

It looks like you've somehow committed a whole-file edit with the wrong line endings.

@akashdeshmukh-git

Copy link
Copy Markdown
Author

Apologies for the noise! The line endings were inadvertently converted to CRLF on Windows. I have pushed a clean commit with unix LF line endings so only the intended 35 lines are changed.

Comment thread src/pcre2_substring.c Outdated
Comment on lines +197 to +198
if (match_data->code == NULL)
return PCRE2_ERROR_NULL;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you. The check for rc is good.

However, I would prefer the nullness checks to be done as preconditions (assertion-only).

/* Preconditions on argument values */

...

/* Preconditions on argument state */

PCRE2_ASSERT(match_data->code != NULL);

...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks, done in 38321c5. The NULL checks are now PCRE2_ASSERT(match_data->code != NULL) under a "Preconditions on argument state" comment. I placed it after the rc < 0 check rather than before, because an early match failure (e.g. bad offset) leaves code unset with a negative rc, which is the case this PR fixes.

Per review, a NULL code after a successful or not yet run match is a
caller error, so it is checked as a precondition on argument state
rather than at runtime. A failed match can leave code unset, which the
rc check above already handles.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Substring "byname" functions crash when pcre2_match() returns early

2 participants