Skip to content

Commit d970ba5

Browse files
Merge branch '5.4' into 6.0
* 5.4: [Mailer] Include all transports' debug messages in RoundRobin transport exception [FrameworkBundle] fix: fix help message Use relative timestamps [Cache] Fix dealing with ext-redis' multi/exec returning a bool [Messenger][Amqp] Added missing rpc_timeout option [Serializer] Prevent GetSetMethodNormalizer from creating invalid magic method call [HttpFoundation] Fix dumping array cookies [WebProfilerBundle] Fix dump header not being displayed TraceableHttpClient: increase decorator's priority Use static methods inside data providers [FrameworkBundle] Allow configuring `framework.exceptions` with a config builder bug #48313 [Mime] Fix MessagePart serialization [ErrorHandler][DebugClassLoader] Fix some new return types support Fix getting the name of closures on PHP 8.1.11+ [Translator] Fix typo "internal" / "interval" fix dumping top-level tagged values
2 parents b607109 + 6c7635f commit d970ba5

File tree

3 files changed

+105
-38
lines changed

3 files changed

+105
-38
lines changed

Tests/Csp/ContentSecurityPolicyHandlerTest.php

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ public function provideRequestAndResponses()
6666
];
6767

6868
return [
69-
[$nonce, ['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce], $this->createRequest(), $this->createResponse()],
70-
[$nonce, ['csp_script_nonce' => $requestScriptNonce, 'csp_style_nonce' => $requestStyleNonce], $this->createRequest($requestNonceHeaders), $this->createResponse($responseNonceHeaders)],
71-
[$nonce, ['csp_script_nonce' => $requestScriptNonce, 'csp_style_nonce' => $requestStyleNonce], $this->createRequest($requestNonceHeaders), $this->createResponse()],
72-
[$nonce, ['csp_script_nonce' => $responseScriptNonce, 'csp_style_nonce' => $responseStyleNonce], $this->createRequest(), $this->createResponse($responseNonceHeaders)],
69+
[$nonce, ['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce], self::createRequest(), self::createResponse()],
70+
[$nonce, ['csp_script_nonce' => $requestScriptNonce, 'csp_style_nonce' => $requestStyleNonce], self::createRequest($requestNonceHeaders), self::createResponse($responseNonceHeaders)],
71+
[$nonce, ['csp_script_nonce' => $requestScriptNonce, 'csp_style_nonce' => $requestStyleNonce], self::createRequest($requestNonceHeaders), self::createResponse()],
72+
[$nonce, ['csp_script_nonce' => $responseScriptNonce, 'csp_style_nonce' => $responseStyleNonce], self::createRequest(), self::createResponse($responseNonceHeaders)],
7373
];
7474
}
7575

@@ -96,112 +96,112 @@ public function provideRequestAndResponsesForOnKernelResponse()
9696
[
9797
$nonce,
9898
['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce],
99-
$this->createRequest(),
100-
$this->createResponse(),
99+
self::createRequest(),
100+
self::createResponse(),
101101
['Content-Security-Policy' => null, 'Content-Security-Policy-Report-Only' => null, 'X-Content-Security-Policy' => null],
102102
],
103103
[
104104
$nonce, ['csp_script_nonce' => $requestScriptNonce, 'csp_style_nonce' => $requestStyleNonce],
105-
$this->createRequest($requestNonceHeaders),
106-
$this->createResponse($responseNonceHeaders),
105+
self::createRequest($requestNonceHeaders),
106+
self::createResponse($responseNonceHeaders),
107107
['Content-Security-Policy' => null, 'Content-Security-Policy-Report-Only' => null, 'X-Content-Security-Policy' => null],
108108
],
109109
[
110110
$nonce,
111111
['csp_script_nonce' => $requestScriptNonce, 'csp_style_nonce' => $requestStyleNonce],
112-
$this->createRequest($requestNonceHeaders),
113-
$this->createResponse(),
112+
self::createRequest($requestNonceHeaders),
113+
self::createResponse(),
114114
['Content-Security-Policy' => null, 'Content-Security-Policy-Report-Only' => null, 'X-Content-Security-Policy' => null],
115115
],
116116
[
117117
$nonce,
118118
['csp_script_nonce' => $responseScriptNonce, 'csp_style_nonce' => $responseStyleNonce],
119-
$this->createRequest(),
120-
$this->createResponse($responseNonceHeaders),
119+
self::createRequest(),
120+
self::createResponse($responseNonceHeaders),
121121
['Content-Security-Policy' => null, 'Content-Security-Policy-Report-Only' => null, 'X-Content-Security-Policy' => null],
122122
],
123123
[
124124
$nonce,
125125
['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce],
126-
$this->createRequest(),
127-
$this->createResponse(['Content-Security-Policy' => 'frame-ancestors https: ; form-action: https:', 'Content-Security-Policy-Report-Only' => 'frame-ancestors http: ; form-action: http:']),
126+
self::createRequest(),
127+
self::createResponse(['Content-Security-Policy' => 'frame-ancestors https: ; form-action: https:', 'Content-Security-Policy-Report-Only' => 'frame-ancestors http: ; form-action: http:']),
128128
['Content-Security-Policy' => 'frame-ancestors https: ; form-action: https:', 'Content-Security-Policy-Report-Only' => 'frame-ancestors http: ; form-action: http:', 'X-Content-Security-Policy' => null],
129129
],
130130
[
131131
$nonce,
132132
['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce],
133-
$this->createRequest(),
134-
$this->createResponse(['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'']),
133+
self::createRequest(),
134+
self::createResponse(['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'']),
135135
['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'; style-src \'self\' domain.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'; style-src \'self\' domain-report-only.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'X-Content-Security-Policy' => null],
136136
],
137137
[
138138
$nonce,
139139
['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce],
140-
$this->createRequest(),
141-
$this->createResponse(['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\'; style-src \'self\' \'unsafe-inline\'; style-src-elem \'self\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\'; style-src \'self\' \'unsafe-inline\'; style-src-elem \'self\'']),
140+
self::createRequest(),
141+
self::createResponse(['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\'; style-src \'self\' \'unsafe-inline\'; style-src-elem \'self\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\'; style-src \'self\' \'unsafe-inline\'; style-src-elem \'self\'']),
142142
['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'self\' \'unsafe-inline\'; style-src-elem \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'self\' \'unsafe-inline\'; style-src-elem \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'X-Content-Security-Policy' => null],
143143
],
144144
[
145145
$nonce,
146146
['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce],
147-
$this->createRequest(),
148-
$this->createResponse(['Content-Security-Policy' => 'default-src \'none\'', 'Content-Security-Policy-Report-Only' => 'default-src \'none\'']),
147+
self::createRequest(),
148+
self::createResponse(['Content-Security-Policy' => 'default-src \'none\'', 'Content-Security-Policy-Report-Only' => 'default-src \'none\'']),
149149
['Content-Security-Policy' => 'default-src \'none\'; script-src \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'Content-Security-Policy-Report-Only' => 'default-src \'none\'; script-src \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'X-Content-Security-Policy' => null],
150150
],
151151
[
152152
$nonce,
153153
['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce],
154-
$this->createRequest(),
155-
$this->createResponse(['Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\'']),
154+
self::createRequest(),
155+
self::createResponse(['Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\'']),
156156
['Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\'', 'X-Content-Security-Policy' => null],
157157
],
158158
[
159159
$nonce,
160160
['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce],
161-
$this->createRequest(),
162-
$this->createResponse(['Content-Security-Policy' => 'script-src \'self\'; style-src \'self\'']),
161+
self::createRequest(),
162+
self::createResponse(['Content-Security-Policy' => 'script-src \'self\'; style-src \'self\'']),
163163
['Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'X-Content-Security-Policy' => null],
164164
],
165165
[
166166
$nonce,
167167
['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce],
168-
$this->createRequest(),
169-
$this->createResponse(['X-Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\'']),
168+
self::createRequest(),
169+
self::createResponse(['X-Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\'']),
170170
['X-Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\'', 'Content-Security-Policy' => null],
171171
],
172172
[
173173
$nonce,
174174
['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce],
175-
$this->createRequest(),
176-
$this->createResponse(['X-Content-Security-Policy' => 'script-src \'self\'']),
175+
self::createRequest(),
176+
self::createResponse(['X-Content-Security-Policy' => 'script-src \'self\'']),
177177
['X-Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'Content-Security-Policy' => null],
178178
],
179179
[
180180
$nonce,
181181
['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce],
182-
$this->createRequest(),
183-
$this->createResponse(['X-Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\' \'sha384-LALALALALAAL\'']),
182+
self::createRequest(),
183+
self::createResponse(['X-Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\' \'sha384-LALALALALAAL\'']),
184184
['X-Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\' \'sha384-LALALALALAAL\' \'nonce-'.$nonce.'\'', 'Content-Security-Policy' => null],
185185
],
186186
[
187187
$nonce,
188188
['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce],
189-
$this->createRequest(),
190-
$this->createResponse(['Content-Security-Policy' => 'script-src \'self\'; style-src \'self\'', 'X-Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\'; style-src \'self\'']),
189+
self::createRequest(),
190+
self::createResponse(['Content-Security-Policy' => 'script-src \'self\'; style-src \'self\'', 'X-Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\'; style-src \'self\'']),
191191
['Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'X-Content-Security-Policy' => 'script-src \'self\' \'unsafe-inline\'; style-src \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\''],
192192
],
193193
];
194194
}
195195

196-
private function createRequest(array $headers = [])
196+
private static function createRequest(array $headers = [])
197197
{
198198
$request = new Request();
199199
$request->headers->add($headers);
200200

201201
return $request;
202202
}
203203

204-
private function createResponse(array $headers = [])
204+
private static function createResponse(array $headers = [])
205205
{
206206
$response = new Response();
207207
$response->headers->add($headers);
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\WebProfilerBundle\Tests\Twig;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bundle\WebProfilerBundle\Twig\WebProfilerExtension;
16+
use Symfony\Component\VarDumper\Cloner\VarCloner;
17+
use Twig\Environment;
18+
use Twig\Extension\CoreExtension;
19+
use Twig\Extension\EscaperExtension;
20+
21+
class WebProfilerExtensionTest extends TestCase
22+
{
23+
/**
24+
* @dataProvider provideMessages
25+
*/
26+
public function testDumpHeaderIsDisplayed(string $message, array $context, bool $dump1HasHeader, bool $dump2HasHeader)
27+
{
28+
class_exists(CoreExtension::class); // Load twig_convert_encoding()
29+
class_exists(EscaperExtension::class); // Load twig_escape_filter()
30+
31+
$twigEnvironment = $this->mockTwigEnvironment();
32+
$varCloner = new VarCloner();
33+
34+
$webProfilerExtension = new WebProfilerExtension();
35+
36+
$needle = 'window.Sfdump';
37+
38+
$dump1 = $webProfilerExtension->dumpLog($twigEnvironment, $message, $varCloner->cloneVar($context));
39+
self::assertSame($dump1HasHeader, str_contains($dump1, $needle));
40+
41+
$dump2 = $webProfilerExtension->dumpData($twigEnvironment, $varCloner->cloneVar([]));
42+
self::assertSame($dump2HasHeader, str_contains($dump2, $needle));
43+
}
44+
45+
public function provideMessages(): iterable
46+
{
47+
yield ['Some message', ['foo' => 'foo', 'bar' => 'bar'], false, true];
48+
yield ['Some message {@see some text}', ['foo' => 'foo', 'bar' => 'bar'], false, true];
49+
yield ['Some message {foo}', ['foo' => 'foo', 'bar' => 'bar'], true, false];
50+
yield ['Some message {foo}', ['bar' => 'bar'], false, true];
51+
}
52+
53+
private function mockTwigEnvironment()
54+
{
55+
$twigEnvironment = $this->createMock(Environment::class);
56+
57+
$twigEnvironment->expects($this->any())->method('getCharset')->willReturn('UTF-8');
58+
59+
return $twigEnvironment;
60+
}
61+
}

Twig/WebProfilerExtension.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,19 @@ public function dumpLog(Environment $env, string $message, Data $context = null)
9090
$message = twig_escape_filter($env, $message);
9191
$message = preg_replace('/&quot;(.*?)&quot;/', '&quot;<b>$1</b>&quot;', $message);
9292

93-
if (null === $context || !str_contains($message, '{')) {
93+
$replacements = [];
94+
foreach ($context ?? [] as $k => $v) {
95+
$k = '{'.twig_escape_filter($env, $k).'}';
96+
if (str_contains($message, $k)) {
97+
$replacements[$k] = $v;
98+
}
99+
}
100+
101+
if (!$replacements) {
94102
return '<span class="dump-inline">'.$message.'</span>';
95103
}
96104

97-
$replacements = [];
98-
foreach ($context as $k => $v) {
99-
$k = '{'.twig_escape_filter($env, $k).'}';
105+
foreach ($replacements as $k => $v) {
100106
$replacements['&quot;<b>'.$k.'</b>&quot;'] = $replacements['&quot;'.$k.'&quot;'] = $replacements[$k] = $this->dumpData($env, $v);
101107
}
102108

0 commit comments

Comments
 (0)