8000 Merge branch '2.7' into 2.8 · symfony/symfony@7a57903 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7a57903

Browse files
Merge branch '2.7' into 2.8
* 2.7: [VarDumper] Fix dumping jsons casted as arrays PassConfig::getMergePass is not an array Revert "bug #19114 [HttpKernel] Dont close the reponse stream in debug (nicolas-grekas)" Fix the retrieval of the last username when using forwarding [Yaml] Fix PHPDoc of the Yaml class [HttpFoundation] Add OPTIONS and TRACE to the list of safe methods Update getAbsoluteUri() for query string uris
2 parents 1f2d6fb + 4590759 commit 7a57903

File tree

14 files changed

+215
-45
lines changed

14 files changed

+215
-45
lines changed

src/Symfony/Component/BrowserKit/Client.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -542,9 +542,9 @@ protected function getAbsoluteUri($uri)
542542
return parse_url($currentUri, PHP_URL_SCHEME).':'.$uri;
543543
}
544544

545-
// anchor?
546-
if (!$uri || '#' == $uri[0]) {
547-
return preg_replace('/#.*?$/', '', $currentUri).$uri;
545+
// anchor or query string parameters?
546+
if (!$uri || '#' == $uri[0] || '?' == $uri[0]) {
547+
return preg_replace('/[#?].*?$/', '', $currentUri).$uri;
548548
}
549549

550550
if ('/' !== $uri[0]) {

src/Symfony/Component/BrowserKit/Tests/ClientTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,15 @@ public function testRequestURIConversion()
212212
$client->request('GET', 'http://www.example.com/');
213213
$client->request('GET', 'http');
214214
$this->assertEquals('http://www.example.com/http', $client->getRequest()->getUri(), '->request() uses the previous request for relative URLs');
215+
216+
$client = new TestClient();
217+
$client->request('GET', 'http://www.example.com/foo');
218+
$client->request('GET', '?');
219+
$this->assertEquals('http://www.example.com/foo?', $client->getRequest()->getUri(), '->request() uses the previous request for ?');
220+
$client->request('GET', '?');
221+
$this->assertEquals('http://www.example.com/foo?', $client->getRequest()->getUri(), '->request() uses the previous request for ?');
222+
$client->request('GET', '?foo=bar');
223+
$this->assertEquals('http://www.example.com/foo?foo=bar', $client->getRequest()->getUri(), '->request() uses the previous request for ?');
215224
}
216225

217226
public function testRequestReferer()

src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,9 @@ public function getRemovingPasses()
153153
}
154154

155155
/**
156-
* Gets all passes for the Merge pass.
156+
* Gets the Merge pass.
157157
*
158-
* @return array An array of passes
158+
* @return CompilerPassInterface The merge pass
159159
*/
160160
public function getMergePass()
161161
{

src/Symfony/Component/HttpFoundation/Request.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,7 @@ public function isMethod($method)
14761476
*/
14771477
public function isMethodSafe()
14781478
{
1479-
return in_array($this->getMethod(), array('GET', 'HEAD'));
1479+
return in_array($this->getMethod(), array('GET', 'HEAD', 'OPTIONS', 'TRACE'));
14801480
}
14811481

14821482
/**

src/Symfony/Component/HttpFoundation/Response.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,12 @@ public function send()
373373
$this->sendHeaders();
374374
$this->sendContent();
375375

376+
if (function_exists('fastcgi_finish_request')) {
377+
fastcgi_finish_request();
378+
} elseif ('cli' !== PHP_SAPI) {
379+
static::closeOutputBuffers(0, true);
380+
}
381+
376382
return $this;
377383
}
378384

src/Symfony/Component/HttpFoundation/Tests/RequestTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,6 +1912,32 @@ public function getLongHostNames()
19121912
array(str_repeat(':', 101)),
19131913
);
19141914
}
1915+
1916+
/**
1917+
* @dataProvider methodSafeProvider
1918+
*/
1919+
public function testMethodSafe($method, $safe)
1920+
{
1921+
$request = new Request();
1922+
$request->setMethod($method);
1923+
$this->assertEquals($safe, $request->isMethodSafe());
1924+
}
1925+
1926+
public function methodSafeProvider()
1927+
{
1928+
return array(
1929+
array('HEAD', true),
1930+
array('GET', true),
1931+
array('POST', false),
1932+
array('PUT', false),
1933+
array('PATCH', false),
1934+
array('DELETE', false),
1935+
array('PURGE', false),
1936+
array('OPTIONS', true),
1937+
array('TRACE', true),
1938+
array('CONNECT', false),
1939+
);
1940+
}
19151941
}
19161942

