Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9cf2d7f

Browse filesBrowse files
committed
[HttpFoundation] allow additinal characters in not raw cookies
1 parent 3a520f2 commit 9cf2d7f
Copy full SHA for 9cf2d7f

File tree

6 files changed

+45
-13
lines changed
Filter options

6 files changed

+45
-13
lines changed

‎src/Symfony/Component/HttpFoundation/Cookie.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/Cookie.php
+17-2Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ class Cookie
2929
private $sameSite;
3030
private $secureDefault = false;
3131

32+
private const RESERVED_CHARS = "=,; \t\r\n\v\f";
33+
private static $reservedChars = [];
34+
private static $reservedCharsEncoded = [];
35+
3236
const SAMESITE_NONE = 'none';
3337
const SAMESITE_LAX = 'lax';
3438
const SAMESITE_STRICT = 'strict';
@@ -93,7 +97,7 @@ public function __construct(string $name, string $value = null, $expire = 0, ?st
9397
}
9498

9599
// from PHP source code
96-
if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
100+
if ($raw && false !== strpbrk($name, self::RESERVED_CHARS)) {
97101
throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name));
98102
}
99103

@@ -132,6 +136,11 @@ public function __construct(string $name, string $value = null, $expire = 0, ?st
132136
}
133137

134138
$this->sameSite = $sameSite;
139+
140+
if (!self::$reservedChars) {
141+
self::$reservedChars = str_split(self::RESERVED_CHARS);
142+
self::$reservedCharsEncoded = array_map('rawurlencode', self::$reservedChars);
143+
}
135144
}
136145

137146
/**
@@ -141,7 +150,13 @@ public function __construct(string $name, string $value = null, $expire = 0, ?st
141150
*/
142151
public function __toString()
143152
{
144-
$str = ($this->isRaw() ? $this->getName() : urlencode($this->getName())).'=';
153+
if ($this->isRaw()) {
154+
$str = $this->getName();
155+
} else {
156+
$str = str_replace(self::$reservedChars, self::$reservedCharsEncoded, $this->getName());
157+
}
158+
159+
$str .= '=';
145160

146161
if ('' === (string) $this->getValue()) {
147162
$str .= 'deleted; expires='.gmdate('D, d-M-Y H:i:s T', time() - 31536001).'; Max-Age=0';

‎src/Symfony/Component/HttpFoundation/Response.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/Response.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ public function sendHeaders()
344344

345345
// cookies
346346
foreach ($this->headers->getCookies() as $cookie) {
347-
header('Set-Cookie: '.$cookie->getName().strstr($cookie, '='), false, $this->statusCode);
347+
header('Set-Cookie: '.$cookie, false, $this->statusCode);
348348
}
349349

350350
// status

‎src/Symfony/Component/HttpFoundation/Tests/CookieTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/Tests/CookieTest.php
+18-5Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@
2424
*/
2525
class CookieTest extends TestCase
2626
{
27-
public function invalidNames()
27+
public function namesWithSpecialCharacters()
2828
{
2929
return [
30-
[''],
3130
[',MyName'],
3231
[';MyName'],
3332
[' MyName'],
@@ -40,12 +39,26 @@ public function invalidNames()
4039
}
4140

4241
/**
43-
* @dataProvider invalidNames
42+
* @dataProvider namesWithSpecialCharacters
4443
*/
45-
public function testInstantiationThrowsExceptionIfCookieNameContainsInvalidCharacters($name)
44+
public function testInstantiationThrowsExceptionIfRawCookieNameContainsSpecialCharacters($name)
4645
{
4746
$this->expectException('InvalidArgumentException');
48-
Cookie::create($name);
47+
Cookie::create($name, null, 0, null, null, null, false, true);
48+
}
49+
50+
/**
51+
* @dataProvider namesWithSpecialCharacters
52+
*/
53+
public function testInstantiationSucceedNonRawCookieNameContainsSpecialCharacters($name)
54+
{
55+
$this->assertInstanceOf(Cookie::class, Cookie::create($name));
56+
}
57+
58+
public function testInstantiationThrowsExceptionIfCookieNameIsEmpty()
59+
{
60+
$this->expectException('InvalidArgumentException');
61+
Cookie::create('');
4962
}
5063

5164
public function testInvalidExpiration()

‎src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.expected

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.expected
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ Array
44
[0] => Content-Type: text/plain; charset=utf-8
55
[1] => Cache-Control: no-cache, private
66
[2] => Date: Sat, 12 Nov 1955 20:04:00 GMT
7-
[3] => Set-Cookie: ?*():@&+$/%#[]=%3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D; path=/
7+
[3] => Set-Cookie: %3D%2C%3B%20%09%0D%0A%0B%0C=%3D%2C%3B%20%09%0D%0A%0B%0C; path=/
88
[4] => Set-Cookie: ?*():@&+$/%#[]=%3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D; path=/
9+
[5] => Set-Cookie: ?*():@&+$/%#[]=%3F%2A%28%29%3A%40%26%2B%24%2F%25%23%5B%5D; path=/
910
)
1011
shutdown

‎src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_urlencode.php
+6-3Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44

55
$r = require __DIR__.'/common.inc';
66

7-
$str = '?*():@&+$/%#[]';
7+
$str1 = "=,; \t\r\n\v\f";
8+
$r->headers->setCookie(new Cookie($str1, $str1, 0, '', null, false, false, false, null));
89

9-
$r->headers->setCookie(new Cookie($str, $str, 0, '', null, false, false, false, null));
10+
$str2 = '?*():@&+$/%#[]';
11+
12+
$r->headers->setCookie(new Cookie($str2, $str2, 0, '', null, false, false, false, null));
1013
$r->sendHeaders();
1114

12-
setcookie($str, $str, 0, '/');
15+
setcookie($str2, $str2, 0, '/');

‎src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/invalid_cookie_name.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/invalid_cookie_name.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
$r = require __DIR__.'/common.inc';
66

77
try {
8-
$r->headers->setCookie(Cookie::create('Hello + world', 'hodor'));
8+
$r->headers->setCookie(Cookie::create('Hello + world', 'hodor', 0, null, null, null, false, true));
99
} catch (\InvalidArgumentException $e) {
1010
echo $e->getMessage();
1111
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.