diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php index 71d97be8d1..f4711b126d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php @@ -179,7 +179,7 @@ EOF $preloadFile = $fs->makePathRelative(\dirname($containerFile, 2), $kernelDir); $preloadFile .= substr_replace(basename($containerFile), '.preload', -4, 0); $preloadFile = var_export('/'.$preloadFile, true); - @file_put_contents($kernelDir.'/preload.php', <<assertSame($expected, $client->getServerList()); } + + public function testKeyEncoding() + { + $reservedMemcachedCharacters = " \n\r\t\v\f\0"; + + $namespace = $reservedMemcachedCharacters.random_int(0, \PHP_INT_MAX); + $pool = $this->createCachePool(0, null, $namespace); + + /** + * Choose a key that is below {@see \Symfony\Component\Cache\Adapter\MemcachedAdapter::$maxIdLength} so that + * {@see \Symfony\Component\Cache\Traits\AbstractTrait::getId()} does not shorten the key but choose special + * characters that would be encoded and therefore increase the key length over the Memcached limit. + */ + // 250 is Memcached’s max key length, 7 bytes for prefix seed + $key = str_repeat('%', 250 - 7 - \strlen($reservedMemcachedCharacters) - \strlen($namespace)).$reservedMemcachedCharacters; + + self::assertFalse($pool->hasItem($key)); + + $item = $pool->getItem($key); + self::assertFalse($item->isHit()); + self::assertSame($key, $item->getKey()); + + self::assertTrue($pool->save($item->set('foobar'))); + + self::assertTrue($pool->hasItem($key)); + $item = $pool->getItem($key); + self::assertTrue($item->isHit()); + self::assertSame($key, $item->getKey()); + + self::assertTrue($pool->deleteItem($key)); + self::assertFalse($pool->hasItem($key)); + } } diff --git a/src/Symfony/Component/HttpClient/Exception/HttpExceptionTrait.php b/src/Symfony/Component/HttpClient/Exception/HttpExceptionTrait.php index 76e650934b..5b7b448307 100644 --- a/src/Symfony/Component/HttpClient/Exception/HttpExceptionTrait.php +++ b/src/Symfony/Component/HttpClient/Exception/HttpExceptionTrait.php @@ -60,7 +60,8 @@ trait HttpExceptionTrait // see http://www.hydra-cg.com/spec/latest/core/#description-of-http-status-codes-and-errors $separator = isset($body['hydra:title'], $body['hydra:description']) ? "\n\n" : ''; $message = ($body['hydra:title'] ?? '').$separator.($body['hydra:description'] ?? ''); - } elseif (isset($body['title']) || isset($body['detail'])) { + } elseif ((isset($body['title']) || isset($body['detail'])) + && (is_scalar($body['title'] ?? '') && is_scalar($body['detail'] ?? ''))) { // see RFC 7807 and https://jsonapi.org/format/#error-objects $separator = isset($body['title'], $body['detail']) ? "\n\n" : ''; $message = ($body['title'] ?? '').$separator.($body['detail'] ?? ''); diff --git a/src/Symfony/Component/HttpClient/Tests/Exception/HttpExceptionTraitTest.php b/src/Symfony/Component/HttpClient/Tests/Exception/HttpExceptionTraitTest.php index ac6c30df1f..c2771cc3ae 100644 --- a/src/Symfony/Component/HttpClient/Tests/Exception/HttpExceptionTraitTest.php +++ b/src/Symfony/Component/HttpClient/Tests/Exception/HttpExceptionTraitTest.php @@ -22,15 +22,24 @@ class HttpExceptionTraitTest extends TestCase { public function provideParseError(): iterable { - yield ['application/ld+json', '{"hydra:title": "An error occurred", "hydra:description": "Some details"}']; - yield ['application/problem+json', '{"title": "An error occurred", "detail": "Some details"}']; - yield ['application/vnd.api+json', '{"title": "An error occurred", "detail": "Some details"}']; + $errorWithoutMessage = 'HTTP/1.1 400 Bad Request returned for "http://example.com".'; + + $errorWithMessage = <<createMock(ResponseInterface::class); $response @@ -47,12 +56,7 @@ class HttpExceptionTraitTest extends TestCase $e = new TestException($response); $this->assertSame(400, $e->getCode()); - $this->assertSame(<<getMessage()); + $this->assertSame($expectedMessage, $e->getMessage()); } }