Skip to content

Handle missing signatures for substituted type custom modifiers - #136847

Open
NinoFloris wants to merge 7 commits into
dotnet:mainfrom
NinoFloris:reflection/substituted-type-custom-modifiers
Open

NinoFloris wants to merge 7 commits into
dotnet:mainfrom
NinoFloris:reflection/substituted-type-custom-modifiers

Conversation

@NinoFloris

@NinoFloris NinoFloris commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Return an empty modifier array for the -1 offset used for nested types of substituted generic parameters, avoiding a native read before the signature buffer. Cover substitutions through generic classes and methods alongside synthetic array parameters.

Closes #136848

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
12 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Nov 2, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @steveisok, @dotnet/area-system-reflection
See info in area-owners.md if you want to be subscribed.

@NinoFloris

Copy link
Copy Markdown
Contributor Author

Two more native helpers could do with bounds checks tbh:

  • SignatureNative::GetTypeParameterOffsetInternal
  • SignatureNative::GetCallingConventionFromFunctionPointerAtOffsetInternal

@NinoFloris

Copy link
Copy Markdown
Contributor Author

This was also unhandled on NativeAOT, also fixed.

Comment thread src/coreclr/vm/runtimehandles.cpp Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The review reports no active issues with the nested-type custom-modifier changes.

No open issues 🎉

What changed in this PR

Fixes custom-modifier queries on nested types of substituted generic parameters, addressing the invalid signature-buffer read reported in #136848 across CoreCLR and NativeAOT.

Changes:

  • Returns empty custom-modifier arrays when a substituted type has no nested signature.
  • Adds native bounds validation before reading a signature offset.
  • Extends reflection tests for generic class and method substitutions, reusing recursive checks for synthetic array parameters.
File Description
src/​libraries/​System.Runtime/​tests/​System.Reflection.Tests/​ParameterInfoTests.cs Adds substitution cases and shares recursive modified-type assertions.
src/​coreclr/​vm/​runtimehandles.cpp Rejects out-of-range offsets before accessing signature data.
src/​coreclr/​System.Private.CoreLib/​src/​System/​Reflection/​ModifiedType.CoreCLR.cs Skips modifier lookup for negative signature offsets.
src/​coreclr/​nativeaot/​System.Private.CoreLib/​src/​System/​Reflection/​ModifiedType.NativeAot.cs Handles nested substituted types without a signature.

Review effort: Balanced

@jkotas

jkotas commented Nov 3, 2026

Copy link
Copy Markdown
Member

Does System.Reflection.MetadataLoadContext handle this correctly?

@NinoFloris

Copy link
Copy Markdown
Contributor Author

Does System.Reflection.MetadataLoadContext handle this correctly?

My clanker states it's ok because MetadataLoadContext never computes offsets, it decodes directly as it walks.

@jkotas

jkotas commented Nov 3, 2026

Copy link
Copy Markdown
Member

MetadataLoadContext never computes offsets, it decodes directly as it walks.

Could you please add a matching test for MetadataLoadContext to validate it?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues are reported for the changes handling missing signatures in custom-modifier queries on substituted generic types.

No open issues 🎉

Review effort: Balanced

@jkotas

jkotas commented Nov 4, 2026

Copy link
Copy Markdown
Member

How does this work for a signature like void M<T>(modopt(SomeModifier) !0 value)?

Return an empty modifier array for the -1 offset used for nested types of substituted generic parameters, avoiding a native read before the signature buffer. Cover substitutions through generic classes and methods alongside synthetic array parameters.
Return a modified-type wrapper without nested signature metadata for type-variable and method-variable signatures. Assert that recursive modified-type results are non-null in the regression tests.
@NinoFloris
NinoFloris force-pushed the reflection/substituted-type-custom-modifiers branch from 8ae2e95 to 4ca2f19 Compare November 4, 2026 15:42
@jkotas
jkotas requested a balanced review from Copilot November 4, 2026 16:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues remain for the reflection signature-handling changes.

No open issues 🎉

Review effort: Balanced

@NinoFloris
NinoFloris marked this pull request as draft November 5, 2026 19:39
@NinoFloris
NinoFloris marked this pull request as ready for review November 5, 2026 19:39
@NinoFloris

Copy link
Copy Markdown
Contributor Author

This is now ready and green @jkotas

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-System.Reflection community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AV when querying custom modifiers on substituted generic types

3 participants