From c48157db5994f0f7df6e7477c00be5bfea2c02af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20J=2E=20Garc=C3=ADa=20Lagar?= Date: Thu, 22 Dec 2016 14:33:30 +0100 Subject: [PATCH 1/6] Specification for optional cookie validation --- spec/CookieSpec.php | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/spec/CookieSpec.php b/spec/CookieSpec.php index 3c0c362..d1d0419 100644 --- a/spec/CookieSpec.php +++ b/spec/CookieSpec.php @@ -239,6 +239,38 @@ function it_matches_other_cookies() $this->match($notMatches)->shouldReturn(false); } + function it_validates_itself() + { + $this->isValid()->shouldReturn(true); + } + + /** + * @dataProvider invalidCharacterExamples + */ + function it_can_be_constructed_without_name_validation($name, $invalid) + { + $this->beConstructedThrough('createWithoutValidation', [$name]); + + $this->isValid()->shouldReturn(!$invalid); + } + + /** + * @dataProvider invalidCharacterExamples + */ + function it_can_be_constructed_without_value_validation($value, $invalid) + { + $this->beConstructedThrough('createWithoutValidation', ['name', $value]); + + $this->isValid()->shouldReturn(!$invalid); + } + + function it_can_be_constructed_without_max_age_validation() + { + $this->beConstructedThrough('createWithoutValidation', ['name', 'value', '-1']); + + $this->isValid()->shouldReturn(false); + } + /** * Provides examples for invalid characers in names and values. * From 5b20f0406015ae7c6d09422f9ee7e00dcfa2a548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20J=2E=20Garc=C3=ADa=20Lagar?= Date: Thu, 22 Dec 2016 23:21:27 +0100 Subject: [PATCH 2/6] Adds Cookie::createWithoutValidation and Cookie::isValid Adds a named constructor to avoid cookie attributes validation during instantination, and a method to check if cookie attributes are valid. --- CHANGELOG.md | 13 ++++++----- src/Cookie.php | 59 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8749fd4..3861da8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,18 +3,21 @@ ## Unreleased -## Added +### Added - Check for empty string in Stream factories +- Cookie::createWithoutValidation Static constructor to create a cookie. Will not perform any attribute validation during instantiation. +- Cookie::isValid Method to check if cookie attributes are valid. -## Fixed +### Fixed - - FilteredStream::getSize returns null because the contents size is unknown. +- FilteredStream::getSize returns null because the contents size is unknown. ### Deprecated - - FilteredStream::getReadFilter The read filter is internal and should never be used by consuming code. - - FilteredStream::getWriteFilter We did not implement writing to the streams at all. And if we do, the filter is an internal information and should not be used by consuming code. +- FilteredStream::getReadFilter The read filter is internal and should never be used by consuming code. +- FilteredStream::getWriteFilter We did not implement writing to the streams at all. And if we do, the filter is an internal information and should not be used by consuming code. +- Attributes validation during Cookie instantiation is deprecated and will be removed in 2.0. Use the new `Cookie::isValid` to check if attributes are valid. ## 1.4.1 - 2016-12-16 diff --git a/src/Cookie.php b/src/Cookie.php index 5022863..127d796 100644 --- a/src/Cookie.php +++ b/src/Cookie.php @@ -53,6 +53,13 @@ final class Cookie */ private $expires; + /** + * Validation state. + * + * @var bool + */ + private $valid; + /** * @param string $name * @param string|null $value @@ -61,9 +68,10 @@ final class Cookie * @param string|null $path * @param bool $secure * @param bool $httpOnly - * @param \DateTime|null $expires Expires attribute is HTTP 1.0 only and should be avoided. + * @param \DateTime|null $expires Expires attribute is HTTP 1.0 only and should be avoided. + * @param bool $requireValidation deprecated since version 1.5. Will be removed in 2.0 * - * @throws \InvalidArgumentException If name, value or max age is not valid. + * @throws \InvalidArgumentException If name, value or max age is not valid. Attributes validation during instantiation is deprecated since 1.5 and will be removed in 2.0. */ public function __construct( $name, @@ -73,11 +81,16 @@ public function __construct( $path = null, $secure = false, $httpOnly = false, - \DateTime $expires = null + \DateTime $expires = null, + $requireValidation = true ) { - $this->validateName($name); - $this->validateValue($value); - $this->validateMaxAge($maxAge); + if ($requireValidation) { + @trigger_error('Attributes validation during instantiation is deprecated since 1.5 and will be removed in 2.0', E_USER_DEPRECATED); + $this->validateName($name); + $this->validateValue($value); + $this->validateMaxAge($maxAge); + $this->valid = true; + } $this->name = $name; $this->value = $value; @@ -89,6 +102,19 @@ public function __construct( $this->httpOnly = (bool) $httpOnly; } + public static function createWithoutValidation( + $name, + $value = null, + $maxAge = null, + $domain = null, + $path = null, + $secure = false, + $httpOnly = false, + \DateTime $expires = null + ) { + return new self($name, $value, $maxAge, $domain, $path, $secure, $httpOnly, $expires, false); + } + /** * Returns the name. * @@ -380,6 +406,27 @@ public function match(Cookie $cookie) return $this->name === $cookie->name && $this->domain === $cookie->domain and $this->path === $cookie->path; } + /** + * Validates cookie attributes. + * + * @return bool + */ + public function isValid() + { + if (null === $this->valid) { + try { + $this->validateName($this->name); + $this->validateValue($this->value); + $this->validateMaxAge($this->maxAge); + $this->valid = true; + } catch (\InvalidArgumentException $e) { + $this->valid = false; + } + } + + return $this->valid; + } + /** * Validates the name attribute. * From 5fb7027e2bf9846917c4c8cff37f308aca0788fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20J=2E=20Garc=C3=ADa=20Lagar?= Date: Tue, 27 Dec 2016 09:53:02 +0100 Subject: [PATCH 3/6] Creates new cookie instance with dummy name to bypass constructor validation --- src/Cookie.php | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/src/Cookie.php b/src/Cookie.php index 127d796..daa8ad4 100644 --- a/src/Cookie.php +++ b/src/Cookie.php @@ -53,13 +53,6 @@ final class Cookie */ private $expires; - /** - * Validation state. - * - * @var bool - */ - private $valid; - /** * @param string $name * @param string|null $value @@ -68,8 +61,7 @@ final class Cookie * @param string|null $path * @param bool $secure * @param bool $httpOnly - * @param \DateTime|null $expires Expires attribute is HTTP 1.0 only and should be avoided. - * @param bool $requireValidation deprecated since version 1.5. Will be removed in 2.0 + * @param \DateTime|null $expires Expires attribute is HTTP 1.0 only and should be avoided. * * @throws \InvalidArgumentException If name, value or max age is not valid. Attributes validation during instantiation is deprecated since 1.5 and will be removed in 2.0. */ @@ -81,15 +73,15 @@ public function __construct( $path = null, $secure = false, $httpOnly = false, - \DateTime $expires = null, - $requireValidation = true + \DateTime $expires = null ) { - if ($requireValidation) { - @trigger_error('Attributes validation during instantiation is deprecated since 1.5 and will be removed in 2.0', E_USER_DEPRECATED); + try { $this->validateName($name); $this->validateValue($value); $this->validateMaxAge($maxAge); - $this->valid = true; + } catch (\InvalidArgumentException $e) { + @trigger_error('Attributes validation during instantiation is deprecated since 1.5 and will be removed in 2.0', E_USER_DEPRECATED); + throw $e; } $this->name = $name; @@ -112,7 +104,12 @@ public static function createWithoutValidation( $httpOnly = false, \DateTime $expires = null ) { - return new self($name, $value, $maxAge, $domain, $path, $secure, $httpOnly, $expires, false); + $cookie = new self('name', null, null, $domain, $path, $secure, $httpOnly, $expires); + $cookie->name = $name; + $cookie->value = $value; + $cookie->maxAge = $maxAge; + + return $cookie; } /** @@ -413,18 +410,15 @@ public function match(Cookie $cookie) */ public function isValid() { - if (null === $this->valid) { - try { - $this->validateName($this->name); - $this->validateValue($this->value); - $this->validateMaxAge($this->maxAge); - $this->valid = true; - } catch (\InvalidArgumentException $e) { - $this->valid = false; - } + try { + $this->validateName($this->name); + $this->validateValue($this->value); + $this->validateMaxAge($this->maxAge); + } catch (\InvalidArgumentException $e) { + return false; } - return $this->valid; + return true; } /** From fbc60f33f24768fb08bb458d41f2f2dad007556a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20J=2E=20Garc=C3=ADa=20Lagar?= Date: Thu, 5 Jan 2017 13:28:40 +0100 Subject: [PATCH 4/6] Remove deprecation of attribute validation in Cookie::__construct --- CHANGELOG.md | 1 - src/Cookie.php | 13 ++++--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3861da8..c178eb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,6 @@ - FilteredStream::getReadFilter The read filter is internal and should never be used by consuming code. - FilteredStream::getWriteFilter We did not implement writing to the streams at all. And if we do, the filter is an internal information and should not be used by consuming code. -- Attributes validation during Cookie instantiation is deprecated and will be removed in 2.0. Use the new `Cookie::isValid` to check if attributes are valid. ## 1.4.1 - 2016-12-16 diff --git a/src/Cookie.php b/src/Cookie.php index daa8ad4..8687626 100644 --- a/src/Cookie.php +++ b/src/Cookie.php @@ -63,7 +63,7 @@ final class Cookie * @param bool $httpOnly * @param \DateTime|null $expires Expires attribute is HTTP 1.0 only and should be avoided. * - * @throws \InvalidArgumentException If name, value or max age is not valid. Attributes validation during instantiation is deprecated since 1.5 and will be removed in 2.0. + * @throws \InvalidArgumentException If name, value or max age is not valid. */ public function __construct( $name, @@ -75,14 +75,9 @@ public function __construct( $httpOnly = false, \DateTime $expires = null ) { - try { - $this->validateName($name); - $this->validateValue($value); - $this->validateMaxAge($maxAge); - } catch (\InvalidArgumentException $e) { - @trigger_error('Attributes validation during instantiation is deprecated since 1.5 and will be removed in 2.0', E_USER_DEPRECATED); - throw $e; - } + $this->validateName($name); + $this->validateValue($value); + $this->validateMaxAge($maxAge); $this->name = $name; $this->value = $value; From f2d32a40feb274c656ded52fa2b62173478d9a31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20J=2E=20Garc=C3=ADa=20Lagar?= Date: Thu, 5 Jan 2017 13:29:21 +0100 Subject: [PATCH 5/6] Adds docblock to Cookie::createWithoutValidation --- src/Cookie.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Cookie.php b/src/Cookie.php index 8687626..5f61b90 100644 --- a/src/Cookie.php +++ b/src/Cookie.php @@ -89,6 +89,18 @@ public function __construct( $this->httpOnly = (bool) $httpOnly; } + /** + * Creates a new cookie without any attribute validation. + * + * @param string $name + * @param string|null $value + * @param int $maxAge + * @param string|null $domain + * @param string|null $path + * @param bool $secure + * @param bool $httpOnly + * @param \DateTime|null $expires Expires attribute is HTTP 1.0 only and should be avoided. + */ public static function createWithoutValidation( $name, $value = null, From 5eeecd1ed44179aa8d9cc76c63ae09fe3abb2419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20J=2E=20Garc=C3=ADa=20Lagar?= Date: Thu, 5 Jan 2017 13:42:58 +0100 Subject: [PATCH 6/6] Drop use of dataProvider in Cookie::createWithoutValidation spec --- spec/CookieSpec.php | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/spec/CookieSpec.php b/spec/CookieSpec.php index d1d0419..3de69f3 100644 --- a/spec/CookieSpec.php +++ b/spec/CookieSpec.php @@ -244,24 +244,18 @@ function it_validates_itself() $this->isValid()->shouldReturn(true); } - /** - * @dataProvider invalidCharacterExamples - */ - function it_can_be_constructed_without_name_validation($name, $invalid) + function it_can_be_constructed_without_name_validation() { - $this->beConstructedThrough('createWithoutValidation', [$name]); + $this->beConstructedThrough('createWithoutValidation', ["\x20"]); - $this->isValid()->shouldReturn(!$invalid); + $this->isValid()->shouldReturn(false); } - /** - * @dataProvider invalidCharacterExamples - */ - function it_can_be_constructed_without_value_validation($value, $invalid) + function it_can_be_constructed_without_value_validation() { - $this->beConstructedThrough('createWithoutValidation', ['name', $value]); + $this->beConstructedThrough('createWithoutValidation', ['name', "\x20"]); - $this->isValid()->shouldReturn(!$invalid); + $this->isValid()->shouldReturn(false); } function it_can_be_constructed_without_max_age_validation()