Giter Club home page Giter Club logo

runtimenullables's People

Contributors

gitter-badger avatar mikernet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

gitter-badger

runtimenullables's Issues

InvalidProgramException when using C# 9 init only setters

Hey, very nice project :) it really helps out on filling the gap with nullable reference types.

There seems to be an issue with C# 9 init only properties on record types, any property setter (nullable or not) throws InvalidProgramException.

Stack trace:

System.InvalidProgramException
Common Language Runtime detected an invalid program.
   at Sample.Tests.Commands.CreateDocumentCommand.set_DocumentNumber(String value)
   at Sample.Tests.CreateDocumentCommandTests.Should_fail_create_command_when_duplicate_found() in D:\Dev\dotnet\Projects\nrttests\test\Sample.Tests\CreateDocumentCommandTests.cs:line 246

Returning Task.FromResult(false) throws NullReferenceException

Unhandled exception. System.NullReferenceException: Task result nullability contract was broken.
   at RuntimeNullables.ThrowHelpers.ThrowOutputNull(String message)
   at FodyTest.Program.DoSomethingAsync() in /home/andrii/development/FodyTest/FodyTest/Program.cs:line 17
   at FodyTest.Program.Main(String[] args) in /home/andrii/development/FodyTest/FodyTest/Program.cs:line 9
   at FodyTest.Program.<Main>(String[] args)

Minimal reproducible example:

using System.Threading.Tasks;

namespace FodyTest
{
    class Program
    {
        static Task Main(string[] args)
        {
            return DoSomethingAsync();
        }

        static Task<bool> DoSomethingAsync()
        {
            // Returning False throws the exception
            // Returning True works fine
            return Task.FromResult(false);
        }
    }
}
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net5.0</TargetFramework>
        <Nullable>enable</Nullable>
    </PropertyGroup>

    <PropertyGroup>
        <WeaverConfiguration>
            <Weavers>
                <RuntimeNullables CheckOutputs="true" CheckNonPublic="true" />
            </Weavers>
        </WeaverConfiguration>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="RuntimeNullables.Fody" Version="0.9.3" />
    </ItemGroup>

</Project>

InvalidProgramException when returning task with nullable struct

Unhandled exception. System.InvalidProgramException: Common Language Runtime detected an invalid program.
   at FodyTest.Program.DoSomethingAsync()
   at FodyTest.Program.Main(String[] args) in /home/andrii/development/FodyTest/FodyTest/Program.cs:line 9
   at FodyTest.Program.<Main>(String[] args)
using System.Threading.Tasks;

namespace FodyTest
{
    class Program
    {
        static Task Main(string[] args)
        {
            return DoSomethingAsync();
        }

        // Works fine with reference types (e.g. string)
        // But throws the exception with value types (e.g. bool)
        static Task<bool?> DoSomethingAsync()
        {
            return Task.FromResult((bool?) null);
        }
    }
}

"Fatal error. Internal CLR error. (0x80131506)" when using ValueTask<T>

Hi! I've got an issue with the package along with ValueTask<T> return types.

If nullable checks are enabled, and you have a method with return type ValueTask<anything> (with anything not nullable), executing that method crashes the process with an Fatal error. Internal CLR error. (0x80131506) message.

How to reproduce (xunit test):

using RuntimeNullables;
using Xunit;

namespace ValueTaskIssue;

public class TestedClass
{
    [NullChecks(true)]
    public ValueTask<string> TestedMethod1()
    {
        return new ValueTask<string>("");
    }
    
    [NullChecks(false)]
    public ValueTask<string> TestedMethod2()
    {
        return new ValueTask<string>("");
    }
}

public class UnitTest1
{
    private readonly TestedClass _testedClass = new TestedClass();

    // this fails with: Fatal error. Internal CLR error. (0x80131506)
    [Fact]
    public async Task Test1()
    {
        var value = await _testedClass.TestedMethod1();

        Assert.Empty(value);
    }
    
