From 50ad6ff12beba9248aaff1e0e2841beeb9fb2b1f Mon Sep 17 00:00:00 2001 From: Aleksi Peebles Date: Thu, 29 Feb 2024 18:39:50 +0200 Subject: [PATCH 1/4] Fix for early return from SessionManager::destroy() Signed-off-by: Aleksi Peebles --- src/SessionManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SessionManager.php b/src/SessionManager.php index 152c0bae..74938286 100644 --- a/src/SessionManager.php +++ b/src/SessionManager.php @@ -194,7 +194,7 @@ protected function initializeValidatorChain() */ public function destroy(?array $options = null) { - if (headers_sent() || ! $this->sessionExists()) { + if (session_status() !== PHP_SESSION_ACTIVE) { return; } From ec62525522d765457b6668f7b481261ac4f64768 Mon Sep 17 00:00:00 2001 From: Aleksi Peebles Date: Thu, 29 Feb 2024 21:19:28 +0200 Subject: [PATCH 2/4] Check that headers are not sent before expiring cookie and add PHPUnit test Signed-off-by: Aleksi Peebles --- src/SessionManager.php | 2 +- test/SessionManagerTest.php | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/SessionManager.php b/src/SessionManager.php index 74938286..5203b5fa 100644 --- a/src/SessionManager.php +++ b/src/SessionManager.php @@ -205,7 +205,7 @@ public function destroy(?array $options = null) } session_destroy(); - if ($options['send_expire_cookie']) { + if (! headers_sent() && $options['send_expire_cookie']) { $this->expireSessionCookie(); } diff --git a/test/SessionManagerTest.php b/test/SessionManagerTest.php index 4efe94b2..5596b66d 100644 --- a/test/SessionManagerTest.php +++ b/test/SessionManagerTest.php @@ -24,6 +24,7 @@ use function extension_loaded; use function headers_sent; use function ini_get; +use function ob_flush; use function preg_match; use function range; use function restore_error_handler; @@ -481,6 +482,21 @@ public function testPassingClearStorageOptionWhenCallingDestroyClearsStorage(): self::assertFalse(isset($storage['foo'])); } + /** + * @runInSeparateProcess + */ + public function testDestroySessionWhenHeadersHaveBeenSent(): void + { + $this->manager = new SessionManager(); + $this->manager->start(); + $storage = $this->manager->getStorage(); + $storage['foo'] = 'bar'; + echo ' '; + ob_flush(); + $this->manager->destroy(['clear_storage' => true]); + self::assertFalse(isset($storage['foo'])); + } + /** * @runInSeparateProcess */ From d5f8681c4becb29b01395cff19ff4815eb0a054e Mon Sep 17 00:00:00 2001 From: Aleksi Peebles Date: Thu, 29 Feb 2024 21:28:59 +0200 Subject: [PATCH 3/4] Add inline comment Co-authored-by: Aleksei Khudiakov Signed-off-by: Aleksi Peebles --- src/SessionManager.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/SessionManager.php b/src/SessionManager.php index 5203b5fa..4c6f748d 100644 --- a/src/SessionManager.php +++ b/src/SessionManager.php @@ -194,9 +194,8 @@ protected function initializeValidatorChain() */ public function destroy(?array $options = null) { + // session_destroy() requires active session while method $this->sessionExists() includes other conditions if (session_status() !== PHP_SESSION_ACTIVE) { - return; - } if (null === $options) { $options = $this->defaultDestroyOptions; From ca80cb417bd6911e1c6651d51ce8c4e71cff80fb Mon Sep 17 00:00:00 2001 From: Aleksi Peebles Date: Thu, 29 Feb 2024 21:35:05 +0200 Subject: [PATCH 4/4] Fix broken GitHub commit Signed-off-by: Aleksi Peebles --- src/SessionManager.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/SessionManager.php b/src/SessionManager.php index 4c6f748d..7fd8102e 100644 --- a/src/SessionManager.php +++ b/src/SessionManager.php @@ -194,8 +194,11 @@ protected function initializeValidatorChain() */ public function destroy(?array $options = null) { - // session_destroy() requires active session while method $this->sessionExists() includes other conditions + // session_destroy() requires active session while method + // $this->sessionExists() includes other conditions if (session_status() !== PHP_SESSION_ACTIVE) { + return; + } if (null === $options) { $options = $this->defaultDestroyOptions;