Skip to content

Commit

Permalink
[serializer] validate that the specified callbacks and max_depth_hand…
Browse files Browse the repository at this point in the history
…ler are actually callable
  • Loading branch information
dbu committed Apr 8, 2019
1 parent ec41d76 commit 3789152
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,14 @@ public function __construct(ClassMetadataFactoryInterface $classMetadataFactory
$this->nameConverter = $nameConverter;
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);

if (\is_array($this->defaultContext[self::CALLBACKS] ?? null)) {
if (isset($this->defaultContext[self::CALLBACKS])) {
if (!\is_array($this->defaultContext[self::CALLBACKS])) {
throw new InvalidArgumentException(sprintf('The "%s" default context option must be an array of callables.', self::CALLBACKS));
}

foreach ($this->defaultContext[self::CALLBACKS] as $attribute => $callback) {
if (!\is_callable($callback)) {
throw new InvalidArgumentException(sprintf('The given callback for attribute "%s" is not callable.', $attribute));
throw new InvalidArgumentException(sprintf('Invalid callback found for attribute "%s" in the "%s" default context option.', $attribute, self::CALLBACKS));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null, ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null, callable $objectClassResolver = null, array $defaultContext = [])
{
parent::__construct($classMetadataFactory, $nameConverter, $defaultContext);

if (isset($this->defaultContext[self::MAX_DEPTH_HANDLER]) && !\is_callable($this->defaultContext[self::MAX_DEPTH_HANDLER])) {
throw new InvalidArgumentException(sprintf('The "%s" given in the default context is not callable.', self::MAX_DEPTH_HANDLER));
}

$this->defaultContext[self::EXCLUDE_FROM_CACHE_KEY] = [self::CIRCULAR_REFERENCE_LIMIT_COUNTERS];

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

if (isset($context[self::CALLBACKS])) {
if (!\is_array($context[self::CALLBACKS])) {
throw new InvalidArgumentException(sprintf('The "%s" context option must be an array of callables.', self::CALLBACKS));
}

foreach ($context[self::CALLBACKS] as $attribute => $callback) {
if (!\is_callable($callback)) {
throw new InvalidArgumentException(sprintf('Invalid callback found for attribute "%s" in the "%s" context option.', $attribute, self::CALLBACKS));
}
}
}

if ($this->isCircularReference($object, $context)) {
return $this->handleCircularReference($object, $format, $context);
}
Expand All @@ -96,7 +113,15 @@ public function normalize($object, $format = null, array $context = [])
$attributes = $this->getAttributes($object, $format, $context);
$class = $this->objectClassResolver ? ($this->objectClassResolver)($object) : \get_class($object);
$attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null;
$maxDepthHandler = $context[self::MAX_DEPTH_HANDLER] ?? $this->defaultContext[self::MAX_DEPTH_HANDLER] ?? $this->maxDepthHandler;
if (isset($context[self::MAX_DEPTH_HANDLER])) {
$maxDepthHandler = $context[self::MAX_DEPTH_HANDLER];
if (!\is_callable($maxDepthHandler)) {
throw new InvalidArgumentException(sprintf('The "%s" given in the context is not callable.', self::MAX_DEPTH_HANDLER));
}
} else {
// already validated in constructor resp by type declaration of setMaxDepthHandler
$maxDepthHandler = $this->defaultContext[self::MAX_DEPTH_HANDLER] ?? $this->maxDepthHandler;
}

foreach ($attributes as $attribute) {
$maxDepthReached = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,11 @@ private function createNormalizerWithMaxDepthHandler(callable $handler = null, b
$this->normalizer->setMaxDepthHandler($handler);
}
} else {
$this->createNormalizer([ObjectNormalizer::MAX_DEPTH_HANDLER => $handler], $classMetadataFactory);
$context = [];
if (null !== $handler) {
$context[ObjectNormalizer::MAX_DEPTH_HANDLER] = $handler;
}
$this->createNormalizer($context, $classMetadataFactory);
}
$this->serializer = new Serializer([$this->normalizer]);
$this->normalizer->setSerializer($this->serializer);
Expand Down

0 comments on commit 3789152

Please sign in to comment.