[serializer] validate that the specified callbacks and max_depth_handler are actually callable
This commit is contained in:
parent
ec41d76624
commit
37891525f7
@ -99,10 +99,14 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
|
|||||||
$this->nameConverter = $nameConverter;
|
$this->nameConverter = $nameConverter;
|
||||||
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
|
$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) {
|
foreach ($this->defaultContext[self::CALLBACKS] as $attribute => $callback) {
|
||||||
if (!\is_callable($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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 = [])
|
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);
|
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->defaultContext[self::EXCLUDE_FROM_CACHE_KEY] = [self::CIRCULAR_REFERENCE_LIMIT_COUNTERS];
|
||||||
|
|
||||||
$this->propertyTypeExtractor = $propertyTypeExtractor;
|
$this->propertyTypeExtractor = $propertyTypeExtractor;
|
||||||
@ -87,6 +92,18 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
$context['cache_key'] = $this->getCacheKey($format, $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)) {
|
if ($this->isCircularReference($object, $context)) {
|
||||||
return $this->handleCircularReference($object, $format, $context);
|
return $this->handleCircularReference($object, $format, $context);
|
||||||
}
|
}
|
||||||
@ -96,7 +113,15 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
|||||||
$attributes = $this->getAttributes($object, $format, $context);
|
$attributes = $this->getAttributes($object, $format, $context);
|
||||||
$class = $this->objectClassResolver ? ($this->objectClassResolver)($object) : \get_class($object);
|
$class = $this->objectClassResolver ? ($this->objectClassResolver)($object) : \get_class($object);
|
||||||
$attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null;
|
$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) {
|
foreach ($attributes as $attribute) {
|
||||||
$maxDepthReached = false;
|
$maxDepthReached = false;
|
||||||
|
@ -815,7 +815,11 @@ class ObjectNormalizerTest extends TestCase
|
|||||||
$this->normalizer->setMaxDepthHandler($handler);
|
$this->normalizer->setMaxDepthHandler($handler);
|
||||||
}
|
}
|
||||||
} else {
|
} 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->serializer = new Serializer([$this->normalizer]);
|
||||||
$this->normalizer->setSerializer($this->serializer);
|
$this->normalizer->setSerializer($this->serializer);
|
||||||
|
Reference in New Issue
Block a user