From fdf285b5c9a85b2cbd9d569ed1682bf7f12e014a Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 9 Oct 2017 12:39:15 +0200 Subject: [PATCH] Fix 7.2 compat layer --- .github/build-packages.php | 1 + .travis.yml | 9 ++-- .../Bridge/Twig/Tests/AppVariableTest.php | 3 ++ src/Symfony/Bridge/Twig/composer.json | 1 + .../CacheClearCommandTest.php | 2 +- .../Tests/Controller/ControllerTest.php | 3 ++ .../Bundle/FrameworkBundle/composer.json | 2 +- .../Debug/Tests/ErrorHandlerTest.php | 4 +- .../Debug/Tests/Fixtures/Throwing.php | 4 +- .../Tests/Loader/XmlFileLoaderTest.php | 3 ++ .../LegacyDefaultCsrfProviderTest.php | 8 ---- .../Session/Storage/NativeSessionStorage.php | 33 +++++++++------ .../Storage/Handler/PdoSessionHandlerTest.php | 41 ++----------------- .../Storage/NativeSessionStorageTest.php | 2 +- .../EventListener/LocaleListenerTest.php | 7 +--- .../EventListener/TestSessionListenerTest.php | 3 +- .../Component/HttpKernel/composer.json | 2 +- .../Routing/Tests/Fixtures/validresource.php | 3 ++ .../NativeSessionTokenStorageTest.php | 10 ----- 19 files changed, 55 insertions(+), 86 deletions(-) diff --git a/.github/build-packages.php b/.github/build-packages.php index 3d186e927c..56112b753a 100644 --- a/.github/build-packages.php +++ b/.github/build-packages.php @@ -9,6 +9,7 @@ chdir(dirname(__DIR__)); $dirs = $_SERVER['argv']; array_shift($dirs); $mergeBase = trim(shell_exec(sprintf('git merge-base %s HEAD', array_shift($dirs)))); + $packages = array(); $flags = \PHP_VERSION_ID >= 50400 ? JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE : 0; diff --git a/.travis.yml b/.travis.yml index 8409baaf05..e34ba5a8bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,9 +25,10 @@ matrix: - php: 5.5 - php: 5.6 - php: 7.0 - env: deps=high - php: 7.1 + env: deps=high - php: 7.2 + env: deps=low fast_finish: true cache: @@ -137,7 +138,7 @@ install: export SYMFONY_DEPRECATIONS_HELPER=weak && cp composer.json composer.json.orig && echo -e '{\n"require":{'"$(grep phpunit-bridge composer.json)"'"php":"*"},"minimum-stability":"dev"}' > composer.json && - (php .github/build-packages.php HEAD^ $COMPONENTS) && + php .github/build-packages.php HEAD^ $COMPONENTS && mv composer.json composer.json.phpunit && mv composer.json.orig composer.json fi @@ -176,9 +177,9 @@ install: if [[ $skip ]]; then echo -e "\\n\\e[1;34mIntermediate PHP version $PHP is skipped for pull requests.\\e[0m" elif [[ $deps = high ]]; then - echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && ($COMPOSER_UP) && $PHPUNIT_X$LEGACY'" + echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && $COMPOSER_UP && $PHPUNIT_X$LEGACY'" elif [[ $deps = low ]]; then - echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && ($COMPOSER_UP --prefer-lowest --prefer-stable) && $PHPUNIT_X'" + echo "$COMPONENTS" | parallel --gnu -j10% "tfold {} 'cd {} && $COMPOSER_UP --prefer-lowest --prefer-stable && $PHPUNIT_X'" elif [[ $PHP = hhvm* ]]; then $PHPUNIT --exclude-group benchmark,intl-data else diff --git a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php index 9abb0e3b6e..b9aa168fd7 100644 --- a/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php +++ b/src/Symfony/Bridge/Twig/Tests/AppVariableTest.php @@ -44,6 +44,9 @@ class AppVariableTest extends TestCase $this->assertEquals('dev', $this->appVariable->getEnvironment()); } + /** + * @runInSeparateProcess + */ public function testGetSession() { $request = $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock(); diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index 9610edc808..04e3819176 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -23,6 +23,7 @@ "symfony/asset": "~2.7", "symfony/finder": "~2.3", "symfony/form": "~2.7.30|^2.8.23", + "symfony/http-foundation": "~2.7.36|^2.8.29", "symfony/http-kernel": "~2.3", "symfony/intl": "~2.3", "symfony/routing": "~2.2", diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php index f1140e86bb..a25aa8e637 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php @@ -55,7 +55,7 @@ class CacheClearCommandTest extends TestCase $finder = new Finder(); $metaFiles = $finder->files()->in($this->kernel->getCacheDir())->name('*.php.meta'); // simply check that cache is warmed up - $this->assertGreaterThanOrEqual(1, count($metaFiles)); + $this->assertNotEmpty($metaFiles); foreach ($metaFiles as $file) { $configCache = new ConfigCache(substr($file, 0, -5), true); $this->assertTrue( diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php index d7f40a24d8..cb813c61d6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php @@ -143,6 +143,9 @@ class ControllerTest extends TestCase $this->assertSame(302, $response->getStatusCode()); } + /** + * @runInSeparateProcess + */ public function testAddFlash() { $flashBag = new FlashBag(); diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 76648774f3..ed611114fe 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -23,7 +23,7 @@ "symfony/config": "~2.4", "symfony/event-dispatcher": "~2.5", "symfony/finder": "^2.0.5", - "symfony/http-foundation": "~2.7", + "symfony/http-foundation": "~2.7.36|^2.8.29", "symfony/http-kernel": "~2.7.29|^2.8.22", "symfony/filesystem": "~2.3", "symfony/routing": "~2.7.24|^2.8.17", diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php index 898a985a29..fd9ac577ee 100644 --- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php +++ b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php @@ -79,7 +79,9 @@ class ErrorHandlerTest extends TestCase $this->assertEquals(E_NOTICE, $exception->getSeverity()); $this->assertEquals(__FILE__, $exception->getFile()); $this->assertRegExp('/^Notice: Undefined variable: (foo|bar)/', $exception->getMessage()); - $this->assertArrayHasKey('foobar', $exception->getContext()); + if (\PHP_VERSION_ID < 70200) { + $this->assertArrayHasKey('foobar', $exception->getContext()); + } $trace = $exception->getTrace(); $this->assertEquals(__FILE__, $trace[0]['file']); diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/Throwing.php b/src/Symfony/Component/Debug/Tests/Fixtures/Throwing.php index 21e0aba17d..d338ca9d57 100644 --- a/src/Symfony/Component/Debug/Tests/Fixtures/Throwing.php +++ b/src/Symfony/Component/Debug/Tests/Fixtures/Throwing.php @@ -1,3 +1,5 @@ markTestSkipped('To run this test, add "phar" to the "suhosin.executor.include.whitelist" settings in your php.ini file.'); } + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('HHVM makes this test conflict with those run in separate processes.'); + } require_once self::$fixturesPath.'/includes/ProjectWithXsdExtensionInPhar.phar'; diff --git a/src/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/LegacyDefaultCsrfProviderTest.php b/src/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/LegacyDefaultCsrfProviderTest.php index c22bd46a7b..8cca486369 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/LegacyDefaultCsrfProviderTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Csrf/CsrfProvider/LegacyDefaultCsrfProviderTest.php @@ -23,14 +23,6 @@ class LegacyDefaultCsrfProviderTest extends TestCase { protected $provider; - public static function setUpBeforeClass() - { - if (\PHP_VERSION_ID < 70200) { - ini_set('session.save_handler', 'files'); - ini_set('session.save_path', sys_get_temp_dir()); - } - } - protected function setUp() { $this->provider = new DefaultCsrfProvider('SECRET'); diff --git a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php index 1ee6d3f34e..09cb242f92 100644 --- a/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php +++ b/src/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php @@ -101,12 +101,11 @@ class NativeSessionStorage implements SessionStorageInterface */ public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null) { - if (empty($options)) { - $options += array('cache_limiter' => 'public'); - } - if (1 !== (int) ini_get('session.use_cookies')) { - ini_set('session.use_cookies', 1); - } + $options += array( + // disable by default because it's managed by HeaderBag (if used) + 'cache_limiter' => '', + 'use_cookies' => 1, + ); if (\PHP_VERSION_ID >= 50400) { session_register_shutdown(); @@ -212,6 +211,10 @@ class NativeSessionStorage implements SessionStorageInterface return false; } + if (headers_sent()) { + return false; + } + if (null !== $lifetime) { ini_set('session.cookie_lifetime', $lifetime); } @@ -336,6 +339,10 @@ class NativeSessionStorage implements SessionStorageInterface */ public function setOptions(array $options) { + if (headers_sent()) { + return; + } + $validOptions = array_flip(array( 'cache_limiter', 'cookie_domain', 'cookie_httponly', 'cookie_lifetime', 'cookie_path', 'cookie_secure', @@ -349,11 +356,9 @@ class NativeSessionStorage implements SessionStorageInterface 'sid_length', 'sid_bits_per_character', 'trans_sid_hosts', 'trans_sid_tags', )); - if (PHP_VERSION_ID < 70200 || !headers_sent()) { - foreach ($options as $key => $value) { - if (isset($validOptions[$key])) { - ini_set('session.'.$key, $value); - } + foreach ($options as $key => $value) { + if (isset($validOptions[$key])) { + ini_set('session.'.$key, $value); } } } @@ -389,6 +394,10 @@ class NativeSessionStorage implements SessionStorageInterface throw new \InvalidArgumentException('Must be instance of AbstractProxy or NativeSessionHandler; implement \SessionHandlerInterface; or be null.'); } + if (headers_sent($file, $line)) { + throw new \RuntimeException(sprintf('Failed to set the session handler because headers have already been sent by "%s" at line %d.', $file, $line)); + } + // Wrap $saveHandler in proxy and prevent double wrapping of proxy if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) { $saveHandler = new SessionHandlerProxy($saveHandler); @@ -398,7 +407,7 @@ class NativeSessionStorage implements SessionStorageInterface } $this->saveHandler = $saveHandler; - if ($this->saveHandler instanceof \SessionHandlerInterface && false === headers_sent()) { + if ($this->saveHandler instanceof \SessionHandlerInterface) { if (\PHP_VERSION_ID >= 50400) { session_set_save_handler($this->saveHandler, false); } else { diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php index 88509b11b9..a9884c1c92 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php @@ -269,12 +269,11 @@ class PdoSessionHandlerTest extends TestCase $this->assertSame('', $data, 'Destroyed session returns empty string'); } + /** + * @runInSeparateProcess + */ public function testSessionGC() { - if (\PHP_VERSION_ID >= 70200) { - $this->markTestSkipped('PHP version is 7.2'); - } - $previousLifeTime = ini_set('session.gc_maxlifetime', 1000); $pdo = $this->getMemorySqlitePdo(); $storage = new PdoSessionHandler($pdo); @@ -286,12 +285,10 @@ class PdoSessionHandlerTest extends TestCase $storage->open('', 'sid'); $storage->read('gc_id'); - // IN 7.2 this does not work ini_set('session.gc_maxlifetime', -1); // test that you can set lifetime of a session after it has been read $storage->write('gc_id', 'data'); $storage->close(); $this->assertEquals(2, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn(), 'No session pruned because gc not called'); - $storage->destroy('gc_id'); $storage->open('', 'sid'); $data = $storage->read('gc_id'); @@ -299,39 +296,7 @@ class PdoSessionHandlerTest extends TestCase $storage->close(); ini_set('session.gc_maxlifetime', $previousLifeTime); - $this->assertSame('', $data, 'Session already considered garbage, so not returning data even if it is not pruned yet'); - $this->assertEquals(1, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn(), 'Expired session is pruned'); - } - public function testSessionGC72() - { - if (\PHP_VERSION_ID <= 70200) { - $this->markTestSkipped('PHP version is not 7.2'); - } - - $previousLifeTime = false === headers_sent() && ini_set('session.gc_maxlifetime', 1000); - $pdo = $this->getMemorySqlitePdo(); - $storage = new PdoSessionHandler($pdo); - - $storage->open('', 'sid'); - $storage->read('id'); - $storage->write('id', 'data'); - $storage->close(); - - $storage->open('', 'sid'); - $storage->read('gc_id'); - false === headers_sent() && ini_set('session.gc_maxlifetime', -1); // test that you can set lifetime of a session after it has been read - $storage->write('gc_id', 'data'); - $storage->close(); - $this->assertEquals(2, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn(), 'No session pruned because gc not called'); - true === headers_sent() && $storage->destroy('gc_id'); - - $storage->open('', 'sid'); - $data = $storage->read('gc_id'); - $storage->gc(-1); - $storage->close(); - - false === headers_sent() && ini_set('session.gc_maxlifetime', $previousLifeTime); $this->assertSame('', $data, 'Session already considered garbage, so not returning data even if it is not pruned yet'); $this->assertEquals(1, $pdo->query('SELECT COUNT(*) FROM sessions')->fetchColumn(), 'Expired session is pruned'); } diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php index d5281c644d..20f9ca060b 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/NativeSessionStorageTest.php @@ -152,7 +152,7 @@ class NativeSessionStorageTest extends TestCase { $this->iniSet('session.cache_limiter', 'nocache'); - $storage = new NativeSessionStorage(array('cache_limiter' => '')); + $storage = new NativeSessionStorage(); $this->assertEquals('', ini_get('session.cache_limiter')); } diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php index 24f9038f35..1898ee0863 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/LocaleListenerTest.php @@ -38,12 +38,7 @@ class LocaleListenerTest extends TestCase public function testLocaleFromRequestAttribute() { $request = Request::create('/'); - - if (PHP_VERSION_ID < 70200 || !headers_sent()) { - session_name('foo'); - } - - $request->cookies->set('foo', 'value'); + $request->cookies->set(session_name(), 'value'); $request->attributes->set('_locale', 'es'); $listener = new LocaleListener('fr', null, $this->requestStack); diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php index 63d5338182..47ee153342 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/TestSessionListenerTest.php @@ -62,8 +62,7 @@ class TestSessionListenerTest extends TestCase { $this->sessionHasBeenStarted(); - $params = session_get_cookie_params(); - // session_set_cookie_params(0, $params['path'], $params['domain'], $params['secure'], $params['httponly']); + @ini_set('session.cookie_lifetime', 0); $response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST); $cookies = $response->headers->getCookies(); diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index 6b6ec3f17b..1b6b096a8a 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=5.3.9", "symfony/event-dispatcher": "^2.6.7", - "symfony/http-foundation": "~2.7.20|^2.8.13", + "symfony/http-foundation": "~2.7.36|^2.8.29", "symfony/debug": "^2.6.2", "psr/log": "~1.0" }, diff --git a/src/Symfony/Component/Routing/Tests/Fixtures/validresource.php b/src/Symfony/Component/Routing/Tests/Fixtures/validresource.php index 482c80b29e..f59a234d65 100644 --- a/src/Symfony/Component/Routing/Tests/Fixtures/validresource.php +++ b/src/Symfony/Component/Routing/Tests/Fixtures/validresource.php @@ -1,5 +1,8 @@ import('validpattern.php'); diff --git a/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php b/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php index 869f14f82e..d7931c09b2 100644 --- a/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php +++ b/src/Symfony/Component/Security/Csrf/Tests/TokenStorage/NativeSessionTokenStorageTest.php @@ -29,16 +29,6 @@ class NativeSessionTokenStorageTest extends TestCase */ private $storage; - public static function setUpBeforeClass() - { - if (\PHP_VERSION_ID < 70200) { - ini_set('session.save_handler', 'files'); - ini_set('session.save_path', sys_get_temp_dir()); - } - - parent::setUpBeforeClass(); - } - protected function setUp() { $_SESSION = array();