8000 [serializer] validate that the specified callbacks and max_depth_hand… · symfony/symfony@3789152 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3789152

Browse files
committed
[serializer] validate that the specified callbacks and max_depth_handler are actually callable
1 parent ec41d76 commit 3789152

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,14 @@ public function __construct(ClassMetadataFactoryInterface $classMetadataFactory
9999
$this->nameConverter = $nameConverter;
100100
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
101101

102-
if (\is_array($this->defaultContext[self::CALLBACKS] ?? null)) {
102+
if (isset($this->defaultContext[self::CALLBACKS])) {
103+
if (!\is_array($this->defaultContext[self::CALLBACKS])) {
104+
throw new InvalidArgumentException(sprintf('The "%s" default context option must be an array of callables.', self::CALLBACKS));
105+
}
106+
103107
foreach ($this->defaultContext[self::CALLBACKS] as $attribute => $callback) {
104108
if (!\is_callable($callback)) {
105-
throw new InvalidArgumentException(sprintf('The given callback for attribute "%s" is not callable.', $attribute));
109+
throw new InvalidArgumentException(sprintf('Invalid callback found for attribute "%s" in the "%s" default context option.', $attribute, self::CALLBACKS));
106110
}
107111
}
108112
}

src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
5959
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null, ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null, callable $objectClassResolver = null, array $defaultContext = [])
6060
{
6161
parent::__construct($classMetadataFactory, $nameConverter, $defaultContext);
62+
63+
if (isset($this->defaultContext[self::MAX_DEPTH_HANDLER]) && !\is_callable($this->defaultContext[self::MAX_DEPTH_HANDLER])) {
64+
throw new InvalidArgumentException(sprintf('The "%s" given in the default context is not callable.', self::MAX_DEPTH_HANDLER));
65+
}
66+
6267
$this->defaultContext[self::EXCLUDE_FROM_CACHE_KEY] = [self::CIRCULAR_REFERENCE_LIMIT_COUNTERS];
6368

6469
$this->propertyTypeExtractor = $propertyTypeExtractor;
@@ -87,6 +92,18 @@ public function normalize($object, $format = null, array $context = [])
8792
$context['cache_key'] = $this->getCacheKey($format, $context);
8893
}
8994

95+
if (isset($context[self::CALLBACKS])) {
96+
if (!\is_array($context[self::CALLBACKS])) {
97+
throw new InvalidArgumentException(sprintf('The "%s" context option must be an array of callables.', self::CALLBACKS));
98+
}
99+
100+
foreach ($context[self::CALLBACKS] as $attribute => $callback) {
101+
if (!\is_callable($callback)) {
102+
throw new InvalidArgumentException(sprintf('Invalid callback found for attribute "%s" in the "%s" context option.', $attribute, self::CALLBACKS));
103+
}
104+
}
105+
}
106+
90107
if ($this->isCircularReference($object, $context)) {
91108
return $this->handleCircularReference($object, $format, $context);
92109
}
@@ -96,7 +113,15 @@ public function normalize($object, $format = null, array $context = [])
96113
$attributes = $this->getAttributes($object, $format, $context);
97114
$class = $this->objectClassResolver ? ($this->objectClassResolver)($object) : \get_class($object);
98115
$attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null;
99-
$maxDepthHandler = $context[self::MAX_DEPTH_HANDLER] ?? $this->defaultContext[self::MAX_DEPTH_HANDLER] ?? $this->maxDepthHandler;
< 8000 /code>
116+
if (isset($context[self::MAX_DEPTH_HANDLER])) {
117+
$maxDepthHandler = $context[self::MAX_DEPTH_HANDLER];
118+
if (!\is_callable($maxDepthHandler)) {
119+
throw new InvalidArgumentException(sprintf('The "%s" given in the context is not callable.', self::MAX_DEPTH_HANDLER));
120+
}
121+
} else {
122+
// already validated in constructor resp by type declaration of setMaxDepthHandler
123+
$maxDepthHandler = $this->defaultContext[self::MAX_DEPTH_HANDLER] ?? $this->maxDepthHandler;
124+
}
100125

101126
foreach ($attributes as $attribute) {
102127
$maxDepthReached = false;

src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,11 @@ private function createNormalizerWithMaxDepthHandler(callable $handler = null, b
815815
$this->normalizer->setMaxDepthHandler($handler);
816816
}
817817
} else {
818-
6874 $this->createNormalizer([ObjectNormalizer::MAX_DEPTH_HANDLER => $handler], $classMetadataFactory);
818+
$context = [];
819+
if (null !== $handler) {
820+
$context[ObjectNormalizer::MAX_DEPTH_HANDLER] = $handler;
821+
}
822+
$this->createNormalizer($context, $classMetadataFactory);
819823
}
820824
$this->serializer = new Serializer([$this->normalizer]);
821825
$this->normalizer->setSerializer($this->serializer);

0 commit comments

Comments
 (0)
0