From 84041a1d6cf0b9688956ad53ea0dae7622da12d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20Szigeti?= Date: Mon, 19 Sep 2022 10:38:33 +0200 Subject: [PATCH 01/14] [Serializer] Allow getting discriminated type by class name --- .../Component/Serializer/Mapping/ClassDiscriminatorMapping.php | 2 +- .../Serializer/Tests/Mapping/ClassDiscriminatorMappingTest.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Serializer/Mapping/ClassDiscriminatorMapping.php b/src/Symfony/Component/Serializer/Mapping/ClassDiscriminatorMapping.php index 0c314c7ba455d..ffaa8eab9a8ec 100644 --- a/src/Symfony/Component/Serializer/Mapping/ClassDiscriminatorMapping.php +++ b/src/Symfony/Component/Serializer/Mapping/ClassDiscriminatorMapping.php @@ -53,7 +53,7 @@ public function getClassForType(string $type): ?string public function getMappedObjectType($object): ?string { foreach ($this->typesMapping as $type => $typeClass) { - if (is_a($object, $typeClass)) { + if (is_a($object, $typeClass, true)) { return $type; } } diff --git a/src/Symfony/Component/Serializer/Tests/Mapping/ClassDiscriminatorMappingTest.php b/src/Symfony/Component/Serializer/Tests/Mapping/ClassDiscriminatorMappingTest.php index aed2d221d4a10..d63fdb68bff34 100644 --- a/src/Symfony/Component/Serializer/Tests/Mapping/ClassDiscriminatorMappingTest.php +++ b/src/Symfony/Component/Serializer/Tests/Mapping/ClassDiscriminatorMappingTest.php @@ -39,6 +39,7 @@ public function testMappedObjectType() 'third' => AbstractDummyThirdChild::class, ]); + $this->assertEquals('first', $mapping->getMappedObjectType(AbstractDummyFirstChild::class)); $this->assertEquals('first', $mapping->getMappedObjectType(new AbstractDummyFirstChild())); $this->assertNull($mapping->getMappedObjectType(new AbstractDummySecondChild())); $this->assertSame('third', $mapping->getMappedObjectType(new AbstractDummyThirdChild())); From 14712aa94790c770ade5e2f8a0548e0ca74568c8 Mon Sep 17 00:00:00 2001 From: Zoli Konta Date: Thu, 29 Sep 2022 16:10:52 +0200 Subject: [PATCH 02/14] fix overflow issue in WebPprofiler Forms panel --- .../Resources/views/Collector/form.html.twig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig index db97100e49b37..d99ad4f77946b 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/form.html.twig @@ -90,7 +90,8 @@ cursor: pointer; padding: 5px 7px 5px 22px; position: relative; - + overflow: hidden; + text-overflow: ellipsis; } .tree .toggle-button { /* provide a bigger clickable area than just 10x10px */ @@ -449,7 +450,7 @@ {% import _self as tree %} {% set has_error = data.errors is defined and data.errors|length > 0 %}
  • -
    +
    {% if has_error %}
    {{ data.errors|length }}
    {% endif %} From 146e0acc269d6638ab17bd14698200661f5a3dc8 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 30 Sep 2022 09:39:45 +0200 Subject: [PATCH 03/14] Bump Symfony version to 4.4.47 --- src/Symfony/Component/HttpKernel/Kernel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index c6476b615d29a..8133c320cd568 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -76,12 +76,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - public const VERSION = '4.4.46'; - public const VERSION_ID = 40446; + public const VERSION = '4.4.47-DEV'; + public const VERSION_ID = 40447; public const MAJOR_VERSION = 4; public const MINOR_VERSION = 4; - public const RELEASE_VERSION = 46; - public const EXTRA_VERSION = ''; + public const RELEASE_VERSION = 47; + public const EXTRA_VERSION = 'DEV'; public const END_OF_MAINTENANCE = '11/2022'; public const END_OF_LIFE = '11/2023'; From 87f58ae800d1f8517349dd599ed2f5161a51f7c3 Mon Sep 17 00:00:00 2001 From: Antonio Pauletich Date: Fri, 30 Sep 2022 14:25:39 +0200 Subject: [PATCH 04/14] Fix BinaryFileResponse content type detection logic --- .../HttpFoundation/BinaryFileResponse.php | 6 +++-- .../Tests/BinaryFileResponseTest.php | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php index 2cd105c3bb0f3..1842256a3f01c 100644 --- a/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php +++ b/src/Symfony/Component/HttpFoundation/BinaryFileResponse.php @@ -201,9 +201,9 @@ public function setContentDisposition($disposition, $filename = '', $filenameFal */ public function prepare(Request $request) { - parent::prepare($request); - if ($this->isInformational() || $this->isEmpty()) { + parent::prepare($request); + $this->maxlen = 0; return $this; @@ -213,6 +213,8 @@ public function prepare(Request $request) $this->headers->set('Content-Type', $this->file->getMimeType() ?: 'application/octet-stream'); } + parent::prepare($request); + $this->offset = 0; $this->maxlen = -1; diff --git a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php index 4e4ddbf4446ef..4ca6dbedf23a4 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php @@ -388,6 +388,32 @@ public function testPrepareNotAddingContentTypeHeaderIfNoContentResponse() $this->assertFalse($response->headers->has('Content-Type')); } + public function testContentTypeIsCorrectlyDetected() + { + $response = new BinaryFileResponse(__DIR__.'/File/Fixtures/test.gif'); + + $request = Request::create('/'); + $response->prepare($request); + + $this->assertSame(200, $response->getStatusCode()); + $this->assertSame('image/gif', $response->headers->get('Content-Type')); + } + + public function testContentTypeIsNotGuessedWhenTheFileWasNotModified() + { + $response = new BinaryFileResponse(__DIR__.'/File/Fixtures/test.gif'); + $response->setAutoLastModified(); + + $request = Request::create('/'); + $request->headers->set('If-Modified-Since', $response->getLastModified()->format('D, d M Y H:i:s').' GMT'); + $isNotModified = $response->isNotModified($request); + $this->assertTrue($isNotModified); + $response->prepare($request); + + $this->assertSame(304, $response->getStatusCode()); + $this->assertFalse($response->headers->has('Content-Type')); + } + protected function provideResponse() { return new BinaryFileResponse(__DIR__.'/../README.md', 200, ['Content-Type' => 'application/octet-stream']); From c9591252f458c0cc02e97b00be84dce82f9cb9d4 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 1 Oct 2022 09:56:21 +0200 Subject: [PATCH 05/14] minor #47751 Norgweiang translations (ibonkonesa) This PR was merged into the 6.2 branch. Discussion ---------- Norgweiang translations | Q | A | ------------- | --- | Branch? | 6.2 for features / 4.4, 5.4, 6.0 or 6.1 for bug fixes | Bug fix? | yes/no | New feature? | yes/no | Deprecations? | yes/no | Tickets | Fix #... | License | MIT | Doc PR | symfony/symfony-docs#... Commits ------- b6998edbd3 Norgweiang translations --- .../Core/Resources/translations/security.nn.xlf | 8 ++++++++ .../Resources/translations/validators.nn.xlf | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Symfony/Component/Security/Core/Resources/translations/security.nn.xlf b/src/Symfony/Component/Security/Core/Resources/translations/security.nn.xlf index 89ca44fa88f26..1c8e065d71d70 100644 --- a/src/Symfony/Component/Security/Core/Resources/translations/security.nn.xlf +++ b/src/Symfony/Component/Security/Core/Resources/translations/security.nn.xlf @@ -70,6 +70,14 @@ Invalid or expired login link. Innloggingslenka er ugyldig eller utgjengen. + + Too many failed login attempts, please try again in %minutes% minute. + For mange mislykkede påloggingsforsøk, prøv igjen om %minutes% minutt. + + + Too many failed login attempts, please try again in %minutes% minutes. + For mange mislykkede påloggingsforsøk, prøv igjen om %minutes% minutter. + diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.nn.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.nn.xlf index 8963ba2d8c2c4..fa472b5c194c2 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.nn.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.nn.xlf @@ -386,6 +386,22 @@ This value is not a valid International Securities Identification Number (ISIN). Verdien er ikkje eit gyldig International Securities Identification Number (ISIN). + + This value should be a valid expression. + Denne verdien skal være et gyldig uttrykk. + + + This value is not a valid CSS color. + Denne verdien er ikke en gyldig CSS-farge. + + + This value is not a valid CIDR notation. + Denne verdien er ikke en gyldig CIDR-notasjon. + + + The value of the netmask should be between {{ min }} and {{ max }}. + Verdien av nettmasken skal være mellom {{ min }} og {{ max }}. + From 47dedf75c1a681b2a242370a591333c053733c41 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 1 Oct 2022 23:39:02 +0200 Subject: [PATCH 06/14] skip a test if the mime type detection feature will not work --- .../HttpFoundation/Tests/BinaryFileResponseTest.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php index 4ca6dbedf23a4..0539f74e9982c 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/BinaryFileResponseTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\HttpFoundation\Tests; use Symfony\Component\HttpFoundation\BinaryFileResponse; +use Symfony\Component\HttpFoundation\File\File; use Symfony\Component\HttpFoundation\File\Stream; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\ResponseHeaderBag; @@ -390,7 +391,15 @@ public function testPrepareNotAddingContentTypeHeaderIfNoContentResponse() public function testContentTypeIsCorrectlyDetected() { - $response = new BinaryFileResponse(__DIR__.'/File/Fixtures/test.gif'); + $file = new File(__DIR__.'/File/Fixtures/test.gif'); + + try { + $file->getMimeType(); + } catch (\LogicException $e) { + $this->markTestSkipped('Guessing the mime type is not possible'); + } + + $response = new BinaryFileResponse($file); $request = Request::create('/'); $response->prepare($request); From f06b842724ceba4b511d1446b8ab7156fade47d6 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 1 Oct 2022 23:56:04 +0200 Subject: [PATCH 07/14] a readonly property must not be reported as being writable --- .../PropertyInfo/Extractor/ReflectionExtractor.php | 8 ++++++-- .../Tests/Extractor/ReflectionExtractorTest.php | 12 ++++++++++++ .../PropertyInfo/Tests/Fixtures/Php81Dummy.php | 4 ++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index a6e3738e7cb0c..4049d914f5df0 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -180,7 +180,7 @@ public function isReadable($class, $property, array $context = []): ?bool */ public function isWritable($class, $property, array $context = []): ?bool { - if ($this->isAllowedProperty($class, $property)) { + if ($this->isAllowedProperty($class, $property, true)) { return true; } @@ -389,11 +389,15 @@ private function isNullableProperty(string $class, string $property): bool return false; } - private function isAllowedProperty(string $class, string $property): bool + private function isAllowedProperty(string $class, string $property, bool $writeAccessRequired = false): bool { try { $reflectionProperty = new \ReflectionProperty($class, $property); + if (\PHP_VERSION_ID >= 80100 && $writeAccessRequired && $reflectionProperty->isReadOnly()) { + return false; + } + if ($this->accessFlags & self::ALLOW_PUBLIC && $reflectionProperty->isPublic()) { return true; } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index 315171333d137..0d587a5f25a36 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -22,6 +22,7 @@ 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\Tests\Fixtures\Php81Dummy; use Symfony\Component\PropertyInfo\Type; /** @@ -234,6 +235,7 @@ public function php71TypesProvider() /** * @dataProvider php80TypesProvider + * * @requires PHP 8 */ public function testExtractPhp80Type($property, array $type = null) @@ -257,6 +259,7 @@ public function php80TypesProvider() /** * @dataProvider php81TypesProvider + * * @requires PHP 8.1 */ public function testExtractPhp81Type($property, array $type = null) @@ -272,8 +275,17 @@ public function php81TypesProvider() ]; } + /** + * @requires PHP 8.1 + */ + public function testReadonlyPropertiesAreNotWriteable() + { + $this->assertFalse($this->extractor->isWritable(Php81Dummy::class, 'foo')); + } + /** * @dataProvider php82TypesProvider + * * @requires PHP 8.2 */ public function testExtractPhp82Type($property, array $type = null) diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php81Dummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php81Dummy.php index 842f59fbfd47b..13713b69dde03 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php81Dummy.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Php81Dummy.php @@ -13,6 +13,10 @@ class Php81Dummy { + public function __construct(public readonly string $foo) + { + } + public function getNothing(): never { throw new \Exception('Oops'); From edaea645dbf71508b7b14e990b3d52c1bb4db071 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 3 Oct 2022 17:07:37 +0200 Subject: [PATCH 08/14] Guard scripts from being run in non-CLI contexts --- src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php | 4 ++++ .../FrameworkBundle/Resources/bin/check-unused-known-tags.php | 4 ++++ .../Resources/bin/generate_operator_regex.php | 4 ++++ src/Symfony/Component/Intl/Resources/bin/common.php | 4 ++++ src/Symfony/Component/Intl/Resources/bin/update-data.php | 4 ++++ .../Component/Mime/Resources/bin/update_mime_types.php | 4 ++++ .../Translation/Resources/bin/translation-status.php | 4 ++++ src/Symfony/Component/VarDumper/Resources/bin/var-dump-server | 4 ++++ 8 files changed, 32 insertions(+) diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php index fe776b90d3df1..ca79f45ac9985 100644 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php @@ -12,6 +12,10 @@ // Please update when phpunit needs to be reinstalled with fresh deps: // Cache-Id: 2021-02-04 11:00 UTC +if ('cli' !== \PHP_SAPI && 'phpdbg' !== \PHP_SAPI) { + throw new Exception('This script must be run from the command line.'); +} + error_reporting(-1); global $argv, $argc; diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/bin/check-unused-known-tags.php b/src/Symfony/Bundle/FrameworkBundle/Resources/bin/check-unused-known-tags.php index ec9ae1f97c0ff..024ba08d9551b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/bin/check-unused-known-tags.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/bin/check-unused-known-tags.php @@ -9,6 +9,10 @@ * file that was distributed with this source code. */ +if ('cli' !== \PHP_SAPI) { + throw new Exception('This script must be run from the command line.'); +} + require dirname(__DIR__, 6).'/vendor/autoload.php'; use Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler\UnusedTagsPassUtils; diff --git a/src/Symfony/Component/ExpressionLanguage/Resources/bin/generate_operator_regex.php b/src/Symfony/Component/ExpressionLanguage/Resources/bin/generate_operator_regex.php index c86e962526182..72b4d25f56d4f 100644 --- a/src/Symfony/Component/ExpressionLanguage/Resources/bin/generate_operator_regex.php +++ b/src/Symfony/Component/ExpressionLanguage/Resources/bin/generate_operator_regex.php @@ -9,6 +9,10 @@ * file that was distributed with this source code. */ +if ('cli' !== \PHP_SAPI) { + throw new Exception('This script must be run from the command line.'); +} + $operators = ['not', '!', 'or', '||', '&&', 'and', '|', '^', '&', '==', '===', '!=', '!==', '<', '>', '>=', '<=', 'not in', 'in', '..', '+', '-', '~', '*', '/', '%', 'matches', '**']; $operators = array_combine($operators, array_map('strlen', $operators)); arsort($operators); diff --git a/src/Symfony/Component/Intl/Resources/bin/common.php b/src/Symfony/Component/Intl/Resources/bin/common.php index cf47fa448b034..89d3459143d96 100644 --- a/src/Symfony/Component/Intl/Resources/bin/common.php +++ b/src/Symfony/Component/Intl/Resources/bin/common.php @@ -9,6 +9,10 @@ * file that was distributed with this source code. */ +if ('cli' !== \PHP_SAPI) { + throw new Exception('This script must be run from the command line.'); +} + define('LINE_WIDTH', 75); define('LINE', str_repeat('-', LINE_WIDTH)."\n"); diff --git a/src/Symfony/Component/Intl/Resources/bin/update-data.php b/src/Symfony/Component/Intl/Resources/bin/update-data.php index 4fc4b2c13a5c9..95a85b4cb3db6 100644 --- a/src/Symfony/Component/Intl/Resources/bin/update-data.php +++ b/src/Symfony/Component/Intl/Resources/bin/update-data.php @@ -23,6 +23,10 @@ use Symfony\Component\Intl\Locale; use Symfony\Component\Intl\Util\GitRepository; +if ('cli' !== \PHP_SAPI) { + throw new Exception('This script must be run from the command line.'); +} + require_once __DIR__.'/common.php'; require_once __DIR__.'/autoload.php'; diff --git a/src/Symfony/Component/Mime/Resources/bin/update_mime_types.php b/src/Symfony/Component/Mime/Resources/bin/update_mime_types.php index 74a9449c75e8d..08c52f7d07cd7 100644 --- a/src/Symfony/Component/Mime/Resources/bin/update_mime_types.php +++ b/src/Symfony/Component/Mime/Resources/bin/update_mime_types.php @@ -9,6 +9,10 @@ * file that was distributed with this source code. */ +if ('cli' !== \PHP_SAPI) { + throw new Exception('This script must be run from the command line.'); +} + // load new map $data = file_get_contents('https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types'); $new = []; diff --git a/src/Symfony/Component/Translation/Resources/bin/translation-status.php b/src/Symfony/Component/Translation/Resources/bin/translation-status.php index fac8acbadca32..53e642c00dca7 100644 --- a/src/Symfony/Component/Translation/Resources/bin/translation-status.php +++ b/src/Symfony/Component/Translation/Resources/bin/translation-status.php @@ -9,6 +9,10 @@ * file that was distributed with this source code. */ +if ('cli' !== \PHP_SAPI) { + throw new Exception('This script must be run from the command line.'); +} + $usageInstructions = << Date: Mon, 3 Oct 2022 22:36:35 +0200 Subject: [PATCH 09/14] [Console] Fix `Helper::removeDecoration` hyperlink bug --- .../Component/Console/Helper/Helper.php | 2 ++ .../Console/Tests/Helper/HelperTest.php | 19 ++++++++++++++ .../Console/Tests/Helper/TableTest.php | 25 +++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/src/Symfony/Component/Console/Helper/Helper.php b/src/Symfony/Component/Console/Helper/Helper.php index 0521aaf7d2933..18d85b94073e0 100644 --- a/src/Symfony/Component/Console/Helper/Helper.php +++ b/src/Symfony/Component/Console/Helper/Helper.php @@ -135,6 +135,8 @@ public static function removeDecoration(OutputFormatterInterface $formatter, $st $string = $formatter->format($string); // remove already formatted characters $string = preg_replace("/\033\[[^m]*m/", '', $string); + // remove terminal hyperlinks + $string = preg_replace('/\\033]8;[^;]*;[^\\033]*\\033\\\\/', '', $string); $formatter->setDecorated($isDecorated); return $string; diff --git a/src/Symfony/Component/Console/Tests/Helper/HelperTest.php b/src/Symfony/Component/Console/Tests/Helper/HelperTest.php index 184d86e092aba..b8c8910874ed8 100644 --- a/src/Symfony/Component/Console/Tests/Helper/HelperTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/HelperTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Console\Tests\Helper; use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Helper\Helper; class HelperTest extends TestCase @@ -42,6 +43,16 @@ public function formatTimeProvider() ]; } + public function decoratedTextProvider() + { + return [ + ['abc', 'abc'], + ['abc', 'abc'], + ["a\033[1;36mbc", 'abc'], + ["a\033]8;;http://url\033\\b\033]8;;\033\\c", 'abc'], + ]; + } + /** * @dataProvider formatTimeProvider * @@ -52,4 +63,12 @@ public function testFormatTime($secs, $expectedFormat) { $this->assertEquals($expectedFormat, Helper::formatTime($secs)); } + + /** + * @dataProvider decoratedTextProvider + */ + public function testRemoveDecoration(string $decoratedText, string $undecoratedText) + { + $this->assertEquals($undecoratedText, Helper::removeDecoration(new OutputFormatter(), $decoratedText)); + } } diff --git a/src/Symfony/Component/Console/Tests/Helper/TableTest.php b/src/Symfony/Component/Console/Tests/Helper/TableTest.php index c0f3f96b2aa95..0e3f30cdadadf 100644 --- a/src/Symfony/Component/Console/Tests/Helper/TableTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/TableTest.php @@ -1388,6 +1388,31 @@ public function testWithColspanAndMaxWith() | | | nsectetur | +-----------------+-----------------+-----------------+ +TABLE; + + $this->assertSame($expected, $this->getOutputContent($output)); + } + + public function testWithHyperlinkAndMaxWidth() + { + $table = new Table($output = $this->getOutputStream(true)); + $table + ->setRows([ + ['Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor'], + ]) + ; + $table->setColumnMaxWidth(0, 20); + $table->render(); + + $expected = + <<assertSame($expected, $this->getOutputContent($output)); From 85c459cff0d032edef25503e74551c05480ed04a Mon Sep 17 00:00:00 2001 From: Pavel Barton Date: Tue, 27 Sep 2022 12:15:14 +0200 Subject: [PATCH 10/14] [Messenger] Fix default serializer not handling DateTime objects properly --- .../Component/Messenger/Transport/Serialization/Serializer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Messenger/Transport/Serialization/Serializer.php b/src/Symfony/Component/Messenger/Transport/Serialization/Serializer.php index b5e93370027b6..3b34140cd4d05 100644 --- a/src/Symfony/Component/Messenger/Transport/Serialization/Serializer.php +++ b/src/Symfony/Component/Messenger/Transport/Serialization/Serializer.php @@ -21,6 +21,7 @@ use Symfony\Component\Serializer\Encoder\XmlEncoder; use Symfony\Component\Serializer\Exception\ExceptionInterface; use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; +use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer as SymfonySerializer; use Symfony\Component\Serializer\SerializerInterface as SymfonySerializerInterface; @@ -50,7 +51,7 @@ public static function create(): self } $encoders = [new XmlEncoder(), new JsonEncoder()]; - $normalizers = [new ArrayDenormalizer(), new ObjectNormalizer()]; + $normalizers = [new DateTimeNormalizer(), new ArrayDenormalizer(), new ObjectNormalizer()]; $serializer = new SymfonySerializer($normalizers, $encoders); return new self($serializer); From f4d4da37125480b133ee8229ccb1606879fbfa67 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Fri, 7 Oct 2022 11:14:34 +0200 Subject: [PATCH 11/14] [HttpClient] Fix seeking in not-yet-initialized requests --- .../HttpClient/Response/StreamWrapper.php | 21 ++++++++++++++----- .../HttpClient/Tests/HttpClientTestCase.php | 12 +++++++++++ .../HttpClient/Tests/MockHttpClientTest.php | 1 + 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/HttpClient/Response/StreamWrapper.php b/src/Symfony/Component/HttpClient/Response/StreamWrapper.php index 6bb31687b949c..989dc90c6d498 100644 --- a/src/Symfony/Component/HttpClient/Response/StreamWrapper.php +++ b/src/Symfony/Component/HttpClient/Response/StreamWrapper.php @@ -22,7 +22,7 @@ */ class StreamWrapper { - /** @var resource|string|null */ + /** @var resource|null */ public $context; /** @var HttpClientInterface */ @@ -31,7 +31,7 @@ class StreamWrapper /** @var ResponseInterface */ private $response; - /** @var resource|null */ + /** @var resource|string|null */ private $content; /** @var resource|null */ @@ -81,6 +81,7 @@ public function bindHandles(&$handle, &$content): void { $this->handle = &$handle; $this->content = &$content; + $this->offset = null; } public function stream_open(string $path, string $mode, int $options): bool @@ -125,7 +126,7 @@ public function stream_read(int $count) } } - if (0 !== fseek($this->content, $this->offset)) { + if (0 !== fseek($this->content, $this->offset ?? 0)) { return false; } @@ -154,6 +155,11 @@ public function stream_read(int $count) try { $this->eof = true; $this->eof = !$chunk->isTimeout(); + + if (!$this->eof && !$this->blocking) { + return ''; + } + $this->eof = $chunk->isLast(); if ($chunk->isFirst()) { @@ -196,7 +202,7 @@ public function stream_set_option(int $option, int $arg1, ?int $arg2): bool public function stream_tell(): int { - return $this->offset; + return $this->offset ?? 0; } public function stream_eof(): bool @@ -206,6 +212,11 @@ public function stream_eof(): bool public function stream_seek(int $offset, int $whence = \SEEK_SET): bool { + if (null === $this->content && null === $this->offset) { + $this->response->getStatusCode(); + $this->offset = 0; + } + if (!\is_resource($this->content) || 0 !== fseek($this->content, 0, \SEEK_END)) { return false; } @@ -213,7 +224,7 @@ public function stream_seek(int $offset, int $whence = \SEEK_SET): bool $size = ftell($this->content); if (\SEEK_CUR === $whence) { - $offset += $this->offset; + $offset += $this->offset ?? 0; } if (\SEEK_END === $whence || $size < $offset) { diff --git a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php index d36e7f70b72ca..3cb7d5d48f926 100644 --- a/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php +++ b/src/Symfony/Component/HttpClient/Tests/HttpClientTestCase.php @@ -118,6 +118,18 @@ public function testNonBlockingStream() $this->assertTrue(feof($stream)); } + public function testSeekAsyncStream() + { + $client = $this->getHttpClient(__FUNCTION__); + $response = $client->request('GET', 'http://localhost:8057/timeout-body'); + $stream = $response->toStream(false); + + $this->assertSame(0, fseek($stream, 0, \SEEK_CUR)); + $this->assertSame('<1>', fread($stream, 8192)); + $this->assertFalse(feof($stream)); + $this->assertSame('<2>', stream_get_contents($stream)); + } + public function testTimeoutIsNotAFatalError() { $client = $this->getHttpClient(__FUNCTION__); diff --git a/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php b/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php index 4e8dbf26d7e29..42accfdf7f713 100644 --- a/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php +++ b/src/Symfony/Component/HttpClient/Tests/MockHttpClientTest.php @@ -311,6 +311,7 @@ protected function getHttpClient(string $testCase): HttpClientInterface return $client; case 'testNonBlockingStream': + case 'testSeekAsyncStream': $responses[] = new MockResponse((function () { yield '<1>'; yield ''; yield '<2>'; })(), ['response_headers' => $headers]); break; From 9726264d8abef72b9117961c63885aa76f04ac97 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 12 Oct 2022 09:05:33 +0200 Subject: [PATCH 12/14] Update CHANGELOG for 4.4.47 --- CHANGELOG-4.4.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG-4.4.md b/CHANGELOG-4.4.md index 9c685daa837a5..c16001b9e6c21 100644 --- a/CHANGELOG-4.4.md +++ b/CHANGELOG-4.4.md @@ -7,6 +7,16 @@ in 4.4 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.4.0...v4.4.1 +* 4.4.47 (2022-10-12) + + * bug #47621 [Serializer] Allow getting discriminated type by class name (TamasSzigeti) + * bug #47808 [HttpClient] Fix seeking in not-yet-initialized requests (nicolas-grekas) + * bug #47702 [Messenger] Fix default serializer not handling DateTime objects properly (barton-webwings) + * bug #47779 [Console] Fix `Helper::removeDecoration` hyperlink bug (greew) + * bug #47763 [PropertyInfo] a readonly property must not be reported as being writable (xabbuh) + * bug #47731 [WebProfiler] Fix overflow issue in Forms panel (zolikonta) + * bug #47746 [HttpFoundation] Fix BinaryFileResponse content type detection logic (X-Coder264) + * 4.4.46 (2022-09-30) * bug #47547 [Ldap] Do not run ldap_set_option on failed connection (tatankat) From a713da420bfb79a16c846049b229232bf5d6a4fa Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 12 Oct 2022 09:05:41 +0200 Subject: [PATCH 13/14] Update CONTRIBUTORS for 4.4.47 --- CONTRIBUTORS.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index d652d3de50a5c..baf049c540d1d 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -90,21 +90,21 @@ The Symfony Connect username in parenthesis allows to get more information - Florin Patan (florinpatan) - Peter Rehm (rpet) - Henrik Bjørnskov (henrikbjorn) + - David Buchmann (dbu) - Konstantin Myakshin (koc) - Andrej Hudec (pulzarraider) - Julien Falque (julienfalque) - Massimiliano Arione (garak) - Douglas Greenshields (shieldo) - - David Buchmann (dbu) - Christian Raue - Jáchym Toušek (enumag) + - Mathias Arlaud (mtarld) - Graham Campbell (graham) - Michel Weimerskirch (mweimerskirch) - Eric Clemmons (ericclemmons) - Issei Murasawa (issei_m) - Fran Moreno (franmomu) - Malte Schlüter (maltemaltesich) - - Mathias Arlaud (mtarld) - Vasilij Dusko - Denis (yethee) - Arnout Boks (aboks) @@ -122,12 +122,12 @@ The Symfony Connect username in parenthesis allows to get more information - Lee McDermott - Brandon Turner - Luis Cordova (cordoval) + - Antoine Lamirault - Daniel Holmes (dholmes) - Toni Uebernickel (havvg) - Bart van den Burg (burgov) - Jordan Alliot (jalliot) - Smaine Milianni (ismail1432) - - Antoine Lamirault - John Wards (johnwards) - Dariusz Ruminski - Lars Strojny (lstrojny) @@ -210,6 +210,7 @@ The Symfony Connect username in parenthesis allows to get more information - Martin Hujer (martinhujer) - Wouter J - Guilliam Xavier + - Antonio Pauletich (x-coder264) - Timo Bakx (timobakx) - Juti Noppornpitak (shiroyuki) - Joe Bennett (kralos) @@ -226,7 +227,6 @@ The Symfony Connect username in parenthesis allows to get more information - Arnaud Kleinpeter (nanocom) - Guilherme Blanco (guilhermeblanco) - Chi-teck - - Antonio Pauletich (x-coder264) - Michael Voříšek - SpacePossum - Pablo Godel (pgodel) @@ -479,6 +479,7 @@ The Symfony Connect username in parenthesis allows to get more information - Quynh Xuan Nguyen (seriquynh) - Ray - Philipp Cordes (corphi) + - Andrii Dembitskyi - Chekote - bhavin (bhavin4u) - Pavel Popov (metaer) @@ -575,7 +576,6 @@ The Symfony Connect username in parenthesis allows to get more information - Adrian Rudnik (kreischweide) - Pavel Batanov (scaytrase) - Francesc Rosàs (frosas) - - Andrii Dembitskyi - Bongiraud Dominique - janschoenherr - Marko Kaznovac (kaznovac) @@ -642,6 +642,7 @@ The Symfony Connect username in parenthesis allows to get more information - Vitaliy Zakharov (zakharovvi) - Tobias Sjösten (tobiassjosten) - Gyula Sallai (salla) + - Stefan Gehrig (sgehrig) - Benjamin Cremer (bcremer) - rtek - Inal DJAFAR (inalgnu) @@ -870,7 +871,6 @@ The Symfony Connect username in parenthesis allows to get more information - Dirk Pahl (dirkaholic) - Cédric Lombardot (cedriclombardot) - Jonas Flodén (flojon) - - Stefan Gehrig (sgehrig) - Adrien Lucas (adrienlucas) - Dominik Zogg - Kai Dederichs @@ -1037,6 +1037,7 @@ The Symfony Connect username in parenthesis allows to get more information - Quentin Dequippe (qdequippe) - Yewhen Khoptynskyi (khoptynskyi) - Jérôme Nadaud (jnadaud) + - wuchen90 - Alexandre Tranchant (alexandre_t) - Anthony Moutte - shreyadenny @@ -1050,6 +1051,7 @@ The Symfony Connect username in parenthesis allows to get more information - Grégoire Hébert (gregoirehebert) - alcaeus - Fred Cox + - Matheo Daninos (mathdns) - Iliya Miroslavov Iliev (i.miroslavov) - Safonov Nikita (ns3777k) - Simon DELICATA @@ -1975,7 +1977,6 @@ The Symfony Connect username in parenthesis allows to get more information - Kirill Nesmeyanov (serafim) - Reece Fowell (reecefowell) - Guillaume Gammelin - - wuchen90 - Valérian Galliat - d-ph - Renan Taranto (renan-taranto) @@ -2051,6 +2052,7 @@ The Symfony Connect username in parenthesis allows to get more information - boite - Silvio Ginter - MGDSoft + - joris - Vadim Tyukov (vatson) - David Wolter (davewww) - Sortex @@ -2099,6 +2101,7 @@ The Symfony Connect username in parenthesis allows to get more information - Thomas - Norbert Schultheisz - Maximilian Berghoff (electricmaxxx) + - SOEDJEDE Felix (fsoedjede) - Piotr Antosik (antek88) - Nacho Martin (nacmartin) - Sergey Novikov (s12v) @@ -2225,6 +2228,7 @@ The Symfony Connect username in parenthesis allows to get more information - Nicolas Fabre (nfabre) - Raul Rodriguez (raul782) - mshavliuk + - Jesper Skytte - MightyBranch - Kacper Gunia (cakper) - Derek Lambert (dlambert) @@ -2413,6 +2417,7 @@ The Symfony Connect username in parenthesis allows to get more information - Daniel González Zaballos (dem3trio) - Emmanuel Vella (emmanuel.vella) - Guillaume BRETOU (guiguiboy) + - Ibon Conesa (ibonkonesa) - nuryagdy mustapayev (nueron) - Carsten Nielsen (phreaknerd) - Jay Severson @@ -2598,6 +2603,7 @@ The Symfony Connect username in parenthesis allows to get more information - Andrew Coulton - Ulugbek Miniyarov - Jeremy Benoist + - sdrewergutland - Michal Gebauer - Phil Davis - Gleb Sidora @@ -2635,6 +2641,7 @@ The Symfony Connect username in parenthesis allows to get more information - Mike Francis - Nil Borodulia - Almog Baku (almogbaku) + - Benjamin Schultz (bschultz) - Gerd Christian Kunze (derdu) - Ionel Scutelnicu (ionelscutelnicu) - Kamil Madejski (kmadejski) @@ -2801,6 +2808,7 @@ The Symfony Connect username in parenthesis allows to get more information - David Christmann - root - pf + - Zoli Konta - Vincent Chalnot - Patrizio Bekerle - Tom Maguire @@ -2917,7 +2925,6 @@ The Symfony Connect username in parenthesis allows to get more information - Kevin Verschaeve (keversc) - Kevin Herrera (kherge) - Luis Ramón López López (lrlopez) - - Matheo Daninos (mathdns) - Mehdi Mabrouk (mehdidev) - Bart Reunes (metalarend) - Muriel (metalmumu) @@ -2936,6 +2943,7 @@ The Symfony Connect username in parenthesis allows to get more information - Lajos Veres (vlajos) - Vladimir Chernyshev (volch) - Yorkie Chadwick (yorkie76) + - Pavel Barton - GuillaumeVerdon - ureimers - akimsko @@ -3203,6 +3211,7 @@ The Symfony Connect username in parenthesis allows to get more information - emilienbouard (neime) - Nicholas Byfleet (nickbyfleet) - Nicolas Bondoux (nsbx) + - Cedric Kastner (nurtext) - ollie harridge (ollietb) - Pawel Szczepanek (pauluz) - Philippe Degeeter (pdegeeter) From ea7d316071fa679fc92b16cf85cf9846e7945f91 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 12 Oct 2022 09:05:45 +0200 Subject: [PATCH 14/14] Update VERSION for 4.4.47 --- src/Symfony/Component/HttpKernel/Kernel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Kernel.php b/src/Symfony/Component/HttpKernel/Kernel.php index 8133c320cd568..f944b3d9e6ac6 100644 --- a/src/Symfony/Component/HttpKernel/Kernel.php +++ b/src/Symfony/Component/HttpKernel/Kernel.php @@ -76,12 +76,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private static $freshCache = []; - public const VERSION = '4.4.47-DEV'; + public const VERSION = '4.4.47'; public const VERSION_ID = 40447; public const MAJOR_VERSION = 4; public const MINOR_VERSION = 4; public const RELEASE_VERSION = 47; - public const EXTRA_VERSION = 'DEV'; + public const EXTRA_VERSION = ''; public const END_OF_MAINTENANCE = '11/2022'; public const END_OF_LIFE = '11/2023';