Security update for Core, with self-updated composer
[yaffs-website] / vendor / symfony / serializer / Normalizer / ObjectNormalizer.php
index c31ba36a7a76ff618fb77670a292c0079f0ba68f..00a0a693ab61cfd1fbd141ab3fd22c121c8d6120 100644 (file)
@@ -14,8 +14,7 @@ namespace Symfony\Component\Serializer\Normalizer;
 use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
 use Symfony\Component\PropertyAccess\PropertyAccess;
 use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
-use Symfony\Component\Serializer\Exception\CircularReferenceException;
-use Symfony\Component\Serializer\Exception\LogicException;
+use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
 use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
 use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
 
@@ -24,18 +23,16 @@ use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
  *
  * @author Kévin Dunglas <dunglas@gmail.com>
  */
-class ObjectNormalizer extends AbstractNormalizer
+class ObjectNormalizer extends AbstractObjectNormalizer
 {
-    private $attributesCache = array();
-
     /**
      * @var PropertyAccessorInterface
      */
     protected $propertyAccessor;
 
-    public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null)
+    public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null)
     {
-        parent::__construct($classMetadataFactory, $nameConverter);
+        parent::__construct($classMetadataFactory, $nameConverter, $propertyTypeExtractor);
 
         $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor();
     }
@@ -43,151 +40,7 @@ class ObjectNormalizer extends AbstractNormalizer
     /**
      * {@inheritdoc}
      */
-    public function supportsNormalization($data, $format = null)
-    {
-        return is_object($data) && !$data instanceof \Traversable;
-    }
-
-    /**
-     * {@inheritdoc}
-     *
-     * @throws CircularReferenceException
-     */
-    public function normalize($object, $format = null, array $context = array())
-    {
-        if (!isset($context['cache_key'])) {
-            $context['cache_key'] = $this->getCacheKey($context);
-        }
-        if ($this->isCircularReference($object, $context)) {
-            return $this->handleCircularReference($object);
-        }
-
-        $data = array();
-        $attributes = $this->getAttributes($object, $context);
-
-        foreach ($attributes as $attribute) {
-            if (in_array($attribute, $this->ignoredAttributes)) {
-                continue;
-            }
-
-            $attributeValue = $this->propertyAccessor->getValue($object, $attribute);
-
-            if (isset($this->callbacks[$attribute])) {
-                $attributeValue = call_user_func($this->callbacks[$attribute], $attributeValue);
-            }
-
-            if (null !== $attributeValue && !is_scalar($attributeValue)) {
-                if (!$this->serializer instanceof NormalizerInterface) {
-                    throw new LogicException(sprintf('Cannot normalize attribute "%s" because injected serializer is not a normalizer', $attribute));
-                }
-
-                $attributeValue = $this->serializer->normalize($attributeValue, $format, $context);
-            }
-
-            if ($this->nameConverter) {
-                $attribute = $this->nameConverter->normalize($attribute);
-            }
-
-            $data[$attribute] = $attributeValue;
-        }
-
-        return $data;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function supportsDenormalization($data, $type, $format = null)
-    {
-        return class_exists($type);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function denormalize($data, $class, $format = null, array $context = array())
-    {
-        if (!isset($context['cache_key'])) {
-            $context['cache_key'] = $this->getCacheKey($context);
-        }
-        $allowedAttributes = $this->getAllowedAttributes($class, $context, true);
-        $normalizedData = $this->prepareForDenormalization($data);
-
-        $reflectionClass = new \ReflectionClass($class);
-        $object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes);
-
-        foreach ($normalizedData as $attribute => $value) {
-            if ($this->nameConverter) {
-                $attribute = $this->nameConverter->denormalize($attribute);
-            }
-
-            $allowed = $allowedAttributes === false || in_array($attribute, $allowedAttributes);
-            $ignored = in_array($attribute, $this->ignoredAttributes);
-
-            if ($allowed && !$ignored) {
-                try {
-                    $this->propertyAccessor->setValue($object, $attribute, $value);
-                } catch (NoSuchPropertyException $exception) {
-                    // Properties not found are ignored
-                }
-            }
-        }
-
-        return $object;
-    }
-
-    private function getCacheKey(array $context)
-    {
-        try {
-            return md5(serialize($context));
-        } catch (\Exception $exception) {
-            // The context cannot be serialized, skip the cache
-            return false;
-        }
-    }
-
-    /**
-     * Gets and caches attributes for this class and context.
-     *
-     * @param object $object
-     * @param array  $context
-     *
-     * @return string[]
-     */
-    private function getAttributes($object, array $context)
-    {
-        $class = get_class($object);
-        $key = $class.'-'.$context['cache_key'];
-
-        if (isset($this->attributesCache[$key])) {
-            return $this->attributesCache[$key];
-        }
-
-        $allowedAttributes = $this->getAllowedAttributes($object, $context, true);
-
-        if (false !== $allowedAttributes) {
-            if ($context['cache_key']) {
-                $this->attributesCache[$key] = $allowedAttributes;
-            }
-
-            return $allowedAttributes;
-        }
-
-        if (isset($this->attributesCache[$class])) {
-            return $this->attributesCache[$class];
-        }
-
-        return $this->attributesCache[$class] = $this->extractAttributes($object);
-    }
-
-    /**
-     * Extracts attributes for this class and context.
-     *
-     * @param object $object
-     *
-     * @return string[]
-     */
-    private function extractAttributes($object)
+    protected function extractAttributes($object, $format = null, array $context = array())
     {
         // If not using groups, detect manually
         $attributes = array();
@@ -205,31 +58,32 @@ class ObjectNormalizer extends AbstractNormalizer
             }
 
             $name = $reflMethod->name;
+            $attributeName = null;
 
             if (0 === strpos($name, 'get') || 0 === strpos($name, 'has')) {
                 // getters and hassers
-                $propertyName = substr($name, 3);
+                $attributeName = substr($name, 3);
 
-                if (!$reflClass->hasProperty($propertyName)) {
-                    $propertyName = lcfirst($propertyName);
+                if (!$reflClass->hasProperty($attributeName)) {
+                    $attributeName = lcfirst($attributeName);
                 }
-
-                $attributes[$propertyName] = true;
             } elseif (strpos($name, 'is') === 0) {
                 // issers
-                $propertyName = substr($name, 2);
+                $attributeName = substr($name, 2);
 
-                if (!$reflClass->hasProperty($propertyName)) {
-                    $propertyName = lcfirst($propertyName);
+                if (!$reflClass->hasProperty($attributeName)) {
+                    $attributeName = lcfirst($attributeName);
                 }
+            }
 
-                $attributes[$propertyName] = true;
+            if (null !== $attributeName && $this->isAllowedAttribute($object, $attributeName, $format, $context)) {
+                $attributes[$attributeName] = true;
             }
         }
 
         // properties
         foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflProperty) {
-            if ($reflProperty->isStatic()) {
+            if ($reflProperty->isStatic() || !$this->isAllowedAttribute($object, $reflProperty->name, $format, $context)) {
                 continue;
             }
 
@@ -238,4 +92,24 @@ class ObjectNormalizer extends AbstractNormalizer
 
         return array_keys($attributes);
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getAttributeValue($object, $attribute, $format = null, array $context = array())
+    {
+        return $this->propertyAccessor->getValue($object, $attribute);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array())
+    {
+        try {
+            $this->propertyAccessor->setValue($object, $attribute, $value);
+        } catch (NoSuchPropertyException $exception) {
+            // Properties not found are ignored
+        }
+    }
 }