diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 0bef18db33536..e459d1e55f616 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -2,6 +2,23 @@
/src/Symfony/Component/Console/Logger/ConsoleLogger.php @dunglas
# DependencyInjection
/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @dunglas
+# Form
+/src/Symfony/Bridge/Twig/Extension/FormExtension.php @xabbuh
+/src/Symfony/Bridge/Twig/Form/* @xabbuh
+/src/Symfony/Bridge/Twig/Node/FormThemeNode.php @xabbuh
+/src/Symfony/Bridge/Twig/Node/RenderBlockNode.php @xabbuh
+/src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php @xabbuh
+/src/Symfony/Bridge/Twig/Tests/Extension/FormExtension* @xabbuh
+/src/Symfony/Bridge/Twig/Tests/Node/FormThemeTest.php @xabbuh
+/src/Symfony/Bridge/Twig/Tests/TokenParser/FormThemeTokenParserTest.php @xabbuh
+/src/Symfony/Bridge/Twig/TokenParser/FormThemeTokenParser.php @xabbuh
+/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/FormPass.php @xabbuh
+/src/Symfony/Bundle/FrameworkBundle/Resources/views/* @xabbuh
+/src/Symfony/Bundle/FrameworkBundle/Templating/Helper/FormHelper.php @xabbuh
+/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/FormPassTest.php @xabbuh
+/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperTableLayoutTest.php @xabbuh
+/src/Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/FormHelperDivLayoutTest.php @xabbuh
+/src/Symfony/Component/Form/* @xabbuh
# HttpKernel
/src/Symfony/Component/HttpKernel/Log/Logger.php @dunglas
# LDAP
diff --git a/src/Symfony/Bridge/PhpUnit/composer.json b/src/Symfony/Bridge/PhpUnit/composer.json
index 24a48b600d1b5..25dcb0cd10272 100644
--- a/src/Symfony/Bridge/PhpUnit/composer.json
+++ b/src/Symfony/Bridge/PhpUnit/composer.json
@@ -21,8 +21,7 @@
"php": ">=5.3.3"
},
"suggest": {
- "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader",
- "ext-zip": "Zip support is required when using bin/simple-phpunit"
+ "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader"
},
"conflict": {
"phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0"
diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/KernelShutdownOnTearDownTrait.php b/src/Symfony/Bundle/FrameworkBundle/Test/KernelShutdownOnTearDownTrait.php
new file mode 100644
index 0000000000000..7eb4d0726e820
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Test/KernelShutdownOnTearDownTrait.php
@@ -0,0 +1,45 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle\Test;
+
+use PHPUnit\Framework\TestCase;
+
+// Auto-adapt to PHPUnit 8 that added a `void` return-type to the tearDown method
+
+if (method_exists(\ReflectionMethod::class, 'hasReturnType') && (new \ReflectionMethod(TestCase::class, 'tearDown'))->hasReturnType()) {
+eval('
+ /**
+ * @internal
+ */
+ trait KernelShutdownOnTearDownTrait
+ {
+ protected function tearDown(): void
+ {
+ static::ensureKernelShutdown();
+ }
+ }
+');
+} else {
+ /**
+ * @internal
+ */
+ trait KernelShutdownOnTearDownTrait
+ {
+ /**
+ * @return void
+ */
+ protected function tearDown()
+ {
+ static::ensureKernelShutdown();
+ }
+ }
+}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php
index 02737b391288e..978f65863220c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php
@@ -23,6 +23,8 @@
*/
abstract class KernelTestCase extends TestCase
{
+ use KernelShutdownOnTearDownTrait;
+
protected static $class;
/**
@@ -208,9 +210,7 @@ protected static function createKernel(array $options = [])
}
/**
- * @after
- *
- * Shuts the kernel down if it was used in the test.
+ * Shuts the kernel down if it was used in the test - called by the tearDown method by default.
*/
protected static function ensureKernelShutdown()
{
diff --git a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/MappingRule.php b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/MappingRule.php
index 590f7df2d8b58..cb9f3f953326b 100644
--- a/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/MappingRule.php
+++ b/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/MappingRule.php
@@ -55,7 +55,7 @@ public function getOrigin()
*/
public function match($propertyPath)
{
- if ($propertyPath === (string) $this->propertyPath) {
+ if ($propertyPath === $this->propertyPath) {
return $this->getTarget();
}
}
diff --git a/src/Symfony/Component/Form/FormTypeGuesserInterface.php b/src/Symfony/Component/Form/FormTypeGuesserInterface.php
index 0aec6364c4ac7..6521ea47ca767 100644
--- a/src/Symfony/Component/Form/FormTypeGuesserInterface.php
+++ b/src/Symfony/Component/Form/FormTypeGuesserInterface.php
@@ -32,7 +32,7 @@ public function guessType($class, $property);
* @param string $class The fully qualified class name
* @param string $property The name of the property to guess for
*
- * @return Guess\ValueGuess A guess for the field's required setting
+ * @return Guess\ValueGuess|null A guess for the field's required setting
*/
public function guessRequired($class, $property);
diff --git a/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTest.php b/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTest.php
index 1a1a24e2b278c..16d4045e6d580 100644
--- a/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTest.php
+++ b/src/Symfony/Component/Form/Tests/AbstractRequestHandlerTest.php
@@ -285,6 +285,26 @@ public function testSubmitMultipleFiles($method)
$this->assertSame($file, $form->getData());
}
+ /**
+ * @dataProvider methodExceptGetProvider
+ */
+ public function testSubmitFileWithNamelessForm($method)
+ {
+ $form = $this->createForm('', $method, true);
+ $fileForm = $this->createBuilder('document', false, ['allow_file_upload' => true])->getForm();
+ $form->add($fileForm);
+ $file = $this->getUploadedFile();
+ $this->setRequestData($method, [
+ 'document' => null,
+ ], [
+ 'document' => $file,
+ ]);
+ $this->requestHandler->handleRequest($form, $this->request);
+
+ $this->assertTrue($form->isSubmitted());
+ $this->assertSame($file, $fileForm->getData());
+ }
+
/**
* @dataProvider getPostMaxSizeFixtures
*/
diff --git a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php
index 79193ece79b04..f80d2ec2caf47 100644
--- a/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php
@@ -83,6 +83,10 @@ public function handle(GetResponseEvent $event)
return;
}
+ if (null === $this->tokenStorage->getToken()) {
+ throw new AuthenticationCredentialsNotFoundException('Could not find original Token object.');
+ }
+
if (self::EXIT_VALUE === $username) {
$this->tokenStorage->setToken($this->attemptExitUser($request));
} else {
@@ -164,7 +168,7 @@ private function attemptSwitchUser(Request $request, $username)
*/
private function attemptExitUser(Request $request)
{
- if (null === ($currentToken = $this->tokenStorage->getToken()) || false === $original = $this->getOriginalToken($currentToken)) {
+ if (false === $original = $this->getOriginalToken($this->tokenStorage->getToken())) {
throw new AuthenticationCredentialsNotFoundException('Could not find original Token object.');
}
diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php
index d29665d55eb74..709bc4c862f9e 100644
--- a/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php
+++ b/src/Symfony/Component/Security/Http/Tests/Firewall/SwitchUserListenerTest.php
@@ -267,6 +267,17 @@ public function testSwitchUserWithReplacedToken()
$this->assertSame($replacedToken, $this->tokenStorage->getToken());
}
+ /**
+ * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException
+ */
+ public function testSwitchtUserThrowsAuthenticationExceptionIfNoCurrentToken()
+ {
+ $this->tokenStorage->setToken(null);
+ $this->request->query->set('_switch_user', 'username');
+ $listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
+ $listener->handle($this->event);
+ }
+
public function testSwitchUserStateless()
{
$token = new UsernamePasswordToken('username', '', 'key', ['ROLE_FOO']);
diff --git a/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php b/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php
index fec0080fe02e9..3c95c097e8e9a 100644
--- a/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php
+++ b/src/Symfony/Component/Validator/Constraints/AbstractComparisonValidator.php
@@ -13,7 +13,7 @@
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
use Symfony\Component\PropertyAccess\PropertyAccess;
-use Symfony\Component\PropertyAccess\PropertyAccessor;
+use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
@@ -29,7 +29,7 @@ abstract class AbstractComparisonValidator extends ConstraintValidator
{
private $propertyAccessor;
- public function __construct(PropertyAccessor $propertyAccessor = null)
+ public function __construct(PropertyAccessorInterface $propertyAccessor = null)
{
$this->propertyAccessor = $propertyAccessor;
}
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.es.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.es.xlf
index 25d5b8a5d33a7..f16b05cb925c2 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.es.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.es.xlf
@@ -322,6 +322,10 @@
This is not a valid UUID.
Este valor no es un UUID válido.
+
+ This value should be a multiple of {{ compared_value }}.
+ Este valor debería ser múltiplo de {{ compared_value }}.
+