fix: handle host-prefixed root path in PublicPathMatcher
Sync GitHub / sync (push) Successful in 6s
Tests / test (pull_request) Successful in 1m3s

The host-prefix regex required at least one character after the slash
(/\+.+/), so a pattern like 'code.example.com/' was silently dropped
instead of matching the root path '/'. Changed \+.+ to \+.* so the
trailing slash alone is accepted as the path '/'.

Added tests covering the exact bug scenario from PUBLIC_PATHS
config: 'code.digitaladapt.com/,code.digitaladapt.com/public/**'
This commit is contained in:
2026-08-13 14:30:52 -04:00
parent 66b960ccea
commit e3cd8c6739
2 changed files with 20 additions and 1 deletions
+1 -1
View File
@@ -79,7 +79,7 @@ final readonly class PublicPathMatcher implements PublicPathMatcherInterface
$host = null;
$path = $entry;
if (preg_match('/^([a-z0-9.-]+)(\/.+)$/i', $entry, $m)) {
if (preg_match('/^([a-z0-9.-]+)(\/.*)$/i', $entry, $m)) {
$host = strtolower($m[1]);
$path = $m[2];
}
@@ -176,6 +176,25 @@ final class PublicPathMatcherTest extends TestCase
self::assertFalse($matcher->matches('other.host', '/public/repo'));
}
public function testDomainPrefixedRootPathMatchesRoot(): void
{
// host/ — the trailing slash is the entire path, nothing after it
$matcher = new PublicPathMatcher('code.example.com/');
self::assertTrue($matcher->matches('code.example.com', '/'));
self::assertFalse($matcher->matches('code.example.com', '/public'));
self::assertFalse($matcher->matches('other.example.com', '/'));
}
public function testDomainPrefixedRootWithOtherPatterns(): void
{
// The exact scenario from the bug report
$matcher = new PublicPathMatcher('code.example.com/,code.example.com/public/**');
self::assertTrue($matcher->matches('code.example.com', '/'));
self::assertTrue($matcher->matches('code.example.com', '/public/repo'));
self::assertFalse($matcher->matches('code.example.com', '/private'));
self::assertFalse($matcher->matches('other.example.com', '/'));
}
public function testDomainPrefixIsCaseInsensitive(): void
{
$matcher = new PublicPathMatcher('Code.Example.COM/public/**');