Merge branch '4.1'

* 4.1: (22 commits)
  [HttpKernel] Fix restoring trusted proxies in tests
  Update UPGRADE-4.0.md
  [Messenger] Fix suggested enqueue adapter package
  bumped Symfony version to 4.1.1
  updated VERSION for 4.1.0
  updated CHANGELOG for 4.1.0
  Insert correct parameter_bag service in AbstractController
  Revert "feature #26702 Mark ExceptionInterfaces throwable (ostrolucky)"
  CODEOWNERS: some more rules
  removed unneeded comments in tests
  removed unneeded comments in tests
  Change PHPDoc in ResponseHeaderBag::getCookies() to help IDEs
  [HttpKernel] fix registering IDE links
  update UPGRADE-4.1 for feature #26332 Form field help option
  [HttpKernel] Set first trusted proxy as REMOTE_ADDR in InlineFragmentRenderer.
  [Process] Consider \"executable\" suffixes first on Windows
  Triggering RememberMe's loginFail() when token cannot be created
  bumped Symfony version to 4.1.0
  updated VERSION for 4.1.0-BETA3
  updated CHANGELOG for 4.1.0-BETA3
  ...
This commit is contained in:
Nicolas Grekas 2018-05-31 12:18:23 +02:00
commit 5abffbbd07
49 changed files with 359 additions and 106 deletions

13
.github/CODEOWNERS vendored
View File

