Skip to content
This repository was archived by the owner on Jan 30, 2020. It is now read-only.

Commit 718b07f

Browse files
committed
Merge branch 'hotfix/207-samesite-case-sensitivity' into develop
Forward port #207 Conflicts: CHANGELOG.md
2 parents 9fb5af9 + e15e0ce commit 718b07f

File tree

3 files changed

+102
-8
lines changed

3 files changed

+102
-8
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ All notable changes to this project will be documented in this file, in reverse
2424

2525
- Nothing.
2626

27-
## 2.11.2 - TBD
27+
## 2.11.2 - 2019-12-30
2828

2929
### Added
3030

@@ -44,7 +44,7 @@ All notable changes to this project will be documented in this file, in reverse
4444

4545
### Fixed
4646

47-
- Nothing.
47+
- [#207](https://github.com/zendframework/zend-http/pull/207) fixes case sensitivity for SameSite directive.
4848

4949
## 2.11.1 - 2019-12-04
5050

src/Header/SetCookie.php

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
use DateTime;
1111
use Zend\Uri\UriFactory;
1212

13+
use function array_key_exists;
14+
use function gettype;
15+
use function is_scalar;
16+
use function strtolower;
17+
1318
/**
1419
* @throws Exception\InvalidArgumentException
1520
* @see http://www.ietf.org/rfc/rfc2109.txt
@@ -39,9 +44,9 @@ class SetCookie implements MultipleHeaderInterface
3944
* @internal
4045
*/
4146
const SAME_SITE_ALLOWED_VALUES = [
42-
self::SAME_SITE_STRICT,
43-
self::SAME_SITE_LAX,
44-
self::SAME_SITE_NONE,
47+
'strict' => self::SAME_SITE_STRICT,
48+
'lax' => self::SAME_SITE_LAX,
49+
'none' => self::SAME_SITE_NONE,
4550
];
4651

4752
/**
@@ -337,7 +342,7 @@ public function getFieldValue()
337342
}
338343

339344
$sameSite = $this->getSameSite();
340-
if ($sameSite !== null && in_array($sameSite, self::SAME_SITE_ALLOWED_VALUES, true)) {
345+
if ($sameSite !== null && array_key_exists(strtolower($sameSite), self::SAME_SITE_ALLOWED_VALUES)) {
341346
$fieldValue .= '; SameSite=' . $sameSite;
342347
}
343348

@@ -618,13 +623,17 @@ public function getSameSite()
618623
*/
619624
public function setSameSite($sameSite)
620625
{
621-
if ($sameSite !== null && ! in_array($sameSite, self::SAME_SITE_ALLOWED_VALUES, true)) {
626+
if ($sameSite === null) {
627+
$this->sameSite = null;
628+
return $this;
629+
}
630+
if (! array_key_exists(strtolower($sameSite), self::SAME_SITE_ALLOWED_VALUES)) {
622631
throw new Exception\InvalidArgumentException(sprintf(
623632
'Invalid value provided for SameSite directive: "%s"; expected one of: Strict, Lax or None',
624633
is_scalar($sameSite) ? $sameSite : gettype($sameSite)
625634
));
626635
}
627-
$this->sameSite = $sameSite;
636+
$this->sameSite = self::SAME_SITE_ALLOWED_VALUES[strtolower($sameSite)];
628637
return $this;
629638
}
630639

test/Header/SetCookieTest.php

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
use Zend\Http\Header\MultipleHeaderInterface;
1515
use Zend\Http\Header\SetCookie;
1616

17+
use function strtolower;
18+
use function strtoupper;
19+
1720
class SetCookieTest extends TestCase
1821
{
1922
/**
@@ -69,6 +72,32 @@ public function testSetCookieConstructorWithSameSite()
6972
$this->assertEquals('Strict', $setCookieHeader->getSameSite());
7073
}
7174

75+
public function testSetCookieConstructorWithSameSiteCaseInsensitive()
76+
{
77+
$setCookieHeader = new SetCookie(
78+
'myname',
79+
'myvalue',
80+
'Wed, 13-Jan-2021 22:23:01 GMT',
81+
'/accounts',
82+
'docs.foo.com',
83+
true,
84+
true,
85+
99,
86+
9,
87+
strtolower(SetCookie::SAME_SITE_STRICT)
88+
);
89+
$this->assertEquals('myname', $setCookieHeader->getName());
90+
$this->assertEquals('myvalue', $setCookieHeader->getValue());
91+
$this->assertEquals('Wed, 13-Jan-2021 22:23:01 GMT', $setCookieHeader->getExpires());
92+
$this->assertEquals('/accounts', $setCookieHeader->getPath());
93+
$this->assertEquals('docs.foo.com', $setCookieHeader->getDomain());
94+
$this->assertTrue($setCookieHeader->isSecure());
95+
$this->assertTrue($setCookieHeader->isHttpOnly());
96+
$this->assertEquals(99, $setCookieHeader->getMaxAge());
97+
$this->assertEquals(9, $setCookieHeader->getVersion());
98+
$this->assertEquals(SetCookie::SAME_SITE_STRICT, $setCookieHeader->getSameSite());
99+
}
100+
72101
public function testSetCookieWithInvalidSameSiteValueThrowException()
73102
{
74103
$this->expectException(InvalidArgumentException::class);
@@ -105,6 +134,29 @@ public function testSetInvalidSameSiteDirectiveValueViaSetter()
105134
$setCookieHeader->setSameSite('InvalidValue');
106135
}
107136

137+
public function testSameSiteGetterReturnsCanonicalValue()
138+
{
139+
$setCookieHeader = new SetCookie(
140+
'myname',
141+
'myvalue',
142+
'Wed, 13-Jan-2021 22:23:01 GMT',
143+
'/accounts',
144+
'docs.foo.com',
145+
true,
146+
true,
147+
99,
148+
9,
149+
SetCookie::SAME_SITE_STRICT
150+
);
151+
$this->assertEquals(SetCookie::SAME_SITE_STRICT, $setCookieHeader->getSameSite());
152+
153+
$setCookieHeader->setSameSite(strtolower(SetCookie::SAME_SITE_LAX));
154+
$this->assertEquals(SetCookie::SAME_SITE_LAX, $setCookieHeader->getSameSite());
155+
156+
$setCookieHeader->setSameSite(strtoupper(SetCookie::SAME_SITE_NONE));
157+
$this->assertEquals(SetCookie::SAME_SITE_NONE, $setCookieHeader->getSameSite());
158+
}
159+
108160
public function testSetCookieFromStringWithQuotedValue()
109161
{
110162
$setCookieHeader = SetCookie::fromString('Set-Cookie: myname="quotedValue"');
@@ -161,6 +213,39 @@ public function testSetCookieFromStringCanCreateSingleHeader()
161213
$this->assertTrue($setCookieHeader->isSecure());
162214
$this->assertTrue($setCookieHeader->isHttponly());
163215
$this->assertEquals(setCookie::SAME_SITE_STRICT, $setCookieHeader->getSameSite());
216+
217+
$setCookieHeader = SetCookie::fromString(
218+
'set-cookie: myname=myvalue; Domain=docs.foo.com; Path=/accounts;'
219+
. 'Expires=Wed, 13-Jan-2021 22:23:01 GMT; Secure; HttpOnly; SameSite=strict'
220+
);
221+
$this->assertInstanceOf(MultipleHeaderInterface::class, $setCookieHeader);
222+
$this->assertEquals('myname', $setCookieHeader->getName());
223+
$this->assertEquals('myvalue', $setCookieHeader->getValue());
224+
$this->assertEquals('docs.foo.com', $setCookieHeader->getDomain());
225+
$this->assertEquals('/accounts', $setCookieHeader->getPath());
226+
$this->assertEquals('Wed, 13-Jan-2021 22:23:01 GMT', $setCookieHeader->getExpires());
227+
$this->assertTrue($setCookieHeader->isSecure());
228+
$this->assertTrue($setCookieHeader->isHttponly());
229+
$this->assertEquals(setCookie::SAME_SITE_STRICT, $setCookieHeader->getSameSite());
230+
}
231+
232+
public function testFieldValueWithSameSiteCaseInsensitive()
233+
{
234+
$setCookieHeader = SetCookie::fromString(
235+
'set-cookie: myname=myvalue; SameSite=Strict'
236+
);
237+
$this->assertEquals(
238+
'myname=myvalue; SameSite=Strict',
239+
$setCookieHeader->getFieldValue()
240+
);
241+
242+
$setCookieHeader = SetCookie::fromString(
243+
'set-cookie: myname=myvalue; SameSite=strict'
244+
);
245+
$this->assertEquals(
246+
'myname=myvalue; SameSite=Strict',
247+
$setCookieHeader->getFieldValue()
248+
);
164249
}
165250

166251
public function testSetCookieFromStringCanCreateMultipleHeaders()

0 commit comments

Comments
 (0)