    // this works:
    [Fact]
    public async Task Test2()
    {
        var value = await _testedClass.TestedMethod2();

        Assert.Empty(value);
    }
}

I'm not super sure, but I suppose it could be related to the weaver trying to add nullable checks to the value of the ValueTask

No null checks for arrays of primitive types?

I encountered a weird issue when using RuntimeNullables: apparently it does not generate null checks for primitive arrays (e.g. byte[]) as can be seen in the example below.

Is this expected behavior?

Source code:

namespace Namespace
{
  public class NullabilityTest
  {
    private readonly string _s;
    private readonly string[] _stringArray;
    private readonly byte[] _byteArray;
    private readonly int _i;

    public NullabilityTest (string s, string[] stringArray, byte[] byteArray, int i)
    {
      _s = s;
      _stringArray = stringArray;
      _byteArray = byteArray;
      _i = i;
    }
  }
}

IL:

.method public hidebysig specialname rtspecialname instance void
    .ctor(
      string s,
      string[] stringArray,
      unsigned int8[] byteArray,
      int32 i
    ) cil managed
  {
    .maxstack 2

    // [10 5 - 10 85]
    IL_0000: ldarg.1      // s
    IL_0001: brtrue.s     IL_000d
    IL_0003: ldstr        "s"
    IL_0008: call         void RuntimeNullables.ThrowHelpers::ThrowArgumentNull(string)
    IL_000d: ldarg.2      // stringArray
    IL_000e: brtrue.s     IL_001a
    IL_0010: ldstr        "stringArray"
    IL_0015: call         void RuntimeNullables.ThrowHelpers::ThrowArgumentNull(string)
    IL_001a: ldarg.0      // this
    IL_001b: call         instance void [mscorlib]System.Object::.ctor()
    IL_0020: nop

    // [11 5 - 11 6]
    IL_0021: nop

    // [12 7 - 12 14]
    IL_0022: ldarg.0      // this
    IL_0023: ldarg.1      // s
    IL_0024: stfld        string SignPath.Application.Domain.Common.NullabilityTest::_s

    // [13 7 - 13 34]
    IL_0029: ldarg.0      // this
    IL_002a: ldarg.2      // stringArray
    IL_002b: stfld        string[] SignPath.Application.Domain.Common.NullabilityTest::_stringArray

    // [14 7 - 14 30]
    IL_0030: ldarg.0      // this
    IL_0031: ldarg.3      // byteArray
    IL_0032: stfld        unsigned int8[] SignPath.Application.Domain.Common.NullabilityTest::_byteArray

    // [15 7 - 15 14]
    IL_0037: ldarg.0      // this
    IL_0038: ldarg.s      i
    IL_003a: stfld        int32 SignPath.Application.Domain.Common.NullabilityTest::_i

    // [16 5 - 16 6]
    IL_003f: ret

  } // end of method NullabilityTest::.ctor

Feature: Ability to automatically skip null checking for requests DTO in ASP.NET Core

First of all thank you very much for a great library!
Here is a case:

  1. Create an ASP.NET Core project and add RuntimeNullables package
  2. Create endpoint and request data class:
[Post]
public IActionResult Auth(AuthRequest request)
{
    //logic
}

public record AuthRequest(string Something);
  1. Send a request to this gateway:
{ "Something": null }
  1. Server returned 500 error (cause Something cannot be null), but had to return 400 (Bad Request). So, as you see this is kind of a bug actually.

Of course we can add [NullChecks(false)] attribute to the request class and the bug will disappear, but what if we forget to do that? Again 500? And it's actually not so convenient to add NullChecks to requests explicitly all times.
I suggest to add an ability to automatically skip null checking for requests DTO in ASP.NET Core. Let's discuss an implementation here.

PS. It's interesting that NullGuard.Fody just crashed my app at all when I sent an incorrect request like in the example, but RuntimeNullables only throws an exception and generates 500 (and also customizable). So, I fully migrated from NullGuard.Fody to RuntimeNullables. Thanks again for your work!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.