Merge branch '3.4' into 4.2
* 3.4: [github] Implement the new security policy. [Finder] fix wrong method call casing Make tempfile path unique minor: fix phpdocs in the ldap component [Process] Fix infinite waiting for stopped process Use absolute URL for when the profiler's domain differs from the controller's domain which initialises the profiler. fix phpdoc [DI] fix using bindings with locators of service subscribers
This commit is contained in:
commit
81f6f3b6d2
10
.github/SECURITY.md
vendored
Normal file
10
.github/SECURITY.md
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Security Policy
|
||||||
|
===============
|
||||||
|
|
||||||
|
If you found any issues that might have security implications,
|
||||||
|
please send a report to security[at]symfony.com
|
||||||
|
DO NOT PUBLISH SECURITY REPORTS PUBLICLY.
|
||||||
|
|
||||||
|
The full [Security Policy][1] is described in the official documentation.
|
||||||
|
|
||||||
|
[1]: https://symfony.com/security
|
@ -146,7 +146,7 @@ class ProfilerController
|
|||||||
|
|
||||||
$url = null;
|
$url = null;
|
||||||
try {
|
try {
|
||||||
$url = $this->generator->generate('_profiler', ['token' => $token]);
|
$url = $this->generator->generate('_profiler', ['token' => $token], UrlGeneratorInterface::ABSOLUTE_URL);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
// the profiler is not enabled
|
// the profiler is not enabled
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div class="sf-toolbar-block sf-toolbar-block-{{ name }} sf-toolbar-status-{{ status|default('normal') }} {{ additional_classes|default('') }}" {{ block_attrs|default('')|raw }}>
|
<div class="sf-toolbar-block sf-toolbar-block-{{ name }} sf-toolbar-status-{{ status|default('normal') }} {{ additional_classes|default('') }}" {{ block_attrs|default('')|raw }}>
|
||||||
{% if link is not defined or link %}<a href="{{ path('_profiler', { token: token, panel: name }) }}">{% endif %}
|
{% if link is not defined or link %}<a href="{{ url('_profiler', { token: token, panel: name }) }}">{% endif %}
|
||||||
<div class="sf-toolbar-icon">{{ icon|default('') }}</div>
|
<div class="sf-toolbar-icon">{{ icon|default('') }}</div>
|
||||||
{% if link|default(false) %}</a>{% endif %}
|
{% if link|default(false) %}</a>{% endif %}
|
||||||
<div class="sf-toolbar-info">{{ text|default('') }}</div>
|
<div class="sf-toolbar-info">{{ text|default('') }}</div>
|
||||||
|
@ -101,7 +101,11 @@ final class ServiceLocatorTagPass extends AbstractRecursivePass
|
|||||||
->setPublic(false)
|
->setPublic(false)
|
||||||
->addTag('container.service_locator');
|
->addTag('container.service_locator');
|
||||||
|
|
||||||
if (!$container->has($id = '.service_locator.'.ContainerBuilder::hash($locator))) {
|
if (null !== $callerId && $container->hasDefinition($callerId)) {
|
||||||
|
$locator->setBindings($container->getDefinition($callerId)->getBindings());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$container->hasDefinition($id = '.service_locator.'.ContainerBuilder::hash($locator))) {
|
||||||
$container->setDefinition($id, $locator);
|
$container->setDefinition($id, $locator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
|
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||||
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
|
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
@ -128,4 +129,19 @@ class ServiceLocatorTagPassTest extends TestCase
|
|||||||
|
|
||||||
$this->assertSame(TestDefinition1::class, \get_class($locator('bar')));
|
$this->assertSame(TestDefinition1::class, \get_class($locator('bar')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testBindingsAreCopied()
|
||||||
|
{
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
|
||||||
|
$container->register('foo')
|
||||||
|
->setBindings(['foo' => 'foo']);
|
||||||
|
|
||||||
|
$locator = ServiceLocatorTagPass::register($container, ['foo' => new Reference('foo')], 'foo');
|
||||||
|
$locator = $container->getDefinition($locator);
|
||||||
|
$locator = $container->getDefinition($locator->getFactory()[0]);
|
||||||
|
|
||||||
|
$this->assertSame(['foo'], array_keys($locator->getBindings()));
|
||||||
|
$this->assertInstanceOf(BoundArgument::class, $locator->getBindings()['foo']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ class SortableIterator implements \IteratorAggregate
|
|||||||
|
|
||||||
if (self::SORT_BY_NAME === $sort) {
|
if (self::SORT_BY_NAME === $sort) {
|
||||||
$this->sort = function ($a, $b) use ($order) {
|
$this->sort = function ($a, $b) use ($order) {
|
||||||
return $order * strcmp($a->getRealpath() ?: $a->getPathname(), $b->getRealpath() ?: $b->getPathname());
|
return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
|
||||||
};
|
};
|
||||||
} elseif (self::SORT_BY_NAME_NATURAL === $sort) {
|
} elseif (self::SORT_BY_NAME_NATURAL === $sort) {
|
||||||
$this->sort = function ($a, $b) use ($order) {
|
$this->sort = function ($a, $b) use ($order) {
|
||||||
@ -56,7 +56,7 @@ class SortableIterator implements \IteratorAggregate
|
|||||||
return $order;
|
return $order;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $order * strcmp($a->getRealpath() ?: $a->getPathname(), $b->getRealpath() ?: $b->getPathname());
|
return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
|
||||||
};
|
};
|
||||||
} elseif (self::SORT_BY_ACCESSED_TIME === $sort) {
|
} elseif (self::SORT_BY_ACCESSED_TIME === $sort) {
|
||||||
$this->sort = function ($a, $b) use ($order) {
|
$this->sort = function ($a, $b) use ($order) {
|
||||||
|
@ -34,7 +34,7 @@ class LoggerTest extends TestCase
|
|||||||
|
|
||||||
protected function setUp()
|
protected function setUp()
|
||||||
{
|
{
|
||||||
$this->tmpFile = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'log';
|
$this->tmpFile = tempnam(sys_get_temp_dir(), 'log');
|
||||||
$this->logger = new Logger(LogLevel::DEBUG, $this->tmpFile);
|
$this->logger = new Logger(LogLevel::DEBUG, $this->tmpFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
namespace Symfony\Component\Ldap\Exception;
|
namespace Symfony\Component\Ldap\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ConnectionException is throw if binding to ldap can not be established.
|
* ConnectionException is thrown if binding to ldap can not be established.
|
||||||
*
|
*
|
||||||
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
||||||
*/
|
*/
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
namespace Symfony\Component\Ldap\Exception;
|
namespace Symfony\Component\Ldap\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LdapException is throw if php ldap module is not loaded.
|
* LdapException is thrown if php ldap module is not loaded.
|
||||||
*
|
*
|
||||||
* @author Charles Sarrazin <charles@sarraz.in>
|
* @author Charles Sarrazin <charles@sarraz.in>
|
||||||
*/
|
*/
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
namespace Symfony\Component\Ldap\Exception;
|
namespace Symfony\Component\Ldap\Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LdapException is throw if php ldap module is not loaded.
|
* LdapException is thrown if php ldap module is not loaded.
|
||||||
*
|
*
|
||||||
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
||||||
*/
|
*/
|
||||||
|
@ -419,6 +419,7 @@ class Process implements \IteratorAggregate
|
|||||||
} while ($running);
|
} while ($running);
|
||||||
|
|
||||||
while ($this->isRunning()) {
|
while ($this->isRunning()) {
|
||||||
|
$this->checkTimeout();
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
36
src/Symfony/Component/Process/Tests/ErrorProcessInitiator.php
Executable file
36
src/Symfony/Component/Process/Tests/ErrorProcessInitiator.php
Executable file
@ -0,0 +1,36 @@
|
|||||||
|
<?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\Process\Tests;
|
||||||
|
|
||||||
|
use Symfony\Component\Process\Exception\ProcessTimedOutException;
|
||||||
|
use Symfony\Component\Process\Process;
|
||||||
|
|
||||||
|
require \dirname(__DIR__).'/vendor/autoload.php';
|
||||||
|
|
||||||
|
list('e' => $php) = getopt('e:') + ['e' => 'php'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$process = new Process("exec $php -r \"echo 'ready'; trigger_error('error', E_USER_ERROR);\"");
|
||||||
|
$process->start();
|
||||||
|
$process->setTimeout(0.5);
|
||||||
|
while (false === strpos($process->getOutput(), 'ready')) {
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
$process->signal(SIGSTOP);
|
||||||
|
$process->wait();
|
||||||
|
|
||||||
|
return $process->getExitCode();
|
||||||
|
} catch (ProcessTimedOutException $t) {
|
||||||
|
echo $t->getMessage().PHP_EOL;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
@ -1510,6 +1510,25 @@ EOTXT;
|
|||||||
$this->assertSame($env, $p->getEnv());
|
$this->assertSame($env, $p->getEnv());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testWaitStoppedDeadProcess()
|
||||||
|
{
|
||||||
|
$process = $this->getProcess(self::$phpBin.' '.__DIR__.'/ErrorProcessInitiator.php -e '.self::$phpBin);
|
||||||
|
$process->start();
|
||||||
|
$process->setTimeout(2);
|
||||||
|
$process->wait();
|
||||||
|
$this->assertFalse($process->isRunning());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $commandline
|
||||||
|
* @param string|null $cwd
|
||||||
|
* @param array|null $env
|
||||||
|
* @param string|null $input
|
||||||
|
* @param int $timeout
|
||||||
|
* @param array $options
|
||||||
|
*
|
||||||
|
* @return Process
|
||||||
|
*/
|
||||||
private function getProcess($commandline, string $cwd = null, array $env = null, $input = null, ?int $timeout = 60): Process
|
private function getProcess($commandline, string $cwd = null, array $env = null, $input = null, ?int $timeout = 60): Process
|
||||||
{
|
{
|
||||||
if (\is_string($commandline)) {
|
if (\is_string($commandline)) {
|
||||||
|
@ -26,7 +26,7 @@ interface AccessDeniedHandlerInterface
|
|||||||
/**
|
/**
|
||||||
* Handles an access denied failure.
|
* Handles an access denied failure.
|
||||||
*
|
*
|
||||||
* @return Response may return null
|
* @return Response|null
|
||||||
*/
|
*/
|
||||||
public function handle(Request $request, AccessDeniedException $accessDeniedException);
|
public function handle(Request $request, AccessDeniedException $accessDeniedException);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user