19171943
class RequestContentProxy extends Request

src/Symfony/Component/HttpKernel/Kernel.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,6 @@ public function terminate(Request $request, Response $response)
150150
}
151151

152152
if ($this->getHttpKernel() instanceof TerminableInterface) {
153-
if (!$this->debug) {
154-
if (function_exists('fastcgi_finish_request')) {
155-
fastcgi_finish_request();
156-
} elseif ('cli' !== PHP_SAPI) {
157-
Response::closeOutputBuffers(0, true);
158-
}
159-
}
160-
161153
$this->getHttpKernel()->terminate($request, $response);
162154
}
163155
}

src/Symfony/Component/Security/Http/Authentication/AuthenticationUtils.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,13 @@ public function getLastAuthenticationError($clearSession = true)
6565
*/
6666
public function getLastUsername()
6767
{
68-
$session = $this->getRequest()->getSession();
68+
$request = $this->getRequest();
69+
70+
if ($request->attributes->has(Security::LAST_USERNAME)) {
71+
return $request->attributes->get(Security::LAST_USERNAME);
72+
}
73+
74+
$session = $request->getSession();
6975

7076
return null === $session ? '' : $session->get(Security::LAST_USERNAME);
7177
}

src/Symfony/Component/VarDumper/Caster/Caster.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,16 @@ public static function castObject($obj, \ReflectionClass $reflector)
4545
{
4646
if ($reflector->hasMethod('__debugInfo')) {
4747
$a = $obj->__debugInfo();
48+
} elseif ($obj instanceof \Closure) {
49+
$a = array();
4850
} else {
4951
$a = (array) $obj;
5052
}
5153

5254
if ($a) {
5355
$p = array_keys($a);
5456
foreach ($p as $i => $k) {
55-
if (!isset($k[0]) || ("\0" !== $k[0] && !$reflector->hasProperty($k))) {
57+
if (isset($k[0]) && "\0" !== $k[0] && !$reflector->hasProperty($k)) {
5658
$p[$i] = self::PREFIX_DYNAMIC.$k;
5759
} elseif (isset($k[16]) && "\0" === $k[16] && 0 === strpos($k, "\0class@anonymous\0")) {
5860
$p[$i] = "\0".$reflector->getParentClass().'@anonymous'.strrchr($k, "\0");

src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public static function castClosure(\Closure $c, array $a, Stub $stub, $isNested)
6969
}
7070

7171
$prefix = Caster::PREFIX_DYNAMIC;
72-
unset($a['name'], $a[$prefix.'0'], $a[$prefix.'this'], $a[$prefix.'parameter'], $a[Caster::PREFIX_VIRTUAL.'extra']);
72+
unset($a['name'], $a[$prefix.'this'], $a[$prefix.'parameter'], $a[Caster::PREFIX_VIRTUAL.'extra']);
7373

7474
return $a;
7575
}

src/Symfony/Component/VarDumper/Cloner/VarCloner.php

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ protected function doClone($var)
2828
$i = 0; // Current iteration position in $queue
2929
$len = 1; // Length of $queue
3030
$pos = 0; // Number of cloned items past the first level
31-
$refs = 0; // Hard references counter
31+
$refsCounter = 0; // Hard references counter
3232
$queue = array(array($var)); // This breadth-first queue is the return value
3333
$arrayRefs = array(); // Map of queue indexes to stub array objects
3434
$hardRefs = array(); // Map of original zval hashes to stub objects
@@ -60,27 +60,32 @@ protected function doClone($ 10000 var)
6060
for ($i = 0; $i < $len; ++$i) {
6161
$indexed = true; // Whether the currently iterated array is numerically indexed or not
6262
$j = -1; // Position in the currently iterated array
63-
$step = $queue[$i]; // Copy of the currently iterated array used for hard references detection
64-
foreach ($step as $k => $v) {
63+
$fromObjCast = array_keys($queue[$i]);
64+
$fromObjCast = array_keys(array_flip($fromObjCast)) !== $fromObjCast;
65+
$refs = $vals = $fromObjCast ? array_values($queue[$i]) : $queue[$i];
66+
foreach ($queue[$i] as $k => $v) {
6567
// $k is the original key
6668
// $v is the original value or a stub object in case of hard references
67-
if ($indexed && $k !== ++$j) {
69+
if ($k !== ++$j) {
6870
$indexed = false;
6971
}
72+
if ($fromObjCast) {
73+
$k = $j;
74+
}
7075
if ($useExt) {
71-
$zval = symfony_zval_info($k, $step);
76+
$zval = symfony_zval_info($k, $refs);
7277
} else {
73-
$step[$k] = $cookie;
74-
if ($zval['zval_isref'] = $queue[$i][$k] === $cookie) {
78+
$refs[$k] = $cookie;
79+
if ($zval['zval_isref'] = $vals[$k] === $cookie) {
7580
$zval['zval_hash'] = $v instanceof Stub ? spl_object_hash($v) : null;
7681
}
7782
$zval['type'] = gettype($v);
7883
}
7984
if ($zval['zval_isref']) {
80-
$queue[$i][$k] = &$stub; // Break hard references to make $queue completely
85+
$vals[$k] = &$stub; // Break hard references to make $queue completely
8186
unset($stub); // independent from the original structure
8287
if (isset($hardRefs[$zval['zval_hash']])) {
83-
$queue[$i][$k] = $useExt ? ($v = $hardRefs[$zval['zval_hash']]) : ($step[$k] = $v);
88+
$vals[$k] = $useExt ? ($v = $hardRefs[$zval['zval_hash']]) : ($refs[$k] = $v);
8489
if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) {
8590
++$v->value->refCount;
8691
}
@@ -204,18 +209,18 @@ protected function doClone($var)
204209
if (isset($stub)) {
205210
if ($zval['zval_isref']) {
206211
if ($useExt) {
207-
$queue[$i][$k] = $hardRefs[$zval['zval_hash']] = $v = new Stub();
212+
$vals[$k] = $hardRefs[$zval['zval_hash']] = $v = new Stub();
208213
$v->value = $stub;
209214
} else {
210-
$step[$k] = new Stub();
211-
$step[$k]->value = $stub;
212-
$h = spl_object_hash($step[$k]);
213-
$queue[$i][$k] = $hardRefs[$h] = &$step[$k];
215+
$refs[$k] = new Stub();
216+
$refs[$k]->value = $stub;
217+
$h = spl_object_hash($refs[$k]);
218+
$vals[$k] = $hardRefs[$h] = &$refs[$k];
214219
$values[$h] = $v;
215220
}
216-
$queue[$i][$k]->handle = ++$refs;
221+
$vals[$k]->handle = ++$refsCounter;
217222
} else {
218-
$queue[$i][$k] = $stub;
223+
$vals[$k] = $stub;
219224
}
220225

221226
if ($a) {
@@ -243,19 +248,38 @@ protected function doClone($var)
243248
$stub = $a = null;
244249
} elseif ($zval['zval_isref']) {
245250
if ($useExt) {
246-
$queue[$i][$k] = $hardRefs[$zval['zval_hash']] = new Stub();
247-
$queue[$i][$k]->value = $v;
251+
$vals[$k] = $hardRefs[$zval['zval_hash']] = new Stub();
252+
$vals[$k]->value = $v;
248253
} else {
249-
$step[$k] = $queue[$i][$k] = new Stub();
250-
$step[$k]->value = $v;
251-
$h = spl_object_hash($step[$k]);
252-
$hardRefs[$h] = &$step[$k];
254+
$refs[$k] = $vals[$k] = new Stub();
255+
$refs[$k]->value = $v;
256+
$h = spl_object_hash($refs[$k]);
257+
$hardRefs[$h] = &$refs[$k];
253258
$values[$h] = $v;
254259
}
255-
$queue[$i][$k]->handle = ++$refs;
260+
$vals[$k]->handle = ++$refsCounter;
261+
}
262+
}
263+
264+
if ($fromObjCast) {
265+
$refs = $vals;
266+
$vals = array();
267+
$j = -1;
268+
foreach ($queue[$i] as $k => $v) {
269+
foreach (array($k => $v) as $a => $v) {
270+
}
271+
if ($a !== $k) {
272+
$vals = (object) $vals;
273+
$vals->{$k} = $refs[++$j];
274+
$vals = (array) $vals;
275+
} else {
276+
$vals[$k] = $refs[++$j];
277+
}
256278
}
257279
}
258280

281+
$queue[$i] = $vals;
282+
259283
if (isset($arrayRefs[$i])) {
260284
if ($indexed) {
261285
$arrayRefs[$i]->class = Stub::ARRAY_INDEXED;

src/Symfony/Component/VarDumper/Tests/CliDumperTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,45 @@ public function testXmlResource()
133133
);
134134
}
135135

136+
public function testJsonCast()
137+
{
138+
$var = (array) json_decode('{"0":{},"1":null}');
139+
foreach ($var as &$v) {
140+
}
141+
$var[] = &$v;
142+
$var[''] = 2;
143+
144+
$this->assertDumpMatchesFormat(
145+
<<<EOTXT
146+
array:4 [
147+
"0" => {}
148+
"1" => &1 null
149+
0 => &1 null
150+
"" => 2
151+
]
152+
EOTXT
153+
,
154+
$var
155+
);
156+
}
157+
158+
public function testObjectCast()
159+
{
160+
$var = (object) array(1 => 1);
161+
$var->{1} = 2;
162+
163+
$this->assertDumpMatchesFormat(
164+
<<<EOTXT
165+
{
166+
+1: 1
167+
+"1": 2
168+
}
169+
EOTXT
170+
,
171+
$var
172+
);
173+
}
174+
136175
public function testClosedResource()
137176
{
138177
if (defined('HHVM_VERSION') && HHVM_VERSION_ID < 30600) {

src/Symfony/Component/VarDumper/Tests/VarClonerTest.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,72 @@ public function testClone()
135135
$this->assertStringMatchesFormat($expected, print_r($clone, true));
136136
}
137137

138+
public function testJsonCast()
139+
{
140+
$data = (array) json_decode('{"1":{}}');
141+
142+
$cloner = new VarCloner();
143+
$clone = $cloner->cloneVar($data);
144+
145+
$expected = <<<'EOTXT'
146+
object(Symfony\Component\VarDumper\Cloner\Data)#%i (4) {
147+
["data":"Symfony\Component\VarDumper\Cloner\Data":private]=>
148+
array(2) {
149+
[0]=>
150+
array(1) {
151+
[0]=>
152+
object(Symfony\Component\VarDumper\Cloner\Stub)#%i (7) {
153+
["type"]=>
154+
string(5) "array"
155+
["class"]=>
156+
string(5) "assoc"
157+
["value"]=>
158+
int(1)
159+
["cut"]=>
160+
int(0)
161+
["handle"]=>
162+
int(0)
163+
["refCount"]=>
164+
int(0)
165+
["position"]=>
166+
int(1)
167+
}
168+
}
169+
[1]=>
170+
array(1) {
171+
["1"]=>
172+
object(Symfony\Component\VarDumper\Cloner\Stub)#%i (7) {
173+
["type"]=>
174+
string(6) "object"
175+
["class"]=>
176+
string(8) "stdClass"
177+
["value"]=>
178+
NULL
179+
["cut"]=>
180+
int(0)
181+
["handle"]=>
182+
int(%i)
183+
["refCount"]=>
184+
int(0)
185+
["position"]=>
186+
int(0)
187+
}
188+
}
189+
}
190+
["maxDepth":"Symfony\Component\VarDumper\Cloner\Data":private]=>
191+
int(20)
192+
["maxItemsPerDepth":"Symfony\Component\VarDumper\Cloner\Data":private]=>
193+
int(-1)
194+
["useRefHandles":"Symfony\Component\VarDumper\Cloner\Data":private]=>
195+
int(-1)
196+
}
197+
198+
EOTXT;
199+
ob_start();
200+
var_dump($clone);
201+
$this->assertStringMatchesFormat($expected, ob_get_clean());
202+
}
203+
138204
public function testCaster()
139205
{
140206
$cloner = new VarCloner(array(

0 commit comments

Comments
 (0)
0