Skip to content

Commit

Permalink
Merge branch '4.0' into 4.1
Browse files Browse the repository at this point in the history
* 4.0:
  [HttpKernel] Fixed invalid REMOTE_ADDR in inline subrequest when configuring trusted proxy with subnet
  [FrameworkBundle] fixed guard event names for transitions
  [DI] Improve class named servics error message
  [HttpFoundation] fixed using _method parameter with invalid type
  [Intl] Replace svn with git in the icu data update script
  [HttpFoundation] Fix Cookie::isCleared
  • Loading branch information
nicolas-grekas committed Aug 1, 2018
2 parents 329d3f7 + e0ce427 commit 1d3f835
Show file tree
Hide file tree
Showing 17 changed files with 306 additions and 270 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,9 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
$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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ public function process(ContainerBuilder $container)
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 '
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,30 @@ public function testNoClassFromGlobalNamespaceClassId()
$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.
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/HttpFoundation/Cookie.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ public function isHttpOnly()
*/
public function isCleared()
{
return $this->expire < time();
return 0 !== $this->expire && $this->expire < time();
}

/**
Expand Down
5 changes: 4 additions & 1 deletion src/Symfony/Component/HttpFoundation/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,10 @@ public function getMethod()
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);
}
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions src/Symfony/Component/HttpFoundation/Tests/CookieTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,18 @@ public function testCookieIsCleared()
$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()
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,11 @@ public function testGetSetMethod()
$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');
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ protected function createSubRequest($uri, Request $request)
$server['HTTP_X_FORWARDED_FOR'] = ($currentXForwardedFor ? $currentXForwardedFor.', ' : '').$request->getClientIp();
}

$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']);
Expand All @@ -136,6 +135,17 @@ protected function createSubRequest($uri, Request $request)
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}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,25 @@ public function testFirstTrustedProxyIsSetAsRemote()
Request::setTrustedProxies(array(), -1);
}

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'), -1);

$strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));

$request = Request::create('/');
$request->headers->set('Surrogate-Capability', 'abc="ESI/1.0"');
$strategy->render('/', $request);

Request::setTrustedProxies(array(), -1);
}

/**
* Creates a Kernel expecting a request equals to $request
* Allows delta in comparison in case REQUEST_TIME changed by 1 second.
Expand Down
20 changes: 0 additions & 20 deletions src/Symfony/Component/Intl/Resources/bin/icu.ini

This file was deleted.

65 changes: 29 additions & 36 deletions src/Symfony/Component/Intl/Resources/bin/update-data.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
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';
Expand All @@ -40,7 +39,7 @@
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
Expand All @@ -64,36 +63,30 @@
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";
if ($argc >= 2) {
$repoDir = $argv[1];
$git = new GitRepository($repoDir);

$maxVersion = 0;
echo "Using the existing git repository at {$repoDir}.\n";
} else {
echo "Starting git clone. This may take a while...\n";

foreach ($urls as $urlVersion => $url) {
$maxVersion = IcuVersion::compare($maxVersion, $urlVersion, '<')
? $urlVersion
: $maxVersion;
$repoDir = sys_get_temp_dir().'/icu-data';
$git = GitRepository::download('https://github.com/unicode-org/icu.git', $repoDir);

echo " $urlVersion\n";
echo "Git clone to {$repoDir} complete.\n";
}

$shortIcuVersion = strip_minor_versions($maxVersion);

if ($argc >= 2) {
$sourceDir = $argv[1];
$svn = new SvnRepository($sourceDir);

echo "Using existing SVN repository at {$sourceDir}.\n";
} else {
echo "Starting SVN checkout for version $shortIcuVersion. This may take a while...\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));

$sourceDir = sys_get_temp_dir().'/icu-data/'.$shortIcuVersion.'/source';
$svn = SvnRepository::download($urls[$shortIcuVersion], $sourceDir);
echo "Checking out `{$gitTag}` for version `{$shortIcuVersion}`...\n";
$git->checkout('tags/'.$gitTag);

echo "SVN checkout to {$sourceDir} complete.\n";
}
$filesystem = new Filesystem();
$sourceDir = $repoDir.'/icu4c/source';

if ($argc >= 3) {
$buildDir = $argv[2];
Expand Down Expand Up @@ -265,23 +258,23 @@

echo "Resource bundle compilation complete.\n";

$svnInfo = <<<SVN_INFO
SVN information
$gitInfo = <<<GIT_INFO
Git information
===============
URL: {$svn->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';

Expand Down
7 changes: 7 additions & 0 deletions src/Symfony/Component/Intl/Resources/data/git-info.txt
Original file line number Diff line number Diff line change
@@ -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
7 changes: 0 additions & 7 deletions src/Symfony/Component/Intl/Resources/data/svn-info.txt

This file was deleted.

73 changes: 73 additions & 0 deletions src/Symfony/Component/Intl/Tests/Util/GitRepositoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?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\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());
}
}

0 comments on commit 1d3f835

Please sign in to comment.