Skip to content

Commit

Permalink
Merge branch '6.4' into 7.0
Browse files Browse the repository at this point in the history
* 6.4:
  Fix merge
  [Routing] Fixed priority getting lost when defining prefix array
  [DoctrineBridge]  Fix detection of Xml/Yaml driver in DoctrineExtension
  [Messenger] PhpSerializer: TypeError should throw MessageDecodingFailedException
  • Loading branch information
nicolas-grekas committed Jan 30, 2024
2 parents 0071107 + a70414a commit c8389b0
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 16 deletions.
Expand Up @@ -193,7 +193,9 @@ protected function registerMappingDrivers(array $objectManager, ContainerBuilder
array_values($driverPaths),
]);
}
if (str_contains($mappingDriverDef->getClass(), 'yml') || str_contains($mappingDriverDef->getClass(), 'xml')) {
if (str_contains($mappingDriverDef->getClass(), 'yml') || str_contains($mappingDriverDef->getClass(), 'xml')
|| str_contains($mappingDriverDef->getClass(), 'Yaml') || str_contains($mappingDriverDef->getClass(), 'Xml')
) {
$mappingDriverDef->setArguments([array_flip($driverPaths)]);
$mappingDriverDef->addMethodCall('setGlobalBasename', ['mapping']);
}
Expand Down
Expand Up @@ -33,50 +33,63 @@ public function testEncodedIsDecodable()

public function testDecodingFailsWithMissingBodyKey()
{
$serializer = $this->createPhpSerializer();

$this->expectException(MessageDecodingFailedException::class);
$this->expectExceptionMessage('Encoded envelope should have at least a "body", or maybe you should implement your own serializer');

$serializer = $this->createPhpSerializer();

$serializer->decode([]);
}

public function testDecodingFailsWithBadFormat()
{
$serializer = $this->createPhpSerializer();

$this->expectException(MessageDecodingFailedException::class);
$this->expectExceptionMessageMatches('/Could not decode/');

$serializer = $this->createPhpSerializer();

$serializer->decode([
'body' => '{"message": "bar"}',
]);
}

public function testDecodingFailsWithBadBase64Body()
{
$serializer = $this->createPhpSerializer();

$this->expectException(MessageDecodingFailedException::class);
$this->expectExceptionMessageMatches('/Could not decode/');

$serializer = $this->createPhpSerializer();

$serializer->decode([
'body' => 'x',
]);
}

public function testDecodingFailsWithBadClass()
{
$serializer = $this->createPhpSerializer();

$this->expectException(MessageDecodingFailedException::class);
$this->expectExceptionMessageMatches('/class "ReceivedSt0mp" not found/');

$serializer = $this->createPhpSerializer();

$serializer->decode([
'body' => 'O:13:"ReceivedSt0mp":0:{}',
]);
}

public function testDecodingFailsForPropertyTypeMismatch()
{
$serializer = $this->createPhpSerializer();
$encodedEnvelope = $serializer->encode(new Envelope(new DummyMessage('true')));
// Simulate a change of property type in the code base
$encodedEnvelope['body'] = str_replace('s:4:\"true\"', 'b:1', $encodedEnvelope['body']);

$this->expectException(MessageDecodingFailedException::class);
$this->expectExceptionMessageMatches('/Could not decode/');

$serializer->decode($encodedEnvelope);
}

public function testEncodedSkipsNonEncodeableStamps()
{
$serializer = $this->createPhpSerializer();
Expand Down
Expand Up @@ -75,16 +75,14 @@ private function safelyUnserialize(string $contents): Envelope
throw new MessageDecodingFailedException('Could not decode an empty message using PHP serialization.');
}

$signalingException = new MessageDecodingFailedException(sprintf('Could not decode message using PHP serialization: %s.', $contents));

if ($this->acceptPhpIncompleteClass) {
$prevUnserializeHandler = ini_set('unserialize_callback_func', null);
} else {
$prevUnserializeHandler = ini_set('unserialize_callback_func', self::class.'::handleUnserializeCallback');
}
$prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$prevErrorHandler, $signalingException) {
$prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$prevErrorHandler) {
if (__FILE__ === $file) {
throw $signalingException;
throw new \ErrorException($msg, 0, $type, $file, $line);
}

return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false;
Expand All @@ -93,13 +91,19 @@ private function safelyUnserialize(string $contents): Envelope
try {
/** @var Envelope */
$envelope = unserialize($contents);
} catch (\Throwable $e) {
if ($e instanceof MessageDecodingFailedException) {
throw $e;
}

throw new MessageDecodingFailedException('Could not decode Envelope: '.$e->getMessage(), 0, $e);
} finally {
restore_error_handler();
ini_set('unserialize_callback_func', $prevUnserializeHandler);
}

if (!$envelope instanceof Envelope) {
throw $signalingException;
throw new MessageDecodingFailedException('Could not decode message into an Envelope.');
}

if ($envelope->getMessage() instanceof \__PHP_Incomplete_Class) {
Expand Down
Expand Up @@ -29,20 +29,21 @@ final protected function addPrefix(RouteCollection $routes, string|array $prefix
}
foreach ($routes->all() as $name => $route) {
if (null === $locale = $route->getDefault('_locale')) {
$priority = $routes->getPriority($name) ?? 0;
$routes->remove($name);
foreach ($prefix as $locale => $localePrefix) {
$localizedRoute = clone $route;
$localizedRoute->setDefault('_locale', $locale);
$localizedRoute->setRequirement('_locale', preg_quote($locale));
$localizedRoute->setDefault('_canonical_route', $name);
$localizedRoute->setPath($localePrefix.(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath()));
$routes->add($name.'.'.$locale, $localizedRoute);
$routes->add($name.'.'.$locale, $localizedRoute, $priority);
}
} elseif (!isset($prefix[$locale])) {
throw new \InvalidArgumentException(sprintf('Route "%s" with locale "%s" is missing a corresponding prefix in its parent collection.', $name, $locale));
} else {
$route->setPath($prefix[$locale].(!$trailingSlashOnRoot && '/' === $route->getPath() ? '' : $route->getPath()));
$routes->add($name, $route);
$routes->add($name, $route, $routes->getPriority($name) ?? 0);
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/Routing/RouteCollection.php
Expand Up @@ -380,4 +380,9 @@ public function getAlias(string $name): ?Alias
{
return $this->aliases[$name] ?? null;
}

public function getPriority(string $name): ?int
{
return $this->priorities[$name] ?? null;
}
}
@@ -0,0 +1,18 @@
<?php

namespace Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures;

use Symfony\Component\Routing\Annotation\Route;

class RouteWithPriorityController
{
#[Route('/important', name: 'important', priority: 2)]
public function important()
{
}

#[Route('/also-important', name: 'also_important', priority: 1, defaults: ['_locale' => 'cs'])]
public function alsoImportant()
{
}
}
@@ -0,0 +1,6 @@
important_controllers:
resource: Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\RouteWithPriorityController
type: attribute
prefix:
cs: /cs
en: /en
19 changes: 19 additions & 0 deletions src/Symfony/Component/Routing/Tests/Loader/YamlFileLoaderTest.php
Expand Up @@ -463,6 +463,25 @@ public function testImportingAliases()
$this->assertEquals($expectedRoutes('yaml'), $routes);
}

public function testPriorityWithPrefix()
{
new LoaderResolver([
$loader = new YamlFileLoader(new FileLocator(\dirname(__DIR__).'/Fixtures/localized')),
new class() extends AttributeClassLoader {
protected function configureRoute(Route $route, \ReflectionClass $class, \ReflectionMethod $method, object $annot): void
{
$route->setDefault('_controller', $class->getName().'::'.$method->getName());
}
},
]);

$routes = $loader->load('localized-prefix.yml');

$this->assertSame(2, $routes->getPriority('important.cs'));
$this->assertSame(2, $routes->getPriority('important.en'));
$this->assertSame(1, $routes->getPriority('also_important'));
}

/**
* @dataProvider providePsr4ConfigFiles
*/
Expand Down

0 comments on commit c8389b0

Please sign in to comment.