diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c113ccbf96..2b27d887c2 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,6 @@ | Q | A | ------------- | --- -| Branch? | 5.x for features / 4.4 or 5.1 for bug fixes +| Branch? | 5.x for features / 4.4, 5.1 or 5.2 for bug fixes | Bug fix? | yes/no | New feature? | yes/no | Deprecations? | yes/no diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php index 255c333fbe..c43a7a6e60 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php @@ -535,7 +535,9 @@ class TextDescriptor extends Descriptor } try { - if (\is_array($controller)) { + if (null === $controller) { + return $anchorText; + } elseif (\is_array($controller)) { $r = new \ReflectionMethod($controller[0], $controller[1]); } elseif ($controller instanceof \Closure) { $r = new \ReflectionFunction($controller); diff --git a/src/Symfony/Component/HttpClient/HttpClientTrait.php b/src/Symfony/Component/HttpClient/HttpClientTrait.php index 77cc4ab284..4db3a3ca8a 100644 --- a/src/Symfony/Component/HttpClient/HttpClientTrait.php +++ b/src/Symfony/Component/HttpClient/HttpClientTrait.php @@ -391,6 +391,10 @@ trait HttpClientTrait throw new InvalidArgumentException(sprintf('Invalid "base_uri" option: host or scheme is missing in "%s".', implode('', $base))); } + if (null === $url['scheme'] && (null === $base || null === $base['scheme'])) { + throw new InvalidArgumentException(sprintf('Invalid URL: scheme is missing in "%s". Did you forget to add "http(s)://"?', implode('', $base ?? $url))); + } + if (null === $base && '' === $url['scheme'].$url['authority']) { throw new InvalidArgumentException(sprintf('Invalid URL: no "base_uri" option was provided and host or scheme is missing in "%s".', implode('', $url))); } diff --git a/src/Symfony/Component/HttpClient/Tests/HttpClientTraitTest.php b/src/Symfony/Component/HttpClient/Tests/HttpClientTraitTest.php index 56ce269e54..bec1f177fb 100644 --- a/src/Symfony/Component/HttpClient/Tests/HttpClientTraitTest.php +++ b/src/Symfony/Component/HttpClient/Tests/HttpClientTraitTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\HttpClient\Tests; use PHPUnit\Framework\TestCase; +use Symfony\Component\HttpClient\Exception\InvalidArgumentException; use Symfony\Component\HttpClient\HttpClientTrait; use Symfony\Contracts\HttpClient\HttpClientInterface; @@ -120,6 +121,20 @@ class HttpClientTraitTest extends TestCase ]; } + public function testResolveUrlWithoutScheme() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid URL: scheme is missing in "//localhost:8080". Did you forget to add "http(s)://"?'); + self::resolveUrl(self::parseUrl('localhost:8080'), null); + } + + public function testResolveBaseUrlWitoutScheme() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid URL: scheme is missing in "//localhost:8081". Did you forget to add "http(s)://"?'); + self::resolveUrl(self::parseUrl('/foo'), self::parseUrl('localhost:8081')); + } + /** * @dataProvider provideParseUrl */ diff --git a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_max_age.expected b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_max_age.expected index bdb9d023f8..6870a27728 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_max_age.expected +++ b/src/Symfony/Component/HttpFoundation/Tests/Fixtures/response-functional/cookie_max_age.expected @@ -1,6 +1,6 @@ Warning: Expiry date cannot have a year greater than 9999 in %scookie_max_age.php on line 10 - +%A Array ( [0] => Content-Type: text/plain; charset=utf-8 diff --git a/src/Symfony/Component/HttpFoundation/Tests/ResponseFunctionalTest.php b/src/Symfony/Component/HttpFoundation/Tests/ResponseFunctionalTest.php index e94f4defc4..49acff5abc 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/ResponseFunctionalTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/ResponseFunctionalTest.php @@ -23,7 +23,7 @@ class ResponseFunctionalTest extends TestCase 1 => ['file', '/dev/null', 'w'], 2 => ['file', '/dev/null', 'w'], ]; - if (!self::$server = @proc_open('exec php -S localhost:8054', $spec, $pipes, __DIR__.'/Fixtures/response-functional')) { + if (!self::$server = @proc_open('exec '.\PHP_BINARY.' -S localhost:8054', $spec, $pipes, __DIR__.'/Fixtures/response-functional')) { self::markTestSkipped('PHP server unable to start.'); } sleep(1); diff --git a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/AbstractSessionHandlerTest.php b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/AbstractSessionHandlerTest.php index 4a045f2ad2..45257abb98 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/AbstractSessionHandlerTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/Session/Storage/Handler/AbstractSessionHandlerTest.php @@ -23,7 +23,7 @@ class AbstractSessionHandlerTest extends TestCase 1 => ['file', '/dev/null', 'w'], 2 => ['file', '/dev/null', 'w'], ]; - if (!self::$server = @proc_open('exec php -S localhost:8053', $spec, $pipes, __DIR__.'/Fixtures')) { + if (!self::$server = @proc_open('exec '.\PHP_BINARY.' -S localhost:8053', $spec, $pipes, __DIR__.'/Fixtures')) { self::markTestSkipped('PHP server unable to start.'); } sleep(1); diff --git a/src/Symfony/Component/Mime/MimeTypes.php b/src/Symfony/Component/Mime/MimeTypes.php index d6260b59ea..eb62c28f55 100644 --- a/src/Symfony/Component/Mime/MimeTypes.php +++ b/src/Symfony/Component/Mime/MimeTypes.php @@ -166,6 +166,7 @@ final class MimeTypes implements MimeTypesInterface 'application/cdmi-queue' => ['cdmiq'], 'application/cdr' => ['cdr'], 'application/coreldraw' => ['cdr'], + 'application/csv' => ['csv'], 'application/cu-seeme' => ['cu'], 'application/davmount+xml' => ['davmount'], 'application/dbase' => ['dbf'], @@ -1818,7 +1819,7 @@ final class MimeTypes implements MimeTypesInterface 'csp' => ['application/vnd.commonspace'], 'css' => ['text/css'], 'cst' => ['application/x-director'], - 'csv' => ['text/csv', 'text/x-comma-separated-values', 'text/x-csv'], + 'csv' => ['text/csv', 'text/x-comma-separated-values', 'text/x-csv', 'application/csv'], 'csvs' => ['text/csv-schema'], 'cu' => ['application/cu-seeme'], 'cue' => ['application/x-cue'], diff --git a/src/Symfony/Component/Mime/Tests/Fixtures/mimetypes/abc.csv b/src/Symfony/Component/Mime/Tests/Fixtures/mimetypes/abc.csv new file mode 100644 index 0000000000..bd1221bfdd --- /dev/null +++ b/src/Symfony/Component/Mime/Tests/Fixtures/mimetypes/abc.csv @@ -0,0 +1,3 @@ +a,b,c +d,e,f +g,h,i diff --git a/src/Symfony/Component/Mime/Tests/MimeTypesTest.php b/src/Symfony/Component/Mime/Tests/MimeTypesTest.php index b1387c9a5c..9b16ff6807 100644 --- a/src/Symfony/Component/Mime/Tests/MimeTypesTest.php +++ b/src/Symfony/Component/Mime/Tests/MimeTypesTest.php @@ -73,4 +73,18 @@ class MimeTypesTest extends AbstractMimeTypeGuesserTest $this->assertContains('text/baz', $mt->getMimeTypes('foo')); $this->assertSame(['foo', 'moof'], $mt->getExtensions('text/baz')); } + + /** + * PHP 8 detects .csv files as "application/csv" while PHP 7 returns "text/plain". + * + * @requires PHP 8 + */ + public function testCsvExtension() + { + $mt = new MimeTypes(); + + $mime = $mt->guessMimeType(__DIR__.'/Fixtures/mimetypes/abc.csv'); + $this->assertSame('application/csv', $mime); + $this->assertSame(['csv'], $mt->getExtensions($mime)); + } } diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 7f80d63c09..baa830601a 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -1178,7 +1178,9 @@ class Parser for (; \strlen($this->currentLine) > $cursor; ++$cursor) { switch ($this->currentLine[$cursor]) { case '\\': - if (isset($this->currentLine[++$cursor])) { + if ("'" === $quotation) { + $value .= '\\'; + } elseif (isset($this->currentLine[++$cursor])) { $value .= '\\'.$this->currentLine[$cursor]; } diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index bc7d881e6b..4e457603c3 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -1617,6 +1617,11 @@ YAML ]; } + public function testBackslashInSingleQuotedString() + { + $this->assertSame(['foo' => 'bar\\'], $this->parser->parse("foo: 'bar\'")); + } + public function testParseMultiLineString() { $this->assertEquals("foo bar\nbaz", $this->parser->parse("foo\nbar\n\nbaz"));