Skip to content

Commit 70921a5

Browse files
committed
Encode user info
If the username or password includes an `@` or `:` or other reserved characters, they need to be encoded. Fixes slimphp#34 Forward ports slimphp/Slim#2327.
1 parent 37e80cc commit 70921a5

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

src/Uri.php

+21-2
Original file line numberDiff line numberDiff line change
@@ -353,12 +353,31 @@ public function getUserInfo()
353353
public function withUserInfo($user, $password = null)
354354
{
355355
$clone = clone $this;
356-
$clone->user = $user;
357-
$clone->password = $password ? $password : '';
356+
$clone->user = $this->filterUserInfo($user);
357+
if ($clone->user) {
358+
$clone->password = $password ? $this->filterUserInfo($password) : '';
359+
}
358360

359361
return $clone;
360362
}
361363

364+
/**
365+
* Filters the user info string.
366+
*
367+
* @param string $query The raw uri query string.
368+
* @return string The percent-encoded query string.
369+
*/
370+
protected function filterUserInfo($query)
371+
{
372+
return preg_replace_callback(
373+
'/(?:[^a-zA-Z0-9_\-\.~!\$&\'\(\)\*\+,;=]+|%(?![A-Fa-f0-9]{2}))/u',
374+
function ($match) {
375+
return rawurlencode($match[0]);
376+
},
377+
$query
378+
);
379+
}
380+
362381
/**
363382
* Retrieve the host component of the URI.
364383
*

tests/UriTest.php

+15
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ public function testGetUserInfoWithUsernameAndPassword()
114114
$this->assertEquals('josh:sekrit', $uri->getUserInfo());
115115
}
116116

117+
public function testGetUserInfoWithUsernameAndPasswordEncodesCorrectly()
118+
{
119+
$uri = Uri::createFromString('https://bob%40example.com:pass%[email protected]:443/foo/bar?abc=123#section3');
120+
121+
$this->assertEquals('bob%40example.com:pass%3Aword', $uri->getUserInfo());
122+
}
123+
117124
public function testGetUserInfoWithUsername()
118125
{
119126
$uri = Uri::createFromString('http://[email protected]/foo/bar?abc=123#section3');
@@ -136,6 +143,14 @@ public function testWithUserInfo()
136143
$this->assertAttributeEquals('pass', 'password', $uri);
137144
}
138145

146+
public function testWithUserInfoEncodesCorrectly()
147+
{
148+
$uri = $this->uriFactory()->withUserInfo('[email protected]', 'pass:word');
149+
150+
$this->assertAttributeEquals('bob%40example.com', 'user', $uri);
151+
$this->assertAttributeEquals('pass%3Aword', 'password', $uri);
152+
}
153+
139154
public function testWithUserInfoRemovesPassword()
140155
{
141156
$uri = $this->uriFactory()->withUserInfo('bob');

0 commit comments

Comments
 (0)