Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 28, 2014

Conversation

webmozart
Copy link
Contributor

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

@@ -139,7 +139,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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Interface needs to be changed as well

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the $propertyPath variable that doesn't have a default value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Tobion Not necessarily, as we're weakening the API here (which is allowed for subclasses). I don't want to change the interface in a patch release, if possible.

@hhamon The default value is only there to allow passing null as $metadata. Both arguments should be passed explicitly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@webmozart Then you would need to check $this->context instanceof ExecutionContext in RecursiveContextualValidator whenever you call setNode. This is pretty ugly. So I think changing the interface is cleaner.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what will you pass to a different implementation when metadata is null? You would need to create a metadata instance, to be able to pass the other parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Tobion After thinking about this some more, I figured that you are right. Passing null to the method of an interface that technically does not accept null values is bogus, and introduces a dependency to the implementation. I changed the interface now.

@redstar504
Copy link
Contributor

Hey guys, if you see my issue #11413 I was thinking that I could use this ExecutionContextInterface::setNode method in order to set the correct property_path for my constraint, but I didn't know what to specify for the $metadata argument. If this PR gets merged, would this be a valid workaround?

@webmozart
Copy link
Contributor Author

@redstar504 See my answer to your ticket. Using setNode() directly is never recommended because it is marked as internal and may be changed anytime (breaking your code).

@tompedals
Copy link

We're still having issues if we use the 2.4 validation API. Errors are being set on the form rather than fields. Works fine with 2.5-bc and 2.5.

@webmozart
Copy link
Contributor Author

@tompedals Could you provide a fork of symfony-standard which reproduces your issue?

@tompedals
Copy link

@webmozart I'll give it a try. It may well have just been cached. The main issue I was having is now resolved anyway as we can use the 2.5 API rather than 2.4. Thanks for looking into it.

@@ -124,7 +124,7 @@ public function getObject();
* @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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please update the phpdoc @param MetadataInterface|null

@Tobion
Copy link
Contributor

Tobion commented Jul 24, 2014

Btw, there is another Interface problem. ExecutionContext::markObjectAsInitialized is not part of the interface, but it is called on the interface by https://github.com/webmozart/symfony/blob/issue11046/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php#L845

@Tobion
Copy link
Contributor

Tobion commented Jul 24, 2014

And ValidatorInterface::startContext() does not have a parameter, but the implementation RecursiveValidator::startContext($root = null) has.

@fabpot
Copy link
Member

fabpot commented Jul 25, 2014

This one is quite critical as without the fix, people cannot upgrade from 2.4 to 2.5 (2.4 being obsolete now.)

@webmozart @Tobion Can you find time to finish this one so that we can merge it soon?

@Tobion
Copy link
Contributor

Tobion commented Jul 25, 2014

Looks good 👍 except the phpdoc I mentioned above. The other problems I figured out are unrelated and can be separate tickets.

@webmozart
Copy link
Contributor Author

@Tobion Thanks, I addressed your comments now. startContext($root = null) shouldn't be a problem, as the parameter is only used internally in RecursiveValidator in validate() and validateProperty(). We could of course introduce a separate, private method, but I'd rather not introduce another method call just for cosmetic purposes.

If I get another go, I can merge the PR. /cc @stof

@Tobion
Copy link
Contributor

Tobion commented Jul 26, 2014

But startContext is a public method. So nothing hinders developers to actually use the parameter. So it's not only cosmetic. And changing the behavior of the parameter at some point could be considered BC break even though it's only intended for internal purposes.

@webmozart
Copy link
Contributor Author

Sure, developers can use the parameter, but then their code is bound to the implementation, not the interface - which is their choice. If we want to change anything about that parameter, we need to do so in a BC fashion, but I don't think this is very likely.

@Tobion
Copy link
Contributor

Tobion commented Jul 26, 2014

I dislike this because it does not respect the interface and is only possible in loosly checked languages like PHP. In stricter languages like Java this is not possible. To me this is a hack without any usefulness. And static code analysis will probably not like this either. I'm +0

@webmozart
Copy link
Contributor Author

I think the solution is pragmatic. But if others agree with you, I'm not opposed to adding another private method either.

@Tobion
Copy link
Contributor

Tobion commented Jul 26, 2014

Another reason against it is that the parameter is not documented. And documentation is not only for users but also for understanding code, i.e. contributors.

@webmozart
Copy link
Contributor Author

Feel free to open a PR to the branch. :)

@fabpot
Copy link
Member

fabpot commented Jul 28, 2014

👍

@webmozart webmozart merged commit ff48939 into symfony:2.5 Jul 28, 2014
webmozart added a commit that referenced this pull request Jul 28, 2014
…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
@peterrehm
Copy link
Contributor

I still see errors attached to a wrong filed with dev-master #7af2563 that errors are attached to the wrong field with 2.5 and 2.5-bc api. 2.4 api works fine.

@webmozart Are you aware of further issues regarding this or shall I try to reproduce it in a SE?

@xabbuh
Copy link
Member

xabbuh commented Jul 28, 2014

@peterrehm 2.5 hasn't been merged into master since then.

@peterrehm
Copy link
Contributor

@xabbuh Good catch, my bad. Just checked it against 2.5.x-master and could not reproduce my test cases. Seems to be fixed. Thanks!

@fabpot
Copy link
Member

fabpot commented Jul 28, 2014

@peterrehm I've just merged 2.5 into master.

@peterrehm
Copy link
Contributor

@fabpot Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants