Skip to content

Commit 0c1023d

Browse files
committed
Merge branch '5.4' into 6.4
* 5.4: [Intl] Update ICU data from 74.1 to 75.1 use DeprecatedCallableInfo for Twig callables if possible [Filesystem] Add a warning about `chown()` and `chgrp()` on Windows [String] Update wcswidth data with Unicode 16 Work around parse_url() bug [Ldap] Clean `ldap_connect()` call in `LdapTestCase` [HttpFoundation] Update links for X-Accel-Redirect and fail properly when X-Accel-Mapping is missing
2 parents f2e8474 + aef8ed5 commit 0c1023d

File tree

161 files changed

+1077
-953
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

161 files changed

+1077
-953
lines changed

src/Symfony/Bridge/Twig/Tests/Command/LintCommandTest.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\Console\Output\OutputInterface;
1919
use Symfony\Component\Console\Tester\CommandCompletionTester;
2020
use Symfony\Component\Console\Tester\CommandTester;
21+
use Twig\DeprecatedCallableInfo;
2122
use Twig\Environment;
2223
use Twig\Loader\FilesystemLoader;
2324
use Twig\TwigFilter;
@@ -159,7 +160,12 @@ private function createCommandTester(): CommandTester
159160
private function createCommand(): Command
160161
{
161162
$environment = new Environment(new FilesystemLoader(\dirname(__DIR__).'/Fixtures/templates/'));
162-
$environment->addFilter(new TwigFilter('deprecated_filter', fn ($v) => $v, ['deprecated' => true]));
163+
if (class_exists(DeprecatedCallableInfo::class)) {
164+
$options = ['deprecation_info' => new DeprecatedCallableInfo('foo/bar', '1.1')];
165+
} else {
166+
$options = ['deprecated' => true];
167+
}
168+
$environment->addFilter(new TwigFilter('deprecated_filter', fn ($v) => $v, $options));
163169

164170
$command = new LintCommand($environment);
165171

src/Symfony/Bundle/FrameworkBundle/Controller/RedirectController.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,17 @@ public function urlRedirectAction(Request $request, string $path, bool $permanen
119119
$statusCode = $permanent ? 301 : 302;
120120
}
121121

122+
$scheme ??= $request->getScheme();
123+
124+
if (str_starts_with($path, '//')) {
125+
$path = $scheme.':'.$path;
126+
}
127+
122128
// redirect if the path is a full URL
123129
if (parse_url($path, \PHP_URL_SCHEME)) {
124130
return new RedirectResponse($path, $statusCode);
125131
}
126132

127-
$scheme ??= $request->getScheme();
128-
129133
if ($qs = $request->server->get('QUERY_STRING') ?: $request->getQueryString()) {
130134
if (!str_contains($path, '?')) {
131135
$qs = '?'.$qs;

src/Symfony/Bundle/FrameworkBundle/Tests/Controller/RedirectControllerTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,20 @@ public function testFullURLWithMethodKeep()
183183
$this->assertEquals(307, $returnResponse->getStatusCode());
184184
}
185185

186+
public function testProtocolRelative()
187+
{
188+
$request = new Request();
189+
$controller = new RedirectController();
190+
191+
$returnResponse = $controller->urlRedirectAction($request, '//foo.bar/');
192+
$this->assertRedirectUrl($returnResponse, 'http://foo.bar/');
193+
$this->assertSame(302, $returnResponse->getStatusCode());
194+
195+
$returnResponse = $controller->urlRedirectAction($request, '//foo.bar/', false, 'https');
196+
$this->assertRedirectUrl($returnResponse, 'https://foo.bar/');
197+
$this->assertSame(302, $returnResponse->getStatusCode());
198+
}
199+
186200
public function testUrlRedirectDefaultPorts()
187201
{
188202
$host = 'www.example.com';

src/Symfony/Component/DomCrawler/Tests/UriResolverTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public static function provideResolverTests()
8686
['foo', 'http://localhost#bar', 'http://localhost/foo'],
8787

8888
['http://', 'http://localhost', 'http://'],
89+
['/foo:123', 'http://localhost', 'http://localhost/foo:123'],
8990
];
9091
}
9192
}

