From 4a66a6098f6072df94edfbe074c15880db4931e2 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 23 Jun 2020 10:33:22 +0200 Subject: [PATCH 1/3] fix handling typed properties as constraint options --- .../Component/Validator/Constraint.php | 2 +- .../Validator/Tests/ConstraintTest.php | 24 +++++++++++++++++++ .../Fixtures/ConstraintWithStaticProperty.php | 10 ++++++++ .../Fixtures/ConstraintWithTypedProperty.php | 10 ++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithStaticProperty.php create mode 100644 src/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithTypedProperty.php diff --git a/src/Symfony/Component/Validator/Constraint.php b/src/Symfony/Component/Validator/Constraint.php index 693689b912..ab2d882290 100644 --- a/src/Symfony/Component/Validator/Constraint.php +++ b/src/Symfony/Component/Validator/Constraint.php @@ -108,7 +108,7 @@ abstract class Constraint $defaultOption = $this->getDefaultOption(); $invalidOptions = []; $missingOptions = array_flip((array) $this->getRequiredOptions()); - $knownOptions = get_object_vars($this); + $knownOptions = get_class_vars(static::class); // The "groups" option is added to the object lazily $knownOptions['groups'] = true; diff --git a/src/Symfony/Component/Validator/Tests/ConstraintTest.php b/src/Symfony/Component/Validator/Tests/ConstraintTest.php index 6c481b0088..26cc460d39 100644 --- a/src/Symfony/Component/Validator/Tests/ConstraintTest.php +++ b/src/Symfony/Component/Validator/Tests/ConstraintTest.php @@ -13,10 +13,13 @@ namespace Symfony\Component\Validator\Tests; use PHPUnit\Framework\TestCase; use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Exception\InvalidOptionsException; use Symfony\Component\Validator\Tests\Fixtures\ClassConstraint; use Symfony\Component\Validator\Tests\Fixtures\ConstraintA; use Symfony\Component\Validator\Tests\Fixtures\ConstraintB; use Symfony\Component\Validator\Tests\Fixtures\ConstraintC; +use Symfony\Component\Validator\Tests\Fixtures\ConstraintWithStaticProperty; +use Symfony\Component\Validator\Tests\Fixtures\ConstraintWithTypedProperty; use Symfony\Component\Validator\Tests\Fixtures\ConstraintWithValue; use Symfony\Component\Validator\Tests\Fixtures\ConstraintWithValueAsDefault; @@ -245,4 +248,25 @@ class ConstraintTest extends TestCase $this->expectExceptionMessage('No default option is configured for constraint "Symfony\Component\Validator\Tests\Fixtures\ConstraintB".'); new ConstraintB(['value' => 1]); } + + public function testStaticPropertiesAreNoOptions() + { + $this->expectException(InvalidOptionsException::class); + + new ConstraintWithStaticProperty([ + 'foo' => 'bar', + ]); + } + + /** + * @requires PHP 7.4 + */ + public function testSetTypedProperty() + { + $constraint = new ConstraintWithTypedProperty([ + 'foo' => 'bar', + ]); + + $this->assertSame('bar', $constraint->foo); + } } diff --git a/src/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithStaticProperty.php b/src/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithStaticProperty.php new file mode 100644 index 0000000000..f8b2169408 --- /dev/null +++ b/src/Symfony/Component/Validator/Tests/Fixtures/ConstraintWithStaticProperty.php @@ -0,0 +1,10 @@ + Date: Fri, 26 Jun 2020 14:15:21 +0200 Subject: [PATCH 2/3] fix guessing form types for DateTime types --- .../Validator/ValidatorTypeGuesser.php | 1 + .../Validator/ValidatorTypeGuesserTest.php | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php b/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php index 80ec926a94..17009d205d 100644 --- a/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php +++ b/src/Symfony/Component/Form/Extension/Validator/ValidatorTypeGuesser.php @@ -97,6 +97,7 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface case 'long': return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\IntegerType', [], Guess::MEDIUM_CONFIDENCE); + case \DateTime::class: case '\DateTime': return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateType', [], Guess::MEDIUM_CONFIDENCE); diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorTypeGuesserTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorTypeGuesserTest.php index 878bbfad21..3ac27cdef7 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorTypeGuesserTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorTypeGuesserTest.php @@ -12,9 +12,17 @@ namespace Symfony\Component\Form\Tests\Extension\Validator; use PHPUnit\Framework\TestCase; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; +use Symfony\Component\Form\Extension\Core\Type\CollectionType; +use Symfony\Component\Form\Extension\Core\Type\DateType; +use Symfony\Component\Form\Extension\Core\Type\IntegerType; +use Symfony\Component\Form\Extension\Core\Type\NumberType; +use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser; use Symfony\Component\Form\Guess\Guess; +use Symfony\Component\Form\Guess\TypeGuess; use Symfony\Component\Form\Guess\ValueGuess; +use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraints\Email; use Symfony\Component\Validator\Constraints\IsTrue; use Symfony\Component\Validator\Constraints\Length; @@ -59,6 +67,35 @@ class ValidatorTypeGuesserTest extends TestCase $this->guesser = new ValidatorTypeGuesser($this->metadataFactory); } + /** + * @dataProvider guessTypeProvider + */ + public function testGuessType(Constraint $constraint, TypeGuess $guess) + { + $this->metadata->addPropertyConstraint(self::TEST_PROPERTY, $constraint); + + $this->assertEquals($guess, $this->guesser->guessType(self::TEST_CLASS, self::TEST_PROPERTY)); + } + + public function guessTypeProvider() + { + return [ + [new Type('array'), new TypeGuess(CollectionType::class, [], Guess::MEDIUM_CONFIDENCE)], + [new Type('bool'), new TypeGuess(CheckboxType::class, [], Guess::MEDIUM_CONFIDENCE)], + [new Type('boolean'), new TypeGuess(CheckboxType::class, [], Guess::MEDIUM_CONFIDENCE)], + [new Type('double'), new TypeGuess(NumberType::class, [], Guess::MEDIUM_CONFIDENCE)], + [new Type('float'), new TypeGuess(NumberType::class, [], Guess::MEDIUM_CONFIDENCE)], + [new Type('numeric'), new TypeGuess(NumberType::class, [], Guess::MEDIUM_CONFIDENCE)], + [new Type('real'), new TypeGuess(NumberType::class, [], Guess::MEDIUM_CONFIDENCE)], + [new Type('int'), new TypeGuess(IntegerType::class, [], Guess::MEDIUM_CONFIDENCE)], + [new Type('integer'), new TypeGuess(IntegerType::class, [], Guess::MEDIUM_CONFIDENCE)], + [new Type('long'), new TypeGuess(IntegerType::class, [], Guess::MEDIUM_CONFIDENCE)], + [new Type('string'), new TypeGuess(TextType::class, [], Guess::LOW_CONFIDENCE)], + [new Type(\DateTime::class), new TypeGuess(DateType::class, [], Guess::MEDIUM_CONFIDENCE)], + [new Type('\DateTime'), new TypeGuess(DateType::class, [], Guess::MEDIUM_CONFIDENCE)], + ]; + } + public function guessRequiredProvider() { return [ From 7cb29c8b4b2990a2555d739ec11d7b9d0d46aff8 Mon Sep 17 00:00:00 2001 From: Juan Mrad Date: Tue, 23 Jun 2020 11:04:58 -0500 Subject: [PATCH 3/3] [MimeType] Duplicated MimeType due to PHP Bug --- .../File/MimeType/FileinfoMimeTypeGuesser.php | 8 +++++++- .../HttpFoundation/Tests/File/Fixtures/test.docx | Bin 0 -> 6062 bytes .../Tests/File/MimeType/MimeTypeTest.php | 8 ++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/HttpFoundation/Tests/File/Fixtures/test.docx diff --git a/src/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php b/src/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php index fc4bc45024..fa4c962d7d 100644 --- a/src/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php +++ b/src/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php @@ -63,7 +63,13 @@ class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface if (!$finfo = new \finfo(FILEINFO_MIME_TYPE, $this->magicFile)) { return null; } + $mimeType = $finfo->file($path); - return $finfo->file($path); + if ($mimeType && 0 === (\strlen($mimeType) % 2)) { + $mimeStart = substr($mimeType, 0, \strlen($mimeType) >> 1); + $mimeType = $mimeStart.$mimeStart === $mimeType ? $mimeStart : $mimeType; + } + + return $mimeType; } } diff --git a/src/Symfony/Component/HttpFoundation/Tests/File/Fixtures/test.docx b/src/Symfony/Component/HttpFoundation/Tests/File/Fixtures/test.docx new file mode 100644 index 0000000000000000000000000000000000000000..2e86b6fcea03c679370c996ba200ccb39d1dd83b GIT binary patch literal 6062 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 Inm-Hw4?2y0ApigX literal 0 HcmV?d00001 diff --git a/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php b/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php index 0418726b5b..e38816687f 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/File/MimeType/MimeTypeTest.php @@ -60,6 +60,14 @@ class MimeTypeTest extends TestCase $this->assertEquals('application/octet-stream', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/.unknownextension')); } + /** + * @requires PHP 7.0 + */ + public function testGuessWithDuplicatedFileType() + { + $this->assertEquals('application/vnd.openxmlformats-officedocument.wordprocessingml.document', MimeTypeGuesser::getInstance()->guess(__DIR__.'/../Fixtures/test.docx')); + } + public function testGuessWithIncorrectPath() { $this->expectException('Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException');