Skip to content

Commit

Permalink
Merge branch '3.4' into 4.0
Browse files Browse the repository at this point in the history
* 3.4:
  Add color support for Hyper terminal .
  [HttpFoundation] Fix tests: new message for status 425
  [Doctrine Bridge] Fixed usage of wrong variable when tagged subscriber is invalid
  [PropertyInfo] added handling of nullable types in PhpDoc
  [HttpKernel] Make AbstractTestSessionListener compatible with CookieClearingLogoutHandler
  [Cache] provider does not respect option maxIdLength with versioning enabled
  • Loading branch information
nicolas-grekas committed Jul 3, 2018
2 parents cfde207 + 771c22b commit 4ce5a1b
Show file tree
Hide file tree
Showing 16 changed files with 127 additions and 14 deletions.
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -101,7 +101,7 @@
},
"conflict": {
"phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2",
"phpdocumentor/type-resolver": "<0.2.1",
"phpdocumentor/type-resolver": "<0.3.0",
"phpunit/phpunit": "<5.4.3"
},
"provide": {
Expand Down
Expand Up @@ -68,7 +68,7 @@ private function addTaggedSubscribers(ContainerBuilder $container)
$connections = isset($tag['connection']) ? array($tag['connection']) : array_keys($this->connections);
foreach ($connections as $con) {
if (!isset($this->connections[$con])) {
throw new RuntimeException(sprintf('The Doctrine connection "%s" referenced in service "%s" does not exist. Available connections names: %s', $con, $taggedSubscriber, implode(', ', array_keys($this->connections))));
throw new RuntimeException(sprintf('The Doctrine connection "%s" referenced in service "%s" does not exist. Available connections names: %s', $con, $id, implode(', ', array_keys($this->connections))));
}

$this->getEventManagerDef($container, $con)->addMethodCall('addEventSubscriber', array(new Reference($id)));
Expand Down
3 changes: 2 additions & 1 deletion src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php
Expand Up @@ -316,7 +316,8 @@ private static function hasColorSupport()
&& sapi_windows_vt100_support(STDOUT))
|| false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
|| 'xterm' === getenv('TERM');
|| 'xterm' === getenv('TERM')
|| 'Hyper' === getenv('TERM_PROGRAM');
}

if (function_exists('stream_isatty')) {
Expand Down
Expand Up @@ -34,6 +34,34 @@ public function testLongKey()
$cache->hasItem(str_repeat('-', 39));
}

public function testLongKeyVersioning()
{
$cache = $this->getMockBuilder(MaxIdLengthAdapter::class)
->setConstructorArgs(array(str_repeat('-', 26)))
->getMock();

$reflectionClass = new \ReflectionClass(AbstractAdapter::class);

$reflectionMethod = $reflectionClass->getMethod('getId');
$reflectionMethod->setAccessible(true);

// No versioning enabled
$this->assertEquals('--------------------------:------------', $reflectionMethod->invokeArgs($cache, array(str_repeat('-', 12))));
$this->assertLessThanOrEqual(50, strlen($reflectionMethod->invokeArgs($cache, array(str_repeat('-', 12)))));
$this->assertLessThanOrEqual(50, strlen($reflectionMethod->invokeArgs($cache, array(str_repeat('-', 23)))));
$this->assertLessThanOrEqual(50, strlen($reflectionMethod->invokeArgs($cache, array(str_repeat('-', 40)))));

$reflectionProperty = $reflectionClass->getProperty('versioningIsEnabled');
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue($cache, true);

// Versioning enabled
$this->assertEquals('--------------------------:1:------------', $reflectionMethod->invokeArgs($cache, array(str_repeat('-', 12))));
$this->assertLessThanOrEqual(50, strlen($reflectionMethod->invokeArgs($cache, array(str_repeat('-', 12)))));
$this->assertLessThanOrEqual(50, strlen($reflectionMethod->invokeArgs($cache, array(str_repeat('-', 23)))));
$this->assertLessThanOrEqual(50, strlen($reflectionMethod->invokeArgs($cache, array(str_repeat('-', 40)))));
}

