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

Commit

Permalink
Merge branch 'hotfix/4776' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 66 deletions.
126 changes: 60 additions & 66 deletions src/Header/SetCookie.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,56 +23,56 @@ class SetCookie implements MultipleHeaderInterface
/**
* Cookie name
*
* @var string
* @var string|null
*/
protected $name = null;

/**
* Cookie value
*
* @var string
* @var string|null
*/
protected $value = null;

/**
* Version
*
* @var int
* @var int|null
*/
protected $version = null;

/**
* Max Age
*
* @var int
* @var int|null
*/
protected $maxAge = null;

/**
* Cookie expiry date
*
* @var int
* @var int|null
*/
protected $expires = null;

/**
* Cookie domain
*
* @var string
* @var string|null
*/
protected $domain = null;

/**
* Cookie path
*
* @var string
* @var string|null
*/
protected $path = null;

/**
* Whether the cookie is secure or not
*
* @var bool
* @var bool|null
*/
protected $secure = null;

Expand Down Expand Up @@ -161,56 +161,30 @@ public static function fromString($headerLine, $bypassHeaderFieldName = false)
*
* @todo Add validation of each one of the parameters (legal domain, etc.)
*
* @param string $name
* @param string $value
* @param int $expires
* @param string $path
* @param string $domain
* @param bool $secure
* @param bool $httponly
* @param string $maxAge
* @param int $version
* @return SetCookie
* @param string $name
* @param string $value
* @param int|string $expires
* @param string $path
* @param string $domain
* @param bool $secure
* @param bool $httponly
* @param string $maxAge
* @param int $version
* @return SetCookie
*/
public function __construct($name = null, $value = null, $expires = null, $path = null, $domain = null, $secure = false, $httponly = false, $maxAge = null, $version = null)
{
$this->type = 'Cookie';

if ($name) {
$this->setName($name);
}

if ($value) {
$this->setValue($value); // in parent
}

if ($version!==null) {
$this->setVersion($version);
}

if ($maxAge!==null) {
$this->setMaxAge($maxAge);
}

if ($domain) {
$this->setDomain($domain);
}

if ($expires) {
$this->setExpires($expires);
}

if ($path) {
$this->setPath($path);
}

if ($secure) {
$this->setSecure($secure);
}

if ($httponly) {
$this->setHttpOnly($httponly);
}
$this->setName($name)
->setValue($value)
->setVersion($version)
->setMaxAge($maxAge)
->setDomain($domain)
->setExpires($expires)
->setPath($path)
->setSecure($secure)
->setHttpOnly($httponly);
}

