diff options
| author | Greg Roach <fisharebest@gmail.com> | 2017-12-05 18:35:16 +0000 |
|---|---|---|
| committer | Greg Roach <fisharebest@gmail.com> | 2017-12-05 18:35:16 +0000 |
| commit | 7ace898ae2c4a9c68bfc303be4ca9ce044f6c8fb (patch) | |
| tree | 540514de76ddd7a7b48c45e6f343982c75e459f6 /vendor/symfony/http-foundation/Session | |
| parent | 52eaf96b933551ac480679c3439951cf6b04a3f0 (diff) | |
| download | webtrees-7ace898ae2c4a9c68bfc303be4ca9ce044f6c8fb.tar.gz webtrees-7ace898ae2c4a9c68bfc303be4ca9ce044f6c8fb.tar.bz2 webtrees-7ace898ae2c4a9c68bfc303be4ca9ce044f6c8fb.zip | |
Update symfony/http-foundation from 3.3 to 3.4
Diffstat (limited to 'vendor/symfony/http-foundation/Session')
20 files changed, 538 insertions, 83 deletions
diff --git a/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php b/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php index 59ba309005..77521c2478 100644 --- a/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php +++ b/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php @@ -25,7 +25,7 @@ class AutoExpireFlashBag implements FlashBagInterface /** * @param string $storageKey The key used to store flashes in the session */ - public function __construct($storageKey = '_sf2_flashes') + public function __construct($storageKey = '_symfony_flashes') { $this->storageKey = $storageKey; } @@ -106,7 +106,7 @@ class AutoExpireFlashBag implements FlashBagInterface public function all() { $return = $this->flashes['display']; - $this->flashes = array('new' => array(), 'display' => array()); + $this->flashes['display'] = array(); return $return; } diff --git a/vendor/symfony/http-foundation/Session/Flash/FlashBag.php b/vendor/symfony/http-foundation/Session/Flash/FlashBag.php index 9c2e3fe7c8..12fb740c52 100644 --- a/vendor/symfony/http-foundation/Session/Flash/FlashBag.php +++ b/vendor/symfony/http-foundation/Session/Flash/FlashBag.php @@ -25,7 +25,7 @@ class FlashBag implements FlashBagInterface /** * @param string $storageKey The key used to store flashes in the session */ - public function __construct($storageKey = '_sf2_flashes') + public function __construct($storageKey = '_symfony_flashes') { $this->storageKey = $storageKey; } diff --git a/vendor/symfony/http-foundation/Session/Session.php b/vendor/symfony/http-foundation/Session/Session.php index 09caa3442f..0c3371fab6 100644 --- a/vendor/symfony/http-foundation/Session/Session.php +++ b/vendor/symfony/http-foundation/Session/Session.php @@ -28,6 +28,7 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable private $flashName; private $attributeName; + private $data = array(); /** * @param SessionStorageInterface $storage A SessionStorageInterface instance @@ -108,7 +109,7 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable */ public function clear() { - $this->storage->getBag($this->attributeName)->clear(); + $this->getAttributeBag()->clear(); } /** @@ -140,6 +141,22 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable } /** + * @return bool + * + * @internal + */ + public function isEmpty() + { + foreach ($this->data as &$data) { + if (!empty($data)) { + return false; + } + } + + return true; + } + + /** * {@inheritdoc} */ public function invalidate($lifetime = null) @@ -210,7 +227,7 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable */ public function registerBag(SessionBagInterface $bag) { - $this->storage->registerBag($bag); + $this->storage->registerBag(new SessionBagProxy($bag, $this->data)); } /** @@ -218,7 +235,7 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable */ public function getBag($name) { - return $this->storage->getBag($name); + return $this->storage->getBag($name)->getBag(); } /** @@ -240,6 +257,6 @@ class Session implements SessionInterface, \IteratorAggregate, \Countable */ private function getAttributeBag() { - return $this->storage->getBag($this->attributeName); + return $this->storage->getBag($this->attributeName)->getBag(); } } diff --git a/vendor/symfony/http-foundation/Session/SessionBagProxy.php b/vendor/symfony/http-foundation/Session/SessionBagProxy.php new file mode 100644 index 0000000000..6c4cab6716 --- /dev/null +++ b/vendor/symfony/http-foundation/Session/SessionBagProxy.php @@ -0,0 +1,79 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session; + +/** + * @author Nicolas Grekas <p@tchwork.com> + * + * @internal + */ +final class SessionBagProxy implements SessionBagInterface +{ + private $bag; + private $data; + + public function __construct(SessionBagInterface $bag, array &$data) + { + $this->bag = $bag; + $this->data = &$data; + } + + /** + * @return SessionBagInterface + */ + public function getBag() + { + return $this->bag; + } + + /** + * @return bool + */ + public function isEmpty() + { + return empty($this->data[$this->bag->getStorageKey()]); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return $this->bag->getName(); + } + + /** + * {@inheritdoc} + */ + public function initialize(array &$array) + { + $this->data[$this->bag->getStorageKey()] = &$array; + + $this->bag->initialize($array); + } + + /** + * {@inheritdoc} + */ + public function getStorageKey() + { + return $this->bag->getStorageKey(); + } + + /** + * {@inheritdoc} + */ + public function clear() + { + return $this->bag->clear(); + } +} diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php new file mode 100644 index 0000000000..7c6c476aac --- /dev/null +++ b/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php @@ -0,0 +1,168 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; + +/** + * This abstract session handler provides a generic implementation + * of the PHP 7.0 SessionUpdateTimestampHandlerInterface, + * enabling strict and lazy session handling. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +abstract class AbstractSessionHandler implements \SessionHandlerInterface, \SessionUpdateTimestampHandlerInterface +{ + private $sessionName; + private $prefetchId; + private $prefetchData; + private $newSessionId; + private $igbinaryEmptyData; + + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + $this->sessionName = $sessionName; + if (!headers_sent() && !ini_get('session.cache_limiter') && '0' !== ini_get('session.cache_limiter')) { + header(sprintf('Cache-Control: max-age=%d, private, must-revalidate', 60 * (int) ini_get('session.cache_expire'))); + } + + return true; + } + + /** + * @param string $sessionId + * + * @return string + */ + abstract protected function doRead($sessionId); + + /** + * @param string $sessionId + * @param string $data + * + * @return bool + */ + abstract protected function doWrite($sessionId, $data); + + /** + * @param string $sessionId + * + * @return bool + */ + abstract protected function doDestroy($sessionId); + + /** + * {@inheritdoc} + */ + public function validateId($sessionId) + { + $this->prefetchData = $this->read($sessionId); + $this->prefetchId = $sessionId; + + return '' !== $this->prefetchData; + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + if (null !== $this->prefetchId) { + $prefetchId = $this->prefetchId; + $prefetchData = $this->prefetchData; + $this->prefetchId = $this->prefetchData = null; + + if ($prefetchId === $sessionId || '' === $prefetchData) { + $this->newSessionId = '' === $prefetchData ? $sessionId : null; + + return $prefetchData; + } + } + + $data = $this->doRead($sessionId); + $this->newSessionId = '' === $data ? $sessionId : null; + if (\PHP_VERSION_ID < 70000) { + $this->prefetchData = $data; + } + + return $data; + } + + /** + * {@inheritdoc} + */ + public function write($sessionId, $data) + { + if (\PHP_VERSION_ID < 70000 && $this->prefetchData) { + $readData = $this->prefetchData; + $this->prefetchData = null; + + if ($readData === $data) { + return $this->updateTimestamp($sessionId, $data); + } + } + if (null === $this->igbinaryEmptyData) { + // see https://github.com/igbinary/igbinary/issues/146 + $this->igbinaryEmptyData = \function_exists('igbinary_serialize') ? igbinary_serialize(array()) : ''; + } + if ('' === $data || $this->igbinaryEmptyData === $data) { + return $this->destroy($sessionId); + } + $this->newSessionId = null; + + return $this->doWrite($sessionId, $data); + } + + /** + * {@inheritdoc} + */ + public function destroy($sessionId) + { + if (\PHP_VERSION_ID < 70000) { + $this->prefetchData = null; + } + if (!headers_sent() && ini_get('session.use_cookies')) { + if (!$this->sessionName) { + throw new \LogicException(sprintf('Session name cannot be empty, did you forget to call "parent::open()" in "%s"?.', get_class($this))); + } + $sessionCookie = sprintf(' %s=', urlencode($this->sessionName)); + $sessionCookieWithId = sprintf('%s%s;', $sessionCookie, urlencode($sessionId)); + $sessionCookieFound = false; + $otherCookies = array(); + foreach (headers_list() as $h) { + if (0 !== stripos($h, 'Set-Cookie:')) { + continue; + } + if (11 === strpos($h, $sessionCookie, 11)) { + $sessionCookieFound = true; + + if (11 !== strpos($h, $sessionCookieWithId, 11)) { + $otherCookies[] = $h; + } + } else { + $otherCookies[] = $h; + } + } + if ($sessionCookieFound) { + header_remove('Set-Cookie'); + foreach ($otherCookies as $h) { + header('Set-Cookie:'.$h, false); + } + } else { + setcookie($this->sessionName, '', 0, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), ini_get('session.cookie_httponly')); + } + } + + return $this->newSessionId === $sessionId || $this->doDestroy($sessionId); + } +} diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/MemcacheSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/MemcacheSessionHandler.php index 89b4dac2c6..84f4357b12 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Handler/MemcacheSessionHandler.php +++ b/vendor/symfony/http-foundation/Session/Storage/Handler/MemcacheSessionHandler.php @@ -11,8 +11,12 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; +@trigger_error(sprintf('The class %s is deprecated since version 3.4 and will be removed in 4.0. Use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcachedSessionHandler instead.', MemcacheSessionHandler::class), E_USER_DEPRECATED); + /** * @author Drak <drak@zikula.org> + * + * @deprecated since version 3.4, to be removed in 4.0. Use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcachedSessionHandler instead. */ class MemcacheSessionHandler implements \SessionHandlerInterface { diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php index 6e2c2ee306..2d600b66cd 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php +++ b/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php @@ -19,7 +19,7 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; * * @author Drak <drak@zikula.org> */ -class MemcachedSessionHandler implements \SessionHandlerInterface +class MemcachedSessionHandler extends AbstractSessionHandler { private $memcached; @@ -36,7 +36,7 @@ class MemcachedSessionHandler implements \SessionHandlerInterface /** * List of available options: * * prefix: The prefix to use for the memcached keys in order to avoid collision - * * expiretime: The time to live in seconds + * * expiretime: The time to live in seconds. * * @param \Memcached $memcached A \Memcached instance * @param array $options An associative array of Memcached options @@ -60,7 +60,7 @@ class MemcachedSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ - public function open($savePath, $sessionName) + public function close() { return true; } @@ -68,23 +68,23 @@ class MemcachedSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ - public function close() + protected function doRead($sessionId) { - return true; + return $this->memcached->get($this->prefix.$sessionId) ?: ''; } /** * {@inheritdoc} */ - public function read($sessionId) + public function updateTimestamp($sessionId, $data) { - return $this->memcached->get($this->prefix.$sessionId) ?: ''; + return $this->memcached->touch($this->prefix.$sessionId, time() + $this->ttl); } /** * {@inheritdoc} */ - public function write($sessionId, $data) + protected function doWrite($sessionId, $data) { return $this->memcached->set($this->prefix.$sessionId, $data, time() + $this->ttl); } @@ -92,7 +92,7 @@ class MemcachedSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ - public function destroy($sessionId) + protected function doDestroy($sessionId) { $result = $this->memcached->delete($this->prefix.$sessionId); diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php index 29fc3f529b..264144d5b5 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php +++ b/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php @@ -12,9 +12,14 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; /** + * Session handler using the mongodb/mongodb package and MongoDB driver extension. + * * @author Markus Bachmann <markus.bachmann@bachi.biz> + * + * @see https://packagist.org/packages/mongodb/mongodb + * @see http://php.net/manual/en/set.mongodb.php */ -class MongoDbSessionHandler implements \SessionHandlerInterface +class MongoDbSessionHandler extends AbstractSessionHandler { private $mongo; @@ -35,7 +40,7 @@ class MongoDbSessionHandler implements \SessionHandlerInterface * * id_field: The field name for storing the session id [default: _id] * * data_field: The field name for storing the session data [default: data] * * time_field: The field name for storing the timestamp [default: time] - * * expiry_field: The field name for storing the expiry-timestamp [default: expires_at] + * * expiry_field: The field name for storing the expiry-timestamp [default: expires_at]. * * It is strongly recommended to put an index on the `expiry_field` for * garbage-collection. Alternatively it's possible to automatically expire @@ -54,14 +59,18 @@ class MongoDbSessionHandler implements \SessionHandlerInterface * If you use such an index, you can drop `gc_probability` to 0 since * no garbage-collection is required. * - * @param \Mongo|\MongoClient|\MongoDB\Client $mongo A MongoDB\Client, MongoClient or Mongo instance - * @param array $options An associative array of field options + * @param \MongoDB\Client $mongo A MongoDB\Client instance + * @param array $options An associative array of field options * * @throws \InvalidArgumentException When MongoClient or Mongo instance not provided * @throws \InvalidArgumentException When "database" or "collection" not provided */ public function __construct($mongo, array $options) { + if ($mongo instanceof \MongoClient || $mongo instanceof \Mongo) { + @trigger_error(sprintf('Using %s with the legacy mongo extension is deprecated as of 3.4 and will be removed in 4.0. Use it with the mongodb/mongodb package and ext-mongodb instead.', __CLASS__), E_USER_DEPRECATED); + } + if (!($mongo instanceof \MongoDB\Client || $mongo instanceof \MongoClient || $mongo instanceof \Mongo)) { throw new \InvalidArgumentException('MongoClient or Mongo instance required'); } @@ -83,14 +92,6 @@ class MongoDbSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ - public function open($savePath, $sessionName) - { - return true; - } - - /** - * {@inheritdoc} - */ public function close() { return true; @@ -99,7 +100,7 @@ class MongoDbSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ - public function destroy($sessionId) + protected function doDestroy($sessionId) { $methodName = $this->mongo instanceof \MongoDB\Client ? 'deleteOne' : 'remove'; @@ -127,7 +128,7 @@ class MongoDbSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ - public function write($sessionId, $data) + protected function doWrite($sessionId, $data) { $expiry = $this->createDateTime(time() + (int) ini_get('session.gc_maxlifetime')); @@ -159,7 +160,34 @@ class MongoDbSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ - public function read($sessionId) + public function updateTimestamp($sessionId, $data) + { + $expiry = $this->createDateTime(time() + (int) ini_get('session.gc_maxlifetime')); + + if ($this->mongo instanceof \MongoDB\Client) { + $methodName = 'updateOne'; + $options = array(); + } else { + $methodName = 'update'; + $options = array('multiple' => false); + } + + $this->getCollection()->$methodName( + array($this->options['id_field'] => $sessionId), + array('$set' => array( + $this->options['time_field'] => $this->createDateTime(), + $this->options['expiry_field'] => $expiry, + )), + $options + ); + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doRead($sessionId) { $dbData = $this->getCollection()->findOne(array( $this->options['id_field'] => $sessionId, diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php index d6ad93749f..4e9704bd58 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php +++ b/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php @@ -26,6 +26,7 @@ class NativeFileSessionHandler extends NativeSessionHandler * @see http://php.net/session.configuration.php#ini.session.save-path for further details. * * @throws \InvalidArgumentException On invalid $savePath + * @throws \RuntimeException When failing to create the save directory */ public function __construct($savePath = null) { diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php index 4ae410f9b9..9ea4629ca1 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php +++ b/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php @@ -12,10 +12,13 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; /** - * Adds SessionHandler functionality if available. - * + * @deprecated since version 3.4, to be removed in 4.0. Use \SessionHandler instead. * @see http://php.net/sessionhandler */ class NativeSessionHandler extends \SessionHandler { + public function __construct() + { + @trigger_error('The '.__NAMESPACE__.'\NativeSessionHandler class is deprecated since version 3.4 and will be removed in 4.0. Use the \SessionHandler class instead.', E_USER_DEPRECATED); + } } diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php index 1516d4314a..8d193155b0 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php +++ b/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php @@ -12,18 +12,16 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; /** - * NullSessionHandler. - * * Can be used in unit testing or in a situations where persisted sessions are not desired. * * @author Drak <drak@zikula.org> */ -class NullSessionHandler implements \SessionHandlerInterface +class NullSessionHandler extends AbstractSessionHandler { /** * {@inheritdoc} */ - public function open($savePath, $sessionName) + public function close() { return true; } @@ -31,7 +29,7 @@ class NullSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ - public function close() + public function validateId($sessionId) { return true; } @@ -39,7 +37,7 @@ class NullSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ - public function read($sessionId) + protected function doRead($sessionId) { return ''; } @@ -47,7 +45,15 @@ class NullSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ - public function write($sessionId, $data) + public function updateTimestamp($sessionId, $data) + { + return true; + } + + /** + * {@inheritdoc} + */ + protected function doWrite($sessionId, $data) { return true; } @@ -55,7 +61,7 @@ class NullSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ - public function destroy($sessionId) + protected function doDestroy($sessionId) { return true; } diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php index daabbc21f0..bccfbf611f 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php +++ b/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php @@ -38,7 +38,7 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; * @author Michael Williams <michael.williams@funsational.com> * @author Tobias Schultze <http://tobion.de> */ -class PdoSessionHandler implements \SessionHandlerInterface +class PdoSessionHandler extends AbstractSessionHandler { /** * No locking is done. This means sessions are prone to loss of data due to @@ -260,11 +260,13 @@ class PdoSessionHandler implements \SessionHandlerInterface */ public function open($savePath, $sessionName) { + $this->sessionExpired = false; + if (null === $this->pdo) { $this->connect($this->dsn ?: $savePath); } - return true; + return parent::open($savePath, $sessionName); } /** @@ -273,7 +275,7 @@ class PdoSessionHandler implements \SessionHandlerInterface public function read($sessionId) { try { - return $this->doRead($sessionId); + return parent::read($sessionId); } catch (\PDOException $e) { $this->rollback(); @@ -296,7 +298,7 @@ class PdoSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ - public function destroy($sessionId) + protected function doDestroy($sessionId) { // delete the record associated with this id $sql = "DELETE FROM $this->table WHERE $this->idCol = :id"; @@ -317,7 +319,7 @@ class PdoSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ - public function write($sessionId, $data) + protected function doWrite($sessionId, $data) { $maxlifetime = (int) ini_get('session.gc_maxlifetime'); @@ -375,6 +377,30 @@ class PdoSessionHandler implements \SessionHandlerInterface /** * {@inheritdoc} */ + public function updateTimestamp($sessionId, $data) + { + $maxlifetime = (int) ini_get('session.gc_maxlifetime'); + + try { + $updateStmt = $this->pdo->prepare( + "UPDATE $this->table SET $this->lifetimeCol = :lifetime, $this->timeCol = :time WHERE $this->idCol = :id" + ); + $updateStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR); + $updateStmt->bindParam(':lifetime', $maxlifetime, \PDO::PARAM_INT); + $updateStmt->bindValue(':time', time(), \PDO::PARAM_INT); + $updateStmt->execute(); + } catch (\PDOException $e) { + $this->rollback(); + + throw $e; + } + + return true; + } + + /** + * {@inheritdoc} + */ public function close() { $this->commit(); @@ -491,10 +517,8 @@ class PdoSessionHandler implements \SessionHandlerInterface * * @return string The session data */ - private function doRead($sessionId) + protected function doRead($sessionId) { - $this->sessionExpired = false; - if (self::LOCK_ADVISORY === $this->lockMode) { $this->unlockStatements[] = $this->doAdvisoryLock($sessionId); } @@ -517,7 +541,9 @@ class PdoSessionHandler implements \SessionHandlerInterface return is_resource($sessionRows[0][0]) ? stream_get_contents($sessionRows[0][0]) : $sessionRows[0][0]; } - if (self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) { + if (!ini_get('session.use_strict_mode') && self::LOCK_TRANSACTIONAL === $this->lockMode && 'sqlite' !== $this->driver) { + // In strict mode, session fixation is not possible: new sessions always start with a unique + // random id, so that concurrency is not possible and this code path can be skipped. // Exclusive-reading of non-existent rows does not block, so we need to do an insert to block // until other connections to the session are committed. try { diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php new file mode 100644 index 0000000000..1bad0641e8 --- /dev/null +++ b/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php @@ -0,0 +1,89 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; + +/** + * Adds basic `SessionUpdateTimestampHandlerInterface` behaviors to another `SessionHandlerInterface`. + * + * @author Nicolas Grekas <p@tchwork.com> + */ +class StrictSessionHandler extends AbstractSessionHandler +{ + private $handler; + + public function __construct(\SessionHandlerInterface $handler) + { + if ($handler instanceof \SessionUpdateTimestampHandlerInterface) { + throw new \LogicException(sprintf('"%s" is already an instance of "SessionUpdateTimestampHandlerInterface", you cannot wrap it with "%s".', get_class($handler), self::class)); + } + + $this->handler = $handler; + } + + /** + * {@inheritdoc} + */ + public function open($savePath, $sessionName) + { + parent::open($savePath, $sessionName); + + return $this->handler->open($savePath, $sessionName); + } + + /** + * {@inheritdoc} + */ + protected function doRead($sessionId) + { + return $this->handler->read($sessionId); + } + + /** + * {@inheritdoc} + */ + public function updateTimestamp($sessionId, $data) + { + return $this->write($sessionId, $data); + } + + /** + * {@inheritdoc} + */ + protected function doWrite($sessionId, $data) + { + return $this->handler->write($sessionId, $data); + } + + /** + * {@inheritdoc} + */ + protected function doDestroy($sessionId) + { + return $this->handler->destroy($sessionId); + } + + /** + * {@inheritdoc} + */ + public function close() + { + return $this->handler->close(); + } + + /** + * {@inheritdoc} + */ + public function gc($maxlifetime) + { + return $this->handler->gc($maxlifetime); + } +} diff --git a/vendor/symfony/http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.php b/vendor/symfony/http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.php index 7f4b6bc034..2fc7e09195 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.php +++ b/vendor/symfony/http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.php @@ -11,10 +11,14 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Handler; +@trigger_error(sprintf('The %s class is deprecated since version 3.4 and will be removed in 4.0. Implement `SessionUpdateTimestampHandlerInterface` or extend `AbstractSessionHandler` instead.', WriteCheckSessionHandler::class), E_USER_DEPRECATED); + /** * Wraps another SessionHandlerInterface to only write the session when it has been modified. * * @author Adrien Brault <adrien.brault@gmail.com> + * + * @deprecated since version 3.4, to be removed in 4.0. Implement `SessionUpdateTimestampHandlerInterface` or extend `AbstractSessionHandler` instead. */ class WriteCheckSessionHandler implements \SessionHandlerInterface { diff --git a/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php b/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php index 0a580d6027..14f427007b 100644 --- a/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php +++ b/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php @@ -91,7 +91,26 @@ class MockFileSessionStorage extends MockArraySessionStorage throw new \RuntimeException('Trying to save a session that was not started yet or was already closed'); } - file_put_contents($this->getFilePath(), serialize($this->data)); + $data = $this->data; + + foreach ($this->bags as $bag) { + if (empty($data[$key = $bag->getStorageKey()])) { + unset($data[$key]); + } + } + if (array($key = $this->metadataBag->getStorageKey()) === array_keys($data)) { + unset($data[$key]); + } + + try { + if ($data) { + file_put_contents($this->getFilePath(), serialize($data)); + } else { + $this->destroy(); + } + } finally { + $this->data = $data; + } // this is needed for Silex, where the session object is re-used across requests // in functional tests. In Symfony, the container is rebooted, so we don't have diff --git a/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php b/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php index 5620aae3cd..0dfad9acb3 100644 --- a/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php +++ b/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php @@ -11,9 +11,8 @@ namespace Symfony\Component\HttpFoundation\Session\Storage; -use Symfony\Component\Debug\Exception\ContextErrorException; use Symfony\Component\HttpFoundation\Session\SessionBagInterface; -use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler; +use Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandler; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy; @@ -25,11 +24,9 @@ use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy; class NativeSessionStorage implements SessionStorageInterface { /** - * Array of SessionBagInterface. - * * @var SessionBagInterface[] */ - protected $bags; + protected $bags = array(); /** * @var bool @@ -42,7 +39,7 @@ class NativeSessionStorage implements SessionStorageInterface protected $closed = false; /** - * @var AbstractProxy + * @var AbstractProxy|\SessionHandlerInterface */ protected $saveHandler; @@ -64,6 +61,7 @@ class NativeSessionStorage implements SessionStorageInterface * PHP starts to execute user-land code. Setting during runtime has no effect). * * cache_limiter, "" (use "0" to prevent headers from being sent entirely). + * cache_expire, "0" * cookie_domain, "" * cookie_httponly, "" * cookie_lifetime, "0" @@ -96,16 +94,17 @@ class NativeSessionStorage implements SessionStorageInterface * trans_sid_hosts, $_SERVER['HTTP_HOST'] * trans_sid_tags, "a=href,area=href,frame=src,form=" * - * @param array $options Session configuration options - * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler - * @param MetadataBag $metaBag MetadataBag + * @param array $options Session configuration options + * @param \SessionHandlerInterface|null $handler + * @param MetadataBag $metaBag MetadataBag */ public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null) { $options += array( - // disable by default because it's managed by HeaderBag (if used) 'cache_limiter' => '', + 'cache_expire' => 0, 'use_cookies' => 1, + 'lazy_write' => 1, ); session_register_shutdown(); @@ -118,7 +117,7 @@ class NativeSessionStorage implements SessionStorageInterface /** * Gets the save handler instance. * - * @return AbstractProxy + * @return AbstractProxy|\SessionHandlerInterface */ public function getSaveHandler() { @@ -220,15 +219,31 @@ class NativeSessionStorage implements SessionStorageInterface */ public function save() { + $session = $_SESSION; + + foreach ($this->bags as $bag) { + if (empty($_SESSION[$key = $bag->getStorageKey()])) { + unset($_SESSION[$key]); + } + } + if (array($key = $this->metadataBag->getStorageKey()) === array_keys($_SESSION)) { + unset($_SESSION[$key]); + } + // Register custom error handler to catch a possible failure warning during session write - set_error_handler(function ($errno, $errstr, $errfile, $errline, $errcontext) { - throw new ContextErrorException($errstr, $errno, E_WARNING, $errfile, $errline, $errcontext); + set_error_handler(function ($errno, $errstr, $errfile, $errline) { + throw new \ErrorException($errstr, $errno, E_WARNING, $errfile, $errline); }, E_WARNING); try { + $e = null; session_write_close(); + } catch (\ErrorException $e) { + } finally { restore_error_handler(); - } catch (ContextErrorException $e) { + $_SESSION = $session; + } + if (null !== $e) { // The default PHP error message is not very helpful, as it does not give any information on the current save handler. // Therefore, we catch this error and trigger a warning with a better error message $handler = $this->getSaveHandler(); @@ -236,7 +251,6 @@ class NativeSessionStorage implements SessionStorageInterface $handler = $handler->getHandler(); } - restore_error_handler(); trigger_error(sprintf('session_write_close(): Failed to write session data with %s handler', get_class($handler)), E_USER_WARNING); } @@ -335,7 +349,7 @@ class NativeSessionStorage implements SessionStorageInterface } $validOptions = array_flip(array( - 'cache_limiter', 'cookie_domain', 'cookie_httponly', + 'cache_limiter', 'cache_expire', 'cookie_domain', 'cookie_httponly', 'cookie_lifetime', 'cookie_path', 'cookie_secure', 'entropy_file', 'entropy_length', 'gc_divisor', 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', @@ -363,7 +377,7 @@ class NativeSessionStorage implements SessionStorageInterface * ini_set('session.save_handler', 'files'); * ini_set('session.save_path', '/tmp'); * - * or pass in a NativeSessionHandler instance which configures session.save_handler in the + * or pass in a \SessionHandler instance which configures session.save_handler in the * constructor, for a template see NativeFileSessionHandler or use handlers in * composer package drak/native-session * @@ -372,24 +386,23 @@ class NativeSessionStorage implements SessionStorageInterface * @see http://php.net/sessionhandler * @see http://github.com/drak/NativeSession * - * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $saveHandler + * @param \SessionHandlerInterface|null $saveHandler * * @throws \InvalidArgumentException */ public function setSaveHandler($saveHandler = null) { if (!$saveHandler instanceof AbstractProxy && - !$saveHandler instanceof NativeSessionHandler && !$saveHandler instanceof \SessionHandlerInterface && null !== $saveHandler) { - throw new \InvalidArgumentException('Must be instance of AbstractProxy or NativeSessionHandler; implement \SessionHandlerInterface; or be null.'); + throw new \InvalidArgumentException('Must be instance of AbstractProxy; implement \SessionHandlerInterface; or be null.'); } // Wrap $saveHandler in proxy and prevent double wrapping of proxy if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) { $saveHandler = new SessionHandlerProxy($saveHandler); } elseif (!$saveHandler instanceof AbstractProxy) { - $saveHandler = new SessionHandlerProxy(new \SessionHandler()); + $saveHandler = new SessionHandlerProxy(new StrictSessionHandler(new \SessionHandler())); } $this->saveHandler = $saveHandler; @@ -397,7 +410,9 @@ class NativeSessionStorage implements SessionStorageInterface return; } - if ($this->saveHandler instanceof \SessionHandlerInterface) { + if ($this->saveHandler instanceof SessionHandlerProxy) { + session_set_save_handler($this->saveHandler->getHandler(), false); + } elseif ($this->saveHandler instanceof \SessionHandlerInterface) { session_set_save_handler($this->saveHandler, false); } } diff --git a/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php b/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php index 9420d086ca..662ed5015a 100644 --- a/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php +++ b/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php @@ -11,9 +11,6 @@ namespace Symfony\Component\HttpFoundation\Session\Storage; -use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; -use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler; - /** * Allows session to be started by PHP and managed by Symfony. * @@ -22,8 +19,8 @@ use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandle class PhpBridgeSessionStorage extends NativeSessionStorage { /** - * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler - * @param MetadataBag $metaBag MetadataBag + * @param \SessionHandlerInterface|null $handler + * @param MetadataBag $metaBag MetadataBag */ public function __construct($handler = null, MetadataBag $metaBag = null) { diff --git a/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php b/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php index a7478656d6..09c92483c7 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php +++ b/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php @@ -12,8 +12,6 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy; /** - * AbstractProxy. - * * @author Drak <drak@zikula.org> */ abstract class AbstractProxy diff --git a/vendor/symfony/http-foundation/Session/Storage/Proxy/NativeProxy.php b/vendor/symfony/http-foundation/Session/Storage/Proxy/NativeProxy.php index a0f48c1e27..460abe15c3 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Proxy/NativeProxy.php +++ b/vendor/symfony/http-foundation/Session/Storage/Proxy/NativeProxy.php @@ -11,9 +11,13 @@ namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy; +@trigger_error('The '.__NAMESPACE__.'\NativeProxy class is deprecated since version 3.4 and will be removed in 4.0. Use your session handler implementation directly.', E_USER_DEPRECATED); + /** * This proxy is built-in session handlers in PHP 5.3.x. * + * @deprecated since version 3.4, to be removed in 4.0. Use your session handler implementation directly. + * * @author Drak <drak@zikula.org> */ class NativeProxy extends AbstractProxy diff --git a/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php b/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php index a96aae265c..53c1209a1c 100644 --- a/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php +++ b/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php @@ -18,9 +18,6 @@ class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterf { protected $handler; - /** - * @param \SessionHandlerInterface $handler - */ public function __construct(\SessionHandlerInterface $handler) { $this->handler = $handler; |