/**
* @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException
* @expectedExceptionMessage Namespace must be 26 chars max, 40 given ("----------------------------------------")
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/Cache/Traits/AbstractTrait.php
Expand Up @@ -255,7 +255,7 @@ private function getId($key)
return $this->namespace.$this->namespaceVersion.$key;
}
if (\strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) {
$id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), ':', -22);
$id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), ':', -(\strlen($this->namespaceVersion) + 22));
}

return $id;
Expand Down
3 changes: 2 additions & 1 deletion src/Symfony/Component/Console/Output/StreamOutput.php
Expand Up @@ -98,7 +98,8 @@ protected function hasColorSupport()
&& @sapi_windows_vt100_support($this->stream))
|| false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
|| 'xterm' === getenv('TERM');
|| 'xterm' === getenv('TERM')
|| 'Hyper' === getenv('TERM_PROGRAM');
}

if (function_exists('stream_isatty')) {
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/Console/Style/SymfonyStyle.php
Expand Up @@ -269,7 +269,7 @@ public function createProgressBar($max = 0)
{
$progressBar = parent::createProgressBar($max);

if ('\\' !== DIRECTORY_SEPARATOR) {
if ('\\' !== DIRECTORY_SEPARATOR || 'Hyper' === getenv('TERM_PROGRAM')) {
$progressBar->setEmptyBarCharacter('░'); // light shade character \u2591
$progressBar->setProgressCharacter('');
$progressBar->setBarCharacter('▓'); // dark shade character \u2593
Expand Down
7 changes: 6 additions & 1 deletion src/Symfony/Component/HttpFoundation/Response.php
Expand Up @@ -64,7 +64,12 @@ class Response
const HTTP_UNPROCESSABLE_ENTITY = 422; // RFC4918
const HTTP_LOCKED = 423; // RFC4918
const HTTP_FAILED_DEPENDENCY = 424; // RFC4918

/**
* @deprecated
*/
const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425; // RFC2817
const HTTP_TOO_EARLY = 425; // RFC-ietf-httpbis-replay-04
const HTTP_UPGRADE_REQUIRED = 426; // RFC2817
const HTTP_PRECONDITION_REQUIRED = 428; // RFC6585
const HTTP_TOO_MANY_REQUESTS = 429; // RFC6585
Expand Down Expand Up @@ -169,7 +174,7 @@ class Response
422 => 'Unprocessable Entity', // RFC4918
423 => 'Locked', // RFC4918
424 => 'Failed Dependency', // RFC4918
425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817
425 => 'Too Early', // RFC-ietf-httpbis-replay-04
426 => 'Upgrade Required', // RFC2817
428 => 'Precondition Required', // RFC6585
429 => 'Too Many Requests', // RFC6585
Expand Down
Expand Up @@ -71,6 +71,13 @@ public function onKernelResponse(FilterResponseEvent $event)

if ($session instanceof Session ? !$session->isEmpty() || (null !== $this->sessionId && $session->getId() !== $this->sessionId) : $wasStarted) {
$params = session_get_cookie_params();

foreach ($event->getResponse()->headers->getCookies() as $cookie) {
if ($session->getName() === $cookie->getName() && $params['path'] === $cookie->getPath() && $params['domain'] == $cookie->getDomain()) {
return;
}
}

$event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']));
$this->sessionId = $session->getId();
}
Expand Down
Expand Up @@ -106,6 +106,36 @@ public function testEmptySessionWithNewSessionIdDoesSendCookie()
$this->assertNotEmpty($response->headers->getCookies());
}

/**
* @dataProvider anotherCookieProvider
*/
public function testSessionWithNewSessionIdAndNewCookieDoesNotSendAnotherCookie($existing, array $expected)
{
$this->sessionHasBeenStarted();
$this->sessionIsEmpty();
$this->fixSessionId('456');

$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$request = Request::create('/', 'GET', array(), array('MOCKSESSID' => '123'));
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$this->listener->onKernelRequest($event);

$response = new Response('', 200, array('Set-Cookie' => $existing));

$response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST, $response);

$this->assertSame($expected, $response->headers->get('Set-Cookie', null, false));
}

public function anotherCookieProvider()
{
return array(
'same' => array('MOCKSESSID=789; path=/', array('MOCKSESSID=789; path=/')),
'different domain' => array('MOCKSESSID=789; path=/; domain=example.com', array('MOCKSESSID=789; path=/; domain=example.com', 'MOCKSESSID=456; path=/')),
'different path' => array('MOCKSESSID=789; path=/foo', array('MOCKSESSID=789; path=/foo', 'MOCKSESSID=456; path=/')),
);
}

public function testUnstartedSessionIsNotSave()
{
$this->sessionHasNotBeenStarted();
Expand All @@ -123,10 +153,10 @@ public function testDoesNotImplementServiceSubscriberInterface()
$this->assertFalse(is_subclass_of(TestSessionListener::class, ServiceSubscriberInterface::class, 'Implementing ServiceSubscriberInterface would create a dep on the DI component, which eg Silex cannot afford'));
}

private function filterResponse(Request $request, $type = HttpKernelInterface::MASTER_REQUEST)
private function filterResponse(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, Response $response = null)
{
$request->setSession($this->session);
$response = new Response();
$response = $response ?: new Response();
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$event = new FilterResponseEvent($kernel, $request, $type, $response);

Expand Down
Expand Up @@ -94,6 +94,9 @@ public function typesProvider()
array('e', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_RESOURCE))), null, null),
array('f', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTime'))), null, null),
array('g', array(new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true)), 'Nullable array.', null),
array('h', array(new Type(Type::BUILTIN_TYPE_STRING, true)), null, null),
array('i', array(new Type(Type::BUILTIN_TYPE_STRING, true), new Type(Type::BUILTIN_TYPE_INT, true)), null, null),
array('j', array(new Type(Type::BUILTIN_TYPE_OBJECT, true, 'DateTime')), null, null),
array('donotexist', null, null, null),
array('staticGetter', null, null, null),
array('staticSetter', null, null, null),
Expand Down Expand Up @@ -130,6 +133,9 @@ public function typesWithCustomPrefixesProvider()
array('e', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_RESOURCE))), null, null),
array('f', array(new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTime'))), null, null),
array('g', array(new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true)), 'Nullable array.', null),
array('h', array(new Type(Type::BUILTIN_TYPE_STRING, true)), null, null),
array('i', array(new Type(Type::BUILTIN_TYPE_STRING, true), new Type(Type::BUILTIN_TYPE_INT, true)), null, null),
array('j', array(new Type(Type::BUILTIN_TYPE_OBJECT, true, 'DateTime')), null, null),
array('donotexist', null, null, null),
array('staticGetter', null, null, null),
array('staticSetter', null, null, null),
Expand Down Expand Up @@ -165,6 +171,9 @@ public function typesWithNoPrefixesProvider()
array('e', null, null, null),
array('f', null, null, null),
array('g', array(new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true)), 'Nullable array.', null),
array('h', array(new Type(Type::BUILTIN_TYPE_STRING, true)), null, null),
array('i', array(new Type(Type::BUILTIN_TYPE_STRING, true), new Type(Type::BUILTIN_TYPE_INT, true)), null, null),
array('j', array(new Type(Type::BUILTIN_TYPE_OBJECT, true, 'DateTime')), null, null),
array('donotexist', null, null, null),
array('staticGetter', null, null, null),
array('staticSetter', null, null, null),
Expand Down
Expand Up @@ -41,6 +41,9 @@ public function testGetProperties()
'B',
'Guid',
'g',
'h',
'i',
'j',
'emptyVar',
'foo',
'foo2',
Expand Down Expand Up @@ -77,6 +80,9 @@ public function testGetPropertiesWithCustomPrefixes()
'B',
'Guid',
'g',
'h',
'i',
'j',
'emptyVar',
'foo',
'foo2',
Expand Down Expand Up @@ -105,6 +111,9 @@ public function testGetPropertiesWithNoPrefixes()
'B',
'Guid',
'g',
'h',
'i',
'j',
'emptyVar',
'foo',
'foo2',
Expand Down
15 changes: 15 additions & 0 deletions src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php
Expand Up @@ -68,6 +68,21 @@ class Dummy extends ParentDummy
*/
public $g;

/**
* @var ?string
*/
public $h;

/**
* @var ?string|int
*/
public $i;

/**
* @var ?\DateTime
*/
public $j;

/**
* This should not be removed.
*
Expand Down
10 changes: 8 additions & 2 deletions src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php
Expand Up @@ -14,6 +14,7 @@
use phpDocumentor\Reflection\Type as DocType;
use phpDocumentor\Reflection\Types\Compound;
use phpDocumentor\Reflection\Types\Null_;
use phpDocumentor\Reflection\Types\Nullable;
use Symfony\Component\PropertyInfo\Type;

/**
Expand All @@ -34,6 +35,11 @@ public function getTypes(DocType $varType): array
$types = array();
$nullable = false;

if ($varType instanceof Nullable) {
$nullable = true;
$varType = $varType->getActualType();
}

if (!$varType instanceof Compound) {
if ($varType instanceof Null_) {
$nullable = true;
Expand All @@ -54,10 +60,10 @@ public function getTypes(DocType $varType): array

// If null is present, all types are nullable
$nullKey = array_search(Type::BUILTIN_TYPE_NULL, $varTypes);
$nullable = false !== $nullKey;
$nullable = $nullable || false !== $nullKey;

// Remove the null type from the type if other types are defined
if ($nullable && count($varTypes) > 1) {
if ($nullable && false !== $nullKey && count($varTypes) > 1) {
unset($varTypes[$nullKey]);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/PropertyInfo/composer.json
Expand Up @@ -35,7 +35,7 @@
},
"conflict": {
"phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2",
"phpdocumentor/type-resolver": "<0.2.1",
"phpdocumentor/type-resolver": "<0.3.0",
"symfony/dependency-injection": "<3.4"
},
"suggest": {
Expand Down
6 changes: 4 additions & 2 deletions src/Symfony/Component/VarDumper/Dumper/CliDumper.php
Expand Up @@ -546,7 +546,8 @@ private function hasColorSupport($stream)
&& @sapi_windows_vt100_support($stream))
|| false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
|| 'xterm' === getenv('TERM');
|| 'xterm' === getenv('TERM')
|| 'Hyper' === getenv('TERM_PROGRAM');
}

if (function_exists('stream_isatty')) {
Expand Down Expand Up @@ -575,7 +576,8 @@ private function isWindowsTrueColor()
{
$result = 183 <= getenv('ANSICON_VER')
|| 'ON' === getenv('ConEmuANSI')
|| 'xterm' === getenv('TERM');
|| 'xterm' === getenv('TERM')
|| 'Hyper' === getenv('TERM_PROGRAM');

if (!$result && PHP_VERSION_ID >= 70200) {
$version = sprintf(
Expand Down

0 comments on commit 4ce5a1b

Please sign in to comment.