8000 bug #37271 [FrameworkBundle] preserve dots in query-string when redir… · symfony/symfony@8ec9770 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8ec9770

Browse files
bug #37271 [FrameworkBundle] preserve dots in query-string when redirecting (nicolas-grekas)
This PR was merged into the 4.4 branch. Discussion ---------- [FrameworkBundle] preserve dots in query-string when redirecting | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #29664 | License | MIT | Doc PR | - Requires #37270 to pass. Commits ------- 3d0d59d [FrameworkBundle] preserve dots in query-string when redirecting
2 parents 7eca3a5 + 3d0d59d commit 8ec9770

File tree

2 files changed

+66
-13
lines changed

2 files changed

+66
-13
lines changed

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

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,17 @@ public function redirectAction(Request $request, string $route, bool $permanent
6262
$attributes = [];
6363
if (false === $ignoreAttributes || \is_array($ignoreAttributes)) {
6464
$attributes = $request->attributes->get('_route_params');
65-
$attributes = $keepQueryParams ? array_merge($request->query->all(), $attributes) : $attributes;
65+
66+
if ($keepQueryParams) {
67+
if ($query = $request->server->get('QUERY_STRING')) {
68+
$query = self::parseQuery($query);
69+
} else {
70+
$query = $request->query->all();
71+
}
72+
73+
$attributes = array_merge($query, $attributes);
74+
}
75+
6676
unset($attributes['route'], $attributes['permanent'], $attributes['ignoreAttributes'], $attributes['keepRequestMethod'], $attributes['keepQueryParams']);
6777
if ($ignoreAttributes) {
6878
$attributes = array_diff_key($attributes, array_flip($ignoreAttributes));
@@ -175,4 +185,49 @@ public function __invoke(Request $request): Response
175185

176186
throw new \RuntimeException(sprintf('The parameter "path" or "route" is required to configure the redirect action in "%s" routing configuration.', $request->attributes->get('_route')));
177187
}
188+
189+
private static function parseQuery(string $query)
190+
{
191+
$q = [];
192+
193+
foreach (explode('&', $query) as $v) {
194+
if (false !== $i = strpos($v, "\0")) {
195+
$v = substr($v, 0, $i);
196+
}
197+
198+
if (false === $i = strpos($v, '=')) {
199+
$k = urldecode($v);
200+
$v = '';
201+
} else {
202+
$k = urldecode(substr($v, 0, $i));
203+
$v = substr($v, $i);
204+
}
205+
206+
if (false !== $i = strpos($k, "\0")) {
207+
$k = substr($k, 0, $i);
208+
}
209+
210+
$k = ltrim($k, ' ');
211+
212+
if (false === $i = strpos($k, '[')) {
213+
$q[] = bin2hex($k).$v;
214+
} else {
215+
$q[] = substr_replace($k, bin2hex(substr($k, 0, $i)), 0, $i).$v;
216+
}
217+
}
218+
219+
parse_str(implode('&', $q), $q);
220+
221+
$query = [];
222+
223+
foreach ($q as $k => $v) {
224+
if (false !== $i = strpos($k, '_')) {
225+
$query[substr_replace($k, hex2bin(substr($k, 0, $i)).'[', 0, 1 + $i)] = $v;
226+
} else {
227+
$query[hex2bin($k)] = $v;
228+
}
229+
}
230+
231+
return $query;
232+
}
178233
}

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

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -302,17 +302,16 @@ public function testRedirectWithQuery()
302302
$baseUrl = '/base';
303303
$port = 80;
304304

305-
$request = $this->createRequestObject($scheme, $host, $port, $baseUrl, 'base=zaza');
306-
$request->query = new ParameterBag(['base' => 'zaza']);
305+
$request = $this->createRequestObject($scheme, $host, $port, $baseUrl, 'b.se=zaza');
307306
$request->attributes = new ParameterBag(['_route_params' => ['base2' => 'zaza']]);
308307
$urlGenerator = $this->getMockBuilder(UrlGeneratorInterface::class)->getMock();
309-
$urlGenerator->expects($this->exactly(2))->method('generate')->willReturn('/test?base=zaza&base2=zaza')->with('/test', ['base' => 'zaza', 'base2' => 'zaza'], UrlGeneratorInterface::ABSOLUTE_URL);
308+
< 6D47 span class="pl-s1">$urlGenerator->expects($this->exactly(2))->method('generate')->willReturn('/test?b.se=zaza&base2=zaza')->with('/test', ['b.se' => 'zaza', 'base2' => 'zaza'], UrlGeneratorInterface::ABSOLUTE_URL);
310309

311310
$controller = new RedirectController($urlGenerator);
312-
$this->assertRedirectUrl($controller->redirectAction($request, '/test', false, false, false, true), '/test?base=zaza&base2=zaza');
311+
$this->assertRedirectUrl($controller->redirectAction($request, '/test', false, false, false, true), '/test?b.se=zaza&base2=zaza');
313312

314313
$request->attributes->set('_route_params', ['base2' => 'zaza', 'route' => '/test', 'ignoreAttributes' => false, 'keepRequestMethod' => false, 'keepQueryParams' => true]);
315-
$this->assertRedirectUrl($controller($request), '/test?base=zaza&base2=zaza');
314+
$this->assertRedirectUrl($controller($request), '/test?b.se=zaza&base2=zaza');
316315
}
317316

318317
public function testRedirectWithQueryWithRouteParamsOveriding()
@@ -322,17 +321,16 @@ public function testRedirectWithQueryWithRouteParamsOveriding()
322321
$baseUrl = '/base';
323322
$port = 80;
324323

325-
$request = $this->createRequestObject($scheme, $host, $port, $baseUrl, 'base=zaza');
326-
$request->query = new ParameterBag(['base' => 'zaza']);
327-
$request->attributes = new ParameterBag(['_route_params' => ['base' => 'zouzou']]);
324+
$request = $this->createRequestObject($scheme, $host, $port, $baseUrl, 'b.se=zaza');
325+
$request->attributes = new ParameterBag(['_route_params' => ['b.se' => 'zouzou']]);
328326
$urlGenerator = $this->getMockBuilder(UrlGeneratorInterface::class)->getMock();
329-
$urlGenerator->expects($this->exactly(2))->method('generate')->willReturn('/test?base=zouzou')->with('/test', ['base' => 'zouzou'], UrlGeneratorInterface::ABSOLUTE_URL);
327+
$urlGenerator->expects($this->exactly(2))->method('generate')->willReturn('/test?b.se=zouzou')->with('/test', ['b.se' => 'zouzou'], UrlGeneratorInterface::ABSOLUTE_URL);
330328

331329
$controller = new RedirectController($urlGenerator);
332-
$this->assertRedirectUrl($controller->redirectAction($request, '/test', false, false, false, true), '/test?base=zouzou');
330+
$this->assertRedirectUrl($controller->redirectAction($request, '/test', false, false, false, true), '/test?b.se=zouzou');
333331

334-
$request->attributes->set('_route_params', ['base' => 'zouzou', 'route' => '/test', 'ignoreAttributes' => false, 'keepRequestMethod' => false, 'keepQueryParams' => true]);
335-
$this->assertRedirectUrl($controller($request), '/test?base=zouzou');
332+
$request->attributes->set('_route_params', ['b.se' => 'zouzou', 'route' => '/test', 'ignoreAttributes' => false, 'keepRequestMethod' => false, 'keepQueryParams' => true]);
333+
$this->assertRedirectUrl($controller($request), '/test?b.se=zouzou');
336334
}
337335

338336
public function testMissingPathOrRouteParameter()

0 commit comments

Comments
 (0)
0