## Why is this an issue?

Accessing a Nothing value will always throw a NullReferenceException most likely causing an abrupt program termination.

Such termination might expose sensitive information that a malicious third party could exploit to, for instance, bypass security measures.

### Exceptions

In the following cases, the rule does not raise:

#### Extensions Methods

Calls to extension methods can still operate on `Nothing` values.

    Imports System.Diagnostics.CodeAnalysis
    Imports System.Runtime.CompilerServices
    Imports System.Text.RegularExpressions

    Module Program
        <Extension>
        Function RemoveVowels(Value As String) As String
            If Value Is Nothing Then
                Return Nothing
            End If
            Return Regex.Replace(Value, "[aeoui]*", "", RegexOptions.IgnoreCase)
        End Function

        Sub Main()
            Dim StrValue As String = Nothing
            Console.WriteLine(StrValue.RemoveVowels()) ' Compliant: 'RemoveVowels' is an extension method
        End Sub
    End Module

#### Unreachable code

Unreachable code is not executed, thus `Nothing` values will never be accessed.

    Public Sub Method()
        Dim o As Object = Nothing
        If False Then
            o.ToString() ' Compliant: code is unreachable
        End If
    End Sub

#### Validated value by analysis attributes

Nullable analysis attributes enable the developer to annotate methods with information about the null-state of its arguments. Thus, potential `Nothing` values validated by one of the following attributes will not raise:

- NotNullAttribute
- NotNullWhenAttribute
- DoesNotReturnAttribute
- DoesNotReturnIfAttribute

It is important to note those attributes are only available starting .NET Core 3. As a workaround, it is possible to define those attributes manually in a custom class:

    Public NotInheritable Class NotNullAttribute ' The alternative name 'ValidatedNotNullAttribute' is also supported
        Inherits Attribute
    End Class

    Public Module Guard
        Public Sub CheckNotNull(Of T)(<NotNull> Value As T, Name As String)
            If Value Is Nothing Then Throw New ArgumentNullException(Name)
        End Sub
    End Module

    Public Module Utils
        Public Function Normalize(Value As String) As String
            CheckNotNull(Value, nameof(Value)) ' Will throw if 'Value' is Nothing
            Return Value.ToUpper() ' Compliant: value is known to be not Nothing here
        End Function
    End Module

#### Validated value by Debug.Assert

A value validated with Debug.Assert to not be `Nothing` is safe to access.

    Imports System.Diagnostics

    Public Sub Method(MyObject As Object)
        Debug.Assert(MyObject IsNot Nothing)
        MyObject.ToString() ' Compliant: 'MyObject' is known to be not Nothing here.
    End Sub

#### Validated value by IDE-specific attributes

Like with null-analysis-attribute, potential `Nothing` values validated by one of the following IDE-specific attributes will not raise

##### Visual Studio

- ValidatedNotNullAttribute (The attribute is interpreted the same as the NotNullAttribute)

##### JetBrains Rider

- NotNullAttribute
- TerminatesProgramAttribute

      Imports System
      Imports JetBrains.Annotations

      Public Class Utils
          <TerminatesProgram>
          Public Sub TerminateProgram()
              Environment.FailFast("A catastrophic failure has occurred.")
          End Sub

          Public Sub Method()
              Dim MyObject As Object = Nothing
              TerminateProgram()
              MyObject.ToString() ' Compliant: unreachable
          End Sub
      End Class

## How to fix it

To fix the issue, the access of the `Nothing` value needs to be prevented by either:

- ensuring the variable has a value, or
- by checking if the value is not `Nothing`

### Code examples

#### Noncompliant code example

The variable `MyObject` is equal to `Nothing`, meaning it has no value:

    Public Sub Method()
        Dim MyObject As Object = Nothing
        Console.WriteLine(MyObject.ToString)   ' Noncompliant: 'MyObject' is always Nothing
    End Sub

The parameter `Input` might be `Nothing` as suggested by the `if` condition:

    Public Sub Method(Input As Object)
        If Input Is Nothing Then
            ' ...
        End If
        Console.WriteLine(Input.ToString) ' Noncompliant: 'Input' might be Nothing
    End Sub

#### Compliant solution

Ensuring the variable `MyObject` has a value resolves the issue:

    Public Sub Method()
        Dim MyObject As New Object
        Console.WriteLine(MyObject.ToString) ' Compliant: 'MyObject' is not Nothing
    End Sub

Preventing the non-compliant code to be executed by returning early:

    Public Sub Method(Input As Object)
        If Input Is Nothing Then
            Return
        End If
        Console.WriteLine(Input.ToString) ' Compliant: if 'Input' is Nothing, this part is unreachable
    End Sub

## Resources

### Documentation

- CVE - CWE-476 - NULL Pointer Dereference
- Microsoft Learn - NullReferenceException Class
- Microsoft Learn - Attributes for null-state static analysis interpreted by the C# compiler
  - Microsoft Learn - NotNullAttribute Class
  - Microsoft Learn - NotNullWhenAttribute Class
  - Microsoft Learn - DoesNotReturnAttribute Class
  - Microsoft Learn - DoesNotReturnIfAttribute Class
- Microsoft Learn - ValidatedNotNullAttribute Class in Visual Studio
- JetBrains Resharper - NotNullAttribute
- JetBrains Resharper - TerminatesProgramAttribute
- Microsoft Learn - Nothing keyword (Visual Basic)