From 7946be2b951612366b31a7b2c222cf2aa10a8e9b Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Tue, 16 Feb 2021 12:01:18 +0100 Subject: [PATCH 1/4] [WebLink] Escape double quotes in attributes values --- src/Symfony/Component/WebLink/HttpHeaderSerializer.php | 4 ++-- .../Component/WebLink/Tests/HttpHeaderSerializerTest.php | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/WebLink/HttpHeaderSerializer.php b/src/Symfony/Component/WebLink/HttpHeaderSerializer.php index 85a9d0e433..2ecdff0905 100644 --- a/src/Symfony/Component/WebLink/HttpHeaderSerializer.php +++ b/src/Symfony/Component/WebLink/HttpHeaderSerializer.php @@ -39,14 +39,14 @@ final class HttpHeaderSerializer foreach ($link->getAttributes() as $key => $value) { if (\is_array($value)) { foreach ($value as $v) { - $attributesParts[] = sprintf('%s="%s"', $key, $v); + $attributesParts[] = sprintf('%s="%s"', $key, preg_replace('/(?assertNull($this->serializer->serialize([])); } + + public function testSerializeDoubleQuotesInAttributeValue() + { + $this->assertSame('; rel="alternate"; title="\"escape me\" \"already escaped\" \"\"\""', $this->serializer->serialize([ + (new Link('alternate', '/foo')) + ->withAttribute('title', '"escape me" \"already escaped\" ""\"'), + ])); + } } From 0e421004eb97c82e87c9dc34cfdab43a1146f825 Mon Sep 17 00:00:00 2001 From: Yendric Date: Sun, 14 Feb 2021 23:09:09 +0100 Subject: [PATCH 2/4] [Console] fix QuestionHelper::getHiddenResponse() not working with space in project directory name --- src/Symfony/Component/Console/Helper/QuestionHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Console/Helper/QuestionHelper.php b/src/Symfony/Component/Console/Helper/QuestionHelper.php index e7ea005559..d211fcfd1e 100644 --- a/src/Symfony/Component/Console/Helper/QuestionHelper.php +++ b/src/Symfony/Component/Console/Helper/QuestionHelper.php @@ -412,7 +412,7 @@ class QuestionHelper extends Helper $exe = $tmpExe; } - $sExec = shell_exec($exe); + $sExec = shell_exec('"'.$exe.'"'); $value = $trimmable ? rtrim($sExec) : $sExec; $output->writeln(''); From e9f2ece991f721813c2be7a5883425b68392bbda Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 16 Feb 2021 11:56:12 +0100 Subject: [PATCH 3/4] fix resolving parent/self/static type annotations --- .../Extractor/PhpDocExtractor.php | 22 +++++++++++- .../Tests/Extractor/PhpDocExtractorTest.php | 34 +++++++++++++++++++ .../Extractor/ReflectionExtractorTest.php | 28 ++++++++++----- .../PropertyInfo/Tests/Fixtures/Dummy.php | 5 +++ .../Tests/Fixtures/ParentDummy.php | 10 ++++++ .../PropertyInfo/Tests/Fixtures/Php7Dummy.php | 2 +- .../Tests/Fixtures/Php7ParentDummy.php | 19 +++++++++++ .../PropertyInfo/Util/PhpDocTypeHelper.php | 4 +++ 8 files changed, 114 insertions(+), 10 deletions(-) create mode 100644 src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php7ParentDummy.php diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php index a701a011c6..25446deb1e 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php @@ -142,11 +142,31 @@ class PhpDocExtractor implements PropertyDescriptionExtractorInterface, Property break; } + $parentClass = null; $types = []; /** @var DocBlock\Tags\Var_|DocBlock\Tags\Return_|DocBlock\Tags\Param $tag */ foreach ($docBlock->getTagsByName($tag) as $tag) { if ($tag && !$tag instanceof InvalidTag && null !== $tag->getType()) { - $types = array_merge($types, $this->phpDocTypeHelper->getTypes($tag->getType())); + foreach ($this->phpDocTypeHelper->getTypes($tag->getType()) as $type) { + switch ($type->getClassName()) { + case 'self': + case 'static': + $resolvedClass = $class; + break; + + case 'parent': + if (false !== $resolvedClass = $parentClass ?? $parentClass = get_parent_class($class)) { + break; + } + // no break + + default: + $types[] = $type; + continue 2; + } + + $types[] = new Type(Type::BUILTIN_TYPE_OBJECT, $type->isNullable(), $resolvedClass, $type->isCollection(), $type->getCollectionKeyType(), $type->getCollectionValueType()); + } } } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php index bd3d5287c2..4e3ff39257 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php @@ -17,6 +17,7 @@ use phpDocumentor\Reflection\Types\Collection; use PHPUnit\Framework\TestCase; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy; +use Symfony\Component\PropertyInfo\Tests\Fixtures\ParentDummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\TraitUsage\DummyUsedInTrait; use Symfony\Component\PropertyInfo\Tests\Fixtures\TraitUsage\DummyUsingTrait; use Symfony\Component\PropertyInfo\Type; @@ -120,6 +121,7 @@ class PhpDocExtractorTest extends TestCase ['staticGetter', null, null, null], ['staticSetter', null, null, null], ['emptyVar', null, $this->isPhpDocumentorV5() ? 'This should not be removed.' : null, null], + ['self', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)], null, null], ]; } @@ -293,6 +295,38 @@ class PhpDocExtractorTest extends TestCase ]; } + /** + * @dataProvider propertiesStaticTypeProvider + */ + public function testPropertiesStaticType(string $class, string $property, Type $type) + { + $this->assertEquals([$type], $this->extractor->getTypes($class, $property)); + } + + public function propertiesStaticTypeProvider(): array + { + return [ + [ParentDummy::class, 'propertyTypeStatic', new Type(Type::BUILTIN_TYPE_OBJECT, false, ParentDummy::class)], + [Dummy::class, 'propertyTypeStatic', new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)], + ]; + } + + /** + * @dataProvider propertiesParentTypeProvider + */ + public function testPropertiesParentType(string $class, string $property, ?array $types) + { + $this->assertEquals($types, $this->extractor->getTypes($class, $property)); + } + + public function propertiesParentTypeProvider(): array + { + return [ + [ParentDummy::class, 'parentAnnotationNoParent', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'parent')]], + [Dummy::class, 'parentAnnotation', [new Type(Type::BUILTIN_TYPE_OBJECT, false, ParentDummy::class)]], + ]; + } + protected function isPhpDocumentorV5() { if (class_exists(InvalidTag::class)) { diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index 0a4f21da05..18f8d4d018 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -20,6 +20,8 @@ use Symfony\Component\PropertyInfo\Tests\Fixtures\NotInstantiable; use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71Dummy; use Symfony\Component\PropertyInfo\Tests\Fixtures\Php71DummyExtended2; use Symfony\Component\PropertyInfo\Tests\Fixtures\Php74Dummy; +use Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy; +use Symfony\Component\PropertyInfo\Tests\Fixtures\Php7ParentDummy; use Symfony\Component\PropertyInfo\Type; /** @@ -57,12 +59,15 @@ class ReflectionExtractorTest extends TestCase 'iteratorCollection', 'iteratorCollectionWithKey', 'nestedIterators', + 'parentAnnotation', 'foo', 'foo2', 'foo3', 'foo4', 'foo5', 'files', + 'propertyTypeStatic', + 'parentAnnotationNoParent', 'a', 'DOB', 'Id', @@ -105,12 +110,15 @@ class ReflectionExtractorTest extends TestCase 'iteratorCollection', 'iteratorCollectionWithKey', 'nestedIterators', + 'parentAnnotation', 'foo', 'foo2', 'foo3', 'foo4', 'foo5', 'files', + 'propertyTypeStatic', + 'parentAnnotationNoParent', 'date', 'c', 'd', @@ -143,12 +151,15 @@ class ReflectionExtractorTest extends TestCase 'iteratorCollection', 'iteratorCollectionWithKey', 'nestedIterators', + 'parentAnnotation', 'foo', 'foo2', 'foo3', 'foo4', 'foo5', 'files', + 'propertyTypeStatic', + 'parentAnnotationNoParent', ], $noPrefixExtractor->getProperties('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy') ); @@ -184,20 +195,21 @@ class ReflectionExtractorTest extends TestCase /** * @dataProvider php7TypesProvider */ - public function testExtractPhp7Type($property, array $type = null) + public function testExtractPhp7Type(string $class, string $property, array $type = null) { - $this->assertEquals($type, $this->extractor->getTypes('Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy', $property, [])); + $this->assertEquals($type, $this->extractor->getTypes($class, $property, [])); } public function php7TypesProvider() { return [ - ['foo', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true)]], - ['bar', [new Type(Type::BUILTIN_TYPE_INT)]], - ['baz', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))]], - ['buz', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy')]], - ['biz', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'stdClass')]], - ['donotexist', null], + [Php7Dummy::class, 'foo', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true)]], + [Php7Dummy::class, 'bar', [new Type(Type::BUILTIN_TYPE_INT)]], + [Php7Dummy::class, 'baz', [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))]], + [Php7Dummy::class, 'buz', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'Symfony\Component\PropertyInfo\Tests\Fixtures\Php7Dummy')]], + [Php7Dummy::class, 'biz', [new Type(Type::BUILTIN_TYPE_OBJECT, false, Php7ParentDummy::class)]], + [Php7Dummy::class, 'donotexist', null], + [Php7ParentDummy::class, 'parent', [new Type(Type::BUILTIN_TYPE_OBJECT, false, \stdClass::class)]], ]; } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php index bcec074438..420cdddae9 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php @@ -130,6 +130,11 @@ class Dummy extends ParentDummy */ public $nestedIterators; + /** + * @var parent + */ + public $parentAnnotation; + public static function getStatic() { } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ParentDummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ParentDummy.php index 8d5c4fe107..d698983254 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ParentDummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ParentDummy.php @@ -48,6 +48,16 @@ class ParentDummy */ public $files; + /** + * @var static + */ + public $propertyTypeStatic; + + /** + * @var parent + */ + public $parentAnnotationNoParent; + /** * @return bool|null */ diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php7Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php7Dummy.php index 5dcb4c565e..a6c2d5f147 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php7Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php7Dummy.php @@ -14,7 +14,7 @@ namespace Symfony\Component\PropertyInfo\Tests\Fixtures; /** * @author Kévin Dunglas */ -class Php7Dummy extends \stdClass +class Php7Dummy extends Php7ParentDummy { public function getFoo(): array { diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php7ParentDummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php7ParentDummy.php new file mode 100644 index 0000000000..69574a749b --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php7ParentDummy.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\PropertyInfo\Tests\Fixtures; + +class Php7ParentDummy extends \stdClass +{ + public function getParent(): parent + { + } +} diff --git a/src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php b/src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php index 06b7489201..41edd3e197 100644 --- a/src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php +++ b/src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php @@ -160,6 +160,10 @@ final class PhpDocTypeHelper return [$docType, null]; } + if (\in_array($docType, ['parent', 'self', 'static'], true)) { + return ['object', $docType]; + } + return ['object', substr($docType, 1)]; } } From 3a231c2030c1147bb8e534a5d766f695011c125c Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 17 Feb 2021 14:10:06 +0100 Subject: [PATCH 4/4] install compatible versions of mongodb/mongodb only --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 98d1c8d4a8..ee0c4c8159 100644 --- a/.travis.yml +++ b/.travis.yml @@ -255,7 +255,7 @@ install: fi phpenv global $PHP rm vendor/composer/package-versions-deprecated -Rf - ([[ $deps ]] && cd src/Symfony/Component/HttpFoundation; cp composer.json composer.bak; composer require --dev --no-update mongodb/mongodb ^1.9.0) + ([[ $deps ]] && cd src/Symfony/Component/HttpFoundation; cp composer.json composer.bak; composer require --dev --no-update mongodb/mongodb) tfold 'composer update' $COMPOSER_UP tfold 'phpunit install' ./phpunit install if [[ $deps = high ]]; then