Skip to content

Commit

Permalink
Merge branch '3.1'
Browse files Browse the repository at this point in the history
* 3.1:
  [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)"
  [Serializer] Include the format in the cache key
  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

Conflicts:
	src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php
	src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
  • Loading branch information
nicolas-grekas committed Jul 17, 2016
2 parents 031b850 + 17de127 commit cbd1915
Show file tree
Hide file tree
Showing 15 changed files with 220 additions and 49 deletions.
6 changes: 3 additions & 3 deletions src/Symfony/Component/BrowserKit/Client.php
Expand Up @@ -542,9 +542,9 @@ protected function getAbsoluteUri($uri)
return parse_url($currentUri, PHP_URL_SCHEME).':'.$uri;
}

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

if ('/' !== $uri[0]) {
Expand Down
9 changes: 9 additions & 0 deletions src/Symfony/Component/BrowserKit/Tests/ClientTest.php
Expand Up @@ -212,6 +212,15 @@ public function testRequestURIConversion()
$client->request('GET', 'http://www.example.com/');
$client->request('GET', 'http');
$this->assertEquals('http://www.example.com/http', $client->getRequest()->getUri(), '->request() uses the previous request for relative URLs');

$client = new TestClient();
$client->request('GET', 'http://www.example.com/foo');
$client->request('GET', '?');
$this->assertEquals('http://www.example.com/foo?', $client->getRequest()->getUri(), '->request() uses the previous request for ?');
$client->request('GET', '?');
$this->assertEquals('http://www.example.com/foo?', $client->getRequest()->getUri(), '->request() uses the previous request for ?');
$client->request('GET', '?foo=bar');
$this->assertEquals('http://www.example.com/foo?foo=bar', $client->getRequest()->getUri(), '->request() uses the previous request for ?');
}

public function testRequestReferer()
Expand Down
Expand Up @@ -166,7 +166,7 @@ public function getRemovingPasses()
}

/**
* Gets all passes for the Merge pass.
* Gets the Merge pass.
*
* @return CompilerPassInterface
*/
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/HttpFoundation/Request.php
Expand Up @@ -1479,7 +1479,7 @@ public function isMethod($method)
*/
public function isMethodSafe()
{
return in_array($this->getMethod(), array('GET', 'HEAD'));
return in_array($this->getMethod(), array('GET', 'HEAD', 'OPTIONS', 'TRACE'));
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/Symfony/Component/HttpFoundation/Response.php
Expand Up @@ -377,6 +377,12 @@ public function send()
$this->sendHeaders();
$this->sendContent();

if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
} elseif ('cli' !== PHP_SAPI) {
static::closeOutputBuffers(0, true);
}

return $this;
}

Expand Down
26 changes: 26 additions & 0 deletions src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
Expand Up @@ -1977,6 +1977,32 @@ public function methodIdempotentProvider()
array('CONNECT', false),
);
}

/**
* @dataProvider methodSafeProvider
*/
public function testMethodSafe($method, $safe)
{
$request = new Request();
$request->setMethod($method);
$this->assertEquals($safe, $request->isMethodSafe());
}

public function methodSafeProvider()
{
return array(
array('HEAD', true),
array('GET', true),
array('POST', false),
array('PUT', false),
array('PATCH', false),
array('DELETE', false),
array('PURGE', false),
array('OPTIONS', true),
array('TRACE', true),
array('CONNECT', false),
);
}
}

class RequestContentProxy extends Request
Expand Down
8 changes: 0 additions & 8 deletions src/Symfony/Component/HttpKernel/Kernel.php
Expand Up @@ -134,14 +134,6 @@ public function terminate(Request $request, Response $response)
}

if ($this->getHttpKernel() instanceof TerminableInterface) {
if (!$this->debug) {
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
} elseif ('cli' !== PHP_SAPI) {
Response::closeOutputBuffers(0, true);
}
}

