org.sonar.plugins.csharp.S2259.html Maven / Gradle / Ivy
Why is this an issue?
Accessing a null 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 null
values.
using System;
using System.Text.RegularExpressions;
public static class Program
{
public static string RemoveVowels(this string value)
{
if (value == null)
{
return null;
}
return Regex.Replace(value, "[aeoui]*","", RegexOptions.IgnoreCase);
}
public static void Main()
{
Console.WriteLine(((string?)null).RemoveVowels()); // Compliant: 'RemoveVowels' is an extension method
}
}
Unreachable code
Unreachable code is not executed, thus null
values will never be accessed.
public void Method()
{
object o = null;
if (false)
{
o.ToString(); // Compliant: code is unreachable
}
}
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 null
values validated by one of
the following attributes will not raise:
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:
using System;
public sealed class NotNullAttribute : Attribute { } // The alternative name 'ValidatedNotNullAttribute' is also supported
public static class Guard
{
public static void NotNull<T>([NotNull] T value, string name) where T : class
{
if (value == null)
{
throw new ArgumentNullException(name);
}
}
}
public static class Utils
{
public static string Normalize(string value)
{
Guard.NotNull(value, nameof(value)); // Will throw if value is null
return value.ToUpper(); // Compliant: value is known to be not null here.
}
}
Validated value by Debug.Assert
A value validated with Debug.Assert to not be
null
is safe to access.
using System.Diagnostics;
public void Method(object myObject)
{
Debug.Assert(myObject != null);
myObject.ToString(); // Compliant: 'myObject' is known to be not null here.
}
Validated value by IDE-specific attributes
Like with null-analysis-attribute, potential null
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
using System;
using JetBrains.Annotations;
public class Utils
{
[TerminatesProgram]
public void TerminateProgram()
{
Environment.FailFast("A catastrophic failure has occurred.")
}
public void TerminatesProgramIsRespected()
{
object myObject = null;
TerminateProgram();
myObject.ToString(); // Compliant: unreachable
}
}
Null forgiving operator
Expression marked with the null forgiving
operator
public void Method()
{
object o = null;
o!.ToString(); // Compliant: the null forgiving operator suppresses the nullable warning
}
How to fix it
To fix the issue, the access of the null
value needs to be prevented by either:
- ensuring the variable has a value, or
- by checking if the value is not
null
Code examples
Noncompliant code example
The variable myObject
is equal to null
, meaning it has no value:
public void Method()
{
object myObject = null;
Console.WriteLine(o.ToString()); // Noncompliant: 'myObject' is always null
}
The parameter input
might be null
as suggested by the if
condition:
public void Method(object input)
{
if (input is null)
{
// ...
}
Console.WriteLine(input.ToString()); // Noncompliant: the if condition suggests 'input' might be null
}
Compliant solution
Ensuring the variable myObject
has a value resolves the issue:
public void Method()
{
var myObject = new object();
Console.WriteLine(myObject.ToString()); // Compliant: 'myObject' is not null
}
Preventing the non-compliant code to be executed by returning early:
public void Method(object input)
{
if (input is null)
{
return;
}
Console.WriteLine(input.ToString()); // Compliant: if 'input' is null, this is unreachable
}
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 - null (C# Reference)
- Microsoft Learn - ! (null-forgiving)
operator (C# reference)