Skip to content

Commit d67f051

Browse files
committed
correctly sanitise user info parameters
1 parent 49c95e6 commit d67f051

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

src/Actions/Parse.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,38 @@
1010
* @internal
1111
*/
1212
final class Parse {
13+
14+
/**
15+
* Unreserved characters for use in a regex.
16+
*
17+
* @see https://tools.ietf.org/html/rfc3986#section-2.3
18+
*/
19+
private const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~';
20+
21+
/**
22+
* Sub-delims for use in a regex.
23+
*
24+
* @see https://tools.ietf.org/html/rfc3986#section-2.2
25+
*/
26+
private const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;=';
27+
1328
static function parseHost (string $host) : string {
1429
return strtolower($host);
1530
}
1631

32+
static function parseUserInfo (?string $userInfo) : ?string {
33+
if ($userInfo === null) {
34+
return null;
35+
}
36+
37+
// Taken from https://github.com/guzzle/psr7/blob/815698d9f11c908bc59471d11f642264b533346a/src/Uri.php#L592-L603
38+
return preg_replace_callback(
39+
'/(?:[^%'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.']+|%(?![A-Fa-f0-9]{2}))/',
40+
fn(array $match) => rawurlencode($match[0]),
41+
$userInfo
42+
);
43+
}
44+
1745
static function parsePath (string $path) : Path {
1846
return Path::createFromString($path);
1947
}

src/Uri.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ function __construct (string|Stringable|null $uri) {
4848
Component::HOST => $this->host = Parse::parseHost($value),
4949
Component::PATH => $this->path = Parse::parsePath($value),
5050
Component::QUERY => $this->query = Parse::parseQuery($value),
51+
Component::USER => $this->user = Parse::parseUserInfo($value),
52+
Component::PASS => $this->pass = Parse::parseUserInfo($value),
5153
default => $this->$component = $value
5254
};
5355
}
@@ -266,8 +268,8 @@ function withUserInfo ($user, $password = null) : static {
266268
}
267269

268270
$instance = clone $this;
269-
$instance->user = ($user !== '') ? $user : null;
270-
$instance->pass = ($password !== '') ? $password : null;
271+
$instance->user = ($user !== '') ? Parse::parseUserInfo($user) : null;
272+
$instance->pass = ($password !== '') ? Parse::parseUserInfo($password) : null;
271273

272274
return $instance;
273275
}

0 commit comments

Comments
 (0)