Skip to content

Commit

Permalink
Fix URI RFC3986 parsing and invalid characters
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Jan 2, 2025
1 parent 4e19562 commit 51719f1
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 38 deletions.
2 changes: 1 addition & 1 deletion interfaces/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ All Notable changes to `League\Uri\Interfaces` will be documented in this file

### Fixed

- `UriString::parse` will fail if the URI contains whitespace.
- `UriString::parse` will fail if the URI contains whitespace or is the empty string.

### Deprecated

Expand Down
9 changes: 6 additions & 3 deletions interfaces/UriString.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ final class UriString
* @var array<string, array<string>>
*/
private const URI_SHORTCUTS = [
'' => [],
'#' => ['fragment' => ''],
'?' => ['query' => ''],
'?#' => ['query' => '', 'fragment' => ''],
Expand Down Expand Up @@ -278,7 +277,7 @@ public static function buildAuthority(array $components): ?string
*/
public static function normalize(Stringable|string $uri): string
{
$components = UriString::parse($uri);
$components = self::parse($uri);
if (null !== $components['scheme']) {
$components['scheme'] = strtolower($components['scheme']);
}
Expand Down Expand Up @@ -339,6 +338,10 @@ public static function normalizeAuthority(Stringable|string $authority): string
*/
public static function resolve(Stringable|string $uri, Stringable|string|null $baseUri = null): string
{
if ('' === $uri) {
$uri = $baseUri ?? throw new SyntaxError('The uri can not be the empty string when there\'s no base URI.');
}

$uri = self::parse($uri);
$baseUri = null !== $baseUri ? self::parse($baseUri) : $uri;
if (null === $baseUri['scheme']) {
Expand Down Expand Up @@ -492,7 +495,7 @@ public static function parse(Stringable|string|int $uri): array
return $components;
}

if (1 === preg_match(self::REGEXP_INVALID_URI_CHARS, $uri)) {
if ('' === $uri || 1 === preg_match(self::REGEXP_INVALID_URI_CHARS, $uri)) {
throw new SyntaxError(sprintf('The uri `%s` contains invalid characters', $uri));
}

Expand Down
18 changes: 1 addition & 17 deletions interfaces/UriStringTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -579,19 +579,6 @@ public static function validUriProvider(): array
'fragment' => 'foo=1/bar=2',
],
],
'empty string' => [
'',
[
'scheme' => null,
'user' => null,
'pass' => null,
'host' => null,
'port' => null,
'path' => '',
'query' => null,
'fragment' => null,
],
],
'complex URI' => [
'htà+d/s:totot',
[
Expand Down Expand Up @@ -776,6 +763,7 @@ public static function invalidUriProvider(): array
'invalid host with fullwidth escaped' => ['http://%ef%bc%85%ef%bc%94%ef%bc%91.com],'],
//'invalid pseudo IDN to ASCII string' => ['http://xn--3/foo.'],
'invalid IDN' => ['//:�@�����������������������������������������������������������������������������������������/'],
'empty string' => [''],
];
}

Expand Down Expand Up @@ -944,10 +932,6 @@ public static function buildUriProvider(): array
'http://example.com#foo=1/bar=2',
'http://example.com#foo=1/bar=2',
],
'empty string' => [
'',
'',
],
'complex URI' => [
'htà+d/s:totot',
'htà+d/s:totot',
Expand Down
7 changes: 6 additions & 1 deletion uri/BaseUri.php
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,12 @@ final protected static function formatPathWithEmptyBaseQuery(string $path): stri
#[Deprecated(message:'no longer used by the isSameDocument method', since:'league/uri-interfaces:7.6.0')]
final protected function normalize(Psr7UriInterface|UriInterface $uri): string
{
return UriString::normalize($uri->withScheme($uri instanceof Psr7UriInterface ? '' : null));
$newUri = $uri->withScheme($uri instanceof Psr7UriInterface ? '' : null);
if ('' === $newUri->__toString()) {
return '';
}

return UriString::normalize($newUri);
}


Expand Down
2 changes: 1 addition & 1 deletion uri/Http.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private function normalizePsr7Uri(UriInterface $uri): UriInterface
*/
public static function new(Stringable|string $uri = ''): self
{
return self::fromComponents(UriString::parse($uri));
return new self(Uri::new($uri));
}

/**
Expand Down
4 changes: 0 additions & 4 deletions uri/HttpTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,6 @@ public static function validUrlProvider(): array
'http://login:[email protected]/',
'http://login:[email protected]/',
],
'empty string' => [
'',
'',
],
];
}

Expand Down
23 changes: 12 additions & 11 deletions uri/Uri.php
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,11 @@ public static function tryNew(Stringable|string|null $uri = ''): ?self
*/
public static function new(Stringable|string $uri = ''): self
{
$uri = (string) $uri;
if ('' === $uri) {
return new self(null, null, null, null, null, '', null, null);
}

$components = UriString::parse($uri);

return new self(
Expand Down Expand Up @@ -473,16 +478,7 @@ public static function fromBaseUri(
Stringable|string $uri,
Stringable|string|null $baseUri = null
): self {
$uri = self::new($uri);
$baseUri = self::tryNew($baseUri) ?? $uri;

/** @var self $uri */
$uri = match (true) {
$baseUri->isAbsolute() => $baseUri->resolve($uri),
default => throw new SyntaxError('the URI `'.$baseUri.'` must be absolute.'),
};

return $uri;
return self::new(UriString::resolve($uri, $baseUri));
}

/**
Expand Down Expand Up @@ -1670,7 +1666,12 @@ public function equals(UriInterface|Stringable|string $uri, bool $excludeFragmen
*/
public function normalize(): UriInterface
{
return self::new(UriString::normalize($this->toString()));
$uriString = $this->toString();
if ('' === $uriString) {
return $this;
}

return self::new(UriString::normalize($uriString));
}

/**
Expand Down

0 comments on commit 51719f1

Please sign in to comment.