/**
Expand Down Expand Up @@ -282,7 +256,7 @@ public function getFieldValue()
*/
public function setName($name)
{
if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
if ($name !== null && preg_match("/[=,; \t\r\n\013\014]/", $name)) {
throw new Exception\InvalidArgumentException("Cookie name cannot contain these characters: =,; \\t\\r\\n\\013\\014 ({$name})");
}

Expand All @@ -300,10 +274,12 @@ public function getName()

/**
* @param string $value
* @return SetCookie
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}

/**
Expand All @@ -319,13 +295,15 @@ public function getValue()
*
* @param int $version
* @throws Exception\InvalidArgumentException
* @return SetCookie
*/
public function setVersion($version)
{
if (!is_int($version)) {
if ($version !== null && !is_int($version)) {
throw new Exception\InvalidArgumentException('Invalid Version number specified');
}
$this->version = $version;
return $this;
}

/**
Expand All @@ -343,13 +321,15 @@ public function getVersion()
*
* @param int $maxAge
* @throws Exception\InvalidArgumentException
* @return SetCookie
*/
public function setMaxAge($maxAge)
{
if (!is_int($maxAge) || ($maxAge<0)) {
if ($maxAge !== null && (!is_int($maxAge) || ($maxAge < 0))) {
throw new Exception\InvalidArgumentException('Invalid Max-Age number specified');
}
$this->maxAge = $maxAge;
return $this;
}

/**
Expand All @@ -363,30 +343,36 @@ public function getMaxAge()
}

/**
* @param int $expires
* @param int|string $expires
* @throws Exception\InvalidArgumentException
* @return SetCookie
*/
public function setExpires($expires)
{
if (!empty($expires)) {
if (is_string($expires)) {
$expires = strtotime($expires);
} elseif (!is_int($expires)) {
throw new Exception\InvalidArgumentException('Invalid expires time specified');
}
$this->expires = (int) $expires;
if ($expires === null) {
$this->expires = null;
return $this;
}

if (is_string($expires)) {
$expires = strtotime($expires);
}

if (!is_int($expires) || $expires < 0) {
throw new Exception\InvalidArgumentException('Invalid expires time specified');
}

$this->expires = $expires;
return $this;
}

/**
* @param bool $inSeconds
* @return int
* @return int|string
*/
public function getExpires($inSeconds = false)
{
if ($this->expires == null) {
if ($this->expires === null) {
return;
}
if ($inSeconds) {
Expand All @@ -397,10 +383,12 @@ public function getExpires($inSeconds = false)

/**
* @param string $domain
* @return SetCookie
*/
public function setDomain($domain)
{
$this->domain = $domain;
return $this;
}

/**
Expand All @@ -413,10 +401,12 @@ public function getDomain()

/**
* @param string $path
* @return SetCookie
*/
public function setPath($path)
{
$this->path = $path;
return $this;
}

/**
Expand All @@ -429,10 +419,12 @@ public function getPath()

/**
* @param bool $secure
* @return SetCookie
*/
public function setSecure($secure)
{
$this->secure = $secure;
return $this;
}

/**
Expand All @@ -445,10 +437,12 @@ public function isSecure()

/**
* @param bool $httponly
* @return SetCookie
*/
public function setHttponly($httponly)
{
$this->httponly = $httponly;
return $this;
}

/**
Expand Down
88 changes: 88 additions & 0 deletions test/Header/SetCookieTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,94 @@ public function testSetCookieCanAppendOtherHeadersInWhenCreatingString()
$this->assertEquals($target, $headerLine);
}

public function testSetCookieAttributesAreUnsettable()
{
$setCookieHeader = new SetCookie();
$setCookieHeader->setName('myname');
$setCookieHeader->setValue('myvalue');
$setCookieHeader->setExpires('Wed, 13-Jan-2021 22:23:01 GMT');
$setCookieHeader->setDomain('docs.foo.com');
$setCookieHeader->setPath('/accounts');
$setCookieHeader->setSecure(true);
$setCookieHeader->setHttponly(true);

$target = 'myname=myvalue; Expires=Wed, 13-Jan-2021 22:23:01 GMT;'
. ' Domain=docs.foo.com; Path=/accounts;'
. ' Secure; HttpOnly';
$this->assertSame($target, $setCookieHeader->getFieldValue()); // attributes set

$setCookieHeader->setExpires(NULL);
$setCookieHeader->setDomain(NULL);
$setCookieHeader->setPath(NULL);
$setCookieHeader->setSecure(NULL);
$setCookieHeader->setHttponly(NULL);
$this->assertSame('myname=myvalue', $setCookieHeader->getFieldValue()); // attributes unset

$setCookieHeader->setValue(NULL);
$this->assertSame('myname=', $setCookieHeader->getFieldValue());
$this->assertNull($setCookieHeader->getValue());
$this->assertNull($setCookieHeader->getExpires());
$this->assertNull($setCookieHeader->getDomain());
$this->assertNull($setCookieHeader->getPath());
$this->assertNull($setCookieHeader->isSecure());
$this->assertNull($setCookieHeader->isHttponly());
}

public function testSetCookieFieldValueIsEmptyStringWhenNameIsUnset()
{
$setCookieHeader = new SetCookie();
$this->assertSame('', $setCookieHeader->getFieldValue()); // empty

$setCookieHeader->setName('myname');
$setCookieHeader->setValue('myvalue');
$setCookieHeader->setExpires('Wed, 13-Jan-2021 22:23:01 GMT');
$setCookieHeader->setDomain('docs.foo.com');
$setCookieHeader->setPath('/accounts');
$setCookieHeader->setSecure(true);
$setCookieHeader->setHttponly(true);

$target = 'myname=myvalue; Expires=Wed, 13-Jan-2021 22:23:01 GMT;'
. ' Domain=docs.foo.com; Path=/accounts;'
. ' Secure; HttpOnly';
$this->assertSame($target, $setCookieHeader->getFieldValue()); // not empty

$setCookieHeader->setName(null);
$this->assertSame('', $setCookieHeader->getFieldValue()); // empty again
$this->assertNull($setCookieHeader->getName());
}

public function testSetCookieSetExpiresWithZeroTimeStamp()
{
$setCookieHeader = new SetCookie('myname', 'myvalue', 0);
$this->assertSame('Thu, 01-Jan-1970 00:00:00 GMT', $setCookieHeader->getExpires());

$setCookieHeader = new SetCookie('myname', 'myvalue', 1);
$this->assertSame('Thu, 01-Jan-1970 00:00:01 GMT', $setCookieHeader->getExpires());

$setCookieHeader->setExpires(0);
$this->assertSame('Thu, 01-Jan-1970 00:00:00 GMT', $setCookieHeader->getExpires());

$target = 'myname=myvalue; Expires=Thu, 01-Jan-1970 00:00:00 GMT';
$this->assertSame($target, $setCookieHeader->getFieldValue());
}

public function testSetCookieSetExpiresWithUnixEpochString()
{
$setCookieHeader = new SetCookie('myname', 'myvalue', 'Thu, 01-Jan-1970 00:00:00 GMT');
$this->assertSame('Thu, 01-Jan-1970 00:00:00 GMT', $setCookieHeader->getExpires());
$this->assertSame(0, $setCookieHeader->getExpires(true));

$setCookieHeader = new SetCookie('myname', 'myvalue', 1);
$this->assertSame('Thu, 01-Jan-1970 00:00:01 GMT', $setCookieHeader->getExpires());

$setCookieHeader->setExpires('Thu, 01-Jan-1970 00:00:00 GMT');
$this->assertSame('Thu, 01-Jan-1970 00:00:00 GMT', $setCookieHeader->getExpires());
$this->assertSame(0, $setCookieHeader->getExpires(true));

$target = 'myname=myvalue; Expires=Thu, 01-Jan-1970 00:00:00 GMT';
$this->assertSame($target, $setCookieHeader->getFieldValue());
}

public function testIsValidForRequestSubdomainMatch()
{
$setCookieHeader = new SetCookie(
Expand Down

0 comments on commit 472ac62

Please sign in to comment.