From 0b84a168e0d212178722ac9865627046c515b212 Mon Sep 17 00:00:00 2001 From: Costin Zaharia <56015273+costin-zaharia-sonarsource@users.noreply.github.com> Date: Wed, 1 Nov 2023 12:38:33 +0100 Subject: [PATCH] Rspec update before release (#8288) --- analyzers/rspec/cs/S106.html | 55 +++-- analyzers/rspec/cs/S1066.html | 40 +++- analyzers/rspec/cs/S1066.json | 2 +- analyzers/rspec/cs/S1075.html | 45 +++- analyzers/rspec/cs/S109.html | 50 ++-- analyzers/rspec/cs/S1104.html | 61 +++-- analyzers/rspec/cs/S1110.html | 26 +- analyzers/rspec/cs/S1116.html | 17 +- analyzers/rspec/cs/S1117.html | 25 +- analyzers/rspec/cs/S1117.json | 4 +- analyzers/rspec/cs/S1118.html | 27 +-- analyzers/rspec/cs/S112.html | 43 +++- analyzers/rspec/cs/S112.json | 2 +- analyzers/rspec/cs/S1121.html | 61 +++-- analyzers/rspec/cs/S1125.html | 17 +- analyzers/rspec/cs/S1128.html | 76 ++++-- analyzers/rspec/cs/S1128.json | 4 +- analyzers/rspec/cs/S113.json | 2 +- analyzers/rspec/cs/S1135.html | 2 +- analyzers/rspec/cs/S1144.html | 35 ++- analyzers/rspec/cs/S1144.json | 2 +- analyzers/rspec/cs/S1155.html | 23 +- analyzers/rspec/cs/S1172.html | 43 ++-- analyzers/rspec/cs/S1186.html | 59 +++-- analyzers/rspec/cs/S1192.html | 30 ++- analyzers/rspec/cs/S1199.html | 26 +- analyzers/rspec/cs/S125.html | 5 +- analyzers/rspec/cs/S134.html | 56 ++++- analyzers/rspec/cs/S1481.html | 47 +++- analyzers/rspec/cs/S1854.html | 58 +++-- analyzers/rspec/cs/S1854.json | 2 +- analyzers/rspec/cs/S1871.html | 63 ++++- analyzers/rspec/cs/S1905.html | 38 ++- analyzers/rspec/cs/S2068.html | 1 - analyzers/rspec/cs/S2077.html | 1 - analyzers/rspec/cs/S2092.html | 1 - analyzers/rspec/cs/S2184.html | 1 - analyzers/rspec/cs/S2257.html | 1 - analyzers/rspec/cs/S2259.html | 2 +- analyzers/rspec/cs/S2589.html | 39 +-- analyzers/rspec/cs/S2612.html | 1 - analyzers/rspec/cs/S2933.html | 29 ++- analyzers/rspec/cs/S2971.html | 84 ++++--- analyzers/rspec/cs/S2971.json | 2 +- analyzers/rspec/cs/S3257.html | 26 +- analyzers/rspec/cs/S3330.html | 1 - analyzers/rspec/cs/S3353.html | 48 ++-- analyzers/rspec/cs/S3353.json | 2 +- analyzers/rspec/cs/S3415.html | 20 +- analyzers/rspec/cs/S3457.html | 82 +++++-- analyzers/rspec/cs/S3457.json | 2 +- analyzers/rspec/cs/S3776.html | 226 ++++++++++++++++-- analyzers/rspec/cs/S4211.html | 56 +++-- analyzers/rspec/cs/S4212.html | 1 + analyzers/rspec/cs/S4212.json | 2 +- analyzers/rspec/cs/S4423.html | 1 - analyzers/rspec/cs/S4502.html | 1 - analyzers/rspec/cs/S4790.html | 1 - analyzers/rspec/cs/S4792.html | 1 - analyzers/rspec/cs/S5122.html | 1 - analyzers/rspec/cs/S5542.html | 1 - analyzers/rspec/cs/S5547.html | 1 - analyzers/rspec/cs/S5773.html | 1 - analyzers/rspec/vbnet/S1066.html | 8 +- analyzers/rspec/vbnet/S1066.json | 2 +- analyzers/rspec/vbnet/S1075.html | 17 +- analyzers/rspec/vbnet/S112.html | 45 +++- analyzers/rspec/vbnet/S112.json | 2 +- analyzers/rspec/vbnet/S1125.html | 16 +- analyzers/rspec/vbnet/S1135.html | 2 +- analyzers/rspec/vbnet/S117.html | 72 +++++- analyzers/rspec/vbnet/S1172.html | 39 +-- analyzers/rspec/vbnet/S1186.html | 60 +++-- analyzers/rspec/vbnet/S1192.html | 30 ++- analyzers/rspec/vbnet/S134.html | 14 +- analyzers/rspec/vbnet/S1481.html | 45 +++- analyzers/rspec/vbnet/S1871.html | 56 ++++- analyzers/rspec/vbnet/S2068.html | 1 - analyzers/rspec/vbnet/S2077.html | 1 - analyzers/rspec/vbnet/S2257.html | 1 - analyzers/rspec/vbnet/S2259.html | 2 +- analyzers/rspec/vbnet/S2589.html | 32 +-- analyzers/rspec/vbnet/S2612.html | 1 - analyzers/rspec/vbnet/S3776.html | 28 ++- analyzers/rspec/vbnet/S4423.html | 1 - analyzers/rspec/vbnet/S4790.html | 1 - analyzers/rspec/vbnet/S4792.html | 1 - analyzers/rspec/vbnet/S5542.html | 1 - analyzers/rspec/vbnet/S5547.html | 1 - analyzers/rspec/vbnet/S5773.html | 1 - .../src/SonarAnalyzer.CSharp/sonarpedia.json | 2 +- .../SonarAnalyzer.VisualBasic/sonarpedia.json | 2 +- .../Helpers/RuleCatalogTest.cs | 2 +- 93 files changed, 1509 insertions(+), 659 deletions(-) diff --git a/analyzers/rspec/cs/S106.html b/analyzers/rspec/cs/S106.html index d74431c3ea4..92d55a52f37 100644 --- a/analyzers/rspec/cs/S106.html +++ b/analyzers/rspec/cs/S106.html @@ -1,29 +1,50 @@

Why is this an issue?

-

When logging a message there are several important requirements which must be fulfilled:

+

In software development, logs serve as a record of events within an application, providing crucial insights for debugging. When logging, it is +essential to ensure that the logs are:

-

If a program directly writes to the standard outputs, there is absolutely no way to comply with those requirements. That’s why defining and using a -dedicated logger is highly recommended.

-

Noncompliant code example

-
-private void DoSomething()
-{
-    // ...
-    Console.WriteLine("so far, so good..."); // Noncompliant
-    // ...
-}
-
+

Those requirements are not met if a program directly writes to the standard outputs (e.g., Console). That is why defining and using a dedicated +logger is highly recommended.

Exceptions

-

The following are ignored by this rule:

+

The rule doesn’t raise an issue for:

+

Code examples

+

The following noncompliant code:

+
+public class MyClass
+{
+    private void DoSomething()
+    {
+        // ...
+        Console.WriteLine("My Message"); // Noncompliant
+        // ...
+    }
+}
+
+

Could be replaced by:

+
+public class MyClass
+{
+    private readonly ILogger _logger;
+
+    // ...
+
+    private void DoSomething()
+    {
+        // ...
+        _logger.LogInformation("My Message");
+        // ...
+    }
+}
+

Resources

diff --git a/analyzers/rspec/cs/S2184.html b/analyzers/rspec/cs/S2184.html index a58e0bd8c44..426319763e3 100644 --- a/analyzers/rspec/cs/S2184.html +++ b/analyzers/rspec/cs/S2184.html @@ -26,6 +26,5 @@

Compliant solution

Resources

diff --git a/analyzers/rspec/cs/S2257.html b/analyzers/rspec/cs/S2257.html index 76c20ed18a3..0bca2cc9d3d 100644 --- a/analyzers/rspec/cs/S2257.html +++ b/analyzers/rspec/cs/S2257.html @@ -39,7 +39,6 @@

See

  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
  • MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
  • -
  • SANS Top 25 - Porous Defenses
  • Derived from FindSecBugs rule MessageDigest is Custom
  • diff --git a/analyzers/rspec/cs/S2259.html b/analyzers/rspec/cs/S2259.html index 85fe41f0876..5bc74a0669d 100644 --- a/analyzers/rspec/cs/S2259.html +++ b/analyzers/rspec/cs/S2259.html @@ -133,7 +133,7 @@

    Null forgiving operator

    }

    How to fix it

    -

    To fix the issue the access of the null value needs to be prevented by either:

    +

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

    In these cases, it is obvious the code is as intended.

    How to fix it

    -

    The conditions should be reviewed to decide whether:

    - +

    Gratuitous boolean expressions are suspicious and should be carefully removed from the code.

    +

    First, the boolean expression in question should be closely inspected for logical errors. If a mistake was made, it can be corrected so the +condition is no longer gratuitous.

    +

    If it becomes apparent that the condition is actually unnecessary, it can be removed. The associated control flow construct (e.g., the +if-statement containing the condition) will be adapted or even removed, leaving only the necessary branches.

    Code examples

    Noncompliant code example

    diff --git a/analyzers/rspec/cs/S2612.html b/analyzers/rspec/cs/S2612.html
    index 8f2091c5578..52b947c6046 100644
    --- a/analyzers/rspec/cs/S2612.html
    +++ b/analyzers/rspec/cs/S2612.html
    @@ -66,6 +66,5 @@ 

    See

    href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/02-Configuration_and_Deployment_Management_Testing/09-Test_File_Permission">OWASP File Permission
  • MITRE, CWE-732 - Incorrect Permission Assignment for Critical Resource
  • MITRE, CWE-266 - Incorrect Privilege Assignment
  • -
  • SANS Top 25 - Porous Defenses
  • diff --git a/analyzers/rspec/cs/S2933.html b/analyzers/rspec/cs/S2933.html index c6f19aae124..59f17ef2940 100644 --- a/analyzers/rspec/cs/S2933.html +++ b/analyzers/rspec/cs/S2933.html @@ -2,11 +2,21 @@

    Why is this an issue?

    readonly fields can only be assigned in a class constructor. If a class has a field that’s not marked readonly but is only set in the constructor, it could cause confusion about the field’s intended use. To avoid confusion, such fields should be marked readonly to make their intended use explicit, and to prevent future maintainers from inadvertently changing their use.

    -

    Noncompliant code example

    -
    +

    Exceptions

    + +

    How to fix it

    +

    Mark the given field with the readonly modifier.

    +

    Code examples

    +

    Noncompliant code example

    +
     public class Person
     {
    -    private int _birthYear;  // Noncompliant
    +    private int _birthYear; // Noncompliant
     
         Person(int birthYear)
         {
    @@ -14,8 +24,8 @@ 

    Noncompliant code example

    } }
    -

    Compliant solution

    -
    +

    Compliant solution

    +
     public class Person
     {
         private readonly int _birthYear;
    @@ -26,13 +36,10 @@ 

    Compliant solution

    } }
    -

    Exceptions

    -
      -
    • Fields with attributes are ignored.
    • -
    • Fields of type struct that are not primitive or pointer types are also ignored because of possible unwanted behavior.
    • -

    Resources

    +

    Documentation

    diff --git a/analyzers/rspec/cs/S2971.html b/analyzers/rspec/cs/S2971.html index 18cd0a854ea..7827fba4d2f 100644 --- a/analyzers/rspec/cs/S2971.html +++ b/analyzers/rspec/cs/S2971.html @@ -1,38 +1,62 @@

    Why is this an issue?

    -

    In the interests of readability, code that can be simplified should be simplified. To that end, there are several ways IEnumerable -language integrated queries (LINQ) can be simplified

    +

    In the interests of readability, code that can be simplified should be simplified. To that end, there are several ways IEnumerable language integrated queries (LINQ) can be +simplified. This not only improves readabilty but can also lead to improved performance.

    +

    How to fix it

    +

    Simplify the LINQ expressions:

      -
    • Use OfType instead of using Select with as to type cast elements and then null-checking in a query - expression to choose elements based on type.
    • -
    • Use OfType instead of using Where and the is operator, followed by a cast in a Select
    • -
    • Use an expression in Any instead of Where(element => [expression]).Any().
    • -
    • Use Count instead of Count() when it’s available.
    • -
    • Don’t call ToArray() or ToList() in the middle of a query chain.
    • +
    • Use OfType instead of Select with the as operator to type cast + elements and then null-checking in a query expression to choose elements based on type.
    • +
    • Use OfType instead of using Where and the + is operator, followed + by a cast in a Select
    • +
    • Use an expression in Any instead of Where(element ⇒ [expression]).Any().
    • +
    • Use the Count or Length properties instead of the Count() method when it’s available (unless you use the + predicate parameter of the method for filtering).
    • +
    • Don’t call ToArray() or ToList() in the middle of a query chain.
    -

    Using EntityFramework may require enforcing client evaluations. Such queries should use AsEnumerable() instead of -ToArray() or ToList() in the middle of a query chain.

    -

    Noncompliant code example

    -
    -seq1.Select(element => element as T).Any(element => element != null);  // Noncompliant; use OfType
    -seq2.Select(element => element as T).Any(element => element != null && CheckCondition(element));  // Noncompliant; use OfType
    -seq3.Where(element => element is T).Select(element => element as T); // Noncompliant; use OfType
    -seq4.Where(element => element is T).Select(element => (T)element); // Noncompliant; use OfType
    -seq5.Where(element => [expression]).Any();  // Noncompliant; use Any([expression])
    +

    Using Entity Framework may require enforcing client evaluations. Such queries should use AsEnumerable() instead of ToArray() or +ToList() in the middle of a query chain.

    +

    Code examples

    +

    Noncompliant code example

    +
    +public void Foo(IEnumerable<Vehicle> seq, List<int> list)
    +{
    +    var result1 = seq.Select(x => x as Car).Any(x => x != null);               // Noncompliant; use OfType
    +    var result2 = seq.Select(x => x as Car).Any(x => x != null && x.HasOwner); // Noncompliant; use OfType before calling Any
    +    var result3 = seq.Where(x => x is Car).Select(x => x as Car);              // Noncompliant; use OfType
    +    var result4 = seq.Where(x => x is Car).Select(x => (Car)x);                // Noncompliant; use OfType
    +    var result5 = seq.Where(x => x.HasOwner).Any();                            // Noncompliant; use Any([predicate])
     
    -var num = seq6.Count(); // Noncompliant
    -var arr = seq.ToList().ToArray(); //Noncompliant
    -var count = seq.ToList().Count(x=>[condition]); //Noncompliant
    +    var num = list.Count();                                                    // Noncompliant; use the Count property
    +    var arr = seq.ToList().ToArray();                                          // Noncompliant; ToList is not needed
    +    var count = seq.ToList().Count(x => x.HasOwner);                           // Noncompliant; ToList is not needed
    +}
     
    -

    Compliant solution

    -
    -seq1.OfType<T>().Any();
    -seq2.OfType<T>().Any(element => CheckCondition(element));
    -seq3.OfType<T>();
    -seq4.OfType<T>();
    -seq5.Any(element => [expression])
    +

    Compliant solution

    +
    +public void Foo(IEnumerable<Vehicle> seq, List<int> list)
    +{
    +    var result1 = seq.OfType<Car>().Any();
    +    var result2 = seq.OfType<Car>().Any(x => x.HasOwner);
    +    var result3 = seq.OfType<Car>();
    +    var result4 = seq.OfType<Car>();
    +    var result5 = seq.Any(x => x.HasOwner);
     
    -var num = seq6.Count;
    -var arr = seq.ToArray();
    -var count = seq.Count(x=>[condition]);
    +    var num = list.Count;
    +    var arr = seq.ToArray();
    +    var count = seq.Count(x => x.HasOwner);
    +}
     
    +

    Resources

    +

    Documentation

    + diff --git a/analyzers/rspec/cs/S2971.json b/analyzers/rspec/cs/S2971.json index 8b465931a29..6d9dd0e7857 100644 --- a/analyzers/rspec/cs/S2971.json +++ b/analyzers/rspec/cs/S2971.json @@ -1,5 +1,5 @@ { - "title": "\"IEnumerable\" LINQs should be simplified", + "title": "LINQ expressions should be simplified", "type": "CODE_SMELL", "code": { "impacts": { diff --git a/analyzers/rspec/cs/S3257.html b/analyzers/rspec/cs/S3257.html index af785bdc113..0f74e78da63 100644 --- a/analyzers/rspec/cs/S3257.html +++ b/analyzers/rspec/cs/S3257.html @@ -1,6 +1,11 @@

    Why is this an issue?

    -

    Unnecessarily verbose declarations and initializations make it harder to read the code, and should be simplified.

    -

    Specifically the following should be omitted when they can be inferred:

    +

    In C#, the type of a variable can often be inferred by the compiler. The use of the [var keyword](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/implicitly-typed-local-variables) +allows you to avoid repeating the type name in a variable declaration and object instantiation because the declared type can often be inferred by the +compiler.

    +

    Additionally, initializations providing the default value can also be omitted, helping to make the code more concise and readable.

    +

    Unnecessarily verbose declarations and initializations should be simplified. Specifically, the following should be omitted when they can be +inferred:

    • array element type
    • array size
    • @@ -10,8 +15,11 @@

      Why is this an issue?

    • type of lambda expression parameters
    • parameter declarations of anonymous methods when the parameters are not used.
    -

    Noncompliant code example

    -
    +

    How to fix it

    +

    Remove any unneeded code. C# provides many features designed to help you write more concise code.

    +

    Code examples

    +

    Noncompliant code example

    +
     var l = new List<int>() {}; // Noncompliant, {} can be removed
     var o = new object() {}; // Noncompliant, {} can be removed
     
    @@ -33,8 +41,8 @@ 

    Noncompliant code example

    } }
    -

    Compliant solution

    -
    +

    Compliant solution

    +
     var l = new List<int>();
     var o = new object();
     
    @@ -56,4 +64,10 @@ 

    Compliant solution

    } }
    +

    Resources

    +

    Documentation

    + diff --git a/analyzers/rspec/cs/S3330.html b/analyzers/rspec/cs/S3330.html index 4a958b36cba..5b3fcb14d11 100644 --- a/analyzers/rspec/cs/S3330.html +++ b/analyzers/rspec/cs/S3330.html @@ -49,7 +49,6 @@

    See

  • OWASP Top 10 2017 Category A7 - Cross-Site Scripting (XSS)
  • MITRE, CWE-1004 - Sensitive Cookie Without 'HttpOnly' Flag
  • -
  • SANS Top 25 - Insecure Interaction Between Components
  • Derived from FindSecBugs rule HTTPONLY_COOKIE
  • diff --git a/analyzers/rspec/cs/S3353.html b/analyzers/rspec/cs/S3353.html index 3462347ae58..5b556b8f820 100644 --- a/analyzers/rspec/cs/S3353.html +++ b/analyzers/rspec/cs/S3353.html @@ -1,8 +1,15 @@

    Why is this an issue?

    -

    Marking a variable that is unchanged after initialization const is an indication to future maintainers that "no this isn’t updated, -and it’s not supposed to be". const should be used in these situations in the interests of code clarity.

    -

    Noncompliant code example

    -
    +

    If a variable that is not supposed to change is not marked as const, it could be accidentally reassigned elsewhere in the code, +leading to unexpected behavior and bugs that can be hard to track down.

    +

    By declaring a variable as const, you ensure that its value remains constant throughout the code. It also signals to other developers +that this value is intended to remain constant. This can make the code easier to understand and maintain.

    +

    In some cases, using const can lead to performance improvements. The compiler might be able to make optimizations knowing that the +value of a const variable will not change.

    +

    How to fix it

    +

    Mark the given variable with the const modifier.

    +

    Code examples

    +

    Noncompliant code example

    +
     public bool Seek(int[] input)
     {
       var target = 32;  // Noncompliant
    @@ -16,18 +23,8 @@ 

    Noncompliant code example

    return false; }
    -

    or

    -
    -public class Sample
    -{
    -  public void Method()
    -  {
    -    var context = $"{nameof(Sample)}.{nameof(Method)}";  // Noncompliant (C# 10 and above only)
    -  }
    -}
    -
    -

    Compliant solution

    -
    +

    Compliant solution

    +
     public bool Seek(int[] input)
     {
       const int target = 32;
    @@ -41,8 +38,18 @@ 

    Compliant solution

    return false; }
    -

    or

    -
    +

    Noncompliant code example

    +
    +public class Sample
    +{
    +  public void Method()
    +  {
    +    var context = $"{nameof(Sample)}.{nameof(Method)}";  // Noncompliant (C# 10 and above only)
    +  }
    +}
    +
    +

    Compliant solution

    +
     public class Sample
     {
       public void Method()
    @@ -51,4 +58,9 @@ 

    Compliant solution

    } }
    +

    Resources

    +

    Documentation

    +
      +
    • Microsoft Learn - const
    • +
    diff --git a/analyzers/rspec/cs/S3353.json b/analyzers/rspec/cs/S3353.json index 4b1ac203f63..fcbb9424781 100644 --- a/analyzers/rspec/cs/S3353.json +++ b/analyzers/rspec/cs/S3353.json @@ -1,5 +1,5 @@ { - "title": "Unchanged local variables should be \"const\"", + "title": "Unchanged variables should be marked as \"const\"", "type": "CODE_SMELL", "code": { "impacts": { diff --git a/analyzers/rspec/cs/S3415.html b/analyzers/rspec/cs/S3415.html index 45c9a72f515..937ab89ccd1 100644 --- a/analyzers/rspec/cs/S3415.html +++ b/analyzers/rspec/cs/S3415.html @@ -1,15 +1,21 @@

    Why is this an issue?

    The standard assertions library methods such as AreEqual and AreSame in MSTest and NUnit, or Equal and Same in XUnit, expect the first argument to be the expected value and -the second argument to be the actual value. Swap them, and your test will still have the same outcome (succeed/fail when it should) but the error -messages will be confusing.

    -

    This rule raises an issue when the second argument to an assertions library method is a hard-coded value and the first argument is not.

    -

    Noncompliant code example

    -
    +the second argument to be the actual value.

    +

    What is the potential impact?

    +

    Having the expected value and the actual value in the wrong order will not alter the outcome of tests, (succeed/fail when it should) but the error +messages will contain misleading information.

    +

    This rule raises an issue when the actual argument to an assertions library method is a hard-coded value and the expected argument is not.

    +

    How to fix it

    +

    You should provide the assertion methods with a hard-coded value as the expected value, while the actual value of the assertion should derive from +the portion of code that you want to test.

    +

    Code examples

    +

    Noncompliant code example

    +
     Assert.AreEqual(runner.ExitCode, 0, "Unexpected exit code"); // Noncompliant; Yields error message like: Expected:<-1>. Actual:<0>.
     
    -

    Compliant solution

    -
    +

    Compliant solution

    +
     Assert.AreEqual(0, runner.ExitCode, "Unexpected exit code");
     
    diff --git a/analyzers/rspec/cs/S3457.html b/analyzers/rspec/cs/S3457.html index 15bd19a1e34..f43bf48ad3a 100644 --- a/analyzers/rspec/cs/S3457.html +++ b/analyzers/rspec/cs/S3457.html @@ -1,38 +1,78 @@

    Why is this an issue?

    +

    A [composite format string](https://learn.microsoft.com/en-us/dotnet/standard/base-types/composite-formatting) +is a string that contains placeholders, represented by indices inside curly braces "{0}", "{1}", etc. These placeholders are replaced by values when +the string is printed or logged.

    Because composite format strings are interpreted at runtime, rather than validated by the compiler, they can contain errors that lead to unexpected -behaviors or runtime errors. This rule statically validates the good behavior of composite formats when calling the methods of -String.Format, StringBuilder.AppendFormat, Console.Write, Console.WriteLine, -TextWriter.Write, TextWriter.WriteLine, Debug.WriteLine(String, Object[]), -Trace.TraceError(String, Object[]), Trace.TraceInformation(String, Object[]), -Trace.TraceWarning(String, Object[]) and TraceSource.TraceInformation(String, Object[]).

    -

    Noncompliant code example

    -
    -s = string.Format("{0}", arg0, arg1); // Noncompliant, arg1 is declared but not used.
    -s = string.Format("{0} {2}", arg0, arg1, arg2); // Noncompliant, the format item with index 1 is missing so arg1 will not be used.
    -s = string.Format("foo"); // Noncompliant, there is no need to use string.Format here.
    -
    -

    Compliant solution

    -
    -s = string.Format("{0}", arg0);
    -s = string.Format("{0} {1}", arg0, arg2);
    -s = "foo";
    -
    +behaviors or runtime errors.

    +

    This rule validates the correspondence between arguments and composite formats when calling the following methods:

    +

    Exceptions

      -
    • No issue is raised if the format string is not a const.
    • +
    • No issue is raised if the format string is not a string literal, but comes from a variable.
     var pattern = "{0} {1} {2}";
    -var res = string.Format(pattern, 1, 2); // Compliant, not const string are not recognized
    +var res = string.Format(pattern, 1, 2); // Incorrect, but the analyzer doesn't raise any warnings here
     
      -
    • No issue is raised if the argument is not an inline creation array.
    • +
    • No issue is raised if the argument is not an inline created array.
     var array = new int[] {};
    -var res = string.Format("{0} {1}", array); // Compliant we don't know the size of the array
    +var res = string.Format("{0} {1}", array); // Compliant; we don't know the size of the array
     
    • This rule doesn’t check whether the format specifier (defined after the :) is actually valid.
    +

    How to fix it

    +

    A composite format string contains placeholders, replaced by values when the string is printed or logged. Mismatch in the format specifiers and the +arguments provided can lead to incorrect strings being created.

    +

    To avoid issues, a developer should ensure that the provided arguments match format specifiers.

    +

    Moreover, use string interpolation when possible.

    +

    Instead of

    +
    +string str = string.Format("Hello {0} {1}!", firstName, lastName);
    +
    +

    use

    +
    +string str = $"Hello {firstName} {lastName}!";
    +
    +

    With string interpolation:

    +
      +
    • the arguments are validated at compilation time rather than runtime
    • +
    • modern code editors provide auto-completion when typing the interpolation expression
    • +
    +

    Code examples

    +

    Noncompliant code example

    +
    +s = string.Format("{0}", arg0, arg1); // Noncompliant, arg1 is declared but not used.
    +s = string.Format("{0} {2}", arg0, arg1, arg2); // Noncompliant, the format item with index 1 is missing, so arg1 will not be used.
    +s = string.Format("foo"); // Noncompliant; there is no need to use "string.Format" here.
    +
    +

    Compliant solution

    +
    +s = string.Format("{0}", arg0);
    +s = string.Format("{0} {1}", arg0, arg2);
    +s = "foo";
    +
    diff --git a/analyzers/rspec/cs/S3457.json b/analyzers/rspec/cs/S3457.json index 0b65de9bdf4..f4de833e146 100644 --- a/analyzers/rspec/cs/S3457.json +++ b/analyzers/rspec/cs/S3457.json @@ -10,7 +10,7 @@ "status": "ready", "remediation": { "func": "Constant\/Issue", - "constantCost": "10min" + "constantCost": "1min" }, "tags": [ "confusing" diff --git a/analyzers/rspec/cs/S3776.html b/analyzers/rspec/cs/S3776.html index c1e8b5f9254..628d1ec0b6a 100644 --- a/analyzers/rspec/cs/S3776.html +++ b/analyzers/rspec/cs/S3776.html @@ -1,53 +1,233 @@ +

    This rule raises an issue when the code cognitive complexity of a function is above a certain threshold.

    Why is this an issue?

    -

    Cognitive Complexity Complexity is a measure of how hard the control flow of -a method is to understand.

    -

    Methods with high Cognitive Complexity will be difficult to maintain.

    +

    Cognitive Complexity is a measure of how hard it is to understand the control flow of a unit of code. Code with high cognitive complexity is hard +to read, understand, test, and modify.

    +

    As a rule of thumb, high cognitive complexity is a sign that the code should be refactored into smaller, easier-to-manage pieces.

    +

    Which syntax in code does impact cognitive complexity score?

    +

    Here are the core concepts:

    +
      +
    • Cognitive complexity is incremented each time the code breaks the normal linear reading flow.
      This concerns, for example: + Loop structures, Conditionals, Catches, Switches, Jumps to label and mixed operators in condition.
    • +
    • Each nesting level adds a malus to the breaking call.
      During code reading, the deeper you go through nested layers, the + harder it becomes to keep the context in mind.
    • +
    • Method calls are free
      A well-picked method name is a summary of multiple lines of code. A reader can first explore a + high-level view of what the code is performing then go deeper and deeper by looking at called functions content.
      Note: This does not + apply to recursive calls, those will increment cognitive score.
    • +
    +

    The method of computation is fully detailed in the pdf linked in the resources.

    +

    What is the potential impact?

    +

    Developers spend more time reading and understanding code than writing it. High cognitive complexity slows down changes and increases the cost of +maintenance.

    +

    How to fix it

    +

    Reducing cognitive complexity can be challenging.
    Here are a few suggestions:

    +
      +
    • Extract complex conditions in a new function.
      Mixed operators in condition will increase complexity. Extracting the + condition in a new function with an appropriate name will reduce cognitive load.
    • +
    • Break down large functions.
      Large functions can be hard to understand and maintain. If a function is doing too many + things, consider breaking it down into smaller, more manageable functions. Each function should have a single responsibility.
    • +
    • Avoid deep nesting by returning early.
      To avoid the nesting of conditions, process exceptional cases first and return + early.
    • +
    • Use null-safe operations (if available in the language).
      When available the .? or ?? operator + replaces multiple tests and simplifies the flow.
    • +
    +

    Code examples

    +

    Extraction of a complex condition in a new function.

    +

    Noncompliant code example

    +

    The code is using a complex condition and has a cognitive cost of 3.

    -int Abs(int n) // Noncompliant: cognitive complexity = 5
    +decimal CalculateFinalPrice(User user, Cart cart)
     {
    -    if (n >= 0)   // +1
    +    decimal total = CalculateTotal(cart);
    +    if (user.HasMembership()               // +1 (if)
    +        && user.OrdersCount > 10           // +1 (more than one condition)
    +        && user.AccountActive
    +        && !user.HasDiscount
    +        || user.OrdersCount == 1)          // +1 (change of operator in condition)
         {
    -        return n;
    +
    +        total = ApplyDiscount(user, total);
         }
    -    else          // +2, due to nesting
    +    return total;
    +}
    +
    +

    Compliant solution

    +

    Even if the cognitive complexity of the whole program did not change, it is easier for a reader to understand the code of the +calculateFinalPrice function, which now only has a cognitive cost of 1.

    +
    +decimal CalculateFinalPrice(User user, Cart cart)
    +{
    +    decimal total = CalculateTotal(cart);
    +    if (IsEligibleForDiscount(user))       // +1 (if)
    +    {
    +        total = applyDiscount(user, total);
    +    }
    +    return total;
    +}
    +
    +bool IsEligibleForDiscount(User user)
    +{
    +    return user.HasMembership()
    +            && user.OrdersCount > 10       // +1 (more than one condition)
    +            && user.AccountActive
    +            && !user.HasDiscount
    +            || user.OrdersCount == 1;      // +1 (change of operator in condition)
    +}
    +
    +

    Break down large functions.

    +

    Noncompliant code example

    +

    For example, consider a function that calculates the total price of a shopping cart, including sales tax and shipping.
    Note: The code +is simplified here, to illustrate the purpose. Please imagine there is more happening in the foreach loops.

    +
    +decimal CalculateTotal(Cart cart)
    +{
    +    decimal total = 0;
    +    foreach (Item item in cart.Items) // +1 (foreach)
         {
    -        if (n == int.MinValue)  // +1
    +        total += item.Price;
    +    }
    +
    +    // calculateSalesTax
    +    foreach (Item item in cart.Items) // +1 (foreach)
    +    {
    +        total += 0.2m * item.Price;
    +    }
    +
    +    //calculateShipping
    +    total += 5m * cart.Items.Count;
    +
    +    return total;
    +}
    +
    +

    This function could be refactored into smaller functions: The complexity is spread over multiple functions and the complex +CalculateTotal has now a complexity score of zero.

    +

    Compliant solution

    +
    +decimal CalculateTotal(Cart cart)
    +{
    +    decimal total = 0;
    +    total = CalculateSubtotal(cart, total);
    +    total += CalculateSalesTax(cart, total);
    +    total += CalculateShipping(cart, total);
    +    return total;
    +}
    +
    +decimal CalculateSubtotal(Cart cart, decimal total)
    +{
    +    foreach (Item item in cart.Items) // +1 (foreach)
    +    {
    +        total += item.Price;
    +    }
    +
    +    return total;
    +}
    +
    +decimal CalculateSalesTax(Cart cart, decimal total)
    +{
    +    foreach (Item item in cart.Items)  // +1 (foreach)
    +    {
    +        total += 0.2m * item.Price;
    +    }
    +
    +    return total;
    +}
    +
    +decimal CalculateShipping(Cart cart, decimal total)
    +{
    +    total += 5m * cart.Items.Count;
    +    return total;
    +}
    +
    +

    Avoid deep nesting by returning early.

    +

    Noncompliant code example

    +

    The below code has a cognitive complexity of 6.

    +
    +decimal CalculateDiscount(decimal price, User user)
    +{
    +    if (IsEligibleForDiscount(user))    // +1 ( if )
    +    {
    +        if (user.HasMembership())       // +2 ( nested if )
             {
    -            throw new ArgumentException("The absolute value of int.MinValue is outside of int boundaries");
    +            return price * 0.9m;
             }
    -        else                    // +1
    +        else if (user.OrdersCount == 1) // +1 ( else )
             {
    -            return -n;
    +            return price * 0.95m;
             }
    +        else                            // +1 ( else )
    +        {
    +            return price;
    +        }
    +    }
    +    else                                // +1 ( else )
    +    {
    +        return price;
         }
     }
     
    -

    They should be refactored to have lower complexity:

    -
    -int Abs(int n) // Compliant: cognitive complexity = 3
    +

    Compliant solution

    +

    Checking for the edge case first flattens the if statements and reduces the cognitive complexity to 3.

    +
    +decimal CalculateDiscount(decimal price, User user)
     {
    -    if (n == int.MinValue)  // +1
    +    if (!IsEligibleForDiscount(user)) // +1 ( if )
    +    {
    +        return price;
    +    }
    +
    +    if (user.HasMembership())         // +1 (  if )
         {
    -        throw new ArgumentException("The absolute value of int.MinValue is outside of int boundaries");
    +        return price * 0.9m;
         }
    -    else if (n >= 0)        // +1
    +
    +    if (user.OrdersCount == 1)        // +1 ( else )
    +    {
    +        return price * 0.95m;
    +    }
    +
    +    return price;
    +}
    +
    +

    Use the null-conditional operator to access data.

    +

    In the below code, the cognitive complexity is increased due to the multiple checks required to access the manufacturer’s name. This can be +simplified using the optional chaining operator.

    +

    Noncompliant code example

    +
    +string GetManufacturerName(Product product)
    +{
    +    string manufacturerName = null;
    +    if (product != null && product.Details != null &&
    +        product.Details.Manufacturer != null) // +1 (if) +1 (multiple condition)
         {
    -        return n;
    +        manufacturerName = product.Details.Manufacturer.Name;
         }
    -    else                    // +1
    +
    +    if (manufacturerName != null) // +1 (if)
         {
    -        return -n;
    +        return manufacturerName;
         }
    +
    +    return "Unknown";
    +}
    +
    +

    Compliant solution

    +

    The optional chaining operator will return null if any reference in the chain is null, avoiding multiple checks. The +?? operator allows to provide the default value to use.

    +
    +string GetManufacturerName(Product product)
    +{
    +    return product?.Details?.Manufacturer?.Name ?? "Unknown";
     }
     
    +

    Pitfalls

    +

    As this code is complex, ensure that you have unit tests that cover the code before refactoring.

    Resources

    Documentation

    Articles & blog posts

    diff --git a/analyzers/rspec/cs/S4211.html b/analyzers/rspec/cs/S4211.html index 177b3e4e240..41ed99afe21 100644 --- a/analyzers/rspec/cs/S4211.html +++ b/analyzers/rspec/cs/S4211.html @@ -1,50 +1,68 @@ +

    Transparency attributes in the .NET Framework, designed to protect security-critical operations, can lead to ambiguities and vulnerabilities when +declared at different levels such as both for the class and a method.

    Why is this an issue?

    -

    Transparency attributes, SecurityCriticalAttribute and SecuritySafeCriticalAttribute are used to identify code that -performs security-critical operations. The second one indicates that it is safe to call this code from transparent, while the first one does not. -Since the transparency attributes of code elements with larger scope take precedence over transparency attributes of code elements that are contained -in the first element a class, for instance, with a SecurityCriticalAttribute can not contain a method with a -SecuritySafeCriticalAttribute.

    -

    This rule raises an issue when a member is marked with a System.Security security attribute that has a different transparency than the -security attribute of a container of the member.

    -

    Noncompliant code example

    -
    +

    Transparency attributes can be declared at several levels. If two different attributes are declared at two different levels, the attribute that +prevails is the one in the highest level. For example, you can declare that a class is SecuritySafeCritical and that a method of this +class is SecurityCritical. In this case, the method will be SecuritySafeCritical and the SecurityCritical +attribute attached to it is ignored.

    +

    What is the potential impact?

    +

    Below are some real-world scenarios that illustrate some impacts of an attacker exploiting the vulnerability.

    +

    Elevation of Privileges

    +

    An attacker could potentially exploit conflicting transparency attributes to perform actions with higher privileges than intended.

    +

    Data Exposure

    +

    If a member with conflicting attributes is involved in handling sensitive data, an attacker could exploit the vulnerability to gain unauthorized +access to this data. This could lead to breaches of confidentiality and potential data loss.

    +

    How to fix it

    +

    Code examples

    +

    Noncompliant code example

    +
     using System;
     using System.Security;
     
     namespace MyLibrary
     {
    -
    -    [SecurityCritical]
    +    [SecuritySafeCritical]
         public class Foo
         {
    -        [SecuritySafeCritical] // Noncompliant
    +        [SecurityCritical] // Noncompliant
             public void Bar()
             {
             }
         }
     }
     
    -

    Compliant solution

    -
    +

    Compliant solution

    +
     using System;
     using System.Security;
     
     namespace MyLibrary
     {
    -
    -    [SecurityCritical]
         public class Foo
         {
    +        [SecurityCritical]
             public void Bar()
             {
             }
         }
     }
     
    +

    How does this work?

    +

    Never set class-level annotations

    +

    A class should never have class-level annotations if some functions have different permission levels. Instead, make sure every function has its own +correct annotation.

    +

    If no function needs a particularly distinct security annotation in a class, just set a class-level [SecurityCritical].

    Resources

    +

    Articles & blog posts

    + +

    Standards

    diff --git a/analyzers/rspec/cs/S4212.html b/analyzers/rspec/cs/S4212.html index 86eacb9a35a..70e7946f098 100644 --- a/analyzers/rspec/cs/S4212.html +++ b/analyzers/rspec/cs/S4212.html @@ -1,3 +1,4 @@ +

    This rule is deprecated, and will eventually be removed.

    Why is this an issue?

    Because serialization constructors allocate and initialize objects, security checks that are present on regular constructors must also be present on a serialization constructor. Failure to do so would allow callers that could not otherwise create an instance to use the serialization constructor diff --git a/analyzers/rspec/cs/S4212.json b/analyzers/rspec/cs/S4212.json index 49e92f81d1c..79bcb902d08 100644 --- a/analyzers/rspec/cs/S4212.json +++ b/analyzers/rspec/cs/S4212.json @@ -7,7 +7,7 @@ }, "attribute": "COMPLETE" }, - "status": "ready", + "status": "deprecated", "remediation": { "func": "Constant\/Issue", "constantCost": "5min" diff --git a/analyzers/rspec/cs/S4423.html b/analyzers/rspec/cs/S4423.html index 2764db7711c..1f3b3539acf 100644 --- a/analyzers/rspec/cs/S4423.html +++ b/analyzers/rspec/cs/S4423.html @@ -113,6 +113,5 @@

    Standards

  • OWASP Top 10 2017 Category A6 - Security Misconfiguration
  • MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
  • -
  • SANS Top 25 - Porous Defenses
  • diff --git a/analyzers/rspec/cs/S4502.html b/analyzers/rspec/cs/S4502.html index 72c235372da..e79f655f06a 100644 --- a/analyzers/rspec/cs/S4502.html +++ b/analyzers/rspec/cs/S4502.html @@ -58,6 +58,5 @@

    See

  • OWASP Top 10 2017 Category A6 - Security Misconfiguration
  • OWASP: Cross-Site Request Forgery
  • -
  • SANS Top 25 - Insecure Interaction Between Components
  • diff --git a/analyzers/rspec/cs/S4790.html b/analyzers/rspec/cs/S4790.html index 3570706aaa9..c9950a1fa1b 100644 --- a/analyzers/rspec/cs/S4790.html +++ b/analyzers/rspec/cs/S4790.html @@ -39,6 +39,5 @@

    See

  • OWASP Mobile Top 10 2016 Category M5 - Insufficient Cryptography
  • MITRE, CWE-1240 - Use of a Risky Cryptographic Primitive
  • -
  • SANS Top 25 - Porous Defenses
  • diff --git a/analyzers/rspec/cs/S4792.html b/analyzers/rspec/cs/S4792.html index 0fee48c3b34..820a1002f80 100644 --- a/analyzers/rspec/cs/S4792.html +++ b/analyzers/rspec/cs/S4792.html @@ -205,6 +205,5 @@

    See

    Insufficient Logging & Monitoring
  • MITRE, CWE-117 - Improper Output Neutralization for Logs
  • MITRE, CWE-532 - Information Exposure Through Log Files
  • -
  • SANS Top 25 - Porous Defenses
  • diff --git a/analyzers/rspec/cs/S5122.html b/analyzers/rspec/cs/S5122.html index 5b16b7c3c6b..5f5fac76ca8 100644 --- a/analyzers/rspec/cs/S5122.html +++ b/analyzers/rspec/cs/S5122.html @@ -154,6 +154,5 @@

    See

    Cheat Sheet - Cross Origin Resource Sharing
  • MITRE, CWE-346 - Origin Validation Error
  • MITRE, CWE-942 - Overly Permissive Cross-domain Whitelist
  • -
  • SANS Top 25 - Porous Defenses
  • diff --git a/analyzers/rspec/cs/S5542.html b/analyzers/rspec/cs/S5542.html index fb10f108f79..f95d1d2c7fa 100644 --- a/analyzers/rspec/cs/S5542.html +++ b/analyzers/rspec/cs/S5542.html @@ -112,6 +112,5 @@

    Standards

  • OWASP Top 10 2017 Category A6 - Security Misconfiguration
  • MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
  • -
  • SANS Top 25 - Porous Defenses
  • diff --git a/analyzers/rspec/cs/S5547.html b/analyzers/rspec/cs/S5547.html index 4aa5ebde6bc..76c442f2aa2 100644 --- a/analyzers/rspec/cs/S5547.html +++ b/analyzers/rspec/cs/S5547.html @@ -87,6 +87,5 @@

    Standards

  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
  • MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
  • -
  • SANS Top 25 - Porous Defenses
  • diff --git a/analyzers/rspec/cs/S5773.html b/analyzers/rspec/cs/S5773.html index 04f3cd4e1f5..259bf3c63e8 100644 --- a/analyzers/rspec/cs/S5773.html +++ b/analyzers/rspec/cs/S5773.html @@ -128,6 +128,5 @@

    Standards

    Deserialization
  • CWE - CWE-134 - Use of Externally-Controlled Format String
  • CWE - CWE-502 - Deserialization of Untrusted Data
  • -
  • SANS - Top 25 - Risky Resource Management
  • diff --git a/analyzers/rspec/vbnet/S1066.html b/analyzers/rspec/vbnet/S1066.html index c5197987bfc..d9074ab7243 100644 --- a/analyzers/rspec/vbnet/S1066.html +++ b/analyzers/rspec/vbnet/S1066.html @@ -1,6 +1,8 @@

    Why is this an issue?

    -

    Merging collapsible if statements increases the code’s readability.

    -

    Noncompliant code example

    +

    Nested code - blocks of code inside blocks of code - is eventually necessary, but increases complexity. This is why keeping the code as flat as +possible, by avoiding unnecessary nesting, is considered a good practice.

    +

    Merging if statements when possible will decrease the nesting of the code and improve its readability.

    +

    Code like

     If condition1 Then
         If condition2 Then ' Noncompliant
    @@ -8,7 +10,7 @@ 

    Noncompliant code example

    End If End If
    -

    Compliant solution

    +

    Will be more readable as

     If condition1 AndAlso condition2 Then
         ' ...
    diff --git a/analyzers/rspec/vbnet/S1066.json b/analyzers/rspec/vbnet/S1066.json
    index f6857be37ab..732a6ea96fb 100644
    --- a/analyzers/rspec/vbnet/S1066.json
    +++ b/analyzers/rspec/vbnet/S1066.json
    @@ -1,5 +1,5 @@
     {
    -  "title": "Collapsible \"if\" statements should be merged",
    +  "title": "Mergeable \"if\" statements should be combined",
       "type": "CODE_SMELL",
       "code": {
         "impacts": {
    diff --git a/analyzers/rspec/vbnet/S1075.html b/analyzers/rspec/vbnet/S1075.html
    index 07181ead5f9..d5278fa91f2 100644
    --- a/analyzers/rspec/vbnet/S1075.html
    +++ b/analyzers/rspec/vbnet/S1075.html
    @@ -1,8 +1,13 @@
     

    Why is this an issue?

    -

    Hard coding a URI makes it difficult to test a program: path literals are not always portable across operating systems, a given absolute path may -not exist on a specific test environment, a specified Internet URL may not be available when executing the tests, production environment filesystems -usually differ from the development environment, …​etc. For all those reasons, a URI should never be hard coded. Instead, it should be replaced by -customizable parameter.

    -

    Further even if the elements of a URI are obtained dynamically, portability can still be limited if the path-delimiters are hard-coded.

    -

    This rule raises an issue when URI’s or path delimiters are hard coded.

    +

    Hard-coding a URI makes it difficult to test a program for a variety of reasons:

    +
      +
    • path literals are not always portable across operating systems
    • +
    • a given absolute path may not exist in a specific test environment
    • +
    • a specified Internet URL may not be available when executing the tests
    • +
    • production environment filesystems usually differ from the development environment
    • +
    +

    In addition, hard-coded URIs can contain sensitive information, like IP addresses, and they should not be stored in the code.

    +

    For all those reasons, a URI should never be hard coded. Instead, it should be replaced by a customizable parameter.

    +

    Further, even if the elements of a URI are obtained dynamically, portability can still be limited if the path delimiters are hard-coded.

    +

    This rule raises an issue when URIs or path delimiters are hard-coded.

    diff --git a/analyzers/rspec/vbnet/S112.html b/analyzers/rspec/vbnet/S112.html index f9299e9a450..4e02981eefa 100644 --- a/analyzers/rspec/vbnet/S112.html +++ b/analyzers/rspec/vbnet/S112.html @@ -1,29 +1,52 @@ +

    This rule raises an issue when a generic exception (such as Exception, SystemException, +ApplicationException, IndexOutOfRangeException, NullReferenceException, OutOfMemoryException or +ExecutionEngineException) is thrown.

    Why is this an issue?

    -

    Throwing such general exceptions as Exception, SystemException, ApplicationException, -IndexOutOfRangeException, NullReferenceException, OutOfMemoryException and -ExecutionEngineException prevents calling methods from handling true, system-generated exceptions differently than application-generated -errors.

    -

    Noncompliant code example

    -
    +

    Throwing general exceptions such as Exception, SystemException and ApplicationException will have a negative +impact on any code trying to catch these exceptions.

    +

    From a consumer perspective, it is generally a best practice to only catch exceptions you intend to handle. Other exceptions should ideally not be +caught and let to propagate up the stack trace so that they can be dealt with appropriately. When a generic exception is thrown, it forces consumers +to catch exceptions they do not intend to handle, which they then have to re-throw.

    +

    Besides, when working with a generic type of exception, the only way to distinguish between multiple exceptions is to check their message, which is +error-prone and difficult to maintain. Legitimate exceptions may be unintentionally silenced and errors may be hidden.

    +

    For instance, if an exception such as StackOverflowException is caught and not re-thrown, it may prevent the program from terminating +gracefully.

    +

    When throwing an exception, it is therefore recommended to throw the most specific exception possible so that it can be handled intentionally by +consumers.

    +

    Additionally, some reserved exceptions should not be thrown manually. Exceptions such as IndexOutOfRangeException, +NullReferenceException, OutOfMemoryException or ExecutionEngineException will be thrown automatically by the +runtime when the corresponding error occurs. Many of them indicate serious errors, which the application may not be able to recover from. It is +therefore recommended to avoid throwing them as well as using them as base classes.

    +

    How to fix it

    +

    To fix this issue, make sure to throw specific exceptions that are relevant to the context in which they arise. It is recommended to either:

    +
      +
    • Throw a subtype of Exception when one matches. For instance ArgumentException could be raised when an unexpected + argument is provided to a function.
    • +
    • Define a custom exception type that derives from Exception or one of its subclasses.
    • +
    +

    Code examples

    +

    Noncompliant code example

    +
     Public Sub DoSomething(obj As Object)
       If obj Is Nothing Then
         ' Noncompliant
    -    Throw New NullReferenceException("obj")
    +    Throw New NullReferenceException("obj") ' Noncompliant: This reserved exception should not be thrown manually
       End If
       ' ...
     End Sub
     
    -

    Compliant solution

    -
    +

    Compliant solution

    +
     Public Sub DoSomething(obj As Object)
       If obj Is Nothing Then
    -    Throw New ArgumentNullException("obj")
    +    Throw New ArgumentNullException("obj") ' Compliant: this is a specific and non-reserved exception type
       End If
       ' ...
     End Sub
     

    Resources

    +

    Standards

    diff --git a/analyzers/rspec/vbnet/S112.json b/analyzers/rspec/vbnet/S112.json index 94bc003b464..161c655f4f8 100644 --- a/analyzers/rspec/vbnet/S112.json +++ b/analyzers/rspec/vbnet/S112.json @@ -1,5 +1,5 @@ { - "title": "General exceptions should never be thrown", + "title": "General or reserved exceptions should never be thrown", "type": "CODE_SMELL", "code": { "impacts": { diff --git a/analyzers/rspec/vbnet/S1125.html b/analyzers/rspec/vbnet/S1125.html index 98ee6da2a7f..95b6a3dfc44 100644 --- a/analyzers/rspec/vbnet/S1125.html +++ b/analyzers/rspec/vbnet/S1125.html @@ -1,7 +1,13 @@

    Why is this an issue?

    -

    Redundant Boolean literals should be removed from expressions to improve readability.

    -

    Noncompliant code example

    -
    +

    A boolean literal can be represented in two different ways: True or False. They can be combined with logical operators +(Not, And, Or, =) to produce logical expressions that represent truth values. However, comparing a boolean literal to a variable or +expression that evaluates to a boolean value is unnecessary and can make the code harder to read and understand. The more complex a boolean expression +is, the harder it will be for developers to understand its meaning and expected behavior, and it will favour the introduction of new bugs.

    +

    How to tix it

    +

    Remove redundant boolean literals from expressions to improve readability and make the code more maintainable.

    +

    Code examples

    +

    Noncompliant code example

    +
     If BooleanMethod() = True Then ' Noncompliant
       ' ...
     End If
    @@ -20,8 +26,8 @@ 

    Noncompliant code example

    booleanVariable = If(BooleanMethod(), exp, True) ' Noncompliant booleanVariable = If(BooleanMethod(), exp, False) ' Noncompliant
    -

    Compliant solution

    -
    +

    Compliant solution

    +
     If BooleanMethod() Then
       ' ...
     End If
    diff --git a/analyzers/rspec/vbnet/S1135.html b/analyzers/rspec/vbnet/S1135.html
    index 3bb6c3fa8a4..99c29968dd6 100644
    --- a/analyzers/rspec/vbnet/S1135.html
    +++ b/analyzers/rspec/vbnet/S1135.html
    @@ -1,5 +1,5 @@
     

    Why is this an issue?

    -

    Developers often use TOOO tags to mark areas in the code where additional work or improvements are needed but are not implemented +

    Developers often use TODO tags to mark areas in the code where additional work or improvements are needed but are not implemented immediately. However, these TODO tags sometimes get overlooked or forgotten, leading to incomplete or unfinished code. This code smell class aims to identify and address such unattended TODO tags to ensure a clean and maintainable codebase. This description will explore why this is a problem and how it can be fixed to improve the overall code quality.

    diff --git a/analyzers/rspec/vbnet/S117.html b/analyzers/rspec/vbnet/S117.html index e77ad902b27..0a7d010b846 100644 --- a/analyzers/rspec/vbnet/S117.html +++ b/analyzers/rspec/vbnet/S117.html @@ -1,27 +1,77 @@ +

    Local variables should be named consistently to communicate intent and improve maintainability. Rename your local variable to follow your project’s +naming convention to address this issue.

    Why is this an issue?

    -

    Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate.This rule checks that all local variables -follow a naming convention.

    -

    The default configuration is:

    +

    A naming convention in software development is a set of guidelines for naming code elements like variables, functions, and classes.
    Local +variables hold the meaning of the written code. Their names should be meaningful and follow a consistent and easily recognizable pattern.
    Adhering +to a consistent naming convention helps to make the code more readable and understandable, which makes it easier to maintain and debug. It also +ensures consistency in the code, especially when multiple developers are working on the same project.

    +

    This rule checks that local variable names match a provided regular expression.

    +

    What is the potential impact?

    +

    Inconsistent naming of local variables can lead to several issues in your code:

      -
    • Camel casing, starting with a lower case character, e.g. backColor
    • -
    • Short abbreviations of 2 letters can be capitalized only when not at the beginning, e.g. id, productID
    • -
    • Longer abbreviations need to be lower cased, e.g. html
    • +
    • Reduced Readability: inconsistent local variable names make the code harder to read and understand; consequently, it is more difficult to + identify the purpose of each variable, spot errors, or comprehend the logic.
    • +
    • Difficulty in Identifying Variables: local variables that don’t adhere to a standard naming convention are challenging to identify; thus, the + coding process slows down, especially when dealing with a large codebase.
    • +
    • Increased Risk of Errors: inconsistent or unclear local variable names lead to misunderstandings about what the variable represents. This + ambiguity leads to incorrect assumptions and, consequently, bugs in the code.
    • +
    • Collaboration Difficulties: in a team setting, inconsistent naming conventions lead to confusion and miscommunication among team members.
    • +
    • Difficulty in Code Maintenance: inconsistent naming leads to an inconsistent codebase. The code is difficult to understand, and making changes + feels like refactoring constantly, as you face different naming methods. Ultimately, it makes the codebase harder to maintain.
    -

    Noncompliant code example

    -

    With the default regular expression ^[a-z][a-z0-9]*([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?$:

    -
    +

    In summary, not adhering to a naming convention for local variables can lead to confusion, errors, and inefficiencies, making the code harder to +read, understand, and maintain.

    +

    How to fix it

    +

    First, familiarize yourself with the particular naming convention of the project in question. Then, update the name to match the convention, as +well as all usages of the name. For many IDEs, you can use built-in renaming and refactoring features to update all usages at once.

    +

    Code examples

    +

    Noncompliant code example

    +

    With the default regular expression ^[a-z][a-z0-9]*([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?$, bringing the following constraints:

    +
      +
    • Camel casing, starting with a lowercase character, for example backColor
    • +
    • Short abbreviations of 2 letters can be capitalized only when not at the beginning, for example id, productID
    • +
    • Longer abbreviations need to be lowercased, for example html
    • +
    +
     Module Module1
         Sub Main()
             Dim Foo = 0 ' Noncompliant
         End Sub
     End Module
     
    -

    Compliant solution

    -
    +

    Compliant solution

    +
     Module Module1
         Sub Main()
             Dim foo = 0 ' Compliant
         End Sub
     End Module
     
    +

    Resources

    +

    Documentation

    + +

    Related rules

    +
      +
    • {rule:vbnet:S101} - Class names should comply with a naming convention
    • +
    • {rule:vbnet:S114} - Interface names should comply with a naming convention
    • +
    • {rule:vbnet:S119} - Generic type parameter names should comply with a naming convention
    • +
    • {rule:vbnet:S1542} - Functions and procedures should comply with a naming convention
    • +
    • {rule:vbnet:S1654} - Method parameters should follow a naming convention
    • +
    • {rule:vbnet:S2304} - Namespace names should comply with a naming convention
    • +
    • {rule:vbnet:S2342} - Enumeration types should comply with a naming convention
    • +
    • {rule:vbnet:S2343} - Enumeration values should comply with a naming convention
    • +
    • {rule:vbnet:S2347} - Event handlers should comply with a naming convention
    • +
    • {rule:vbnet:S2348} - Events should comply with a naming convention
    • +
    • {rule:vbnet:S2362} - Private constants should comply with a naming convention
    • +
    • {rule:vbnet:S2363} - "Private Shared ReadOnly" fields should comply with a naming convention
    • +
    • {rule:vbnet:S2364} - "Private" fields should comply with a naming convention
    • +
    • {rule:vbnet:S2366} - Properties should comply with a naming convention
    • +
    • {rule:vbnet:S2367} - Non-private constants should comply with a naming convention
    • +
    • {rule:vbnet:S2369} - Non-private fields should comply with a naming convention
    • +
    • {rule:vbnet:S2370} - Non-private "Shared ReadOnly" fields should comply with a naming convention
    • +
    diff --git a/analyzers/rspec/vbnet/S1172.html b/analyzers/rspec/vbnet/S1172.html index 2bedde69baf..770f914588f 100644 --- a/analyzers/rspec/vbnet/S1172.html +++ b/analyzers/rspec/vbnet/S1172.html @@ -1,9 +1,27 @@

    Why is this an issue?

    -

    Unused parameters are misleading. Whatever the values passed to such parameters, the behavior will be the same.

    +

    A typical code smell known as unused function parameters refers to parameters declared in a function but not used anywhere within the function’s +body. While this might seem harmless at first glance, it can lead to confusion and potential errors in your code. Disregarding the values passed to +such parameters, the function’s behavior will be the same, but the programmer’s intention won’t be clearly expressed anymore. Therefore, removing +function parameters that are not being utilized is considered best practice.

    This rule raises an issue when a private procedure of a Class, Module or Structure takes a parameter without using it.

    -

    Noncompliant code example

    -
    +

    Exceptions

    +

    This rule doesn’t raise any issue in the following contexts:

    +
      +
    • Procedures decorated with attributes.
    • +
    • Empty procedures.
    • +
    • Procedures which only throw NotImplementedException.
    • +
    • Main methods.
    • +
    • virtual, override procedures.
    • +
    • Interface implementations.
    • +
    • Event handlers.
    • +
    +

    How to fix it

    +

    Having unused function parameters in your code can lead to confusion and misunderstanding of a developer’s intention. They reduce code readability +and introduce the potential for errors. To avoid these problems, developers should remove unused parameters from function declarations.

    +

    Code examples

    +

    Noncompliant code example

    +
     Private Sub DoSomething(ByVal a As Integer, ByVal b as Integer) ' "b" is unused
         Compute(a)
     End Sub
    @@ -13,8 +31,8 @@ 

    Noncompliant code example

    Return b End Function
    -

    Compliant solution

    -
    +

    Compliant solution

    +
     Private Sub DoSomething(ByVal a As Integer)
         Compute(a)
     End Sub
    @@ -24,15 +42,4 @@ 

    Compliant solution

    Return b End Function
    -

    Exceptions

    -

    This rule doesn’t raise any issue in the following contexts:

    -
      -
    • Procedures decorated with attributes.
    • -
    • Empty procedures.
    • -
    • Procedures which only throw NotImplementedException.
    • -
    • Main methods.
    • -
    • virtual, override procedures.
    • -
    • Interface implementations.
    • -
    • Event handlers.
    • -
    diff --git a/analyzers/rspec/vbnet/S1186.html b/analyzers/rspec/vbnet/S1186.html index 084b9043393..fe82d948560 100644 --- a/analyzers/rspec/vbnet/S1186.html +++ b/analyzers/rspec/vbnet/S1186.html @@ -1,29 +1,11 @@

    Why is this an issue?

    An empty method is generally considered bad practice and can lead to confusion, readability, and maintenance issues. Empty methods bring no functionality and are misleading to others as they might think the method implementation fulfills a specific and identified requirement.

    -

    Such methods should be avoided and possibly removed.

    -
    -Sub DoSomething() ' Noncompliant
    -End Sub
    -
    -

    However, there are some cases where a method needs to be empty. In those cases, it is essential to minimize confusion and enhance clarity.

    -

    Here are a few examples:

    +

    There are several reasons for a method not to have a body:

      -
    • The method will never be implemented. By throwing the NotSupportedException, it makes clear the initial intention not to implement it in the future.
      -Sub DoSomething() ' Compliant
      -    Throw New NotSupportedException
      -End Sub
      -
    • -
    • The method will be implemented in the future. By throwing the NotImplementedException, the initial intention to add an implementation in the future is clear.
      -Sub DoSomething() ' Compliant
      -    Throw New NotImplementedException
      -End Sub
      -
    • -
    • The method implementation is empty intentionally. In this case, it is important to put a comment explaining the reason for the empty implementation.
      -Sub DoSomething() ' Compliant
      -    ' Do nothing because of X
      -End Sub
      -
    • +
    • It is an unintentional omission, and should be fixed to prevent an unexpected behavior in production.
    • +
    • It is not yet, or never will be, supported. In this case an exception should be thrown.
    • +
    • The method is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.

    Exceptions

    The following empty methods are considered compliant:

    @@ -32,4 +14,38 @@

    Exceptions

  • empty methods that override a MustOverride method as the implementation is mandatory for child class
  • empty overrides in test assemblies for mocking purposes
  • +

    How to fix it

    +

    Code examples

    +

    Noncompliant code example

    +
    +Sub ShouldNotBeEmpty()  ' Noncompliant - method is empty
    +End Sub
    +
    +Sub NotImplementedYet()  ' Noncompliant - method is empty
    +End Sub
    +
    +Sub WillNeverBeImplemented()  ' Noncompliant - method is empty
    +End Sub
    +
    +Sub EmptyOnPurpose()  ' Noncompliant - method is empty
    +End Sub
    +
    +

    Compliant solution

    +
    +Sub ShouldNotBeEmpty()
    +    DoSomething()
    +End Sub
    +
    +Sub NotImplementedYet()
    +    Throw New NotImplementedException
    +End Sub
    +
    +Sub WillNeverBeImplemented()
    +    Throw New NotSupportedException
    +End Sub
    +
    +Sub EmptyOnPurpose()
    +    ' Do nothing because of X
    +End Sub
    +
    diff --git a/analyzers/rspec/vbnet/S1192.html b/analyzers/rspec/vbnet/S1192.html index 5e6a208b75e..5ddafb1c473 100644 --- a/analyzers/rspec/vbnet/S1192.html +++ b/analyzers/rspec/vbnet/S1192.html @@ -1,8 +1,19 @@

    Why is this an issue?

    -

    Duplicated string literals make the process of refactoring error-prone, since you must be sure to update all occurrences.

    -

    On the other hand, constants can be referenced from many places, but only need to be updated in a single place.

    -

    Noncompliant code example

    -
    +

    Duplicated string literals make the process of refactoring complex and error-prone, as any change would need to be propagated on all +occurrences.

    +

    Exceptions

    +

    The following are ignored:

    +
      +
    • literals with fewer than 5 characters
    • +
    • literals matching one of the parameter names
    • +
    • literals used in attributes
    • +
    +

    How to fix it

    +

    Instead, use constants to replace the duplicated string literals. Constants can be referenced from many places, but only need to be updated in a +single place.

    +

    Code examples

    +

    Noncompliant code example

    +
     Public Class Foo
     
         Private Name As String = "foobar" ' Noncompliant
    @@ -17,8 +28,8 @@ 

    Noncompliant code example

    End Class
    -

    Compliant solution

    -
    +

    Compliant solution

    +
     Public Class Foo
     
         Private Const Foobar As String = "foobar"
    @@ -35,11 +46,4 @@ 

    Compliant solution

    End Class
    -

    Exceptions

    -

    The following are ignored:

    -
      -
    • literals with fewer than 5 characters
    • -
    • literals matching one of the parameter names
    • -
    • literals used in attributes
    • -
    diff --git a/analyzers/rspec/vbnet/S134.html b/analyzers/rspec/vbnet/S134.html index 97a80b8b8a8..73f6aaaba4e 100644 --- a/analyzers/rspec/vbnet/S134.html +++ b/analyzers/rspec/vbnet/S134.html @@ -1,9 +1,13 @@

    Why is this an issue?

    -

    Nested If, Select, For, For Each, While, Do, and Try -statements are key ingredients for making what’s known as "Spaghetti code".

    -

    Such code is hard to read, refactor and therefore maintain.

    -

    Noncompliant code example

    -

    With the default threshold of 3:

    +

    Nested control flow statements If, Select, For, For Each, While, Do, +and Try are often key ingredients in creating what’s known as "Spaghetti code". This code smell can make your program difficult to +understand and maintain.

    +

    When numerous control structures are placed inside one another, the code becomes a tangled, complex web. This significantly reduces the code’s +readability and maintainability, and it also complicates the testing process.

    +

    How to fix it

    +

    Code examples

    +

    The following example demonstrates the behavior of the rule with the default threshold of 3 levels of nesting:

    +

    Noncompliant code example

     If condition1 ' Compliant - depth = 1
       ' ...
    diff --git a/analyzers/rspec/vbnet/S1481.html b/analyzers/rspec/vbnet/S1481.html
    index 902a0f5a049..6745290be5a 100644
    --- a/analyzers/rspec/vbnet/S1481.html
    +++ b/analyzers/rspec/vbnet/S1481.html
    @@ -1,23 +1,44 @@
     

    Why is this an issue?

    -

    If a local variable is declared but not used, it is dead code and should be removed. Doing so will improve maintainability because developers will -not wonder what the variable is used for.

    -

    Noncompliant code example

    +

    An unused local variable is a variable that has been declared but is not used anywhere in the block of code where it is defined. It is dead code, +contributing to unnecessary complexity and leading to confusion when reading the code. Therefore, it should be removed from your code to maintain +clarity and efficiency.

    +

    What is the potential impact?

    +

    Having unused local variables in your code can lead to several issues:

    +
      +
    • Decreased Readability: Unused variables can make your code more difficult to read. They add extra lines and complexity, which can distract from + the main logic of the code.
    • +
    • Misunderstanding: When other developers read your code, they may wonder why a variable is declared but not used. This can lead to confusion and + misinterpretation of the code’s intent.
    • +
    • Potential for Bugs: If a variable is declared but not used, it might indicate a bug or incomplete code. For example, if you declared a variable + intending to use it in a calculation, but then forgot to do so, your program might not work as expected.
    • +
    • Maintenance Issues: Unused variables can make code maintenance more difficult. If a programmer sees an unused variable, they might think it is + a mistake and try to 'fix' the code, potentially introducing new bugs.
    • +
    • Memory Usage: Although modern compilers are smart enough to ignore unused variables, not all compilers do this. In such cases, unused variables + take up memory space, leading to inefficient use of resources.
    • +
    +

    In summary, unused local variables can make your code less readable, more confusing, and harder to maintain, and they can potentially lead to bugs +or inefficient memory use. Therefore, it is best to remove them.

    +

    Exceptions

    +

    Unused locally created resources in a Using statement are not reported.

    +Using t = New TestTimer()
    +End Using
    +
    +

    How to fix it

    +

    The fix for this issue is straightforward. Once you ensure the unused variable is not part of an incomplete implementation leading to bugs, you +just need to remove it.

    +

    Code examples

    +

    Noncompliant code example

    +
     Public Function NumberOfMinutes(ByVal hours As Integer) As Integer
    -    Dim seconds As Integer = 0 ' Seconds never used
    +    Dim seconds As Integer = 0 ' Noncompliant - seconds is unused
         Return hours * 60
     End Function
     
    -

    Compliant solution

    -
    +

    Compliant solution

    +
     Public Function NumberOfMinutes(ByVal hours As Integer) As Integer
         Return hours * 60
     End Function
     
    -

    Exceptions

    -

    Unused locally created resources in a Using statement are not reported.

    -
    -Using t = New TestTimer()
    -End Using
    -
    diff --git a/analyzers/rspec/vbnet/S1871.html b/analyzers/rspec/vbnet/S1871.html index 1c19f0d72ad..247247a22ce 100644 --- a/analyzers/rspec/vbnet/S1871.html +++ b/analyzers/rspec/vbnet/S1871.html @@ -1,9 +1,22 @@

    Why is this an issue?

    +

    When the same code is duplicated in two or more separate branches of a conditional, it can make the code harder to understand, maintain, and can +potentially introduce bugs if one instance of the code is changed but others are not.

    Having two Cases in the same Select statement or branches in the same If structure with the same -implementation is at best duplicate code, and at worst a coding error. If the same logic is truly needed for both instances, then in an -If structure they should be combined, or for a Select, one should fall through to the other.

    -

    Noncompliant code example

    -
    +implementation is at best duplicate code, and at worst a coding error.

    +
    +If a >= 0 AndAlso a < 10 Then
    +  DoFirst()
    +  DoTheThing()
    +ElseIf a >= 10 AndAlso a < 20 Then
    +  DoTheOtherThing()
    +ElseIf a >= 20 AndAlso a < 50   ' Noncompliant; duplicates first condition
    +  DoFirst()
    +  DoTheThing()
    +Else
    +  DoTheRest();
    +End If
    +
    +
     Select i
       Case 1
         DoFirst()
    @@ -16,19 +29,35 @@ 

    Noncompliant code example

    Case Else: DoTheRest() End Select - -If a >= 0 AndAlso a < 10 Then +
    +

    If the same logic is needed for both instances, then:

    +
      +
    • in an If structure they should be combined
    • +
    +
    +If (a >= 0 AndAlso a < 10) OrElse (a >= 20 AndAlso a < 50) Then
       DoFirst()
       DoTheThing()
     ElseIf a >= 10 AndAlso a < 20 Then
       DoTheOtherThing()
    -ElseIf a >= 20 AndAlso a < 50   ' Noncompliant; duplicates first condition
    -  DoFirst()
    -  DoTheThing()
     Else
       DoTheRest();
     End If
     
    +
      +
    • for a Select, the values should be put in the Case expression list.
    • +
    +
    +Select i
    +  Case 1, 3
    +    DoFirst()
    +    DoSomething()
    +  Case 2
    +    DoSomethingDifferent()
    +  Case Else:
    +    DoTheRest()
    +End Select
    +

    Exceptions

    Blocks in an If chain or Case clause that contain a single line of code are ignored.

    @@ -41,8 +70,8 @@ 

    Exceptions

    End If

    But this exception does not apply to If chains without Else-s, or to Select-s without Case Else -clauses when all branches have the same single line of code. In case of If chains with Else-s, or of Select-es -with Case Else clauses, rule {rule:vbnet:S3923} raises a bug.

    +clauses when all branches have the same single line of code. In the case of If chains with Else-s, or of +Select-es with Case Else clauses, rule {rule:vbnet:S3923} raises a bug.

     If a >= 0 AndAlso a < 10 Then
       DoTheThing()
    @@ -50,4 +79,9 @@ 

    Exceptions

    DoTheOtherThing() ' Noncompliant, this might have been done on purpose but probably not End If
    +

    Resources

    +

    Related rules

    +
      +
    • {rule:vbnet:S3923} - All branches in a conditional structure should not have exactly the same implementation
    • +
    diff --git a/analyzers/rspec/vbnet/S2068.html b/analyzers/rspec/vbnet/S2068.html index a7b25102dc3..af34f01ec9c 100644 --- a/analyzers/rspec/vbnet/S2068.html +++ b/analyzers/rspec/vbnet/S2068.html @@ -53,7 +53,6 @@

    See

  • MITRE, CWE-798 - Use of Hard-coded Credentials
  • MITRE, CWE-259 - Use of Hard-coded Password
  • -
  • SANS Top 25 - Porous Defenses
  • Derived from FindSecBugs rule Hard Coded Password
  • diff --git a/analyzers/rspec/vbnet/S2077.html b/analyzers/rspec/vbnet/S2077.html index c1c04cdafe5..9f8115aba1a 100644 --- a/analyzers/rspec/vbnet/S2077.html +++ b/analyzers/rspec/vbnet/S2077.html @@ -45,7 +45,6 @@

    See

  • MITRE, CWE-20 - Improper Input Validation
  • MITRE, CWE-89 - Improper Neutralization of Special Elements used in an SQL Command
  • -
  • SANS Top 25 - Insecure Interaction Between Components
  • Derived from FindSecBugs rules Potential SQL/JPQL Injection (JPA), Potential SQL/JDOQL Injection (JDO), Potential SQL/HQL Injection (Hibernate)
  • diff --git a/analyzers/rspec/vbnet/S2257.html b/analyzers/rspec/vbnet/S2257.html index 03f01f79e7a..6f2b9be5320 100644 --- a/analyzers/rspec/vbnet/S2257.html +++ b/analyzers/rspec/vbnet/S2257.html @@ -47,7 +47,6 @@

    See

  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
  • MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
  • -
  • SANS Top 25 - Porous Defenses
  • Derived from FindSecBugs rule MessageDigest is Custom
  • diff --git a/analyzers/rspec/vbnet/S2259.html b/analyzers/rspec/vbnet/S2259.html index 4f8b5229487..00020e54a2e 100644 --- a/analyzers/rspec/vbnet/S2259.html +++ b/analyzers/rspec/vbnet/S2259.html @@ -110,7 +110,7 @@
    JetBrains Rider

    How to fix it

    -

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

    +

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

    In these cases, it is obvious the code is as intended.

    How to fix it

    -

    The conditions should be reviewed to decide whether:

    -
      -
    • to update the unnecessary operand
    • -
    • to remove the unnecessary operand
    • -
    +

    Gratuitous boolean expressions are suspicious and should be carefully removed from the code.

    +

    First, the boolean expression in question should be closely inspected for logical errors. If a mistake was made, it can be corrected so the +condition is no longer gratuitous.

    +

    If it becomes apparent that the condition is actually unnecessary, it can be removed. The associated control flow construct (e.g., the +if-statement containing the condition) will be adapted or even removed, leaving only the necessary branches.

    Code examples

    Noncompliant code example

    diff --git a/analyzers/rspec/vbnet/S2612.html b/analyzers/rspec/vbnet/S2612.html
    index 199ea44d811..96ad5b7ae6d 100644
    --- a/analyzers/rspec/vbnet/S2612.html
    +++ b/analyzers/rspec/vbnet/S2612.html
    @@ -66,6 +66,5 @@ 

    See

    href="https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/02-Configuration_and_Deployment_Management_Testing/09-Test_File_Permission">OWASP File Permission
  • MITRE, CWE-732 - Incorrect Permission Assignment for Critical Resource
  • MITRE, CWE-266 - Incorrect Privilege Assignment
  • -
  • SANS Top 25 - Porous Defenses
  • diff --git a/analyzers/rspec/vbnet/S3776.html b/analyzers/rspec/vbnet/S3776.html index 526571e1d53..f0578801c1b 100644 --- a/analyzers/rspec/vbnet/S3776.html +++ b/analyzers/rspec/vbnet/S3776.html @@ -1,7 +1,23 @@ +

    This rule raises an issue when the code cognitive complexity of a function is above a certain threshold.

    Why is this an issue?

    -

    Cognitive Complexity Complexity is a measure of how hard the control flow of -a method is to understand.

    -

    Methods with high Cognitive Complexity will be difficult to maintain.

    +

    Cognitive Complexity is a measure of how hard it is to understand the control flow of a unit of code. Code with high cognitive complexity is hard +to read, understand, test, and modify.

    +

    As a rule of thumb, high cognitive complexity is a sign that the code should be refactored into smaller, easier-to-manage pieces.

    +

    Which syntax in code does impact cognitive complexity score?

    +

    Here are the core concepts:

    +
      +
    • Cognitive complexity is incremented each time the code breaks the normal linear reading flow.
      This concerns, for example: + Loop structures, Conditionals, Catches, Switches, Jumps to label and mixed operators in condition.
    • +
    • Each nesting level adds a malus to the breaking call.
      During code reading, the deeper you go through nested layers, the + harder it becomes to keep the context in mind.
    • +
    • Method calls are free
      A well-picked method name is a summary of multiple lines of code. A reader can first explore a + high-level view of what the code is performing then go deeper and deeper by looking at called functions content.
      Note: This does not + apply to recursive calls, those will increment cognitive score.
    • +
    +

    The method of computation is fully detailed in the pdf linked in the resources.

    +

    What is the potential impact?

    +

    Developers spend more time reading and understanding code than writing it. High cognitive complexity slows down changes and increases the cost of +maintenance.

     Function Abs(ByVal n As Integer) As Integer ' Noncompliant: cognitive complexity = 5
         If n >= 0 Then    ' +1
    @@ -30,11 +46,11 @@ 

    Why is this an issue?

    Resources

    Documentation

    Articles & blog posts

    diff --git a/analyzers/rspec/vbnet/S4423.html b/analyzers/rspec/vbnet/S4423.html index 5f26568008b..f89e3ae80b9 100644 --- a/analyzers/rspec/vbnet/S4423.html +++ b/analyzers/rspec/vbnet/S4423.html @@ -111,6 +111,5 @@

    Standards

  • OWASP Top 10 2017 Category A6 - Security Misconfiguration
  • MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
  • -
  • SANS Top 25 - Porous Defenses
  • diff --git a/analyzers/rspec/vbnet/S4790.html b/analyzers/rspec/vbnet/S4790.html index ed3688cfb1b..fa61edf4bf3 100644 --- a/analyzers/rspec/vbnet/S4790.html +++ b/analyzers/rspec/vbnet/S4790.html @@ -59,6 +59,5 @@

    See

  • OWASP Mobile Top 10 2016 Category M5 - Insufficient Cryptography
  • MITRE, CWE-1240 - Use of a Risky Cryptographic Primitive
  • -
  • SANS Top 25 - Porous Defenses
  • diff --git a/analyzers/rspec/vbnet/S4792.html b/analyzers/rspec/vbnet/S4792.html index e85d669801a..a281d3894a4 100644 --- a/analyzers/rspec/vbnet/S4792.html +++ b/analyzers/rspec/vbnet/S4792.html @@ -202,6 +202,5 @@

    See

    Insufficient Logging & Monitoring
  • MITRE, CWE-117 - Improper Output Neutralization for Logs
  • MITRE, CWE-532 - Information Exposure Through Log Files
  • -
  • SANS Top 25 - Porous Defenses
  • diff --git a/analyzers/rspec/vbnet/S5542.html b/analyzers/rspec/vbnet/S5542.html index 422c5486f94..89e48d55fda 100644 --- a/analyzers/rspec/vbnet/S5542.html +++ b/analyzers/rspec/vbnet/S5542.html @@ -121,6 +121,5 @@

    Standards

  • OWASP Top 10 2017 Category A6 - Security Misconfiguration
  • MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
  • -
  • SANS Top 25 - Porous Defenses
  • diff --git a/analyzers/rspec/vbnet/S5547.html b/analyzers/rspec/vbnet/S5547.html index 27ff96e0019..5b2e347dda4 100644 --- a/analyzers/rspec/vbnet/S5547.html +++ b/analyzers/rspec/vbnet/S5547.html @@ -82,6 +82,5 @@

    Standards

  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
  • MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
  • -
  • SANS Top 25 - Porous Defenses
  • diff --git a/analyzers/rspec/vbnet/S5773.html b/analyzers/rspec/vbnet/S5773.html index 13a17971e8f..d1e66174295 100644 --- a/analyzers/rspec/vbnet/S5773.html +++ b/analyzers/rspec/vbnet/S5773.html @@ -125,6 +125,5 @@

    Standards

    Deserialization
  • CWE - CWE-134 - Use of Externally-Controlled Format String
  • CWE - CWE-502 - Deserialization of Untrusted Data
  • -
  • SANS - Top 25 - Risky Resource Management
  • diff --git a/analyzers/src/SonarAnalyzer.CSharp/sonarpedia.json b/analyzers/src/SonarAnalyzer.CSharp/sonarpedia.json index 1ad472bfd63..e4cf1d61141 100644 --- a/analyzers/src/SonarAnalyzer.CSharp/sonarpedia.json +++ b/analyzers/src/SonarAnalyzer.CSharp/sonarpedia.json @@ -3,7 +3,7 @@ "languages": [ "CSH" ], - "latest-update": "2023-10-09T08:25:23.804824400Z", + "latest-update": "2023-11-01T10:21:37.374207Z", "options": { "no-language-in-filenames": true } diff --git a/analyzers/src/SonarAnalyzer.VisualBasic/sonarpedia.json b/analyzers/src/SonarAnalyzer.VisualBasic/sonarpedia.json index 4e866ece165..85c637ace12 100644 --- a/analyzers/src/SonarAnalyzer.VisualBasic/sonarpedia.json +++ b/analyzers/src/SonarAnalyzer.VisualBasic/sonarpedia.json @@ -3,7 +3,7 @@ "languages": [ "VBNET" ], - "latest-update": "2023-10-09T08:26:00.454774600Z", + "latest-update": "2023-11-01T10:21:56.202995600Z", "options": { "no-language-in-filenames": true } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Helpers/RuleCatalogTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Helpers/RuleCatalogTest.cs index 67599aaf705..57b4c6ff4b1 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Helpers/RuleCatalogTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Helpers/RuleCatalogTest.cs @@ -68,7 +68,7 @@ public void Description_TakesFirstParagraph() => [TestMethod] public void Description_TagsAreRemoved() => - ValidateDescription("S1116", "i.e. ;, are", "Empty statements, i.e. ;, are usually introduced by mistake, for example because:"); + ValidateDescription("S1116", "by a semicolon ;", "Empty statements represented by a semicolon ; are statements that do not perform any operation."); [TestMethod] public void Description_HtmlIsDecoded() =>