Validate invalid base type declarations in ILVerify#129118
Conversation
|
Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/jit-contrib |
|
@dotnet-policy-service agree |
a03f2df to
87dc394
Compare
|
Hi @jkotas, just checking in on this PR. I’ve addressed the feedback and made the requested updates. Please let me know if there’s anything else I should adjust. Thanks! |
|
Thanks for the review. I updated the PR to address the latest feedback, The TypeSpec validation now follows the ECMA-335 augment behavior. Please let me know if there is anything else I should adjust. |
|
(Edited to fix issue number) I wonder if we should approach this from an angle that also allows to address #4945
|
Yes, I think it would look better. @pkuyo Could you please implement it? |
| } | ||
| else | ||
| { | ||
| if (baseType.Kind == HandleKind.TypeSpecification && |
There was a problem hiding this comment.
This should not be needed. It is covered by the resolvedBaseType.IsValueType || resolvedBaseType.IsInterface || !resolvedBaseType.IsDefType check below.
There was a problem hiding this comment.
Thanks. I simplified this to a smaller TypeSpec-specific check.
The resolvedBaseType.IsValueType || resolvedBaseType.IsInterface || !resolvedBaseType.IsDefType check alone does not catch the #119536 case, because a TypeSpec that resolves to System.Object passes those resolved-type checks. The extra TypeSpec check is only for that context-specific extends validation.
There was a problem hiding this comment.
Ok, I see.
It does not feel right to have a different "spec" for typespecs depending on the context. Maybe we should be more restrictive in the default type spec parser like you had it originally and update the augments doc to match.
There was a problem hiding this comment.
@MichalStrehovsky Do you have opinion about this? Should we stick with the stricter definition of typespec to avoid bifurcating typespec spec?
There was a problem hiding this comment.
Stricter sounds good to me. If we find out there are mainstream compilers breaking it, we could relax I guess. (MSVC doesn't count, it never even pretended to target ECMA-335.)
Sure, thanks. I’ll implement it this way and update the PR. |
Thanks, I reworked this to use the The TypeSpec validation is now done through For CMOD_OPT/CMOD_REQ, I kept the check simple for now: it reports a TypeSpec reference while parsing another TypeSpec, but does not try to distinguish whether it actually forms a cycle. Full cycle detection would need extra tracking for the active TypeSpec resolution stack, since the current TypeSpec is not in the cache yet. I wasn't sure that extra state was necessary for this PR, so I wanted to check before adding it. |
We shouldn't allow TypeSpec as a modifier. It only causes problems. If the augment says we allow it, we should update the augment. We can capture the reason so that somebody doesn't try to relax it without thinking about the consequences (@jkotas do you agree?). I think this recently came up in #123819 and we decided not to handle TypeSpec either, but GitHub makes it really hard to find the relevant comment. |
Yes |
| table, TypeRef table, or TypeSpec table. However, these tokens are encoded and compressed – | ||
| see §II.23.2.8 for details. Furthermore, if a row in the TypeSpec table is indicated, | ||
| it must not create cycle. | ||
| table or TypeRef table. However, these tokens are encoded and compressed – |
There was a problem hiding this comment.
This is not proposing any actual change anymore. Both original and proposed replacements are identical. If we want to propose any change here, it should be to add a sentence that explains why typespecs are not allowed.
There was a problem hiding this comment.
Updated. I added a sentence explaining that TypeSpec tokens are not valid in this position because allowing them could form recursive TypeSpec encodings.
| then there should be a clarification that cycles are nonetheless not | ||
| permitted, and ideally readers would detect such cycles and handle the | ||
| error with a suitable message rather than a stack overflow. | ||
| Allowing TypeSpec custom modifier types also creates a path for |
There was a problem hiding this comment.
| Allowing TypeSpec custom modifier types also creates a path for | |
| Allowing TypeSpec custom modifier types creates a path for |
| recursive TypeSpec encodings, which has caused problems in runtimes | ||
| and tools. Such metadata should be rejected rather than cycle-detected. |
There was a problem hiding this comment.
| recursive TypeSpec encodings, which has caused problems in runtimes | |
| and tools. Such metadata should be rejected rather than cycle-detected. | |
| recursive TypeSpec encodings that are complicated to detect. Such metadata should be rejected rather than cycle-detected. |
| Related issues: | ||
|
|
||
| * https://github.com/dotnet/roslyn/issues/7971 | ||
| * https://github.com/dotnet/runtime/issues/4945 |
There was a problem hiding this comment.
| * https://github.com/dotnet/runtime/issues/4945 | |
| * https://github.com/dotnet/runtime/pull/123819#discussion_r2810397721 |
| by a TypeRef or TypeDef metadata token. TypeSpec tokens in this | ||
| position should be treated as invalid metadata. | ||
|
|
||
| Allowing TypeSpec custom modifier types creates a path for |
There was a problem hiding this comment.
Nit: Could you please reformat this to have similar text width, and add new line before "Related issues"
Fixes #119536
This adds ILVerify validation for invalid class base type declarations.
The original issue reports a case where ILAsm accepts a type declared with
extends object, but the resulting type cannot be loaded by the runtime.ILVerify previously accepted that assembly without reporting an error.
This change reports
InvalidBaseTypefor invalid base type declarations ratherthan special-casing only the exact
extends objectspelling.Tests added in
BaseTypeTests.il:ObjectTypeSpecBase_InvalidType_InvalidBaseTypeextends object.InvalidBaseType.NilBaseInterface_ValidType_ValidGenericClassTypeSpecBase_ValidType_ValidValueTypeBase_InvalidType_InvalidBaseTypeGenericValueTypeSpecBase_InvalidType_InvalidBaseType