$this->getHttpKernel()->terminate($request, $response);
}
}
Expand Down
Expand Up @@ -65,7 +65,13 @@ public function getLastAuthenticationError($clearSession = true)
*/
public function getLastUsername()
{
$session = $this->getRequest()->getSession();
$request = $this->getRequest();

if ($request->attributes->has(Security::LAST_USERNAME)) {
return $request->attributes->get(Security::LAST_USERNAME);
}

$session = $request->getSession();

return null === $session ? '' : $session->get(Security::LAST_USERNAME);
}
Expand Down
Expand Up @@ -56,7 +56,7 @@ public function supportsNormalization($data, $format = null)
public function normalize($object, $format = null, array $context = array())
{
if (!isset($context['cache_key'])) {
$context['cache_key'] = $this->getCacheKey($context);
$context['cache_key'] = $this->getCacheKey($format, $context);
}

if ($this->isCircularReference($object, $context)) {
Expand Down Expand Up @@ -169,7 +169,7 @@ public function supportsDenormalization($data, $type, $format = null)
public function denormalize($data, $class, $format = null, array $context = array())
{
if (!isset($context['cache_key'])) {
$context['cache_key'] = $this->getCacheKey($context);
$context['cache_key'] = $this->getCacheKey($format, $context);
}
$allowedAttributes = $this->getAllowedAttributes($class, $context, true);
$normalizedData = $this->prepareForDenormalization($data);
Expand Down Expand Up @@ -336,14 +336,15 @@ private function isMaxDepthReached($class, $attribute, array &$context)
/**
* Gets the cache key to use.
*
* @param array $context
* @param string|null $format
* @param array $context
*
* @return bool|string
*/
private function getCacheKey(array $context)
private function getCacheKey($format, array $context)
{
try {
return md5(serialize($context));
return md5($format.serialize($context));
} catch (\Exception $exception) {
// The context cannot be serialized, skip the cache
return false;
Expand Down
4 changes: 3 additions & 1 deletion src/Symfony/Component/VarDumper/Caster/Caster.php
Expand Up @@ -45,14 +45,16 @@ public static function castObject($obj, \ReflectionClass $reflector)
{
if ($reflector->hasMethod('__debugInfo')) {
$a = $obj->__debugInfo();
} elseif ($obj instanceof \Closure) {
$a = array();
} else {
$a = (array) $obj;
}

if ($a) {
$p = array_keys($a);
foreach ($p as $i => $k) {
if (!isset($k[0]) || ("\0" !== $k[0] && !$reflector->hasProperty($k))) {
if (isset($k[0]) && "\0" !== $k[0] && !$reflector->hasProperty($k)) {
$p[$i] = self::PREFIX_DYNAMIC.$k;
} elseif (isset($k[16]) && "\0" === $k[16] && 0 === strpos($k, "\0class@anonymous\0")) {
$p[$i] = "\0".$reflector->getParentClass().'@anonymous'.strrchr($k, "\0");
Expand Down
Expand Up @@ -58,7 +58,7 @@ public static function castClosure(\Closure $c, array $a, Stub $stub, $isNested)
}

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

return $a;
}
Expand Down
70 changes: 47 additions & 23 deletions src/Symfony/Component/VarDumper/Cloner/VarCloner.php
Expand Up @@ -28,7 +28,7 @@ protected function doClone($var)
$i = 0; // Current iteration position in $queue
$len = 1; // Length of $queue
$pos = 0; // Number of cloned items past the first level
$refs = 0; // Hard references counter
$refsCounter = 0; // Hard references counter
$queue = array(array($var)); // This breadth-first queue is the return value
$arrayRefs = array(); // Map of queue indexes to stub array objects
$hardRefs = array(); // Map of original zval hashes to stub objects
Expand Down Expand Up @@ -60,27 +60,32 @@ protected function doClone($var)
for ($i = 0; $i < $len; ++$i) {
$indexed = true; // Whether the currently iterated array is numerically indexed or not
$j = -1; // Position in the currently iterated array
$step = $queue[$i]; // Copy of the currently iterated array used for hard references detection
foreach ($step as $k => $v) {
$fromObjCast = array_keys($queue[$i]);
$fromObjCast = array_keys(array_flip($fromObjCast)) !== $fromObjCast;
$refs = $vals = $fromObjCast ? array_values($queue[$i]) : $queue[$i];
foreach ($queue[$i] as $k => $v) {
// $k is the original key
// $v is the original value or a stub object in case of hard references
if ($indexed && $k !== ++$j) {
if ($k !== ++$j) {
$indexed = false;
}
if ($fromObjCast) {
$k = $j;
}
if ($useExt) {
$zval = symfony_zval_info($k, $step);
$zval = symfony_zval_info($k, $refs);
} else {
$step[$k] = $cookie;
if ($zval['zval_isref'] = $queue[$i][$k] === $cookie) {
$refs[$k] = $cookie;
if ($zval['zval_isref'] = $vals[$k] === $cookie) {
$zval['zval_hash'] = $v instanceof Stub ? spl_object_hash($v) : null;
}
$zval['type'] = gettype($v);
}
if ($zval['zval_isref']) {
$queue[$i][$k] = &$stub; // Break hard references to make $queue completely
$vals[$k] = &$stub; // Break hard references to make $queue completely
unset($stub); // independent from the original structure
if (isset($hardRefs[$zval['zval_hash']])) {
$queue[$i][$k] = $useExt ? ($v = $hardRefs[$zval['zval_hash']]) : ($step[$k] = $v);
$vals[$k] = $useExt ? ($v = $hardRefs[$zval['zval_hash']]) : ($refs[$k] = $v);
if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) {
++$v->value->refCount;
}
Expand Down Expand Up @@ -204,18 +209,18 @@ protected function doClone($var)
if (isset($stub)) {
if ($zval['zval_isref']) {
if ($useExt) {
$queue[$i][$k] = $hardRefs[$zval['zval_hash']] = $v = new Stub();
$vals[$k] = $hardRefs[$zval['zval_hash']] = $v = new Stub();
$v->value = $stub;
} else {
$step[$k] = new Stub();
$step[$k]->value = $stub;
$h = spl_object_hash($step[$k]);
$queue[$i][$k] = $hardRefs[$h] = &$step[$k];
$refs[$k] = new Stub();
$refs[$k]->value = $stub;
$h = spl_object_hash($refs[$k]);
$vals[$k] = $hardRefs[$h] = &$refs[$k];
$values[$h] = $v;
}
$queue[$i][$k]->handle = ++$refs;
$vals[$k]->handle = ++$refsCounter;
} else {
$queue[$i][$k] = $stub;
$vals[$k] = $stub;
}

if ($a) {
Expand Down Expand Up @@ -243,19 +248,38 @@ protected function doClone($var)
$stub = $a = null;
} elseif ($zval['zval_isref']) {
if ($useExt) {
$queue[$i][$k] = $hardRefs[$zval['zval_hash']] = new Stub();
$queue[$i][$k]->value = $v;
$vals[$k] = $hardRefs[$zval['zval_hash']] = new Stub();
$vals[$k]->value = $v;
} else {
$step[$k] = $queue[$i][$k] = new Stub();
$step[$k]->value = $v;
$h = spl_object_hash($step[$k]);
$hardRefs[$h] = &$step[$k];
$refs[$k] = $vals[$k] = new Stub();
$refs[$k]->value = $v;
$h = spl_object_hash($refs[$k]);
$hardRefs[$h] = &$refs[$k];
$values[$h] = $v;
}
$queue[$i][$k]->handle = ++$refs;
$vals[$k]->handle = ++$refsCounter;
}
}

if ($fromObjCast) {
$refs = $vals;
$vals = array();
$j = -1;
foreach ($queue[$i] as $k => $v) {
foreach (array($k => $v) as $a => $v) {
}
if ($a !== $k) {
$vals = (object) $vals;
$vals->{$k} = $refs[++$j];
$vals = (array) $vals;
} else {
$vals[$k] = $refs[++$j];
}
}
}

$queue[$i] = $vals;

if (isset($arrayRefs[$i])) {
if ($indexed) {
$arrayRefs[$i]->class = Stub::ARRAY_INDEXED;
Expand Down
39 changes: 39 additions & 0 deletions src/Symfony/Component/VarDumper/Tests/CliDumperTest.php
Expand Up @@ -128,6 +128,45 @@ public function testXmlResource()
);
}

public function testJsonCast()
{
$var = (array) json_decode('{"0":{},"1":null}');
foreach ($var as &$v) {
}
$var[] = &$v;
$var[''] = 2;

$this->assertDumpMatchesFormat(
<<<EOTXT
array:4 [
"0" => {}
"1" => &1 null
0 => &1 null
"" => 2
]
EOTXT
,
$var
);
}

public function testObjectCast()
{
$var = (object) array(1 => 1);
$var->{1} = 2;

$this->assertDumpMatchesFormat(
<<<EOTXT
{
+1: 1
+"1": 2
}
EOTXT
,
$var
);
}

public function testClosedResource()
{
if (defined('HHVM_VERSION') && HHVM_VERSION_ID < 30600) {
Expand Down

0 comments on commit cbd1915

Please sign in to comment.