-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Prohibits class typo in the discriminator map #8122
Prohibits class typo in the discriminator map #8122
Conversation
This PR is better than #8112 in term of DX as it will raise errors way before any sql query will hit the DB. Pointing the user exactly where the issue is. |
75ffa10
to
0d2c8d5
Compare
$refl = new ReflectionClass($className); | ||
if ($refl->name !== $className) { | ||
throw MappingException::invalidClassInDiscriminatorMap($className, $this->className); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm opened to suggestion if you see a more efficient way to grab actual class name without using reflection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, I'm not sure efficiency is really researched here, as metadata are cached.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the reflection API performance are that bad, and since this is about metadata, there is probably caching after this, right? So it's not a hot path, and it's cached, isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's my belief as well 👍
This change could probably be considered as a BC break. |
@@ -1002,6 +1003,11 @@ public function addDiscriminatorMapClass($name, string $className) : void | |||
throw MappingException::invalidClassInDiscriminatorMap($className, $this->className); | |||
} | |||
|
|||
$refl = new ReflectionClass($className); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throws ReflectionException if the class to reflect does not exist. Source
It won't as we check for class existence on line 1001.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A+ commit message, and nice tests! I'm unsure if this should really be considered a BC-break. If it is, we should probably trigger a deprecation but that sounds weird to me. In any case, I would target the bugfix branch (so 2.7)
$refl = new ReflectionClass($className); | ||
if ($refl->name !== $className) { | ||
throw MappingException::invalidClassInDiscriminatorMap($className, $this->className); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the reflection API performance are that bad, and since this is about metadata, there is probably caching after this, right? So it's not a hot path, and it's cached, isn't it?
Why did you change it back? |
Switching the base branch to 2.7 showed 500+ commits to merge. Let me work on that. |
|
0d2c8d5
to
cad84ac
Compare
Done, thanks for the hint 👍 I'm curious, how would you transpose this fix into master? I've noticed quite a few changes that'll make it non trivial (ClassMetadataInfo has been renamed ClassMetadata and a few metadata drivers have been removed). |
I'm curious about that too to be honest 😅 |
a2badf9
to
33a3e2d
Compare
The build fails, please run |
33a3e2d
to
41ef28f
Compare
Done ✔️ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
In any case, I would target the bugfix branch (so 2.7)
Correction: if someone feels there is a BC-break and this should instead be a deprecation, then 2.8 should be targeted. Otherwise, 2.7 is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -2816,6 +2816,11 @@ public function addDiscriminatorMapClass($name, $className) | |||
throw MappingException::invalidClassInDiscriminatorMap($className, $this->name); | |||
} | |||
|
|||
$refl = new ReflectionClass($className); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to swoop in so late, but loading ReflectionClass inside ClassMetadataInfo is not allowed from architecture POV. This code doesn't work with static runtime reflection, which will break detached metadata use cases (such as everything with the EntityGenerator).
Instead this check is something you should put either into ClassMetadataFactory if we want this to fail at runtime, or in the SchemaValidator if we want this to fail only in debug/dev mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The right place for validation is ClassMetadataFactory::validateRuntimeMetadata
Thanks for pointing this out. |
476a1c6
to
701b50a
Compare
When a defined subclass has a case typo, the query builder will be lost and will generate exotic table alias. This commit fixes the issue at the root by prohibiting case typo in discriminator map. See doctrine#8112 for the consequence of such typo.
The Cube class must be autoloaded with the correct case, otherwise composer autoloader will complain.
701b50a
to
3b85ec8
Compare
3b85ec8
to
2daee11
Compare
I'm wondering if this case sensitivity check should not be performed more globally as The underlying issue is that once the class has been included once (FYI, composer autoload will not autoload class with incorrect case, as it does not respect psr-0/4 AFAIK), In the case of the discriminator map, this will generate incorrect sql statement because the system won't be able to determine the correct table alias. I'm wondering if a similar issue could not appear anywhere where I'm thinking about associations (targetEntity with incorrect case), entity definition (name with incorrect case), ... I need to take some more time to investigate, any hint is welcome in the meantime :) |
When a defined subclass has a case typo, the query builder will be lost
and will generate exotic table alias. This commit fixes the issue at the
root by prohibiting case typo in discriminator map.
See #8112 for the consequence of
such typo.