From d3d7766874309f60249f3b0f72518d3149431cd0 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Mon, 23 Jul 2018 20:55:22 +0200 Subject: [PATCH 1/6] [HttpFoundation] Fix Cookie::isCleared --- src/Symfony/Component/HttpFoundation/Cookie.php | 2 +- .../Component/HttpFoundation/Tests/CookieTest.php | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Cookie.php b/src/Symfony/Component/HttpFoundation/Cookie.php index 93bb099cd5..d31f087704 100644 --- a/src/Symfony/Component/HttpFoundation/Cookie.php +++ b/src/Symfony/Component/HttpFoundation/Cookie.php @@ -183,6 +183,6 @@ class Cookie */ public function isCleared() { - return $this->expire < time(); + return 0 !== $this->expire && $this->expire < time(); } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php index 2d9fb09d3d..e10ee18c26 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/CookieTest.php @@ -153,6 +153,18 @@ class CookieTest extends TestCase $cookie = new Cookie('foo', 'bar', time() - 20); $this->assertTrue($cookie->isCleared(), '->isCleared() returns true if the cookie has expired'); + + $cookie = new Cookie('foo', 'bar'); + + $this->assertFalse($cookie->isCleared()); + + $cookie = new Cookie('foo', 'bar', 0); + + $this->assertFalse($cookie->isCleared()); + + $cookie = new Cookie('foo', 'bar', -1); + + $this->assertFalse($cookie->isCleared()); } public function testToString() From ebdf972e49c3596447b8b724df7f33bd60b1be6f Mon Sep 17 00:00:00 2001 From: Jakub Zalas Date: Thu, 26 Jul 2018 16:51:50 +0100 Subject: [PATCH 2/6] [Intl] Replace svn with git in the icu data update script --- .../Component/Intl/Resources/bin/icu.ini | 20 --- .../Intl/Resources/bin/update-data.php | 67 ++++----- .../Intl/Resources/data/git-info.txt | 7 + .../Intl/Resources/data/svn-info.txt | 7 - .../Intl/Tests/Util/GitRepositoryTest.php | 73 +++++++++ .../Component/Intl/Util/GitRepository.php | 117 +++++++++++++++ src/Symfony/Component/Intl/Util/SvnCommit.php | 62 -------- .../Component/Intl/Util/SvnRepository.php | 140 ------------------ 8 files changed, 227 insertions(+), 266 deletions(-) delete mode 100644 src/Symfony/Component/Intl/Resources/bin/icu.ini create mode 100644 src/Symfony/Component/Intl/Resources/data/git-info.txt delete mode 100644 src/Symfony/Component/Intl/Resources/data/svn-info.txt create mode 100644 src/Symfony/Component/Intl/Tests/Util/GitRepositoryTest.php create mode 100644 src/Symfony/Component/Intl/Util/GitRepository.php delete mode 100644 src/Symfony/Component/Intl/Util/SvnCommit.php delete mode 100644 src/Symfony/Component/Intl/Util/SvnRepository.php diff --git a/src/Symfony/Component/Intl/Resources/bin/icu.ini b/src/Symfony/Component/Intl/Resources/bin/icu.ini deleted file mode 100644 index 9845e0bb1a..0000000000 --- a/src/Symfony/Component/Intl/Resources/bin/icu.ini +++ /dev/null @@ -1,20 +0,0 @@ -; ICU data source URLs -; We use always the latest release of a major version. -4.0 = http://source.icu-project.org/repos/icu/icu/tags/release-4-0-1/source -4.2 = http://source.icu-project.org/repos/icu/icu/tags/release-4-2-1/source -4.4 = http://source.icu-project.org/repos/icu/icu/tags/release-4-4-2/source -4.6 = http://source.icu-project.org/repos/icu/icu/tags/release-4-6-1/source -4.8 = http://source.icu-project.org/repos/icu/icu/tags/release-4-8-1-1/source -49 = http://source.icu-project.org/repos/icu/icu/tags/release-49-1-2/source -50 = http://source.icu-project.org/repos/icu/icu/tags/release-50-1-2/source -51 = http://source.icu-project.org/repos/icu/icu/tags/release-51-2/source -52 = http://source.icu-project.org/repos/icu/icu/tags/release-52-1/source -53 = http://source.icu-project.org/repos/icu/icu/tags/release-53-1/source -54 = http://source.icu-project.org/repos/icu/icu/tags/release-54-1/source -55 = http://source.icu-project.org/repos/icu/icu/tags/release-55-1/source -57 = http://source.icu-project.org/repos/icu/icu/tags/release-57-1/source -58 = http://source.icu-project.org/repos/icu/tags/release-58-2/icu4c/source -59 = http://source.icu-project.org/repos/icu/tags/release-59-1/icu4c/source -60 = http://source.icu-project.org/repos/icu/tags/release-60-2/icu4c/source -61 = http://source.icu-project.org/repos/icu/tags/release-61-1/icu4c/source -62 = http://source.icu-project.org/repos/icu/tags/release-62-1/icu4c/source diff --git a/src/Symfony/Component/Intl/Resources/bin/update-data.php b/src/Symfony/Component/Intl/Resources/bin/update-data.php index 80a34fe152..7238f46880 100644 --- a/src/Symfony/Component/Intl/Resources/bin/update-data.php +++ b/src/Symfony/Component/Intl/Resources/bin/update-data.php @@ -25,8 +25,7 @@ use Symfony\Component\Intl\Data\Provider\RegionDataProvider; use Symfony\Component\Intl\Data\Provider\ScriptDataProvider; use Symfony\Component\Intl\Intl; use Symfony\Component\Intl\Locale; -use Symfony\Component\Intl\Util\IcuVersion; -use Symfony\Component\Intl\Util\SvnRepository; +use Symfony\Component\Intl\Util\GitRepository; require_once __DIR__.'/common.php'; require_once __DIR__.'/autoload.php'; @@ -40,7 +39,7 @@ Usage: php update-data.php Updates the ICU data for Symfony to the latest version of ICU. -If you downloaded the SVN repository before, you can pass the path to the +If you downloaded the git repository before, you can pass the path to the repository source in the first optional argument. If you also built the repository before, you can pass the directory where that @@ -64,37 +63,31 @@ if (!Intl::isExtensionLoaded()) { bailout('The intl extension for PHP is not installed.'); } -$filesystem = new Filesystem(); -$urls = parse_ini_file(__DIR__.'/icu.ini'); - -echo "icu.ini parsed. Available versions:\n"; - -$maxVersion = 0; - -foreach ($urls as $urlVersion => $url) { - $maxVersion = IcuVersion::compare($maxVersion, $urlVersion, '<') - ? $urlVersion - : $maxVersion; - - echo " $urlVersion\n"; -} - -$shortIcuVersion = strip_minor_versions($maxVersion); - if ($argc >= 2) { - $sourceDir = $argv[1]; - $svn = new SvnRepository($sourceDir); + $repoDir = $argv[1]; + $git = new GitRepository($repoDir); - echo "Using existing SVN repository at {$sourceDir}.\n"; + echo "Using the existing git repository at {$repoDir}.\n"; } else { - echo "Starting SVN checkout for version $shortIcuVersion. This may take a while...\n"; + echo "Starting git clone. This may take a while...\n"; - $sourceDir = sys_get_temp_dir().'/icu-data/'.$shortIcuVersion.'/source'; - $svn = SvnRepository::download($urls[$shortIcuVersion], $sourceDir); + $repoDir = sys_get_temp_dir().'/icu-data'; + $git = GitRepository::download('https://github.com/unicode-org/icu.git', $repoDir); - echo "SVN checkout to {$sourceDir} complete.\n"; + echo "Git clone to {$repoDir} complete.\n"; } +$gitTag = $git->getLastTag(function ($tag) { + return preg_match('#^release-[0-9]{1,}-[0-9]{1}$#', $tag); +}); +$shortIcuVersion = strip_minor_versions(preg_replace('#release-([0-9]{1,})-([0-9]{1,})#', '$1.$2', $gitTag)); + +echo "Checking out `{$gitTag}` for version `{$shortIcuVersion}`...\n"; +$git->checkout('tags/'.$gitTag); + +$filesystem = new Filesystem(); +$sourceDir = $repoDir.'/icu4c/source'; + if ($argc >= 3) { $buildDir = $argv[2]; } else { @@ -265,23 +258,23 @@ $generator->generateData($config); echo "Resource bundle compilation complete.\n"; -$svnInfo = <<getUrl()} -Revision: {$svn->getLastCommit()->getRevision()} -Author: {$svn->getLastCommit()->getAuthor()} -Date: {$svn->getLastCommit()->getDate()} +URL: {$git->getUrl()} +Revision: {$git->getLastCommitHash()} +Author: {$git->getLastAuthor()} +Date: {$git->getLastAuthoredDate()->format('c')} -SVN_INFO; +GIT_INFO; foreach ($targetDirs as $targetDir) { - $svnInfoFile = $targetDir.'/svn-info.txt'; + $gitInfoFile = $targetDir.'/git-info.txt'; - file_put_contents($svnInfoFile, $svnInfo); + file_put_contents($gitInfoFile, $gitInfo); - echo "Wrote $svnInfoFile.\n"; + echo "Wrote $gitInfoFile.\n"; $versionFile = $targetDir.'/version.txt'; diff --git a/src/Symfony/Component/Intl/Resources/data/git-info.txt b/src/Symfony/Component/Intl/Resources/data/git-info.txt new file mode 100644 index 0000000000..fe7ce33232 --- /dev/null +++ b/src/Symfony/Component/Intl/Resources/data/git-info.txt @@ -0,0 +1,7 @@ +Git information +=============== + +URL: https://github.com/unicode-org/icu.git +Revision: 4a3ba8eee90ea1414d4f7ee36563e6c9b28fda96 +Author: Yoshito Umaoka +Date: 2018-06-20T05:34:56+00:00 diff --git a/src/Symfony/Component/Intl/Resources/data/svn-info.txt b/src/Symfony/Component/Intl/Resources/data/svn-info.txt deleted file mode 100644 index 556c6cf358..0000000000 --- a/src/Symfony/Component/Intl/Resources/data/svn-info.txt +++ /dev/null @@ -1,7 +0,0 @@ -SVN information -=============== - -URL: http://source.icu-project.org/repos/icu/tags/release-62-1/icu4c/source -Revision: 41542 -Author: yoshito -Date: 2018-06-20T05:34:56.496986Z diff --git a/src/Symfony/Component/Intl/Tests/Util/GitRepositoryTest.php b/src/Symfony/Component/Intl/Tests/Util/GitRepositoryTest.php new file mode 100644 index 0000000000..a9eb531907 --- /dev/null +++ b/src/Symfony/Component/Intl/Tests/Util/GitRepositoryTest.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Tests\Util; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Intl\Util\GitRepository; + +/** + * @group intl-data + */ +class GitRepositoryTest extends TestCase +{ + private $targetDir; + + const REPO_URL = 'https://github.com/symfony/intl.git'; + + /** + * @before + * @after + */ + protected function cleanup() + { + $this->targetDir = sys_get_temp_dir().'/GitRepositoryTest/source'; + + $fs = new Filesystem(); + $fs->remove($this->targetDir); + } + + public function testItThrowsAnExceptionIfInitialisedWithNonGitDirectory() + { + $this->expectException('Symfony\Component\Intl\Exception\RuntimeException'); + + @mkdir($this->targetDir, '0777', true); + + new GitRepository($this->targetDir); + } + + public function testItClonesTheRepository() + { + $git = GitRepository::download(self::REPO_URL, $this->targetDir); + + $this->assertInstanceOf('Symfony\Component\Intl\Util\GitRepository', $git); + $this->assertDirectoryExists($this->targetDir.'/.git'); + $this->assertSame($this->targetDir, $git->getPath()); + $this->assertSame(self::REPO_URL, $git->getUrl()); + $this->assertRegExp('#^[0-9a-z]{40}$#', $git->getLastCommitHash()); + $this->assertNotEmpty($git->getLastAuthor()); + $this->assertInstanceOf('DateTime', $git->getLastAuthoredDate()); + $this->assertStringMatchesFormat('v%s', $git->getLastTag()); + $this->assertStringMatchesFormat('v3%s', $git->getLastTag(function ($tag) { return 0 === strpos($tag, 'v3'); })); + } + + public function testItCheckoutsToTheLastTag() + { + $git = GitRepository::download(self::REPO_URL, $this->targetDir); + $lastCommitHash = $git->getLastCommitHash(); + $lastV3Tag = $git->getLastTag(function ($tag) { return 0 === strpos($tag, 'v3'); }); + + $git->checkout($lastV3Tag); + + $this->assertNotEquals($lastCommitHash, $git->getLastCommitHash()); + } +} diff --git a/src/Symfony/Component/Intl/Util/GitRepository.php b/src/Symfony/Component/Intl/Util/GitRepository.php new file mode 100644 index 0000000000..35020c6706 --- /dev/null +++ b/src/Symfony/Component/Intl/Util/GitRepository.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Intl\Util; + +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Intl\Exception\RuntimeException; + +/** + * @internal + */ +final class GitRepository +{ + private $path; + + /** + * @param string $path + */ + public function __construct($path) + { + $this->path = $path; + + $this->getUrl(); + } + + /** + * @param string $remote + * @param string $targetDir + * + * @return GitRepository + */ + public static function download($remote, $targetDir) + { + self::exec('which git', 'The command "git" is not installed.'); + + $filesystem = new Filesystem(); + + if (!$filesystem->exists($targetDir.'/.git')) { + $filesystem->remove($targetDir); + $filesystem->mkdir($targetDir); + + self::exec(sprintf('git clone %s %s', escapeshellarg($remote), escapeshellarg($targetDir))); + } + + return new self(realpath($targetDir)); + } + + public function getPath() + { + return $this->path; + } + + public function getUrl() + { + return $this->getLastLine($this->execInPath('git config --get remote.origin.url')); + } + + public function getLastCommitHash() + { + return $this->getLastLine($this->execInPath('git log -1 --format="%H"')); + } + + public function getLastAuthor() + { + return $this->getLastLine($this->execInPath('git log -1 --format="%an"')); + } + + public function getLastAuthoredDate() + { + return new \DateTime($this->getLastLine($this->execInPath('git log -1 --format="%ai"'))); + } + + public function getLastTag(callable $filter = null) + { + $tags = $this->execInPath('git tag -l --sort=v:refname'); + + if (null !== $filter) { + $tags = array_filter($tags, $filter); + } + + return $this->getLastLine($tags); + } + + public function checkout($branch) + { + $this->execInPath(sprintf('git checkout %s', escapeshellarg($branch))); + } + + private function execInPath($command) + { + return self::exec(sprintf('cd %s && %s', escapeshellarg($this->path), $command)); + } + + private static function exec($command, $customErrorMessage = null) + { + exec(sprintf('%s 2>&1', $command), $output, $result); + + if (0 !== $result) { + throw new RuntimeException(null !== $customErrorMessage ? $customErrorMessage : sprintf('The `%s` command failed.', $command)); + } + + return $output; + } + + private function getLastLine(array $output) + { + return array_pop($output); + } +} diff --git a/src/Symfony/Component/Intl/Util/SvnCommit.php b/src/Symfony/Component/Intl/Util/SvnCommit.php deleted file mode 100644 index f83958fe38..0000000000 --- a/src/Symfony/Component/Intl/Util/SvnCommit.php +++ /dev/null @@ -1,62 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Intl\Util; - -/** - * An SVN commit. - * - * @author Bernhard Schussek - */ -class SvnCommit -{ - private $svnInfo; - - /** - * Creates a commit from the given "svn info" data. - * - * @param \SimpleXMLElement $svnInfo the XML result from the "svn info" command - */ - public function __construct(\SimpleXMLElement $svnInfo) - { - $this->svnInfo = $svnInfo; - } - - /** - * Returns the revision of the commit. - * - * @return string The revision of the commit - */ - public function getRevision() - { - return (string) $this->svnInfo['revision']; - } - - /** - * Returns the author of the commit. - * - * @return string The author name - */ - public function getAuthor() - { - return (string) $this->svnInfo->author; - } - - /** - * Returns the date of the commit. - * - * @return string The commit date - */ - public function getDate() - { - return (string) $this->svnInfo->date; - } -} diff --git a/src/Symfony/Component/Intl/Util/SvnRepository.php b/src/Symfony/Component/Intl/Util/SvnRepository.php deleted file mode 100644 index 9716a5425e..0000000000 --- a/src/Symfony/Component/Intl/Util/SvnRepository.php +++ /dev/null @@ -1,140 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Intl\Util; - -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\Intl\Exception\RuntimeException; - -/** - * A SVN repository containing ICU data. - * - * @author Bernhard Schussek - */ -class SvnRepository -{ - /** - * @var string The path to the repository - */ - private $path; - - /** - * @var \SimpleXMLElement - */ - private $svnInfo; - - /** - * @var SvnCommit - */ - private $lastCommit; - - /** - * Downloads the ICU data for the given version. - * - * @param string $url The URL to download from - * @param string $targetDir The directory in which to store the repository - * - * @return static - * - * @throws RuntimeException if an error occurs during the download - */ - public static function download($url, $targetDir) - { - exec('which svn', $output, $result); - - if (0 !== $result) { - throw new RuntimeException('The command "svn" is not installed.'); - } - - $filesystem = new Filesystem(); - - if (!$filesystem->exists($targetDir.'/.svn')) { - $filesystem->remove($targetDir); - $filesystem->mkdir($targetDir); - - exec('svn checkout '.$url.' '.$targetDir, $output, $result); - - if (0 !== $result) { - throw new RuntimeException('The SVN checkout of '.$url.'failed.'); - } - } - - return new static(realpath($targetDir)); - } - - /** - * Reads the SVN repository at the given path. - * - * @param string $path The path to the repository - */ - public function __construct($path) - { - $this->path = $path; - } - - /** - * Returns the path to the repository. - * - * @return string The path to the repository - */ - public function getPath() - { - return $this->path; - } - - /** - * Returns the URL of the repository. - * - * @return string The URL of the repository - */ - public function getUrl() - { - return (string) $this->getSvnInfo()->entry->url; - } - - /** - * Returns the last commit of the repository. - * - * @return SvnCommit The last commit - */ - public function getLastCommit() - { - if (null === $this->lastCommit) { - $this->lastCommit = new SvnCommit($this->getSvnInfo()->entry->commit); - } - - return $this->lastCommit; - } - - /** - * Returns information about the SVN repository. - * - * @return \SimpleXMLElement The XML result from the "svn info" command - * - * @throws RuntimeException if the "svn info" command failed - */ - private function getSvnInfo() - { - if (null === $this->svnInfo) { - exec('svn info --xml '.$this->path, $output, $result); - - $svnInfo = simplexml_load_string(implode("\n", $output)); - - if (0 !== $result) { - throw new RuntimeException('svn info failed'); - } - - $this->svnInfo = $svnInfo; - } - - return $this->svnInfo; - } -} From 63583debd20817f55f67e11224f61618abb9835d Mon Sep 17 00:00:00 2001 From: Phobetor Date: Fri, 27 Jul 2018 16:18:31 +0200 Subject: [PATCH 3/6] [HttpFoundation] fixed using _method parameter with invalid type --- src/Symfony/Component/HttpFoundation/Request.php | 5 ++++- src/Symfony/Component/HttpFoundation/Tests/RequestTest.php | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Request.php b/src/Symfony/Component/HttpFoundation/Request.php index e8dfa452c7..4e9f99a05b 100644 --- a/src/Symfony/Component/HttpFoundation/Request.php +++ b/src/Symfony/Component/HttpFoundation/Request.php @@ -1276,7 +1276,10 @@ class Request if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) { $this->method = strtoupper($method); } elseif (self::$httpMethodParameterOverride) { - $this->method = strtoupper($this->request->get('_method', $this->query->get('_method', 'POST'))); + $method = $this->request->get('_method', $this->query->get('_method', 'POST')); + if (\is_string($method)) { + $this->method = strtoupper($method); + } } } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php index eca3048f91..65687cf391 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/RequestTest.php @@ -816,6 +816,11 @@ class RequestTest extends TestCase $request->setMethod('POST'); $request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete'); $this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override if defined and POST'); + + $request = new Request(); + $request->setMethod('POST'); + $request->query->set('_method', array('delete', 'patch')); + $this->assertSame('POST', $request->getMethod(), '->getMethod() returns the request method if invalid type is defined in query'); } /** From 61de0601a141000ef8796a0c69c8f1da49a044e8 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Wed, 25 Jul 2018 12:20:49 +0200 Subject: [PATCH 4/6] [DI] Improve class named servics error message --- .../Compiler/CheckDefinitionValidityPass.php | 9 +++++++ .../Tests/ContainerBuilderTest.php | 24 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php index d7d44d90ce..6f70352b25 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php @@ -48,6 +48,15 @@ class CheckDefinitionValidityPass implements CompilerPassInterface throw new RuntimeException(sprintf('Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.', $id)); } if (class_exists($id) || interface_exists($id, false)) { + if (0 === strpos($id, '\\') && 1 < substr_count($id, '\\')) { + throw new RuntimeException(sprintf( + 'The definition for "%s" has no class attribute, and appears to reference a class or interface. ' + .'Please specify the class attribute explicitly or remove the leading backslash by renaming ' + .'the service to "%s" to get rid of this error.', + $id, substr($id, 1) + )); + } + throw new RuntimeException(sprintf( 'The definition for "%s" has no class attribute, and appears to reference a ' .'class or interface in the global namespace. Leaving out the "class" attribute ' diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index d8e7203028..2534def00b 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -1264,6 +1264,30 @@ class ContainerBuilderTest extends TestCase $container->compile(); } + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException + * @expectedExceptionMessage The definition for "\DateTime" has no class attribute, and appears to reference a class or interface in the global namespace. + */ + public function testNoClassFromGlobalNamespaceClassIdWithLeadingSlash() + { + $container = new ContainerBuilder(); + + $container->register('\\'.\DateTime::class); + $container->compile(); + } + + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException + * @expectedExceptionMessage The definition for "\Symfony\Component\DependencyInjection\Tests\FooClass" has no class attribute, and appears to reference a class or interface. Please specify the class attribute explicitly or remove the leading backslash by renaming the service to "Symfony\Component\DependencyInjection\Tests\FooClass" to get rid of this error. + */ + public function testNoClassFromNamespaceClassIdWithLeadingSlash() + { + $container = new ContainerBuilder(); + + $container->register('\\'.FooClass::class); + $container->compile(); + } + /** * @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException * @expectedExceptionMessage The definition for "123_abc" has no class. From 9bbb1e5cff04b2c876b176333e9d5aa8aa5db38e Mon Sep 17 00:00:00 2001 From: Ivan Nikolaev Date: Thu, 19 Jul 2018 20:09:12 +0300 Subject: [PATCH 5/6] [FrameworkBundle] fixed guard event names for transitions --- .../DependencyInjection/FrameworkExtension.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index f1deb1e512..df71e3bf04 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -679,7 +679,9 @@ class FrameworkExtension extends Extension $guard = new Definition(Workflow\EventListener\GuardListener::class); $guard->setPrivate(true); $configuration = array(); - foreach ($workflow['transitions'] as $transitionName => $config) { + foreach ($workflow['transitions'] as $config) { + $transitionName = $config['name']; + if (!isset($config['guard'])) { continue; } From f657dd2444a5604148f3ed8dd3ee1181352c7d9b Mon Sep 17 00:00:00 2001 From: Zacharias Luiten Date: Thu, 19 Jul 2018 15:02:57 +0200 Subject: [PATCH 6/6] [HttpKernel] Fixed invalid REMOTE_ADDR in inline subrequest when configuring trusted proxy with subnet --- .../Fragment/InlineFragmentRenderer.php | 14 ++++++++++++-- .../Fragment/InlineFragmentRendererTest.php | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php index d7d2e55a9e..31cfb0de09 100644 --- a/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php +++ b/src/Symfony/Component/HttpKernel/Fragment/InlineFragmentRenderer.php @@ -122,8 +122,7 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer // Do nothing } - $trustedProxies = Request::getTrustedProxies(); - $server['REMOTE_ADDR'] = $trustedProxies ? reset($trustedProxies) : '127.0.0.1'; + $server['REMOTE_ADDR'] = $this->resolveTrustedProxy(); unset($server['HTTP_IF_MODIFIED_SINCE']); unset($server['HTTP_IF_NONE_MATCH']); @@ -140,6 +139,17 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer return $subRequest; } + private function resolveTrustedProxy() + { + if (!$trustedProxies = Request::getTrustedProxies()) { + return '127.0.0.1'; + } + + $firstTrustedProxy = reset($trustedProxies); + + return false !== ($i = strpos($firstTrustedProxy, '/')) ? substr($firstTrustedProxy, 0, $i) : $firstTrustedProxy; + } + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php index bb56536c58..481dcc7f4b 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php @@ -226,6 +226,25 @@ class InlineFragmentRendererTest extends TestCase Request::setTrustedProxies(array()); } + public function testIpAddressOfRangedTrustedProxyIsSetAsRemote() + { + $expectedSubRequest = Request::create('/'); + $expectedSubRequest->headers->set('Surrogate-Capability', 'abc="ESI/1.0"'); + $expectedSubRequest->server->set('REMOTE_ADDR', '1.1.1.1'); + $expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1')); + $expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1'); + + Request::setTrustedProxies(array('1.1.1.1/24')); + + $strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest)); + + $request = Request::create('/'); + $request->headers->set('Surrogate-Capability', 'abc="ESI/1.0"'); + $strategy->render('/', $request); + + Request::setTrustedProxies(array()); + } + /** * Creates a Kernel expecting a request equals to $request * Allows delta in comparison in case REQUEST_TIME changed by 1 second.