@ -1,3 +1,9 @@
# Console
/src/Symfony/Component/Console/Logger/ConsoleLogger.php @dunglas
# DependencyInjection
/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @dunglas
# HttpKernel
/src/Symfony/Component/HttpKernel/Log/Logger.php @dunglas
# LDAP
/src/Symfony/Component/Ldap/* @csarrazi
# Lock
@ -5,6 +11,13 @@
# Messenger
/src/Symfony/Bridge/Doctrine/Messenger/* @sroze
/src/Symfony/Component/Messenger/* @sroze
# PropertyInfo
/src/Symfony/Component/PropertyInfo/* @dunglas
/src/Symfony/Bridge/Doctrine/PropertyInfo/* @dunglas
# Serializer
/src/Symfony/Component/Serializer/* @dunglas
# WebLink
/src/Symfony/Component/WebLink/* @dunglas
# Workflow
/src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php @lyrixx
/src/Symfony/Bridge/Twig/Tests/Extension/WorkflowExtensionTest.php @lyrixx

View File

@ -7,6 +7,35 @@ in 4.1 minor versions.
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.1.0...v4.1.1
* 4.1.0 (2018-05-30)
* bug #27420 Revert "feature #26702 Mark ExceptionInterfaces throwable (ostrolucky)" (nicolas-grekas)
* bug #27415 Insert correct parameter_bag service in AbstractController (curry684)
* 4.1.0-BETA3 (2018-05-26)
* bug #27388 [Routing] Account for greediness when merging route patterns (nicolas-grekas)
* bug #27344 [HttpKernel] reset kernel start time on reboot (kiler129)
* bug #27365 [Serializer] Check the value of enable_max_depth if defined (dunglas)
* bug #27358 [PhpUnitBridge] silence some stderr outputs (ostrolucky)
* bug #27366 [DI] never inline lazy services (nicolas-grekas)
* bug #27352 Remove reference to the test container after kernel shutdown (stof)
* bug #27350 [HttpKernel] fix deprecation in AbstractTestSessionListener (alekitto)
* bug #27367 [FrameworkBundle] cleanup generated test container (nicolas-grekas)
* bug #27379 [FrameworkBundle] Fix using test.service_container when Client is rebooted (nicolas-grekas)
* bug #27364 [DI] Fix bad exception on uninitialized references to non-shared services (nicolas-grekas)
* bug #27359 [HttpFoundation] Fix perf issue during MimeTypeGuesser intialization (nicolas-grekas)
* security #cve-2018-11408 [SecurityBundle] Fail if security.http_utils cannot be configured
* security #cve-2018-11406 clear CSRF tokens when the user is logged out
* security #cve-2018-11385 migrating session for UsernamePasswordJsonAuthenticationListener
* security #cve-2018-11385 migrating session for UsernamePasswordJsonAuthenticationListener
* security #cve-2018-11385 Adding session authentication strategy to Guard to avoid session fixation
* security #cve-2018-11385 Adding session strategy to ALL listeners to avoid *any* possible fixation
* security #cve-2018-11386 [HttpFoundation] Break infinite loop in PdoSessionHandler when MySQL is in loose mode
* bug #27341 [WebProfilerBundle] Fixed validator/dump trace CSS (yceruto)
* bug #27337 [FrameworkBundle] fix typo in CacheClearCommand (emilielorenzo)
* bug #27292 [Serializer] Fix and improve constraintViolationListNormalizer's RFC7807 compliance (dunglas)
* 4.1.0-BETA2 (2018-05-21)
* bug #27312 Supress deprecation notices thrown when getting private servies from container in tests (arderyp)

View File

@ -759,6 +759,9 @@ Security
* The `GuardAuthenticatorInterface` interface has been removed.
Use `AuthenticatorInterface` instead.
* When extending `AbstractGuardAuthenticator` getCredentials() cannot return
`null` anymore, return false from `supports()` if no credentials available instead.
SecurityBundle
--------------

View File

@ -64,6 +64,9 @@ Form
}
```
* Added `help` option to the form field. If you have custom Form extension for it, you should remove it.
Also remove it from the custom form theme.
FrameworkBundle
---------------

View File

@ -49,6 +49,8 @@ class WebProcessorTest extends TestCase
$this->assertEquals($server['REQUEST_METHOD'], $record['extra']['http_method']);
$this->assertEquals($server['SERVER_NAME'], $record['extra']['server']);
$this->assertEquals($server['HTTP_REFERER'], $record['extra']['referrer']);
Request::setTrustedProxies(array(), -1);
}
public function testCanBeConstructedWithExtraFields()

View File

@ -13,6 +13,7 @@ namespace Symfony\Bundle\FrameworkBundle\Controller;
use Psr\Container\ContainerInterface;
use Doctrine\Common\Persistence\ManagerRegistry;
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RequestStack;
@ -84,7 +85,7 @@ abstract class AbstractController implements ServiceSubscriberInterface
'form.factory' => '?'.FormFactoryInterface::class,
'security.token_storage' => '?'.TokenStorageInterface::class,
'security.csrf.token_manager' => '?'.CsrfTokenManagerInterface::class,
'parameter_bag' => '?'.ContainerInterface::class,
'parameter_bag' => '?'.ContainerBagInterface::class,
'message_bus' => '?'.MessageBusInterface::class,
);
}

View File

@ -64,9 +64,6 @@ class FrameworkBundle extends Bundle
{
public function boot()
{
if (!ini_get('xdebug.file_link_format') && !get_cfg_var('xdebug.file_link_format')) {
ini_set('xdebug.file_link_format', $this->container->getParameter('debug.file_link_format'));
}
ErrorHandler::register(null, false)->throwAt($this->container->getParameter('debug.error_handler.throw_at'), true);
if ($this->container->getParameter('kernel.http_method_override')) {
@ -102,7 +99,7 @@ class FrameworkBundle extends Bundle
$this->addCompilerPassIfExists($container, AddConstraintValidatorsPass::class, PassConfig::TYPE_BEFORE_REMOVING);
$container->addCompilerPass(new AddAnnotationsCachedReaderPass(), PassConfig::TYPE_AFTER_REMOVING, -255);
$this->addCompilerPassIfExists($container, AddValidatorInitializersPass::class);
$this->addCompilerPassIfExists($container, AddConsoleCommandPass::class);
$this->addCompilerPassIfExists($container, AddConsoleCommandPass::class, PassConfig::TYPE_BEFORE_REMOVING);
$this->addCompilerPassIfExists($container, TranslatorPass::class);
$container->addCompilerPass(new LoggingTranslatorPass());
$container->addCompilerPass(new AddExpressionLanguageProvidersPass());

View File

@ -74,6 +74,7 @@
<argument type="service" id="logger" on-invalid="null" />
<argument>%kernel.debug%</argument>
<argument>%kernel.charset%</argument>
<argument>%debug.file_link_format%</argument>
</service>
<service id="validate_request_listener" class="Symfony\Component\HttpKernel\EventListener\ValidateRequestListener">

View File

@ -24,6 +24,32 @@ class AbstractControllerTest extends ControllerTraitTest
return new TestAbstractController();
}
/**
* This test protects the default subscribed core services against accidental modification.
*/
public function testSubscribedServices()
{
$subscribed = AbstractController::getSubscribedServices();
$expectedServices = array(
'router' => '?Symfony\\Component\\Routing\\RouterInterface',
'request_stack' => '?Symfony\\Component\\HttpFoundation\\RequestStack',
'http_kernel' => '?Symfony\\Component\\HttpKernel\\HttpKernelInterface',
'serializer' => '?Symfony\\Component\\Serializer\\SerializerInterface',
'session' => '?Symfony\\Component\\HttpFoundation\\Session\\SessionInterface',
'security.authorization_checker' => '?Symfony\\Component\\Security\\Core\\Authorization\\AuthorizationCheckerInterface',
'templating' => '?Symfony\\Component\\Templating\\EngineInterface',
'twig' => '?Twig\\Environment',
'doctrine' => '?Doctrine\\Common\\Persistence\\ManagerRegistry',
'form.factory' => '?Symfony\\Component\\Form\\FormFactoryInterface',
'parameter_bag' => '?Symfony\\Component\\DependencyInjection\\ParameterBag\\ContainerBagInterface',
'message_bus' => '?Symfony\\Component\\Messenger\\MessageBusInterface',
'security.token_storage' => '?Symfony\\Component\\Security\\Core\\Authentication\\Token\\Storage\\TokenStorageInterface',
'security.csrf.token_manager' => '?Symfony\\Component\\Security\\Csrf\\CsrfTokenManagerInterface',
);
$this->assertEquals($expectedServices, $subscribed, 'Subscribed core services in AbstractController have changed');
}
public function testGetParameter()
{
$container = new Container(new FrozenParameterBag(array('foo' => 'bar')));

View File

@ -30,6 +30,7 @@ class ExceptionController
protected $twig;
protected $debug;
protected $profiler;
private $fileLinkFormat;
public function __construct(Profiler $profiler = null, Environment $twig, bool $debug, FileLinkFormatter $fileLinkFormat = null)
{

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Asset\Exception;
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Console\Exception;
*
* @author Jérôme Tamarelle <jerome@tamarelle.net>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -12,10 +12,12 @@
namespace Symfony\Component\Console\Tests\DependencyInjection;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\TypedReference;
@ -28,7 +30,7 @@ class AddConsoleCommandPassTest extends TestCase
public function testProcess($public)
{
$container = new ContainerBuilder();
$container->addCompilerPass(new AddConsoleCommandPass());
$container->addCompilerPass(new AddConsoleCommandPass(), PassConfig::TYPE_BEFORE_REMOVING);
$container->setParameter('my-command.class', 'Symfony\Component\Console\Tests\DependencyInjection\MyCommand');
$id = 'my-command';
@ -124,7 +126,7 @@ class AddConsoleCommandPassTest extends TestCase
{
$container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->addCompilerPass(new AddConsoleCommandPass());
$container->addCompilerPass(new AddConsoleCommandPass(), PassConfig::TYPE_BEFORE_REMOVING);
$definition = new Definition('Symfony\Component\Console\Tests\DependencyInjection\MyCommand');
$definition->addTag('console.command');
@ -142,7 +144,7 @@ class AddConsoleCommandPassTest extends TestCase
{
$container = new ContainerBuilder();
$container->setResourceTracking(false);
$container->addCompilerPass(new AddConsoleCommandPass());
$container->addCompilerPass(new AddConsoleCommandPass(), PassConfig::TYPE_BEFORE_REMOVING);
$definition = new Definition('SplObjectStorage');
$definition->addTag('console.command');
@ -171,6 +173,79 @@ class AddConsoleCommandPassTest extends TestCase
$this->assertTrue($container->hasAlias($aliasPrefix.'my-command1'));
$this->assertTrue($container->hasAlias($aliasPrefix.'my-command2'));
}
public function testProcessOnChildDefinitionWithClass()
{
$container = new ContainerBuilder();
$container->addCompilerPass(new AddConsoleCommandPass(), PassConfig::TYPE_BEFORE_REMOVING);
$className = 'Symfony\Component\Console\Tests\DependencyInjection\MyCommand';
$parentId = 'my-parent-command';
$childId = 'my-child-command';
$parentDefinition = new Definition(/* no class */);
$parentDefinition->setAbstract(true)->setPublic(false);
$childDefinition = new ChildDefinition($parentId);
$childDefinition->addTag('console.command')->setPublic(true);
$childDefinition->setClass($className);
$container->setDefinition($parentId, $parentDefinition);
$container->setDefinition($childId, $childDefinition);
$container->compile();
$command = $container->get($childId);
$this->assertInstanceOf($className, $command);
}
public function testProcessOnChildDefinitionWithParentClass()
{
$container = new ContainerBuilder();
$container->addCompilerPass(new AddConsoleCommandPass(), PassConfig::TYPE_BEFORE_REMOVING);
$className = 'Symfony\Component\Console\Tests\DependencyInjection\MyCommand';
$parentId = 'my-parent-command';
$childId = 'my-child-command';
$parentDefinition = new Definition($className);
$parentDefinition->setAbstract(true)->setPublic(false);
$childDefinition = new ChildDefinition($parentId);
$childDefinition->addTag('console.command')->setPublic(true);
$container->setDefinition($parentId, $parentDefinition);
$container->setDefinition($childId, $childDefinition);
$container->compile();
$command = $container->get($childId);
$this->assertInstanceOf($className, $command);
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage The definition for "my-child-command" has no class.
*/
public function testProcessOnChildDefinitionWithoutClass()
{
$container = new ContainerBuilder();
$container->addCompilerPass(new AddConsoleCommandPass(), PassConfig::TYPE_BEFORE_REMOVING);
$parentId = 'my-parent-command';
$childId = 'my-child-command';
$parentDefinition = new Definition();
$parentDefinition->setAbstract(true)->setPublic(false);
$childDefinition = new ChildDefinition($parentId);
$childDefinition->addTag('console.command')->setPublic(true);
$container->setDefinition($parentId, $parentDefinition);
$container->setDefinition($childId, $childDefinition);
$container->compile();
}
}
class MyCommand extends Command

View File

@ -19,6 +19,6 @@ namespace Symfony\Component\CssSelector\Exception;
*
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Dotenv\Exception;
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Filesystem\Exception;
*
* @author Romain Neutron <imprec@gmail.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Form\Exception;
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -210,7 +210,7 @@ class ResponseHeaderBag extends HeaderBag
*
* @param string $format
*
* @return array
* @return Cookie[]
*
* @throws \InvalidArgumentException When the $format is invalid
*/

View File

@ -21,7 +21,6 @@ class RequestTest extends TestCase
{
protected function tearDown()
{
// reset
Request::setTrustedProxies(array(), -1);
Request::setTrustedHosts(array());
}

View File

@ -36,13 +36,15 @@ class ExceptionListener implements EventSubscriberInterface
protected $logger;
protected $debug;
private $charset;
private $fileLinkFormat;
public function __construct($controller, LoggerInterface $logger = null, $debug = false, $charset = null)
public function __construct($controller, LoggerInterface $logger = null, $debug = false, $charset = null, $fileLinkFormat = null)
{
$this->controller = $controller;
$this->logger = $logger;
$this->debug = $debug;
$this->charset = $charset;
$this->fileLinkFormat = $fileLinkFormat;
}
public function logKernelException(GetResponseForExceptionEvent $event)
@ -130,7 +132,7 @@ class ExceptionListener implements EventSubscriberInterface
$attributes = array(
'exception' => $exception = FlattenException::create($exception),
'_controller' => $this->controller ?: function () use ($exception) {
$handler = new ExceptionHandler($this->debug, $this->charset);
$handler = new ExceptionHandler($this->debug, $this->charset, $this->fileLinkFormat);
return new Response($handler->getHtml($exception), $exception->getStatusCode(), $exception->getHeaders());
},

View File

@ -115,7 +115,9 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer
$server['HTTP_X_FORWARDED_FOR'] = ($currentXForwardedFor ? $currentXForwardedFor.', ' : '').$request->getClientIp();
}
$server['REMOTE_ADDR'] = '127.0.0.1';
$trustedProxies = Request::getTrustedProxies();
$server['REMOTE_ADDR'] = $trustedProxies ? reset($trustedProxies) : '127.0.0.1';
unset($server['HTTP_IF_MODIFIED_SINCE']);
unset($server['HTTP_IF_NONE_MATCH']);

View File

@ -21,6 +21,11 @@ use Symfony\Component\HttpKernel\KernelEvents;
class ValidateRequestListenerTest extends TestCase
{
protected function tearDown()
{
Request::setTrustedProxies(array(), -1);
}
/**
* @expectedException \Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException
*/

View File

@ -168,16 +168,33 @@ class InlineFragmentRendererTest extends TestCase
public function testHeadersPossiblyResultingIn304AreNotAssignedToSubrequest()
{
$expectedSubRequest = Request::create('/');
if (Request::HEADER_X_FORWARDED_FOR & Request::getTrustedHeaderSet()) {
$expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
$expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
}
$expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
$expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
$strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));
$request = Request::create('/', 'GET', array(), array(), array(), array('HTTP_IF_MODIFIED_SINCE' => 'Fri, 01 Jan 2016 00:00:00 GMT', 'HTTP_IF_NONE_MATCH' => '*'));
$strategy->render('/', $request);
}
public function testFirstTrustedProxyIsSetAsRemote()
{
Request::setTrustedProxies(array('1.1.1.1'), -1);
$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');
$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.

View File

@ -1350,6 +1350,8 @@ class HttpCacheTest extends HttpCacheTestCase
$this->request('GET', '/', array('REMOTE_ADDR' => '10.0.0.1'));
$this->assertEquals($expected, Request::getTrustedProxies());
Request::setTrustedProxies(array(), -1);
}
public function getTrustedProxyData()

View File

@ -340,6 +340,8 @@ class HttpKernelTest extends TestCase
$kernel = $this->getHttpKernel($dispatcher);
$kernel->handle($request, $kernel::MASTER_REQUEST, false);
Request::setTrustedProxies(array(), -1);
}
private function getHttpKernel(EventDispatcherInterface $eventDispatcher, $controller = null, RequestStack $requestStack = null, array $arguments = array())

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Intl\Exception;
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Ldap\Exception;
*
* @author Charles Sarrazin <charles@sarraz.in>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Lock\Exception;
*
* @author Jérémy Derussé <jeremy@derusse.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Messenger\Exception;
*
* @author Samuel Roze <samuel.roze@gmail.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -30,7 +30,7 @@
"symfony/var-dumper": "~3.4|~4.0"
},
"suggest": {
"sroze/enqueue-bridge": "For using the php-enqueue library as a transport."
"enqueue/messenger-adapter": "For using the php-enqueue library as a transport."
},
"autoload": {
"psr-4": { "Symfony\\Component\\Messenger\\": "" },

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\OptionsResolver\Exception;
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -29,10 +29,6 @@ class OptionsResolverTest extends TestCase
$this->resolver = new OptionsResolver();
}
////////////////////////////////////////////////////////////////////////////
// resolve()
////////////////////////////////////////////////////////////////////////////
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException
* @expectedExceptionMessage The option "foo" does not exist. Defined options are: "a", "z".
@ -69,10 +65,6 @@ class OptionsResolverTest extends TestCase
$this->resolver->resolve();
}
////////////////////////////////////////////////////////////////////////////
// setDefault()/hasDefault()
////////////////////////////////////////////////////////////////////////////
public function testSetDefaultReturnsThis()
{
$this->assertSame($this->resolver, $this->resolver->setDefault('foo', 'bar'));
@ -115,10 +107,6 @@ class OptionsResolverTest extends TestCase
$this->assertTrue($this->resolver->hasDefault('foo'));
}
////////////////////////////////////////////////////////////////////////////
// lazy setDefault()
////////////////////////////////////////////////////////////////////////////
public function testSetLazyReturnsThis()
{
$this->assertSame($this->resolver, $this->resolver->setDefault('foo', function (Options $options) {}));
@ -232,10 +220,6 @@ class OptionsResolverTest extends TestCase
$this->assertSame(2, $calls);
}
////////////////////////////////////////////////////////////////////////////
// setRequired()/isRequired()/getRequiredOptions()
////////////////////////////////////////////////////////////////////////////
public function testSetRequiredReturnsThis()
{
$this->assertSame($this->resolver, $this->resolver->setRequired('foo'));
@ -330,10 +314,6 @@ class OptionsResolverTest extends TestCase
$this->assertSame(array('foo', 'bar'), $this->resolver->getRequiredOptions());
}
////////////////////////////////////////////////////////////////////////////
// isMissing()/getMissingOptions()
////////////////////////////////////////////////////////////////////////////
public function testIsMissingIfNotSet()
{
$this->assertFalse($this->resolver->isMissing('foo'));
@ -373,10 +353,6 @@ class OptionsResolverTest extends TestCase
$this->assertSame(array('bar'), $this->resolver->getMissingOptions());
}
////////////////////////////////////////////////////////////////////////////
// setDefined()/isDefined()/getDefinedOptions()
////////////////////////////////////////////////////////////////////////////
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\AccessException
*/
@ -474,10 +450,6 @@ class OptionsResolverTest extends TestCase
$this->assertFalse($this->resolver->isDefined('foo'));
}
////////////////////////////////////////////////////////////////////////////
// setAllowedTypes()
////////////////////////////////////////////////////////////////////////////
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException
*/
@ -662,10 +634,6 @@ class OptionsResolverTest extends TestCase
$this->resolver->resolve();
}
////////////////////////////////////////////////////////////////////////////
// addAllowedTypes()
////////////////////////////////////////////////////////////////////////////
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException
*/
@ -748,10 +716,6 @@ class OptionsResolverTest extends TestCase
$this->assertNotEmpty($this->resolver->resolve());
}
////////////////////////////////////////////////////////////////////////////
// setAllowedValues()
////////////////////////////////////////////////////////////////////////////
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException
*/
@ -903,10 +867,6 @@ class OptionsResolverTest extends TestCase
$this->assertEquals(array('foo' => 'bar'), $this->resolver->resolve());
}
////////////////////////////////////////////////////////////////////////////
// addAllowedValues()
////////////////////////////////////////////////////////////////////////////
/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException
*/
@ -1023,10 +983,6 @@ class OptionsResolverTest extends TestCase
$this->assertEquals(array('foo' => 'bar'), $this->resolver->resolve());
}
////////////////////////////////////////////////////////////////////////////
// setNormalizer()
////////////////////////////////////////////////////////////////////////////
public function testSetNormalizerReturnsThis()
{
$this->resolver->setDefault('foo', 'bar');
@ -1278,10 +1234,6 @@ class OptionsResolverTest extends TestCase
$this->assertEmpty($this->resolver->resolve());
}
////////////////////////////////////////////////////////////////////////////
// setDefaults()
////////////////////////////////////////////////////////////////////////////
public function testSetDefaultsReturnsThis()
{
$this->assertSame($this->resolver, $this->resolver->setDefaults(array('foo', 'bar')));
@ -1316,10 +1268,6 @@ class OptionsResolverTest extends TestCase
$this->resolver->resolve();
}
////////////////////////////////////////////////////////////////////////////
// remove()
////////////////////////////////////////////////////////////////////////////
public function testRemoveReturnsThis()
{
$this->resolver->setDefault('foo', 'bar');
@ -1408,10 +1356,6 @@ class OptionsResolverTest extends TestCase
$this->assertNotNull($this->resolver->remove('foo'));
}
////////////////////////////////////////////////////////////////////////////
// clear()
////////////////////////////////////////////////////////////////////////////
public function testClearReturnsThis()
{
$this->assertSame($this->resolver, $this->resolver->clear());
@ -1498,10 +1442,6 @@ class OptionsResolverTest extends TestCase
$this->assertEmpty($this->resolver->resolve());
}
////////////////////////////////////////////////////////////////////////////
// ArrayAccess
////////////////////////////////////////////////////////////////////////////
public function testArrayAccess()
{
$this->resolver->setDefault('default1', 0);
@ -1616,10 +1556,6 @@ class OptionsResolverTest extends TestCase
$this->resolver->resolve();
}
////////////////////////////////////////////////////////////////////////////
// Countable
////////////////////////////////////////////////////////////////////////////
public function testCount()
{
$this->resolver->setDefault('default', 0);

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Process\Exception;
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -73,7 +73,7 @@ class ExecutableFinder
$suffixes = array('');
if ('\\' === DIRECTORY_SEPARATOR) {
$pathExt = getenv('PATHEXT');
$suffixes = array_merge($suffixes, $pathExt ? explode(PATH_SEPARATOR, $pathExt) : $this->suffixes);
$suffixes = array_merge($pathExt ? explode(PATH_SEPARATOR, $pathExt) : $this->suffixes, $suffixes);
}
foreach ($suffixes as $suffix) {
foreach ($dirs as $dir) {

View File

@ -117,6 +117,36 @@ class ExecutableFinderTest extends TestCase
$this->assertSamePath(PHP_BINARY, $result);
}
/**
* @requires PHP 5.4
*/
public function testFindBatchExecutableOnWindows()
{
if (ini_get('open_basedir')) {
$this->markTestSkipped('Cannot test when open_basedir is set');
}
if ('\\' !== DIRECTORY_SEPARATOR) {
$this->markTestSkipped('Can be only tested on windows');
}
$target = tempnam(sys_get_temp_dir(), 'example-windows-executable');
touch($target);
touch($target.'.BAT');
$this->assertFalse(is_executable($target));
$this->setPath(sys_get_temp_dir());
$finder = new ExecutableFinder();
$result = $finder->find(basename($target), false);
unlink($target);
unlink($target.'.BAT');
$this->assertSamePath($target.'.BAT', $result);
}
private function assertSamePath($expected, $tested)
{
if ('\\' === DIRECTORY_SEPARATOR) {

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\PropertyAccess\Exception;
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Routing\Exception;
*
* @author Alexandre Salomé <alexandre.salome@gmail.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -41,7 +41,7 @@ CHANGELOG
* Added `getUser`, `getToken` and `isGranted` methods to `Security`.
* added a `setToken()` method to the `SwitchUserEvent` class to allow to replace the created token while switching users
when custom token generation is required by application.
when custom token generation is required by application.
* Using voters that do not implement the `VoterInterface`is now deprecated in
the `AccessDecisionManager` and this functionality will be removed in 4.0.
* Using the `ContextListener` without setting the `logoutOnUserChange`
@ -51,6 +51,8 @@ CHANGELOG
* deprecated HTTP digest authentication
* Added a new password encoder for the Argon2i hashing algorithm
* deprecated `GuardAuthenticatorInterface` in favor of `AuthenticatorInterface`
* deprecated to return `null` from `getCredentials()` in classes that extend
`AbstractGuardAuthenticator`. Return `false` from `supports()` instead.
3.3.0
-----

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Security\Core\Exception;
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -59,7 +59,25 @@ class RememberMeListener implements ListenerInterface
}
$request = $event->getRequest();
if (null === $token = $this->rememberMeServices->autoLogin($request)) {
try {
if (null === $token = $this->rememberMeServices->autoLogin($request)) {
return;
}
} catch (AuthenticationException $e) {
if (null !== $this->logger) {
$this->logger->warning(
'The token storage was not populated with remember-me token as the'
.' RememberMeServices was not able to create a token from the remember'
.' me information.', array('exception' => $e)
);
}
$this->rememberMeServices->loginFail($request);
if (!$this->catchExceptions) {
throw $e;
}
return;
}

View File

@ -145,6 +145,43 @@ class RememberMeListenerTest extends TestCase
$listener->handle($event);
}
public function testOnCoreSecurityAuthenticationExceptionDuringAutoLoginTriggersLoginFail()
{
list($listener, $tokenStorage, $service, $manager) = $this->getListener();
$tokenStorage
->expects($this->once())
->method('getToken')
->will($this->returnValue(null))
;
$exception = new AuthenticationException('Authentication failed.');
$service
->expects($this->once())
->method('autoLogin')
->will($this->throwException($exception))
;
$service
->expects($this->once())
->method('loginFail')
;
$manager
->expects($this->never())
->method('authenticate')
;
$event = $this->getGetResponseEvent();
$event
->expects($this->once())
->method('getRequest')
->will($this->returnValue(new Request()))
;
$listener->handle($event);
}
public function testOnCoreSecurity()
{
list($listener, $tokenStorage, $service, $manager) = $this->getListener();

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Serializer\Exception;
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -349,6 +349,12 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
}
} elseif ($allowed && !$ignored && (isset($data[$key]) || array_key_exists($key, $data))) {
$parameterData = $data[$key];
if (null === $parameterData && $constructorParameter->allowsNull()) {
$params[] = null;
// Don't run set for a parameter passed to the constructor
unset($data[$key]);
continue;
}
try {
if (null !== $constructorParameter->getClass()) {
if (!$this->serializer instanceof DenormalizerInterface) {

View File

@ -0,0 +1,32 @@
<?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\Serializer\Tests\Fixtures;
class NullableConstructorArgumentDummy
{
private $foo;
public function __construct(?\stdClass $foo)
{
$this->foo = $foo;
}
public function setFoo($foo)
{
$this->foo = 'this setter should not be called when using the constructor argument';
}
public function getFoo()
{
return $this->foo;
}
}

View File

@ -9,6 +9,7 @@ use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Tests\Fixtures\AbstractNormalizerDummy;
use Symfony\Component\Serializer\Tests\Fixtures\NullableConstructorArgumentDummy;
use Symfony\Component\Serializer\Tests\Fixtures\ProxyDummy;
use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorDummy;
use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorNormalizer;
@ -116,4 +117,15 @@ class AbstractNormalizerTest extends TestCase
$this->assertEquals('baz', $dummy->quz);
$this->assertNull($dummy->foo);
}
/**
* @requires PHP 7.1
*/
public function testObjectWithNullableConstructorArgument()
{
$normalizer = new ObjectNormalizer();
$dummy = $normalizer->denormalize(array('foo' => null), NullableConstructorArgumentDummy::class);
$this->assertNull($dummy->getFoo());
}
}

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Translation\Exception;
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Validator\Exception;
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -15,6 +15,6 @@ namespace Symfony\Component\Workflow\Exception;
* @author Fabien Potencier <fabien@symfony.com>
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}

View File

@ -16,6 +16,6 @@ namespace Symfony\Component\Yaml\Exception;
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface ExceptionInterface extends \Throwable
interface ExceptionInterface
{
}