diff options
author | David Fowler <davidfowl@gmail.com> | 2022-09-03 15:59:31 +0300 |
---|---|---|
committer | David Fowler <davidfowl@gmail.com> | 2022-09-03 15:59:31 +0300 |
commit | 240a7c40eab4742d93514fcd7651251baa26d11e (patch) | |
tree | 9d377859c2d8dcef01849f015c313b45303006db | |
parent | 04d8d0f7ce69b266ea094bd08f70d2bc04f0e0df (diff) |
Throw if a by ref type is returned to avoid making invalid ILdavidfowl/fix-ref-structs
-rw-r--r-- | src/Http/Http.Extensions/src/RequestDelegateFactory.cs | 7 | ||||
-rw-r--r-- | src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs | 26 |
2 files changed, 32 insertions, 1 deletions
diff --git a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs index 810d902964..d87660f451 100644 --- a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs +++ b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs @@ -972,7 +972,7 @@ public static partial class RequestDelegateFactory else { // TODO: Handle custom awaitables - throw new NotSupportedException($"Unsupported return type: {returnType}"); + throw new NotSupportedException($"Unsupported return type: {TypeNameHelper.GetTypeDisplayName(returnType)}"); } } else if (typeof(IResult).IsAssignableFrom(returnType)) @@ -988,6 +988,11 @@ public static partial class RequestDelegateFactory { return Expression.Call(StringResultWriteResponseAsyncMethod, HttpContextExpr, methodCall); } + else if (returnType.IsByRefLike) + { + // Unsupported + throw new NotSupportedException($"Unsupported return type: {TypeNameHelper.GetTypeDisplayName(returnType)}"); + } else if (returnType.IsValueType) { var box = Expression.TypeAs(methodCall, typeof(object)); diff --git a/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs b/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs index 3517fe81b4..808fd4bf0d 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs +++ b/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs @@ -2179,6 +2179,32 @@ public class RequestDelegateFactoryTests : LoggedTest Assert.Equal(default, structToBeZeroed); } + [Fact] + public void RequestDelegateFactoryThrowsForByRefReturnTypes() + { + ReadOnlySpan<byte> Method1() => "hello world"u8; + Span<byte> Method2() => "hello world"u8.ToArray(); + RefStruct Method3() => new("hello world"u8); + + var ex1 = Assert.Throws<NotSupportedException>(() => RequestDelegateFactory.Create(Method1)); + var ex2 = Assert.Throws<NotSupportedException>(() => RequestDelegateFactory.Create(Method2)); + var ex3 = Assert.Throws<NotSupportedException>(() => RequestDelegateFactory.Create(Method3)); + + Assert.Equal("Unsupported return type: System.ReadOnlySpan<byte>", ex1.Message); + Assert.Equal("Unsupported return type: System.Span<byte>", ex2.Message); + Assert.Equal($"Unsupported return type: {typeof(RefStruct).FullName}", ex3.Message); + } + + ref struct RefStruct + { + public ReadOnlySpan<byte> Buffer { get; } + + public RefStruct(ReadOnlySpan<byte> buffer) + { + Buffer = buffer; + } + } + [Theory] [InlineData(true)] [InlineData(false)] |