Skip to content
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

Draft: Prevent disallowed conversions between object and by-ref-like parameter and return types #665

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

stakx
Copy link
Member

@stakx stakx commented Sep 3, 2023

DynamicProxy currently does not support intercepting methods that have any by-ref-like (ref struct) parameter or return types (such as Span<T> or ReadOnlySpan<T>), because by-ref-like types cannot be converted to or from object. DynamicProxy however attempts such conversions when it transfers argument and return values into or out of IInvocation instances, thus causing InvalidProgramExceptions and, to a lesser degree, NullReferenceExceptions.

This PR targets the code locations (hopefully all of them) where such conversions between object and by-ref-like types occur, and suppresses those conversions in favor of writing certain default values:

  • null where assignments are made to IInvocation.Arguments or IInvocation.ReturnValue
  • the default value of the by-ref-like type where assignments are made to out arguments or when values are return-ed to callers.

This work should be merged before #664, because the code locations that it touches are the same ones where #664 would introduce (optional) user-defined conversions instead of always writing fixed default values.

This is currently still a draft because two things is still missing:

Fixes #651.

 * Most tests fail with a `InvalidProgramException`: "Cannot create
   boxed ByRef-like values.".

 * One test fails with a `InvalidOperationException`: "Interceptors
   failed to set a return value [...]."
 * Wherever we are currently converting a by-ref-like argument or return
   value to `object`, we substitute `null` (because boxing is disallowed
   for by-ref-like types).

 * Wherever we convert from `object`, we substitute the default value
   for the by-ref-like type (because unboxing likewise doesn't work).
... which might be a bug in the runtime. We need a workaround for that.
@stakx stakx self-assigned this Sep 3, 2023
@stakx stakx marked this pull request as draft September 3, 2023 21:51
@stakx stakx mentioned this pull request Sep 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

InvalidProgramException when proxying MemoryStream with .NET 7
1 participant