Browse Source

Fix cookies being doubly encoded by ResponseEmitter.

setcookie() applies URL encoding to the name & value. We need to remove
a layer of encoding before calling setcookie(), as the Set-Cookie
headers will have already been encoded and double encoded values break
things like CookieComponent.

Refs #9553
Mark Story 9 years ago
parent
commit
5c7bd528c0
2 changed files with 12 additions and 2 deletions
  1. 2 2
      src/Http/ResponseEmitter.php
  2. 10 0
      tests/TestCase/Http/ResponseEmitterTest.php

+ 2 - 2
src/Http/ResponseEmitter.php

@@ -194,8 +194,8 @@ class ResponseEmitter implements EmitterInterface
 
             list($name, $value) = explode('=', array_shift($parts), 2);
             $data = [
-                'name' => $name,
-                'value' => $value,
+                'name' => urldecode($name),
+                'value' => urldecode($value),
                 'expires' => 0,
                 'path' => '',
                 'domain' => '',

+ 10 - 0
tests/TestCase/Http/ResponseEmitterTest.php

@@ -75,6 +75,7 @@ class ResponseEmitterTest extends TestCase
             ->withAddedHeader('Set-Cookie', 'people=jim,jack,jonny";";Path=/accounts')
             ->withAddedHeader('Set-Cookie', 'google=not=nice;Path=/accounts; HttpOnly')
             ->withAddedHeader('Set-Cookie', 'a=b;  Expires=Wed, 13 Jan 2021 22:23:01 GMT; Domain=www.example.com;')
+            ->withAddedHeader('Set-Cookie', 'list%5B%5D=a%20b%20c')
             ->withHeader('Content-Type', 'text/plain');
         $response->getBody()->write('ok');
 
@@ -125,6 +126,15 @@ class ResponseEmitterTest extends TestCase
                 'secure' => false,
                 'httponly' => false
             ],
+            [
+                'name' => 'list[]',
+                'value' => 'a b c',
+                'path' => '',
+                'expire' => 0,
+                'domain' => '',
+                'secure' => false,
+                'httponly' => false
+            ],
         ];
         $this->assertEquals($expected, $GLOBALS['mockedCookies']);
     }