src/Symfony/Component/DomCrawler/UriResolver.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,12 @@ public static function resolve(string $uri, ?string $baseUri): string
3232
{
3333
$uri = trim($uri);
3434

35+
if (false === ($scheme = parse_url($uri, \PHP_URL_SCHEME)) && '/' === ($uri[0] ?? '')) {
36+
$scheme = parse_url($uri.'#', \PHP_URL_SCHEME);
37+
}
38+
3539
// absolute URL?
36-
if (null !== parse_url($uri, \PHP_URL_SCHEME)) {
40+
if (null !== $scheme) {
3741
return $uri;
3842
}
3943

src/Symfony/Component/Filesystem/Filesystem.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool
233233
/**
234234
* Change the owner of an array of files or directories.
235235
*
236+
* This method always throws on Windows, as the underlying PHP function is not supported.
237+
* @see https://www.php.net/chown
238+
*
236239
* @param string|int $user A user name or number
237240
* @param bool $recursive Whether change the owner recursively or not
238241
*
@@ -261,6 +264,9 @@ public function chown(string|iterable $files, string|int $user, bool $recursive
261264
/**
262265
* Change the group of an array of files or directories.
263266
*
267+
* This method always throws on Windows, as the underlying PHP function is not supported.
268+
* @see https://www.php.net/chgrp
269+
*
264270
* @param string|int $group A group name or number
265271
* @param bool $recursive Whether change the group recursively or not
266272
*

src/Symfony/Component/HttpClient/HttpClientTrait.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,10 @@ private static function resolveUrl(array $url, ?array $base, array $queryDefault
627627
private static function parseUrl(string $url, array $query = [], array $allowedSchemes = ['http' => 80, 'https' => 443]): array
628628
{
629629
if (false === $parts = parse_url($url)) {
630-
throw new InvalidArgumentException(sprintf('Malformed URL "%s".', $url));
630+
if ('/' !== ($url[0] ?? '') || false === $parts = parse_url($url.'#')) {
631+
throw new InvalidArgumentException(sprintf('Malformed URL "%s".', $url));
632+
}
633+
unset($parts['fragment']);
631634
}
632635

633636
if ($query) {

src/Symfony/Component/HttpClient/NativeHttpClient.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ private static function createRedirectResolver(array $options, string $host, str
414414

415415
[$host, $port] = self::parseHostPort($url, $info);
416416

417-
if (false !== (parse_url($location, \PHP_URL_HOST) ?? false)) {
417+
if (false !== (parse_url($location.'#', \PHP_URL_HOST) ?? false)) {
418418
// Authorization and Cookie headers MUST NOT follow except for the initial host name
419419
$requestHeaders = $redirectHeaders['host'] === $host && $redirectHeaders['port'] === $port ? $redirectHeaders['with_auth'] : $redirectHeaders['no_auth'];
420420
$requestHeaders[] = 'Host: '.$host.$port;

src/Symfony/Component/HttpFoundation/BinaryFileResponse.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,12 @@ public function prepare(Request $request): static
217217
}
218218
if ('x-accel-redirect' === strtolower($type)) {
219219
// Do X-Accel-Mapping substitutions.
220-
// @link https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/#x-accel-redirect
221-
$parts = HeaderUtils::split($request->headers->get('X-Accel-Mapping', ''), ',=');
220+
// @link https://github.com/rack/rack/blob/main/lib/rack/sendfile.rb
221+
// @link https://mattbrictson.com/blog/accelerated-rails-downloads
222+
if (!$request->headers->has('X-Accel-Mapping')) {
223+
throw new \LogicException('The "X-Accel-Mapping" header must be set when "X-Sendfile-Type" is set to "X-Accel-Redirect".');
224+
}
225+
$parts = HeaderUtils::split($request->headers->get('X-Accel-Mapping'), ',=');
222226
foreach ($parts as $part) {
223227
[$pathPrefix, $location] = $part;
224228
if (str_starts_with($path, $pathPrefix)) {

src/Symfony/Component/HttpFoundation/Request.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,11 +348,12 @@ public static function create(string $uri, string $method = 'GET', array $parame
348348
$server['PATH_INFO'] = '';
349349
$server['REQUEST_METHOD'] = strtoupper($method);
350350

351-
$components = parse_url($uri);
352-
if (false === $components) {
351+
if (false === ($components = parse_url($uri)) && '/' === ($uri[0] ?? '')) {
353352
trigger_deprecation('symfony/http-foundation', '6.3', 'Calling "%s()" with an invalid URI is deprecated.', __METHOD__);
354-
$components = [];
353+
$components = parse_url($uri.'#');
354+
unset($components['fragment']);
355355
}
356+
356357
if (isset($components['host'])) {
357358
$server['SERVER_NAME'] = $components['host'];
358359
$server['HTTP_HOST'] = $components['host'];

0 commit comments

Comments
 (0)