Skip to content

Commit

Permalink
bug #11412 [Validator] Made sure that context changes don't leak out …
Browse files Browse the repository at this point in the history
…of (Contextual)ValidatorInterface (webmozart)

This PR was merged into the 2.5 branch.

Discussion
----------

[Validator] Made sure that context changes don't leak out of (Contextual)ValidatorInterface

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #11046
| License       | MIT
| Doc PR        | -

Commits
-------

ff48939 [Validator] Added markObjectAsInitialized() and isObjectInitialized() to ExecutionContextInterface
14b60c8 [Validator] Fixed doc block
91bf277 [Validator] Made sure that context changes don't leak out of (Contextual)ValidatorInterface
  • Loading branch information
webmozart committed Jul 28, 2014
2 parents d6bbf04 + ff48939 commit e8b53e9
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 29 deletions.
23 changes: 3 additions & 20 deletions src/Symfony/Component/Validator/Context/ExecutionContext.php
Expand Up @@ -18,7 +18,6 @@
use Symfony\Component\Validator\Exception\BadMethodCallException;
use Symfony\Component\Validator\Mapping\MetadataInterface;
use Symfony\Component\Validator\Mapping\PropertyMetadataInterface;
use Symfony\Component\Validator\ObjectInitializerInterface;
use Symfony\Component\Validator\Util\PropertyPath;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Component\Validator\Violation\ConstraintViolationBuilder;
Expand Down Expand Up @@ -147,7 +146,7 @@ public function __construct(ValidatorInterface $validator, $root, TranslatorInte
/**
* {@inheritdoc}
*/
public function setNode($value, $object, MetadataInterface $metadata, $propertyPath)
public function setNode($value, $object, MetadataInterface $metadata = null, $propertyPath)
{
$this->value = $value;
$this->object = $object;
Expand Down Expand Up @@ -370,31 +369,15 @@ public function isConstraintValidated($cacheKey, $constraintHash)
}

/**
* Marks that an object was initialized.
*
* @param string $cacheKey The hash of the object
*
* @internal Used by the validator engine. Should not be called by user
* code.
*
* @see ObjectInitializerInterface
* {@inheritdoc}
*/
public function markObjectAsInitialized($cacheKey)
{
$this->initializedObjects[$cacheKey] = true;
}

/**
* Returns whether an object was initialized.
*
* @param string $cacheKey The hash of the object
*
* @return bool Whether the object was already initialized
*
* @internal Used by the validator engine. Should not be called by user
* code.
*
* @see ObjectInitializerInterface
* {@inheritdoc}
*/
public function isObjectInitialized($cacheKey)
{
Expand Down
Expand Up @@ -116,15 +116,15 @@ public function getObject();
/**
* Sets the currently validated value.
*
* @param mixed $value The validated value
* @param object|null $object The currently validated object
* @param MetadataInterface $metadata The validation metadata
* @param string $propertyPath The property path to the current value
* @param mixed $value The validated value
* @param object|null $object The currently validated object
* @param MetadataInterface|null $metadata The validation metadata
* @param string $propertyPath The property path to the current value
*
* @internal Used by the validator engine. Should not be called by user
* code.
*/
public function setNode($value, $object, MetadataInterface $metadata, $propertyPath);
public function setNode($value, $object, MetadataInterface $metadata = null, $propertyPath);

/**
* Sets the currently validated group.
Expand Down Expand Up @@ -186,4 +186,30 @@ public function markConstraintAsValidated($cacheKey, $constraintHash);
* code.
*/
public function isConstraintValidated($cacheKey, $constraintHash);

/**
* Marks that an object was initialized.
*
* @param string $cacheKey The hash of the object
*
* @internal Used by the validator engine. Should not be called by user
* code.
*
* @see ObjectInitializerInterface
*/
public function markObjectAsInitialized($cacheKey);

/**
* Returns whether an object was initialized.
*
* @param string $cacheKey The hash of the object
*
* @return bool Whether the object was already initialized
*
* @internal Used by the validator engine. Should not be called by user
* code.
*
* @see ObjectInitializerInterface
*/
public function isObjectInitialized($cacheKey);
}
Expand Up @@ -193,13 +193,26 @@ public function testValidateInContext()
$entity = new Entity();
$entity->reference = new Reference();

$callback1 = function ($value, ExecutionContextInterface $context) {
$callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
$previousValue = $context->getValue();
$previousObject = $context->getObject();
$previousMetadata = $context->getMetadata();
$previousPath = $context->getPropertyPath();
$previousGroup = $context->getGroup();

$context
->getValidator()
->inContext($context)
->atPath('subpath')
->validate($value->reference)
;

// context changes shouldn't leak out of the validate() call
$test->assertSame($previousValue, $context->getValue());
$test->assertSame($previousObject, $context->getObject());
$test->assertSame($previousMetadata, $context->getMetadata());
$test->assertSame($previousPath, $context->getPropertyPath());
$test->assertSame($previousGroup, $context->getGroup());
};

$callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
Expand Down Expand Up @@ -244,13 +257,26 @@ public function testValidateArrayInContext()
$entity = new Entity();
$entity->reference = new Reference();

$callback1 = function ($value, ExecutionContextInterface $context) {
$callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
$previousValue = $context->getValue();
$previousObject = $context->getObject();
$previousMetadata = $context->getMetadata();
$previousPath = $context->getPropertyPath();
$previousGroup = $context->getGroup();

$context
->getValidator()
->inContext($context)
->atPath('subpath')
->validate(array('key' => $value->reference))
;

// context changes shouldn't leak out of the validate() call
$test->assertSame($previousValue, $context->getValue());
$test->assertSame($previousObject, $context->getObject());
$test->assertSame($previousMetadata, $context->getMetadata());
$test->assertSame($previousPath, $context->getPropertyPath());
$test->assertSame($previousGroup, $context->getGroup());
};

$callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
Expand Down
Expand Up @@ -120,8 +120,19 @@ public function testValidateInContext()
$entity = new Entity();
$entity->reference = new Reference();

$callback1 = function ($value, ExecutionContextInterface $context) {
$callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
$previousValue = $context->getValue();
$previousMetadata = $context->getMetadata();
$previousPath = $context->getPropertyPath();
$previousGroup = $context->getGroup();

$context->validate($value->reference, 'subpath');

// context changes shouldn't leak out of the validate() call
$test->assertSame($previousValue, $context->getValue());
$test->assertSame($previousMetadata, $context->getMetadata());
$test->assertSame($previousPath, $context->getPropertyPath());
$test->assertSame($previousGroup, $context->getGroup());
};

$callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
Expand Down Expand Up @@ -167,8 +178,19 @@ public function testValidateArrayInContext()
$entity = new Entity();
$entity->reference = new Reference();

$callback1 = function ($value, ExecutionContextInterface $context) {
$callback1 = function ($value, ExecutionContextInterface $context) use ($test) {
$previousValue = $context->getValue();
$previousMetadata = $context->getMetadata();
$previousPath = $context->getPropertyPath();
$previousGroup = $context->getGroup();

$context->validate(array('key' => $value->reference), 'subpath');

// context changes shouldn't leak out of the validate() call
$test->assertSame($previousValue, $context->getValue());
$test->assertSame($previousMetadata, $context->getMetadata());
$test->assertSame($previousPath, $context->getPropertyPath());
$test->assertSame($previousGroup, $context->getGroup());
};

$callback2 = function ($value, ExecutionContextInterface $context) use ($test, $entity) {
Expand Down
Expand Up @@ -96,6 +96,12 @@ public function validate($value, $constraints = null, $groups = null)
{
$groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups;

$previousValue = $this->context->getValue();
$previousObject = $this->context->getObject();
$previousMetadata = $this->context->getMetadata();
$previousPath = $this->context->getPropertyPath();
$previousGroup = $this->context->getGroup();

// If explicit constraints are passed, validate the value against
// those constraints
if (null !== $constraints) {
Expand All @@ -120,6 +126,9 @@ public function validate($value, $constraints = null, $groups = null)
$this->context
);

$this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
$this->context->setGroup($previousGroup);

return $this;
}

Expand All @@ -134,6 +143,9 @@ public function validate($value, $constraints = null, $groups = null)
$this->context
);

$this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
$this->context->setGroup($previousGroup);

return $this;
}

Expand All @@ -148,6 +160,9 @@ public function validate($value, $constraints = null, $groups = null)
$this->context
);

