Skip to content

fix(graphql): escape host in resolve-uris preg_match pattern - #125

Merged
kuuak merged 1 commit into
futurefrom
fix/resolve-uris-preg-quote
Jul 22, 2026
Merged

fix(graphql): escape host in resolve-uris preg_match pattern#125
kuuak merged 1 commit into
futurefrom
fix/resolve-uris-preg-quote

Conversation

@kuuak

@kuuak kuuak commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Problem

graphql_resolve_relative_uris() interpolates the site/FE hosts straight into a preg_match pattern:

$site_url = preg_replace('/https?:\/\//', '', get_site_url());
$next_url = preg_replace('/https?:\/\//', '', get_next_url());

if (! preg_match("/^https?:\/\/($site_url|$next_url)/i", $result)) return $result;

The pattern uses / as its delimiter, but the interpolated hosts are not escaped. On a sub-path install the host contains a slash (e.g. localhost/us), so the first / inside the host is read as the closing delimiter and PHP parses the remainder (us|localhost:3000...) as modifiers — hitting the |:

PHP Warning: preg_match(): Unknown modifier '|' in .../graphql/resolve-uris.php on line 54

Because this filter runs on graphql_resolve_field for every uri/url/link/guid/sourceUrl/mediaItemUrl field, the warning (plus a full stack trace) is emitted on essentially every GraphQL request, flooding the logs.

It's a latent bug on root-domain installs (host has no slash) and only surfaces once the site runs under a sub-path — or if a host ever contains another regex-special char.

Fix

Wrap both hosts in preg_quote(..., '/') so slashes and other regex-special characters are matched literally.

Notes

  • Behaviour is unchanged on root-domain installs; the pattern was previously broken/truncated on sub-path installs, so this also makes the host match actually correct there.
  • These were notice/warning-level entries, not fatals — the site kept working, but the log noise (and per-request stack-trace overhead) is eliminated.
  • Discovered on a downstream project (samantree.com) running under /us.

get_site_url()/get_next_url() hosts are interpolated straight into the
preg_match pattern that gates URL rewriting. On sub-path installs the
host contains a slash (e.g. "localhost/us"), which is read as the regex
delimiter, so PHP parses the remainder as modifiers and emits
"preg_match(): Unknown modifier '|'" on every resolved URI field.

Wrap both hosts in preg_quote(..., '/') so slashes and other
regex-special characters are treated literally.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a regex parsing bug in the WordPress GraphQL URI resolver by properly escaping the backend (WP) and frontend (Next.js) URL fragments before interpolating them into a preg_match() pattern. This prevents warnings (and associated stack traces) on sub-path installs (e.g. /us) and ensures the host/path match works correctly.

Changes:

  • Escape $site_url and $next_url using preg_quote(..., '/') before building the preg_match() pattern.
  • Add an inline comment explaining why escaping is required (slashes in sub-path installs).

@kuuak
kuuak merged commit 97c8a1b into future Jul 22, 2026
1 check passed
@kuuak
kuuak deleted the fix/resolve-uris-preg-quote branch July 22, 2026 13:57
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.

2 participants