Skip to content

Commit

Permalink
Merge pull request #180 from mdawaffe/encode-path
Browse files Browse the repository at this point in the history
Improve URL Encoding of Path Component
  • Loading branch information
nyamsprod authored Nov 20, 2020
2 parents 1d6a347 + 8a7d334 commit f89ee19
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

All Notable changes to `League\Uri` will be documented in this file

## 6.3.1 - 2020-11-23

### Added

- None

### Fixed

- Bugfix `Uri::formatPath` to improve URL encoding in the path component [#180](https://github.com/thephpleague/uri/pull/180) thanks [mdawaffe](https://github.com/mdawaffe).

### Deprecated

- Nothing

### Remove

- None

## 6.3.0 - 2020-08-13

### Added
Expand Down
10 changes: 7 additions & 3 deletions src/Uri.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,11 @@ final class Uri implements UriInterface

/**
* Regular expression pattern to for file URI.
* <volume> contains the volume but not the volume separator.
* The volume separator may be URL-encoded (`|` as `%7C`) by ::formatPath(),
* so we account for that here.
*/
private const REGEXP_FILE_PATH = ',^(?<delim>/)?(?<root>[a-zA-Z][:|\|])(?<rest>.*)?,';
private const REGEXP_FILE_PATH = ',^(?<delim>/)?(?<volume>[a-zA-Z])(?:[:|\|]|%7C)(?<rest>.*)?,';

/**
* Mimetype regular expression pattern.
Expand All @@ -164,6 +167,7 @@ final class Uri implements UriInterface

/**
* Windows file path string regular expression pattern.
* <root> contains both the volume and volume separator.
*/
private const REGEXP_WINDOW_PATH = ',^(?<root>[a-zA-Z][:|\|]),';

Expand Down Expand Up @@ -972,7 +976,7 @@ private function formatPath(string $path): string
{
$path = $this->formatDataPath($path);

static $pattern = '/(?:[^'.self::REGEXP_CHARS_UNRESERVED.self::REGEXP_CHARS_SUBDELIM.'%:@\/}{]++\|%(?![A-Fa-f0-9]{2}))/';
static $pattern = '/(?:[^'.self::REGEXP_CHARS_UNRESERVED.self::REGEXP_CHARS_SUBDELIM.'%:@\/}{]++|%(?![A-Fa-f0-9]{2}))/';

$path = (string) preg_replace_callback($pattern, [Uri::class, 'urlEncodeMatch'], $path);

Expand Down Expand Up @@ -1071,7 +1075,7 @@ private function formatFilePath(string $path): string
}

$replace = static function (array $matches): string {
return $matches['delim'].str_replace('|', ':', $matches['root']).$matches['rest'];
return $matches['delim'].$matches['volume'].':'.$matches['rest'];
};

return (string) preg_replace_callback(self::REGEXP_FILE_PATH, $replace, $path);
Expand Down
14 changes: 14 additions & 0 deletions tests/UriTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,20 @@ public function testReservedCharsInPathUnencoded(): void
);
}

/**
* @covers ::formatPath
*/
public function testUnreservedCharsInPathUnencoded(): void
{
$uri = Uri::createFromString('http://www.example.com/')
->withPath('/h"ell\'o/./wor ld<i>/%25abc%xyz');

self::assertSame(
"/h%22ell'o/./wor%20ld%3Ci%3E/%25abc%25xyz",
$uri->getPath()
);
}

/**
* @dataProvider userInfoProvider
* @param ?string $credential
Expand Down

0 comments on commit f89ee19

Please sign in to comment.