$this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
$this->context->setGroup($previousGroup);

return $this;
}

Expand Down Expand Up @@ -180,6 +195,12 @@ public function validateProperty($object, $propertyName, $groups = null)
$groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups;
$cacheKey = spl_object_hash($object);

$previousValue = $this->context->getValue();
$previousObject = $this->context->getObject();
$previousMetadata = $this->context->getMetadata();
$previousPath = $this->context->getPropertyPath();
$previousGroup = $this->context->getGroup();

foreach ($propertyMetadatas as $propertyMetadata) {
$propertyValue = $propertyMetadata->getPropertyValue($object);

Expand All @@ -196,6 +217,9 @@ public function validateProperty($object, $propertyName, $groups = null)
);
}

$this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
$this->context->setGroup($previousGroup);

return $this;
}

Expand All @@ -221,6 +245,12 @@ public function validatePropertyValue($object, $propertyName, $value, $groups =
$groups = $groups ? $this->normalizeGroups($groups) : $this->defaultGroups;
$cacheKey = spl_object_hash($object);

$previousValue = $this->context->getValue();
$previousObject = $this->context->getObject();
$previousMetadata = $this->context->getMetadata();
$previousPath = $this->context->getPropertyPath();
$previousGroup = $this->context->getGroup();

foreach ($propertyMetadatas as $propertyMetadata) {
$this->validateGenericNode(
$value,
Expand All @@ -235,6 +265,9 @@ public function validatePropertyValue($object, $propertyName, $value, $groups =
);
}

$this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath);
$this->context->setGroup($previousGroup);

return $this;
}

Expand Down

0 comments on commit e8b53e9

Please sign in to comment.