From 5314099e532fdbce8c2198e00683645d77ec0a4f Mon Sep 17 00:00:00 2001 From: Zsolt Kolbay Date: Fri, 10 Mar 2023 10:38:03 +0100 Subject: [PATCH] Update RSPEC --- analyzers/rspec/cs/S3900_c#.html | 57 ++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/analyzers/rspec/cs/S3900_c#.html b/analyzers/rspec/cs/S3900_c#.html index 57509e5eb08..1de43aa95eb 100644 --- a/analyzers/rspec/cs/S3900_c#.html +++ b/analyzers/rspec/cs/S3900_c#.html @@ -1,5 +1,6 @@ -

A publicly accessible method can be called from anywhere, which means you should validate parameters to be within the expected constraints. In -general, checking against null is recommended defensive programming.

+

Methods declared as public, protected, or protected internal can be accessed from other assemblies, which +means you should validate parameters to be within the expected constraints. In general, checking against null is recommended in defensive +programming.

This rule raises an issue when a parameter of a publicly accessible method is not validated against null before being dereferenced.

Noncompliant Code Example

@@ -9,16 +10,11 @@

Noncompliant Code Example

private MyOtherClass other; public void Foo(MyOtherClass other) - { - this.other = other; // Compliant: other not being dereferenced - } - - public void Bar(MyOtherClass other) { this.other = other.Clone(); // Noncompliant } - protected void FooBar(MyOtherClass other) + protected void Bar(MyOtherClass other) { this.other = other.Clone(); // Noncompliant } @@ -31,11 +27,6 @@

Compliant Solution

private MyOtherClass other; public void Foo(MyOtherClass other) - { - this.other = other; - } - - public void Bar(MyOtherClass other) { if (other != null) { @@ -43,26 +34,51 @@

Compliant Solution

} } - protected void FooBar(MyOtherClass other) + protected void Bar(MyOtherClass other) { if (other != null) { this.other = other.Clone(); } } + + public void Baz(MyOtherClass other) + { + ArgumentNullException.ThrowIfNull(other); + + this.other = other.Clone(); + } + + public void Qux(MyOtherClass other) + { + this.other = other; // Compliant: "other" is not being dereferenced + } + + private void Xyzzy(MyOtherClass other) + { + this.other = other; // Compliant: method is not publicly accessible + } }

Exceptions

-

To create a custom null validation method declare an attribute with name ValidatedNotNullAttribute and mark the parameter that is -validated for null in your method declaration with it:

+
 using System;
 
+[AttributeUsage(AttributeTargets.Parameter, Inherited=false)]
 public sealed class ValidatedNotNullAttribute : Attribute { }
 
 public static class Guard
 {
-    public static void NotNull<T>([ValidatedNotNullAttribute] this T value, string name) where T : class
+    public static void NotNull<T>([ValidatedNotNullAttribute] T value, [CallerArgumentExpression("value")] string name = "") where T : class
     {
         if (value == null)
             throw new ArgumentNullException(name);
@@ -73,11 +89,8 @@ 

Exceptions

{ public static string ToUpper(string value) { - Guard.NotNull(value, nameof(value)); - if (value == null) - { - return value.ToString(); - } + Guard.NotNull(value); + return value.ToUpper(); // Compliant } }