SonarQube Vulnerability Report

Report Generated On
Thu Aug 01 2019
Project Name
Sonar Report
Application
sonar-report
Release
1.0.0
Delta analysis
No

Summary of the Detected Vulnerabilities

Severity Number of Issues
BLOCKER 0
CRITICAL 0
MAJOR 0
MINOR 0

Known Security Rules

Rule Description
csharpsquid:S4524

switch can contain a default clause for various reasons: to handle unexpected values, to show that all the cases were properly considered.

For readability purpose, to help a developer to quickly find the default behavior of a switch statement, it is recommended to put the default clause at the end of the switch statement. This rule raises an issue if the default clause is not the first or the last one of the switch's cases.

Noncompliant Code Example

switch (param)
{
    case 0:
      DoSomething();
      break;
    default: // default clause should be the first or last one
      Error();
      break;
    case 1:
      DoSomethingElse();
      break;
}

Compliant Solution

switch (param)
{
    case 0:
      DoSomething();
      break;
    case 1:
      DoSomethingElse();
      break;
    default:
      Error();
      break;
}

See

  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
c:S116

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that field names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

class MyClass {
  int my_field;
};

Compliant Solution

class MyClass {
  int myField;
};
c:S117

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a local variable or function parameter name does not match the provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

void doSomething(int my_param) {
  int LOCAL;
  ...
}

Compliant Solution

void doSomething(int myParam) {
  int local;
  ...
}

Exceptions

Loop counters and const variables are ignored by this rule.

csharpsquid:S1215

Calling GC.Collect is rarely necessary, and can significantly affect application performance. That's because it triggers a blocking operation that examines every object in memory for cleanup. Further, you don't have control over when this blocking cleanup will actually run.

As a general rule, the consequences of calling this method far outweigh the benefits unless perhaps you've just triggered some event that is unique in the run of your program that caused a lot of long-lived objects to die.

This rule raises an issue when GC.Collect is invoked.

Noncompliant Code Example

static void Main(string[] args)
{
  // ...
  GC.Collect(2, GCCollectionMode.Optimized); // Noncompliant
}
go:S131

The requirement for a final default clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken.

Noncompliant Code Example

switch tag { // Noncompliant - default case is missing
case 0, 1, 2, 3:
	foo()
case 4, 5, 6, 7:
	bar()
}

Compliant Solution

switch tag {
case 0, 1, 2, 3:
	foo()
case 4, 5, 6, 7:
	bar()
default:
	qix()
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
  • MITRE, CWE-478 - Missing Default Case in Switch Statement
  • CERT, MSC01-C. - Strive for logical completeness
squid:NoSonar

Any issue to quality rule can be deactivated with the NOSONAR marker. This marker is pretty useful to exclude false-positive results but it can also be used abusively to hide real quality flaws.

This rule raises an issue when NOSONAR is used.

squid:S1309

This rule allows you to track the usage of the @SuppressWarnings mechanism.

Noncompliant Code Example

With a parameter value of "unused" :

@SuppressWarnings("unused")
@SuppressWarnings("unchecked")  // Noncompliant
squid:S1213

According to the Java Code Conventions as defined by Oracle, the members of a class or interface declaration should appear in the following order in the source files:

  • Class and instance variables
  • Constructors
  • Methods

Noncompliant Code Example

public class Foo{
   private int field = 0;
   public boolean isTrue() {...}
   public Foo() {...}                         // Noncompliant, constructor defined after methods
   public static final int OPEN = 4;  //Noncompliant, variable defined after constructors and methods
}

Compliant Solution

public class Foo{
   public static final int OPEN = 4;
   private int field = 0;
   public Foo() {...}
   public boolean isTrue() {...}
}
squid:S3578

Shared naming conventions allow teams to collaborate efficiently. This rule raises an issue when a test method name does not match the provided regular expression.

Noncompliant Code Example

With the default value: ^test[A-Z][a-zA-Z0-9]*$

@Test
public void foo() {  // Noncompliant
  //...
}

Compliant Solution

@Test
public void testFoo() {
  // ...
}
squid:S3577

Shared naming conventions allow teams to collaborate efficiently. This rule raises an issue when a test class name does not match the provided regular expression.

Noncompliant Code Example

With the default value: ^((Test|IT)[a-zA-Z0-9]+|[A-Z][a-zA-Z0-9]*(Test|IT|TestCase|ITCase))$

class Foo {  // Noncompliant
}

Compliant Solution

class FooTest {
}
squid:S00122

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

if(someCondition) doSomething();

Compliant Solution

if(someCondition) {
  doSomething();
}
squid:S818

Using upper case literal suffixes removes the potential ambiguity between "1" (digit 1) and "l" (letter el) for declaring literals.

Noncompliant Code Example

long long1 = 1l; // Noncompliant
float float1 = 1.0f; // Noncompliant
double double1 = 1.0d; // Noncompliant

Compliant Solution

long long1 = 1L;
float float1 = 1.0F;
double double1 = 1.0D;

See

  • MISRA C++:2008, 2-13-4 - Literal suffixes shall be upper case
  • MISRA C:2012, 7.3 - The lowercase character "l" shall not be used in a literal suffix
  • CERT DCL16-C. - Use "L," not "l," to indicate a long value
  • CERT, DCL50-J. - Use visually distinct identifiers
squid:S00103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

squid:S1161

Using the @Override annotation is useful for two reasons :

  • It elicits a warning from the compiler if the annotated method doesn't actually override anything, as in the case of a misspelling.
  • It improves the readability of the source code by making it obvious that methods are overridden.

Noncompliant Code Example

class ParentClass {
  public boolean doSomething(){...}
}
class FirstChildClass extends ParentClass {
  public boolean doSomething(){...}  // Noncompliant
}

Compliant Solution

class ParentClass {
  public boolean doSomething(){...}
}
class FirstChildClass extends ParentClass {
  @Override
  public boolean doSomething(){...}  // Compliant
}

Exceptions

This rule is relaxed when overriding a method from the Object class like toString(), hashCode(), ...

squid:S3008

Shared naming conventions allow teams to collaborate efficiently. This rule checks that static non-final field names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

public final class MyClass {
   private static String foo_bar;
}

Compliant Solution

class MyClass {
   private static String fooBar;
}
squid:S00120

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all package names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z_]+(\.[a-z_][a-z0-9_]*)*$:

package org.exAmple; // Noncompliant

Compliant Solution

package org.example;
squid:S00100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all method names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression ^[a-z][a-zA-Z0-9]*$:

public int DoSomething(){...}

Compliant Solution

public int doSomething(){...}

Exceptions

Overriding methods are excluded.

@Override
public int Do_Something(){...}
squid:S00116

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that field names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

class MyClass {
   private int my_field;
}

Compliant Solution

class MyClass {
   private int myField;
}
squid:S00115

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all constant names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$:

public class MyClass {
  public static final int first = 1;
}

public enum MyEnum {
  first;
}

Compliant Solution

public class MyClass {
  public static final int FIRST = 1;
}

public enum MyEnum {
  FIRST;
}
squid:S00101

Shared coding conventions allow teams to collaborate effectively. This rule allows to check that all class names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression ^[A-Z][a-zA-Z0-9]*$:

class my_class {...}

Compliant Solution

class MyClass {...}
squid:ModifiersOrderCheck

The Java Language Specification recommends listing modifiers in the following order:

1. Annotations

2. public

3. protected

4. private

5. abstract

6. static

7. final

8. transient

9. volatile

10. synchronized

11. native

12. strictfp

Not following this convention has no technical impact, but will reduce the code's readability because most developers are used to the standard order.

Noncompliant Code Example

static public void main(String[] args) {   // Noncompliant
}

Compliant Solution

public static void main(String[] args) {   // Compliant
}
squid:IndentationCheck

Proper indentation is a simple and effective way to improve the code's readability. Consistent indentation among the developers within a team also reduces the differences that are committed to source control systems, making code reviews easier.

This rule raises an issue when indentation does not match the configured value. Only the first line of a badly indented section is reported.

Noncompliant Code Example

With an indent size of 2:

class Foo {
  public int a;
   public int b;   // Noncompliant, expected to start at column 4

...

  public void doSomething() {
    if(something) {
          doSomethingElse();  // Noncompliant, expected to start at column 6
  }   // Noncompliant, expected to start at column 4
  }
}

Compliant Solution

class Foo {
  public int a;
  public int b;

...

  public void doSomething() {
    if(something) {
        doSomethingElse();
    }
  }
}
squid:S00105

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

squid:S2208

Blindly importing all the classes in a package clutters the class namespace and could lead to conflicts between classes in different packages with the same name. On the other hand, specifically listing the necessary classes avoids that problem and makes clear which versions were wanted.

Noncompliant Code Example

import java.sql.*; // Noncompliant
import java.util.*; // Noncompliant

private Date date; // Date class exists in java.sql and java.util. Which one is this?

Compliant Solution

import java.sql.Date;
import java.util.List;
import java.util.ArrayList;

private Date date;

Exceptions

Static imports are ignored by this rule. E.G.

import static java.lang.Math.*;
squid:S1312

Regardless of the logging framework in use (logback, log4j, commons-logging, java.util.logging, ...), loggers should be:

  • private: never be accessible outside of its parent class. If another class needs to log something, it should instantiate its own logger.
  • static: not be dependent on an instance of a class (an object). When logging something, contextual information can of course be provided in the messages but the logger should be created at class level to prevent creating a logger along with each object.
  • final: be created once and only once per class.

Noncompliant Code Example

With a default regular expression of LOG(?:GER)?:

public Logger logger = LoggerFactory.getLogger(Foo.class);  // Noncompliant

Compliant Solution

private static final Logger LOGGER = LoggerFactory.getLogger(Foo.class);

Exceptions

Variables of type org.apache.maven.plugin.logging.Log are ignored.

squid:S00121

While not technically incorrect, the omission of curly braces can be misleading, and may lead to the introduction of errors during maintenance.

Noncompliant Code Example

if (condition)  // Noncompliant
  executeSomething();

Compliant Solution

if (condition) {
  executeSomething();
}

See

  • MISRA C:2004, 14.8 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C:2004, 14.9 - An if (expression) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C++:2008, 6-3-1 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C++:2008, 6-4-1 - An if (condition) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C:2012, 15.6 - The body of an iteration-statement or a selection-statement shall be a compound-statement
  • CERT, EXP19-C. - Use braces for the body of an if, for, or while statement
  • CERT, EXP52-J. - Use braces for the body of an if, for, or while statement
squid:RightCurlyBraceDifferentLineAsNextBlockCheck

Shared coding conventions make it possible for a team to collaborate efficiently.

This rule makes it mandatory to place a closing curly brace and the next else, catch or finally keyword on two different lines.

Noncompliant Code Example

public void myMethod() {
  if(something) {
    executeTask();
  } else if (somethingElse) {          // Noncompliant
    doSomethingElse();
  }
  else {                               // Compliant
     generateError();
  }

  try {
    generateOrder();
  } catch (Exception e) {
    log(e);
  }
  finally {
    closeConnection();
  }
}

Compliant Solution

public void myMethod() {
  if(something) {
    executeTask();
  }
  else if (somethingElse) {
    doSomethingElse();
  }
  else {
     generateError();
  }

  try {
    generateOrder();
  }
  catch (Exception e) {
    log(e);
  }
  finally {
    closeConnection();
  }
}
squid:S1943

Using classes and methods that rely on the default system encoding can result in code that works fine in its "home" environment. But that code may break for customers who use different encodings in ways that are extremely difficult to diagnose and nearly, if not completely, impossible to reproduce when it's time to fix them.

This rule detects uses of the following classes and methods:

  • FileReader
  • FileWriter
  • String constructors with a byte[] argument but no Charset argument
    • String(byte[] bytes)
    • String(byte[] bytes, int offset, int length)
  • String.getBytes()
  • String.getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin)
  • InputStreamReader(InputStream in)
  • OutputStreamWriter(OutputStream out)
  • ByteArrayOutputStream.toString()
  • Some Formatter constructors
    • Formatter(String fileName)
    • Formatter(File file)
    • Formatter(OutputStream os)
  • Some Scanner constructors
    • Scanner(File source)
    • Scanner(Path source)
    • Scanner(InputStream source)
  • Some PrintStream constructors
    • PrintStream(File file)
    • PrintStream(OutputStream out)
    • PrintStream(OutputStream out, boolean autoFlush)
    • PrintStream(String fileName)
  • Some PrintWriter constructors
    • PrintWriter(File file)
    • PrintWriter(OutputStream out)
    • PrintWriter(OutputStream out, boolean autoFlush)
    • PrintWriter(String fileName)
  • methods from Apache commons-io library which accept an encoding argument when that argument is null, and overloads of those methods that omit the encoding argument
    • IOUtils.copy(InputStream, Writer)
    • IOUtils.copy(Reader, OutputStream)
    • IOUtils.readLines(InputStream)
    • IOUtils.toByteArray(Reader)
    • IOUtils.toByteArray(String)
    • IOUtils.toCharArray(InputStream)
    • IOUtils.toInputStream(TypeCriteria.subtypeOf(CharSequence))
    • IOUtils.toString(byte[])
    • IOUtils.toString(URI)
    • IOUtils.toString(URL)
    • IOUtils.write(char[], OutputStream)
    • IOUtils.write(CharSequence, OutputStream)
    • IOUtils.writeLines(Collection, String, OutputStream)
    • FileUtils.readFileToString(File)
    • FileUtils.readLines(File)
    • FileUtils.write(File, CharSequence)
    • FileUtils.write(File, CharSequence, boolean)
    • FileUtils.writeStringToFile(File, String)

See

  • CERT, STR04-J. - Use compatible character encodings when communicating string data between JVMs
  • CERT, STR50-J. - Use the appropriate method for counting characters in a string
squid:LeftCurlyBraceEndLineCheck

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when an open curly brace is not placed at the end of a line of code.

Noncompliant Code Example

if(condition)
{
  doSomething();
}

Compliant Solution

if(condition) {
  doSomething();
}

Exceptions

When blocks are inlined (left and right curly braces on the same line), no issue is triggered.

if(condition) {doSomething();}
squid:RightCurlyBraceStartLineCheck

Shared coding conventions make it possible for a team to efficiently collaborate. This rule makes it mandatory to place a close curly brace at the beginning of a line.

Noncompliant Code Example

if(condition) {
  doSomething();}

Compliant Solution

if(condition) {
  doSomething();
}

Exceptions

When blocks are inlined (open and close curly braces on the same line), no issue is triggered.

if(condition) {doSomething();}
squid:S1195

According to the Java Language Specification:

For compatibility with older versions of the Java SE platform,

the declaration of a method that returns an array is allowed to place (some or all of) the empty bracket pairs that form the declaration of the array type after the formal parameter list.

This obsolescent syntax should not be used in new code.

Noncompliant Code Example

public int getVector()[] { /* ... */ }    // Noncompliant

public int[] getMatrix()[] { /* ... */ }  // Noncompliant

Compliant Solution

public int[] getVector() { /* ... */ }

public int[][] getMatrix() { /* ... */ }
squid:S1197

Array designators should always be located on the type for better code readability. Otherwise, developers must look both at the type and the variable name to know whether or not a variable is an array.

Noncompliant Code Example

int matrix[][];   // Noncompliant
int[] matrix[];   // Noncompliant

Compliant Solution

int[][] matrix;   // Compliant
squid:S3599

Because Double Brace Initialization (DBI) creates an anonymous class with a reference to the instance of the owning object, its use can lead to memory leaks if the anonymous inner class is returned and held by other objects. Even when there's no leak, DBI is so obscure that it's bound to confuse most maintainers.

For collections, use Arrays.asList instead, or explicitly add each item directly to the collection.

Noncompliant Code Example

Map source = new HashMap(){{ // Noncompliant
    put("firstName", "John");
    put("lastName", "Smith");
}};

Compliant Solution

Map source = new HashMap();
// ...
source.put("firstName", "John");
source.put("lastName", "Smith");
// ...
squid:S00114

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all interface names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[A-Z][a-zA-Z0-9]*$:

public interface myInterface {...} // Noncompliant

Compliant Solution

public interface MyInterface {...}
squid:S00117

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a local variable or function parameter name does not match the provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

public void doSomething(int my_param) {
  int LOCAL;
  ...
}

Compliant Solution

public void doSomething(int myParam) {
  int local;
  ...
}

Exceptions

Loop counters are ignored by this rule.

for (int i_1 = 0; i_1 < limit; i_1++) {  // Compliant
  // ...
}

as well as one-character catch variables:

try {
//...
} catch (Exception e) { // Compliant
}
squid:S2681

Curly braces can be omitted from a one-line block, such as with an if statement or for loop, but doing so can be misleading and induce bugs.

This rule raises an issue when the whitespacing of the lines after a one line block indicates an intent to include those lines in the block, but the omission of curly braces means the lines will be unconditionally executed once.

Noncompliant Code Example

if (condition)
  firstActionInBlock();
  secondAction();  // Noncompliant; executed unconditionally
thirdAction();

if (condition) firstActionInBlock(); secondAction();  // Noncompliant; secondAction executed unconditionally

if (condition) firstActionInBlock();  // Noncompliant
  secondAction();  // Executed unconditionally

if (condition); secondAction();  // Noncompliant; secondAction executed unconditionally

String str = null;
for (int i = 0; i < array.length; i++)
  str = array[i];
  doTheThing(str);  // Noncompliant; executed only on last array element

Compliant Solution

if (condition) {
  firstActionInBlock();
  secondAction();
}
thirdAction();

String str = null;
for (int i = 0; i < array.length; i++) {
  str = array[i];
  doTheThing(str);
}

See

squid:S1659

Declaring multiple variables on one line is difficult to read.

Noncompliant Code Example

class MyClass {

  private int a, b;

  public void method(){
    int c; int d;
  }
}

Compliant Solution

class MyClass {

  private int a;
  private int b;

  public void method(){
    int c;
    int d;
  }
}

See

  • MISRA C++:2008, 8-0-1 - An init-declarator-list or a member-declarator-list shall consist of a single init-declarator or member-declarator respectively
  • CERT, DCL52-J. - Do not declare more than one variable per declaration
  • CERT, DCL04-C. - Do not declare more than one variable per declaration
squid:S1181

Throwable is the superclass of all errors and exceptions in Java. Error is the superclass of all errors, which are not meant to be caught by applications.

Catching either Throwable or Error will also catch OutOfMemoryError and InternalError, from which an application should not attempt to recover.

Noncompliant Code Example

try { /* ... */ } catch (Throwable t) { /* ... */ }
try { /* ... */ } catch (Error e) { /* ... */ }

Compliant Solution

try { /* ... */ } catch (RuntimeException e) { /* ... */ }
try { /* ... */ } catch (MyException e) { /* ... */ }

See

squid:S00119

Shared naming conventions make it possible for a team to collaborate efficiently. Following the established convention of single-letter type parameter names helps users and maintainers of your code quickly see the difference between a type parameter and a poorly named class.

This rule check that all type parameter names match a provided regular expression. The following code snippets use the default regular expression.

Noncompliant Code Example

public class MyClass<TYPE> { // Noncompliant
  <TYPE> void method(TYPE t) { // Noncompliant
  }
}

Compliant Solution

public class MyClass<T> {
  <T> void method(T t) {
  }
}
squid:S4087

Java 7's try-with-resources structure automatically handles closing the resources that the try itself opens. Thus, adding an explicit close() call is redundant and potentially confusing.

Noncompliant Code Example

try (PrintWriter writer = new PrintWriter(process.getOutputStream())) {
  String contents = file.contents();
  writer.write(new Gson().toJson(new MyObject(contents)));
  writer.flush();
  writer.close();  // Noncompliant
}

Compliant Solution

try (PrintWriter writer = new PrintWriter(process.getOutputStream())) {
  String contents = file.contents();
  writer.write(new Gson().toJson(new MyObject(contents)));
  writer.flush();
}
squid:S2095

Connections, streams, files, and other classes that implement the Closeable interface or its super-interface, AutoCloseable, needs to be closed after use. Further, that close call must be made in a finally block otherwise an exception could keep the call from being made. Preferably, when class implements AutoCloseable, resource should be created using "try-with-resources" pattern and will be closed automatically.

Failure to properly close resources will result in a resource leak which could bring first the application and then perhaps the box it's on to their knees.

Noncompliant Code Example

private void readTheFile() throws IOException {
  Path path = Paths.get(this.fileName);
  BufferedReader reader = Files.newBufferedReader(path, this.charset);
  // ...
  reader.close();  // Noncompliant
  // ...
  Files.lines("input.txt").forEach(System.out::println); // Noncompliant: The stream needs to be closed
}

private void doSomething() {
  OutputStream stream = null;
  try {
    for (String property : propertyList) {
      stream = new FileOutputStream("myfile.txt");  // Noncompliant
      // ...
    }
  } catch (Exception e) {
    // ...
  } finally {
    stream.close();  // Multiple streams were opened. Only the last is closed.
  }
}

Compliant Solution

private void readTheFile(String fileName) throws IOException {
    Path path = Paths.get(fileName);
    try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
      reader.readLine();
      // ...
    }
    // ..
    try (Stream<String> input = Files.lines("input.txt"))  {
      input.forEach(System.out::println);
    }
}

private void doSomething() {
  OutputStream stream = null;
  try {
    stream = new FileOutputStream("myfile.txt");
    for (String property : propertyList) {
      // ...
    }
  } catch (Exception e) {
    // ...
  } finally {
    stream.close();
  }
}

Exceptions

Instances of the following classes are ignored by this rule because close has no effect:

  • java.io.ByteArrayOutputStream
  • java.io.ByteArrayInputStream
  • java.io.CharArrayReader
  • java.io.CharArrayWriter
  • java.io.StringReader
  • java.io.StringWriter

Java 7 introduced the try-with-resources statement, which implicitly closes Closeables. All resources opened in a try-with-resources statement are ignored by this rule.

try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
  //...
}
catch ( ... ) {
  //...
}

See

squid:ObjectFinalizeOverridenCheck

The Object.finalize() method is called on an object by the garbage collector when it determines that there are no more references to the object. But there is absolutely no warranty that this method will be called AS SOON AS the last references to the object are removed. It can be few microseconds to few minutes later. So when system resources need to be disposed by an object, it's better to not rely on this asynchronous mechanism to dispose them.

Noncompliant Code Example

public class MyClass {
  ...
  protected void finalize() {
    releaseSomeResources();    // Noncompliant
  }
  ...
}

See

squid:ObjectFinalizeCheck

According to the official javadoc documentation, this Object.finalize() is called by the garbage collector on an object when garbage collection determines that there are no more references to the object. Calling this method explicitly breaks this contract and so is misleading.

Noncompliant Code Example

public void dispose() throws Throwable {
  this.finalize();                       // Noncompliant
}

See

squid:S2209

While it is possible to access static members from a class instance, it's bad form, and considered by most to be misleading because it implies to the readers of your code that there's an instance of the member per class instance.

Noncompliant Code Example

public class A {
  public static int counter = 0;
}

public class B {
  private A first = new A();
  private A second = new A();

  public void runUpTheCount() {
    first.counter ++;  // Noncompliant
    second.counter ++;  // Noncompliant. A.counter is now 2, which is perhaps contrary to expectations
  }
}

Compliant Solution

public class A {
  public static int counter = 0;
}

public class B {
  private A first = new A();
  private A second = new A();

  public void runUpTheCount() {
    A.counter ++;  // Compliant
    A.counter ++;  // Compliant
  }
}
squid:S1166

When handling a caught exception, the original exception's message and stack trace should be logged or passed forward.

Noncompliant Code Example

try {
  /* ... */
} catch (Exception e) {   // Noncompliant - exception is lost
  LOGGER.info("context");
}

try {
  /* ... */
} catch (Exception e) {  // Noncompliant - exception is lost (only message is preserved)
  LOGGER.info(e.getMessage());
}

try {
  /* ... */
} catch (Exception e) {  // Noncompliant - original exception is lost
  throw new RuntimeException("context");
}

Compliant Solution

try {
  /* ... */
} catch (Exception e) {
  LOGGER.info(e);  // exception is logged
}

try {
  /* ... */
} catch (Exception e) {
  throw new RuntimeException(e);   // exception stack trace is propagated
}

try {
  /* ... */
} catch (RuntimeException e) {
  doSomething();
  throw e;  // original exception passed forward
} catch (Exception e) {
  throw new RuntimeException(e);  // Conversion into unchecked exception is also allowed
}

Exceptions

InterruptedException, NumberFormatException, DateTimeParseException, ParseException and MalformedURLException exceptions are arguably used to indicate nonexceptional outcomes. Similarly, handling NoSuchMethodException is often required when dealing with the Java reflection API.

Because they are part of Java, developers have no choice but to deal with them. This rule does not verify that those particular exceptions are correctly handled.

int myInteger;
try {
  myInteger = Integer.parseInt(myString);
} catch (NumberFormatException e) {
  // It is perfectly acceptable to not handle "e" here
  myInteger = 0;
}

Furthermore, no issue will be raised if the exception message is logged with additional information, as it shows that the developer added some context to the error message.

try {
  /* ... */
} catch (Exception e) {
  String message = "Exception raised while authenticating user: " + e.getMessage();
  LOGGER.warn(message); // Compliant - exception message logged with some contextual information
}

See

squid:SwitchLastCaseIsDefaultCheck

The requirement for a final default clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken.

Noncompliant Code Example

switch (param) {  //missing default clause
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
}

switch (param) {
  default: // default clause should be the last one
    error();
    break;
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
}

Compliant Solution

switch (param) {
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
  default:
    error();
    break;
}

Exceptions

If the switch parameter is an Enum and if all the constants of this enum are used in the case statements, then no default clause is expected.

Example:

public enum Day {
    SUNDAY, MONDAY
}
...
switch(day) {
  case SUNDAY:
    doSomething();
    break;
  case MONDAY:
    doSomethingElse();
    break;
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
  • MITRE, CWE-478 - Missing Default Case in Switch Statement
  • CERT, MSC01-C. - Strive for logical completeness
squid:S2658

Dynamically loaded classes could contain malicious code executed by a static class initializer. I.E. you wouldn't even have to instantiate or explicitly invoke methods on such classes to be vulnerable to an attack.

This rule raises an issue for each use of dynamic class loading.

Noncompliant Code Example

String className = System.getProperty("messageClassName");
Class clazz = Class.forName(className);  // Noncompliant

See

common-java:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
css:S4670

HTML, SVG, and MathML define the selectors which can be used in a CSS. A selector that is not part of them is likely to be a typo or a misunderstanding of the CSS syntax.

Noncompliant Code Example

field {}

ul list {}

Compliant Solution

input {}

ul li {}
php:S101

Shared coding conventions allow teams to collaborate effectively. This rule allows to check that all class names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression ^[A-Z][a-zA-Z0-9]*$:

class my_class {...}

Compliant Solution

class MyClass {...}
php:S1779

All developers should use the same end-line character(s) to prevent polluting the history changelog of source files in the SCM engine. Moreover some SCM engines like Git might sometimes badly support use of Windows 'CRLF' end of line characters.

php:S105

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

php:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
csharpsquid:S125

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

csharpsquid:S103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

php:S3626

Jump statements, such as return, goto, and continue let you change the default flow of program execution, but jump statements that direct the control flow to the original direction are just a waste of keystrokes.

Noncompliant Code Example

function foo($p) {
  $i = $p;
  while ($i > 0) {
    $i--;
    continue; // Noncompliant
  }
}

Compliant Solution

function foo($p) {
  $i = $p;
  while ($i > 0) {
    $i--;
  }
}
php:S2046

Shared coding conventions allow teams to collaborate effectively. This rule flags all Perl-style comments.

Noncompliant Code Example

$myvar; # Noncompliant; this comment should have started with "//"

Compliant Solution

$myvar; // Compliant; this comment started with "//"
php:S117

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a local variable or function parameter name does not match the provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

public function doSomething($my_param){
  $LOCAL;
  ...
}

Compliant Solution

public function doSomething($myParam){
  $local;
  ...
}
php:S1997

Shared coding conventions allow teams to collaborate efficiently. To avoid the confusion that can be caused by tangling two coding languages in the same file, inline HTML should be avoided.

Noncompliant Code Example

<?php
$name = "George";
?>
<p> Hello <?php echo $name ?>!</p>

Exceptions

File having the extension .phtml are ignored by this rule because they are expected to have mixed PHP and HTML.

php:S1578

Shared coding conventions allow teams to collaborate effectively. For that reason, file names should conform to a defined standard. This rule raises an issue when the names of analyzed files don't match the provided regular expression.

See

php:S116

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that field names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

class MyClass {
  $my_field;
}

Compliant Solution

class MyClass {
  $myField;
}
squid:S1192

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

With the default threshold of 3:

public void run() {
  prepare("action1");                              // Noncompliant - "action1" is duplicated 3 times
  execute("action1");
  release("action1");
}

@SuppressWarning("all")                            // Compliant - annotations are excluded
private void method1() { /* ... */ }
@SuppressWarning("all")
private void method2() { /* ... */ }

public String method3(String a) {
  System.out.println("'" + a + "'");               // Compliant - literal "'" has less than 5 characters and is excluded
  return "";                                       // Compliant - literal "" has less than 5 characters and is excluded
}

Compliant Solution

private static final String ACTION_1 = "action1";  // Compliant

public void run() {
  prepare(ACTION_1);                               // Compliant
  execute(ACTION_1);
  release(ACTION_1);
}

Exceptions

To prevent generating some false-positives, literals having less than 5 characters are excluded.

php:S1105

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when an open curly brace is not placed at the end of a line of code.

Noncompliant Code Example

if(condition)
{
  doSomething();
}

Compliant Solution

if(condition) {
  doSomething();
}

Exceptions

When blocks are inlined (left and right curly braces on the same line), no issue is triggered.

if(condition) {doSomething();}
squid:S1602

There are two ways to write lambdas that contain single statement, but one is definitely more compact and readable than the other.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 8.

Noncompliant Code Example

x -> {System.out.println(x+1);}
(a, b) -> { return a+b; }

Compliant Solution

x -> System.out.println(x+1)
(a, b) -> a+b    //For return statement, the return keyword should also be dropped
squid:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

void doSomething() {
  // TODO
}

See

squid:S1488

Declaring a variable only to immediately return or throw it is a bad practice.

Some developers argue that the practice improves code readability, because it enables them to explicitly name what is being returned. However, this variable is an internal implementation detail that is not exposed to the callers of the method. The method name should be sufficient for callers to know exactly what will be returned.

Noncompliant Code Example

public long computeDurationInMilliseconds() {
  long duration = (((hours * 60) + minutes) * 60 + seconds ) * 1000 ;
  return duration;
}

public void doSomething() {
  RuntimeException myException = new RuntimeException();
  throw myException;
}

Compliant Solution

public long computeDurationInMilliseconds() {
  return (((hours * 60) + minutes) * 60 + seconds ) * 1000 ;
}

public void doSomething() {
  throw new RuntimeException();
}
squid:S3369

Websphere, Tomcat, and JBoss web servers allow the definition of role-based access to servlets. It may not be granular enough for your purposes, but it's a start, and should be used at least as a base.

This rule raises an issue when a web.xml file has no <security-constraint> elements.

See

squid:S2039

Failing to explicitly declare the visibility of a member variable could result it in having a visibility you don't expect, and potentially leave it open to unexpected modification by other classes.

Noncompliant Code Example

class Ball {
    String color="red";  // Noncompliant
}
enum A {
  B;
  int a;
}

Compliant Solution

class Ball {
    private String color="red";  // Compliant
}
enum A {
  B;
  private int a;
}

Exceptions

Members annotated with Guava's @VisibleForTesting annotation are ignored, as it indicates that visibility has been purposely relaxed to make the code testable.

class Cone {
  @VisibleForTesting
  Logger logger; // Compliant
}
squid:S3306

Field injection seems like a tidy way to get your classes what they need to do their jobs, but it's really a NullPointerException waiting to happen unless all your class constructors are private. That's because any class instances that are constructed by callers, rather than instantiated by a Dependency Injection framework compliant with the JSR-330 (Spring, Guice, ...), won't have the ability to perform the field injection.

Instead @Inject should be moved to the constructor and the fields required as constructor parameters.

This rule raises an issue when classes with non-private constructors (including the default constructor) use field injection.

Noncompliant Code Example

class MyComponent {  // Anyone can call the default constructor

  @Inject MyCollaborator collaborator;  // Noncompliant

  public void myBusinessMethod() {
    collaborator.doSomething();  // this will fail in classes new-ed by a caller
  }
}

Compliant Solution

class MyComponent {

  private final MyCollaborator collaborator;

  @Inject
  public MyComponent(MyCollaborator collaborator) {
    Assert.notNull(collaborator, "MyCollaborator must not be null!");
    this.collaborator = collaborator;
  }

  public void myBusinessMethod() {
    collaborator.doSomething();
  }
}
javasecurity:S5135

User provided data such as URL parameters, POST data payloads or cookies should always be considered untrusted and tainted. Deserialization based on data supplied by the user could result in two types of attacks:

  • Remote code execution attacks, where the structure of the serialized data is changed to modify the behavior of the object being unserialized.
  • Parameter tampering attacks, where data is modified to escalate privileges or change for example quantity or price of products.

The problem could be mitigated in any of the following ways:

  • Instead of using a native data interchange format, use a safe, standard format such as JSON.
  • To ensure integrity is not compromised, add a digital signature to the serialized data that is validated before deserialization.
  • As a last resort, restrict deserialization to be possible only to specific, whitelisted classes.

Noncompliant Code Example

public class RequestProcessor {
  protected void processRequest(HttpServletRequest request) {
    ServletInputStream sis = request.getInputStream();
    ObjectInputStream ois = new ObjectInputStream(sis);
    Object obj = ois.readObject(); // Noncompliant
  }
}

Compliant Solution

public class SecureObjectInputStream extends ObjectInputStream {
  // Constructor here

  @Override
  protected Class<?> resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException {
    // Only deserialize instances of AllowedClass
    if (!osc.getName().equals(AllowedClass.class.getName())) {
      throw new InvalidClassException("Unauthorized deserialization", osc.getName());
    }
    return super.resolveClass(osc);
  }
}

public class RequestProcessor {
  protected void processRequest(HttpServletRequest request) {
    ServletInputStream sis = request.getInputStream();
    SecureObjectInputStream sois = new SecureObjectInputStream(sis);
    Object obj = sois.readObject();
  }
}

See

javasecurity:S5334

Applications that execute code dynamically should neutralize any externally-provided values used to construct the code. Failure to do so could allow an attacker to execute arbitrary code. This could enable a wide range of serious attacks like accessing/modifying sensitive information or gain full system access.

The mitigation strategy should be based on whitelisting of allowed values or casting to safe types.

Noncompliant Code Example

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String input = req.getParameter("input");

  ScriptEngineManager manager = new ScriptEngineManager();
  ScriptEngine engine = manager.getEngineByName("JavaScript");
  engine.eval(input); // Noncompliant
}

Compliant Solution

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String input = req.getParameter("input");

  // Match the input against a whitelist
  if (!whiteList.contains(input))
    throw new IOException();

  ScriptEngineManager manager = new ScriptEngineManager();
  ScriptEngine engine = manager.getEngineByName("JavaScript");
  engine.eval(input);
}

See

javasecurity:S3649

User provided data, such as URL parameters, should always be considered untrusted and tainted. Constructing SQL queries directly from tainted data enables attackers to inject specially crafted values that change the initial meaning of the query itself. Successful SQL injection attacks can read, modify, or delete sensitive information from the database and sometimes even shut it down or execute arbitrary operating system commands.

Typically, the solution is to rely on prepared statements rather than string concatenation to inject tainted data into SQL queries, which ensures that they will be properly escaped.

This rule supports: JDBC, Java EE Entity Manager, Spring Framework, Hibernate, JDO, Android Database, Apache Torque, Rapidoid.

Noncompliant Code Example

public boolean authenticate(javax.servlet.http.HttpServletRequest request, java.sql.Connection connection) throws SQLException {
  String user = request.getParameter("user");
  String pass = request.getParameter("pass");

  String query = "SELECT * FROM users WHERE user = '" + user + "' AND pass = '" + pass + "'"; // Unsafe

  // If the special value "foo' OR 1=1 --" is passed as either the user or pass, authentication is bypassed
  // Indeed, if it is passed as a user, the query becomes:
  // SELECT * FROM users WHERE user = 'foo' OR 1=1 --' AND pass = '...'
  // As '--' is the comment till end of line syntax in SQL, this is equivalent to:
  // SELECT * FROM users WHERE user = 'foo' OR 1=1
  // which is equivalent to:
  // SELECT * FROM users WHERE 1=1
  // which is equivalent to:
  // SELECT * FROM users

  java.sql.Statement statement = connection.createStatement();
  java.sql.ResultSet resultSet = statement.executeQuery(query); // Noncompliant
  return resultSet.next();
}

Compliant Solution

public boolean authenticate(javax.servlet.http.HttpServletRequest request, java.sql.Connection connection) throws SQLException {
  String user = request.getParameter("user");
  String pass = request.getParameter("pass");

  String query = "SELECT * FROM users WHERE user = ? AND pass = ?"; // Safe even if authenticate() method is still vulnerable to brute-force attack in this specific case

  java.sql.PreparedStatement statement = connection.prepareStatement(query);
  statement.setString(1, user); // Will be properly escaped
  statement.setString(2, pass);
  java.sql.ResultSet resultSet = statement.executeQuery();
  return resultSet.next();
}

See

roslyn.sonaranalyzer.security.cs:S2078

User provided data such as URL parameters should always be considered as untrusted and tainted. Constructing LDAP names or search filters directly from tainted data enables attackers to inject specially crafted values that changes the initial meaning of the name or filter itself. Successful LDAP injections attacks can read, modify or delete sensitive information from the directory service.

Within LDAP names, the special characters ' ', '#', '"', '+', ',', ';', '<', '>', '\' and null must be escaped according to RFC 4514, for example by replacing them with the backslash character '\' followed by the two hex digits corresponding to the ASCII code of the character to be escaped. Similarly, LDAP search filters must escape a different set of special characters (including but not limited to '*', '(', ')', '\' and null) according to RFC 4515.

Noncompliant Code Example

public class LDAPInjection : Controller
{
  public DirectorySearcher ds { get; set; }

  // GET /LDAPInjection/Authenticate
  public IActionResult Authenticate(string user, string pass)
  {
    ds.Filter = "(&(uid=" + user + ")(userPassword=" + pass + "))"; // Noncompliant

    // If the special value "*)(uid=*))(|(uid=*" is passed as user, authentication is bypassed
    // Indeed, if it is passed as a user, the filter becomes:
    // (&(uid=*)(uid=*))(|(uid=*)(userPassword=...))
    // as uid=* match all users, it is equivalent to:
    // (|(uid=*)(userPassword=...))
    // again, as uid=* match all users, the filter becomes useless

    return Content(ds.FindOne() != null ? "success" : "fail");
  }
}

Compliant Solution

public class LDAPInjection : Controller
{
  public DirectorySearcher ds { get; set; }

  // GET /LDAPInjection/Authenticate
  public IActionResult Authenticate(string user, string pass)
  {
    // Restrict the username and password to letters only
    if (!Regex.IsMatch(user, "^[a-zA-Z]+$") || !Regex.IsMatch(pass, "^[a-zA-Z]+$"))
    {
      return BadRequest();
    }

    ds.Filter = "(&(uid=" + user + ")(userPassword=" + pass + "))"; // Now safe
    return Content(ds.FindOne() != null ? "success" : "fail");
  }
}

See

roslyn.sonaranalyzer.security.cs:S3649

User provided data, such as URL parameters, should always be considered untrusted and tainted. Constructing SQL or SQL-like queries directly from tainted data enables attackers to inject specially crafted values that change the initial meaning of the query itself. Successful database query injection attacks can read, modify, or delete sensitive information from the database and sometimes even shut it down or execute arbitrary operating system commands.

Typically, the solution is to rely on prepared statements rather than string concatenation to inject tainted data into database queries, which ensures that they will be properly escaped.

Noncompliant Code Example

public class SqlInjection : Controller
{
  private readonly UsersContext _context;

  public SqlInjection(UsersContext context)
  {
    _context = context;
  }

  // GET /SqlInjection/Authenticate
  public IActionResult Authenticate(string user)
  {
    var query = "SELECT * FROM Users WHERE Username = '" + user + "'"; // Unsafe
    var userExists = _context.Users.FromSql(query).Any(); // Noncompliant

    // An attacker can bypass authentication by setting user to this special value
    user = "' or 1=1 or ''='";

    return Content(userExists ? "success" : "fail");
  }
}

Compliant Solution

public class SqlInjection : Controller
{
  private readonly UsersContext _context;

  public SqlInjection(UsersContext context)
  {
    _context = context;
  }

  // GET /SqlInjection/Authenticate
  public IActionResult Authenticate(string user)
  {
    var query = "SELECT * FROM Users WHERE Username = {0}"; // Safe
    var userExists = _context.Users.FromSql(query, user).Any();
    return Content(userExists ? "success" : "fail");
  }
}

See

roslyn.sonaranalyzer.security.cs:S2091

User provided data, such as URL parameters, should always be considered untrusted and tainted. Constructing XPath expressions directly from tainted data enables attackers to inject specially crafted values that changes the initial meaning of the expression itself. Successful XPath injection attacks can read sensitive information from XML documents.

Noncompliant Code Example

public class XPathInjection : Controller
{
  public XmlDocument doc { get; set; }

  // GET /XPathInjection/Authenticate
  public IActionResult Authenticate(string user, string pass)
  {
    String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']"; // Unsafe

    // An attacker can bypass authentication by setting user to this special value
    user = "' or 1=1 or ''='";

    return Content(doc.SelectSingleNode(expression) != null ? "success" : "fail"); // Noncompliant
  }
}

Compliant Solution

public class XPathInjection : Controller
{
  public XmlDocument doc { get; set; }

  // GET /XPathInjection/Authenticate
  public IActionResult Authenticate(string user, string pass)
  {
    // Restrict the username and password to letters only
    if (!Regex.IsMatch(user, "^[a-zA-Z]+$") || !Regex.IsMatch(pass, "^[a-zA-Z]+$"))
    {
      return BadRequest();
    }

    String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']"; // Now safe
    return Content(doc.SelectSingleNode(expression) != null ? "success" : "fail");
  }
}

See

phpsecurity:S2631

Evaluating regular expressions against input strings can be an extremely CPU-intensive task. For example, a specially crafted regular expression such as (a+)++ will take several seconds to evaluate the input string, aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!. The problem is that every additional "a" added to the input doubles the time required to evaluate the regex. However, the equivalent regular expression, a (without grouping), is efficiently evaluated in milliseconds and scales linearly with the input size.

Evaluating user-provided strings as regular expressions opens the door for Denial Of Service attacks. In the context of a web application, attackers can force the web server to spend all of its resources evaluating regular expressions thereby making the service inaccessible to genuine users.

Noncompliant Code Example

$regex = $_GET["regex"];
$input = $_GET["input"];

// Enables attackers to force the web server to evaluate
// regex such as "(a+)+" on inputs such as "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!"

preg_grep ( $regex, $input ); // Noncompliant

Compliant Solution

$input = $_GET["input"];

preg_grep ( "a+", $input ); // Compliant - use a safe hardcoded regex

See

phpsecurity:S5135

User provided data such as URL parameters, POST data payloads or cookies should always be considered untrusted and tainted. Deserialization based on data supplied by the user could result in two types of attacks:

  • Remote code execution attacks, where the structure of the serialized data is changed to modify the behavior of the object being unserialized.
  • Parameter tampering attacks, where data is modified to escalate privileges or change for example quantity or price of products.

The problem could be mitigated in any of the following ways:

  • Instead of using a native data interchange format, use a safe, standard format such as JSON.
  • To ensure integrity is not compromised, add a digital signature to the serialized data that is validated before deserialization.
  • As a last resort, restrict deserialization to be possible only to specific, whitelisted classes.

Noncompliant Code Example

$data = $_GET["data"];
$object = unserialize($data);
// ...

Compliant Solution

$data = $_GET["data"];

list($hash, $data) = explode('|', $data, 2);
$hash_confirm = hash_hmac("sha256", $data, "secret-key");

// Confirm that the data integrity is not compromised
if ($hash === $hash_confirm) {
  $object = unserialize($data);
  // ...
}

See

phpsecurity:S2078

User provided data such as URL parameters should always be considered as untrusted and tainted. Constructing LDAP names or search filters directly from tainted data enables attackers to inject specially crafted values that changes the initial meaning of the name or filter itself. Successful LDAP injections attacks can read, modify or delete sensitive information from the directory service.

Within LDAP names, the special characters ' ', '#', '"', '+', ',', ';', '<', '>', '\' and null must be escaped according to RFC 4514, for example by replacing them with the backslash character '\' followed by the two hex digits corresponding to the ASCII code of the character to be escaped. Similarly, LDAP search filters must escape a different set of special characters (including but not limited to '*', '(', ')', '\' and null) according to RFC 4515.

Noncompliant Code Example

$user = $_GET["user"];
$pass = $_GET["pass"];

$filter = "(&(uid=" . $user . ")(userPassword=" . $pass . "))"; // Unsafe

$ds = ...
$basedn = "o=My Company, c=US";

$sr = ldap_list($ds, $basedn, $filter); // Noncompliant

Compliant Solution

function sanitize_ldap_criteria($val) {
  $val = str_replace(['\\', '*', '(', ')'], ['\5c', '\2a', '\28', '\29'], $val);
  for ($i = 0; $i<strlen($val); $i++) {
    $char = substr($val, $i, 1);
    if (ord($char)<32) {
      $hex = dechex(ord($char));
      if (strlen($hex) == 1) $hex = '0' . $hex;
      $val = str_replace($char, '\\' . $hex, $val);
    }
  }
  return $val;
}

$user = sanitize_ldap_criteria( $_GET["user"] );
$pass = sanitize_ldap_criteria( $_GET["pass"] );

$filter = "(&(uid=" . $user . ")(userPassword=" . $pass . "))"; // Safe

$ds = ...
$basedn = "o=My Company, c=US";

$sr = ldap_list($ds, $basedn, $filter);

See

phpsecurity:S5335

User provided data such as URL parameters, POST data payloads or cookies should always be considered untrusted and tainted. Constructing include statements based on data supplied by the user could enable an attacker to control which files are included. If the attacker has the ability to upload files to the system, then arbitrary code could be executed. This could enable a wide range of serious attacks like accessing/modifying sensitive information or gain full system access.

The mitigation strategy should be based on whitelisting of allowed values or casting to safe types.

Noncompliant Code Example

$filename = $_GET["filename"];
include $filename . ".php";

Compliant Solution

$filename = $_GET["filename"];
if (in_array($filename, $whitelist)) {
  include $filename . ".php";
}

See

phpsecurity:S2076

Applications that execute operating system commands or execute commands that interact with the underlying system should neutralize any externally-provided values used in those commands. Failure to do so could allow an attacker to include input that executes unintended commands or exposes sensitive data.

The mitigation strategy should be based on whitelisting of allowed characters or commands.

Noncompliant Code Example

$binary = $_GET["binary"];

// If the value "/sbin/shutdown" is passed as binary and the web server is running as root,
// then the machine running the web server will be shut down and become unavailable for future requests

exec( $binary ); // Noncompliant

Compliant Solution

$binary = $_GET["binary"];

// Restrict to binaries within the current working directory whose name only contains letters
$pattern = "[a-zA-Z]++";
if ( preg_match($pattern, $binary) ) {
  exec( $binary ); // Compliant
}

See

phpsecurity:S5334

Applications that execute code dynamically should neutralize any externally-provided values used to construct the code. Failure to do so could allow an attacker to execute arbitrary code. This could enable a wide range of serious attacks like accessing/modifying sensitive information or gain full system access.

The mitigation strategy should be based on whitelisting of allowed values or casting to safe types.

Noncompliant Code Example

$data = $_GET["data"];
eval("echo \$data;");

Compliant Solution

$data = $_GET["data"];
if (in_array($data, $whitelist)) {
  eval("echo \$data;");
}

See

phpsecurity:S3649

User provided data, such as URL parameters, should always be considered untrusted and tainted. Constructing SQL queries directly from tainted data enables attackers to inject specially crafted values that change the initial meaning of the query itself. Successful SQL injection attacks can read, modify, or delete sensitive information from the database and sometimes even shut it down or execute arbitrary operating system commands.

Typically, the solution is to rely on the prepared statements rather than string concatenation, which ensures that user provided data will be properly escaped.

This rule supports: Native Database Extensions, PDO, Symfony/Doctrine, Laravel/Eloquent.

Noncompliant Code Example

function authenticate() {
  if( isset( $_POST[ 'Connect' ] ) ) {
    $login = $_POST[ 'login' ];
    $pass = $_POST[ 'pass' ];

    $query = "SELECT * FROM users WHERE login = '" . $login . "' AND pass = '" . $pass . "'"; // Unsafe

    // If the special value "foo' OR 1=1 --" is passed as either the user or pass, authentication is bypassed
    // Indeed, if it is passed as a user, the query becomes:
    // SELECT * FROM users WHERE user = 'foo' OR 1=1 --' AND pass = '...'
    // As '--' is the comment till end of line syntax in SQL, this is equivalent to:
    // SELECT * FROM users WHERE user = 'foo' OR 1=1
    // which is equivalent to:
    // SELECT * FROM users WHERE 1=1
    // which is equivalent to:
    // SELECT * FROM users

    $con = getDatabaseConnection();
    $result = mysqli_query($con, $query);

    $authenticated = false;
    if ( $row = mysqli_fetch_row( $result ) ) {
      $authenticated = true;
    }
    mysqli_free_result( $result );
    return $authenticated;
  }
}

Compliant Solution

function authenticate() {
  if( isset( $_POST[ 'Connect' ] ) ) {
    $login = $_POST[ 'login' ];
    $pass = $_POST[ 'pass' ];

    $query = "SELECT * FROM users WHERE login = ? AND pass = ?"; // Safe even if authenticate() method is still vulnerable to brute-force attack in this specific case

    $stmt = $pdo->prepare($query);

    $stmt->execute(array($login, $pass));

    $authenticated = false;
    if ( $stmt->rowCount() == 1 ) {
      $authenticated = true;
    }

    return $authenticated;
  }
}

See

phpsecurity:S2083

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Constructing file system paths directly from tainted data could enable an attacker to inject specially crafted values, such as '../', that change the initial path and, when accessed, resolve to a path on the filesystem where the user should normally not have access.

A successful attack might give an attacker the ability to read, modify, or delete sensitive information from the file system and sometimes even execute arbitrary operating system commands. This is often referred to as a "path traversal" or "directory traversal" attack.

The mitigation strategy should be based on the whitelisting of allowed paths or characters.

Noncompliant Code Example

$userId = $_GET["userId"];
$fileUUID = $_GET["fileUUID"];

if ( $_SESSION["userId"] == $userId ) {
  unlink("/storage/" . $userId . "/" . $fileUUID); // Noncompliant
}

Compliant Solution

$userId = (int) $_GET["userId"];
$fileUUID = (int) $_GET["fileUUID"];

if ( $_SESSION["userId"] == $userId ) {
  unlink("/storage/" . $userId . "/" . $fileUUID);
}

See

phpsecurity:S2091

User provided data, such as URL parameters, should always be considered untrusted and tainted. Constructing XPath expressions directly from tainted data enables attackers to inject specially crafted values that changes the initial meaning of the expression itself. Successful XPath injection attacks can read sensitive information from XML documents.

Noncompliant Code Example

$user = $_GET["user"];
$pass = $_GET["pass"];

$doc = new DOMDocument();
$doc->load("test.xml");
$xpath = new DOMXPath($doc);

$expression = "/users/user[@name='" . $user . "' and @pass='" . $pass . "']";
$xpath->evaluate($expression); // Noncompliant

Compliant Solution

$user = $_GET["user"];
$pass = $_GET["pass"];

$doc = new DOMDocument();
$doc->load("test.xml");
$xpath = new DOMXPath($doc);

$user = str_replace("'", "&apos;", $user);
$pass = str_replace("'", "&apos;", $pass);

$expression = "/users/user[@name='" . $user . "' and @pass='" . $pass . "']";
$xpath->evaluate($expression); // Compliant

See

typescript:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
objc:S990

<stdlib.h>'s abort, exit, getenv, and system have undefined, and implementation-defined behaviors, and should therefore be used.

Noncompliant Code Example

#include <stdlib.h>

void f( ) {
  exit(0); // Noncompliant
}

See

  • MISRA C:2004, 20.11 - The library functions abort, exit, getenv and system from library <stdlib.h> shall not be used.
  • MISRA C++:2008, 18-0-3 - The library functions abort, exit, getenv and system from library <cstdlib> shall not be used.
  • MISRA C:2012, 21.8 - The library functions abort, exit, getenv and system of <stdlib.h> shall not be used
  • CERT, ENV33-C. - Do not call system()
  • CERT, ERR50-CPP. - Do not abruptly terminate the program
objc:PPIncludeSignal

Signal handling contains implementation-defined and undefined behavior.

Noncompliant Code Example

#include <signal.h> /* Noncompliant */

See

  • MISRA C:2004, 20.8 - The signal handling facilities of <signal.h> shall not be used.
  • MISRA C:2012, 21.5 - The standard header file <signal.h> shall not be used
objc:TrigraphUsage

Trigraphs are denoted by a sequence of 2 question marks followed by a specified third character (e.g. ??- represents a '~' (tilde) character and ??) represents a ']'). They can cause accidental confusion with other uses of two question marks.

Noncompliant Code Example

static const char str[] = "(Date should be in the form ??-??-??)"; // Noncompliant. Evaluates to "(Date should be in the form ~~]"

Compliant Solution

static const char str[] = "(Date should be in the form ?" "?-?" "?-?" ?)";  // adjacent string literals concatenated at compile time
static const char str2[] = "(Date should be in the form ?-?-?)"; // problem avoided by eliminating 2nd '?' in each sequence
static const char str3[] = "(Date should be in the form ? ?-? ?-? ?)"; // problem avoided by spacing '?'s out

See

  • MISRA C:2004, 4.2 - Trigraphs shall not be used
  • MISRA C++:2008, 2-3-1 - Trigraphs shall not be used
  • MISRA C:2012, 4.2 - Trigraphs shall not be used
  • CERT, PRE07-C. - Avoid using repeated question marks
objc:S982

setjmp.h functions allow the normal function mechanisms to be bypassed and should be used only with extreme caution, if at all.

Calling setjmp saves the program environment into the buffer passed into the call. Later calling longjmp returns execution to the point at which setjmp was called and restores the context that was saved into the buffer. But the values of non-volatile local variables after longjmp are indeterminate. Additionally invoking longjmp from a nested signal handler is undefined, as is longjmping back to a method that has already completed execution.

This rule flags all instances of setjmp, _setjmp, longjmp, _longjmp, sigsetjmp, siglongjmp and <setjmp.h>.

Noncompliant Code Example

#include <setjmp.h>  // Noncompliant

jmp_buf buf;

int main(int argc, char* argv[]) {
  int i = setjmp(buf);  // Noncompliant
  if (i == 0) { // value of i was assigned after env was saved & will be indeterminate after longjmp();
    // normal execution
  } else {
    // recover
  }
}

//...

void fun() {
  //...
  longjmp(buf, 1);  // Noncompliant
}

Compliant Solution

int main(int argc, char* argv[]) {
  // normal execution
}

//...

void fun() {
  //...
}

See

  • MISRA C:2004, 20.7 - The setjmp macro and the longjmp function shall not be used.
  • MISRA C++:2008, 17-0-5 - The setjmp macro and the longjmp function shall not be used.
  • MISRA C:2012, 21.4 - The standard header file <setjmp.h> shall not be used
  • CERT, MSC22-C. - Use the setjmp(), longjmp() facility securely
  • CERT, ERR52-CPP. - Do not use setjmp() or longjmp()
objc:S985

errno is a facility of C++ which should in theory be useful, but which in practice is poorly defined by ISO/IEC 14882:2003. A non-zero value may or may not indicate that a problem has occurred; therefore errno shall not be used.

Even for those functions for which the behaviour of errno is well defined, it is preferable to check the values of inputs before calling the function rather than relying on using errno to trap errors.

Noncompliant Code Example

#include <cstdlib>
#include <cerrno>

void f1 ( const char_t * str )
{
  errno = 0; // Noncompliant
  int32_t i = atoi ( str );
  if ( 0 != errno ) // Noncompliant
  {
    // handle error case???
  }
}

See

  • MISRA C:2004, 20.5 - The error indicator errno shall not be used.
  • MISRA C++:2008, 19-3-1 - The error indicator errno shall not be used.

See Also

  • ISO/IEC 14882:2003
objc:S864

The rules of operator precedence are complicated and can lead to errors. For this reason, parentheses should be used for clarification in complex statements. However, this does not mean that parentheses should be gratuitously added around every operation.

Parentheses are not needed:

  • with a unary operator, except when ! is used as left operand in comparison expressions
  • when all the operators in an expression are the same
  • when only a single operator is involved
  • around the right-hand side of an assignment operator unless the right-hand side itself contains an assignment

Parentheses are needed:

  • in the condition of a ternary operator if it uses operators
  • when overloaded shift operator << or >> is used in an expression with comparison operators

Noncompliant Code Example

x = a + b;
x = a * -1;
x = a + b + c;
x = f ( a + b, c );

x = a == b ? a : a - b; // Noncompliant
x = a + b - c + d; // Noncompliant
x = a * 3 + c + d; // Noncompliant

if (a = f(b,c) == true) { ... } // Noncompliant; == evaluated first
x - b ? a : c; // Noncompliant; "-" evaluated first
s << 5 == 1; // Noncompliant; "<<" evaluated first

Compliant Solution

x = a + b;
x = a * -1;
x = a + b + c;
x = f ( a + b, c );

x = ( a == b ) ? a : ( a - b );
x = ( a + b ) - ( c + d );
x = ( a * 3 ) + c + d;

if ( (a = f(b,c)) == true) { ... }
(x - b) ? a : c; // Compliant
(s << 5) == 1; // Compliant

See

  • MISRA C:2004, 12.1 - Limited dependence should be placed on C's operator precedence rules in expressions
  • MISRA C:2004, 12.2 - The value of an expression shall be the same under any order of evaluation that the standard permits.
  • MISRA C:2004, 12.5 - The operands of a logical && or || shall be primary-expressions.
  • MISRA C++:2008, 5-0-1 - The value of an expression shall be the same under any order of evaluation that the standard permits.
  • MISRA C++:2008, 5-0-2 - Limited dependence should be placed on C++ operator precedence rules in expressions
  • MISRA C++:2008, 5-2-1 - Each operand of a logical && or || shall be a postfix-expression.
  • MISRA C:2012, 12.1 - The precedence of operators within expressions should be made explicit
  • CERT, EXP00-C. - Use parentheses for precedence of operation
  • CERT, EXP53-J. - Use parentheses for precedence of operation
  • MITRE, CWE-783 - Operator Precedence Logic Error
objc:S984

The use of dynamic memory can lead to out-of-storage run-time failures, which are undesirable.

The built-in new and delete operators, other than the placement versions, use dynamic heap memory. The functions calloc, malloc, realloc and free also use dynamic heap memory.

There is a range of unspecified, undefined and implementation-defined behaviour associated with dynamic memory allocation, as well as a number of other potential pitfalls. Dynamic heap memory allocation may lead to memory leaks, data inconsistency, memory exhaustion, non-deterministic behaviour, etc.

Note that some implementations may use dynamic heap memory allocation to implement other functions (for example, functions in the library cstring). If this is the case, then these functions shall also be avoided.

Noncompliant Code Example

int *b;
void initialize()
{
  b = (int *b) alloc ( 1024 * sizeof ( int ) ); // Noncompliant, could lead to an out-of-storage run-time failure.
  if( b == 0 )
  {
    // handle case when dynamic allocation failed.
  }
}

Compliant Solution

int b[1024]; // Compliant solution.

See

  • MISRA C:2004, 20.4 - Dynamic heap memory allocation shall not be used.
  • MISRA C++ 2008, 18-4-1 - Dynamic heap memory allocation shall not be used.
  • MISRA C:2012, 21.3 The memory allocation and deallocation functions of <stdlib.h> shall not be used
objc:GotoUsage

goto is an unstructured control flow statement. It makes code less readable and maintainable. Structured control flow statements such as if, for, while, continue or break should be used instead.

Noncompliant Code Example

int i = 0;
loop:
  printf("i = %d\n", i);
  i++;
  if (i < 10){
    goto loop; // Noncompliant
  }

Compliant Solution

for (int i = 0; i < 10; i++) {
  printf("i = %d\n", i);
}

See

  • MISRA C:2004, 14.4 - The goto statement shall not be used.
  • MISRA C:2012, 15.1 - The goto statement should not be used
objc:S986

offsetof can lead to undefined behavior when the argument types are incompatible or when bit fields are used. Therefore offsetof should be avoided.

Noncompliant Code Example

#include <stddef.h>

struct A
{
  int32_t i;
};

void f1 ( )
{
  offsetof ( A, i ); // Noncompliant
}

See

  • MISRA C:2004, 20.6 - The macro offsetof, in library <stddef.h>, shall not be used.
  • MISRA C++ 2008, 18-2-1 - The macro offsetof, in library <stddef.h>, shall not be used.
objc:S989

<stdlib.h>'s atof, atoi, and atol functions, which convert strings to numbers, have undefined behavior when the strings cannot be converted, and should therefore be avoided.

Noncompliant Code Example

int converter (const char * numstr) {
  return atoi(numstr); // Noncompliant
}

Compliant Solution

int converter (const char * numstr) {
  return strtol(numstr, NULL, 10);
}

See

  • MISRA C:2004, 20.10 - The library functions atof, atoi and atol from library <stdlib.h> shall not be used.
  • MISRA C++:2008, 18-0-2 - The library functions atof, atoi and atol from library <cstdlib> shall not be used.
  • MISRA C:2012, 21.7 - The atof, atoi, atol and atoll functions of <stdlib.h> shall not be used
  • CERT, ERR34-C. - Detect errors when converting a string to a number
objc:S867

The use of operands with types other than bool with these operators is unlikely to be meaningful (or intended). This rule allows the detection of such uses, which often occur because the logical operators (&&, || and !) can be easily confused with the bitwise operators (&, | and ~).

Noncompliant Code Example

if ( 1 && ( c < d ) ) // Noncompliant
if ( ( a < b ) && ( c + d ) ) // Noncompliant
if ( u8_a && ( c + d ) ) // Noncompliant
if ( !0 ) // Noncompliant, always true
if ( !ptr ) // Noncompliant
if ( ( a < b ) && ( c < d ) ) // Compliant
if ( !false ) // Compliant

Compliant Solution

if ( 1 != 0 && ( c < d ) ) // Compliant, but left operand is always true
if ( ( a < b ) && ( c + d ) != 0 ) // Compliant
if ( u8_a != 0 && ( c + d ) != 0) // Compliant
if ( 0 == 0 ) // Compliant, always true
if ( ptr != NULL ) // Compliant

See

  • MISRA C:2004, 12.6 - The operands of logical operators (&&, || and !) should be effectively Boolean. Expressions that are effectively Boolean should not be used as operands to operators other than (&&, || and !).
  • MISRA C++:2008, 5-3-1 - Each operand of the ! operator, the logical && or the logical || operators shall have type bool.
  • CERT, EXP54-J. - Understand the differences between bitwise and logical operators
objc:SingleGotoOrBreakPerIteration

Restricting the number of exits from a loop is done in the interests of good structured programming. One break or goto statement is acceptable in a loop since this allows, for example, for dual-outcome loops or optimal coding.

Noncompliant Code Example

With the default threshold of 1:

for (int i = 0; i < 10; i++) {
  if (...) {
    break;      //  Compliant
  }
  else if (...) {
    break;      //  Non-compliant - second jump from loop
  }
  else {
    ...
  }
}
while (...) {
  if (...) {
    break;      // Compliant
  }
  if (...) {
    break;      // Non-compliant - second jump from loop
  }
}

Compliant Solution

for (int i = 0; i < 10; i++) {
  if (...) {
    break;      //  Compliant
  }
}
while (...) {
  if (...) {
    break;    // Compliant
  }
}

See

  • MISRA C:2004, 14.6 - For any iteration statement there shall be at most one break statement used for loop termination.
  • MISRA C++:2008, 6-6-4 - For any iteration statement there shall be no more than one break or goto statement used for loop termination.
  • MISRA C:2012, 15.4 - There should be no more than one break or goto statement used to terminate any iteration statement
objc:S1144

private methods that are never executed are dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.

Noncompliant Code Example

static void unusedStaticFunction() { // Noncompliant
}

class Server {
public:
  void start() { // Compliant, the member function "start()" is public
    log("start");
  }
private:
  void clear() { // Noncompliant, the member function "clear()" is unused
  }
  void log(const char * msg) { // Compliant, the member function "log()" is used in "start() { ... }"
    printf(msg);
  }
};

See

* MISRA C++:2008, 0-1-10 - Every defined function shall be called at least once.

objc:NarrowAndWideStringConcat

Concatenation of wide and narrow string literals leads to undefined behavior.

Noncompliant Code Example

wchar_t n_array[] = "Hello" L"World";     // Noncompliant
wchar_t w_array[] = L"Hello" "World";     // Noncompliant

Compliant Solution

char_t n_array[] = "Hello" "World";     // Compliant
wchar_t w_array[] = L"Hello" L"World";	// Compliant

See

  • MISRA C++:2008, 2-13-5 - Narrow and wide string literals shall not be concatenated.
  • CERT STR10-C. - Do not concatenate different type of string literals
objc:S873

Enumerations have implementation-defined representation and so should not be used in arithmetic contexts.

Noncompliant Code Example

enum { COLOUR_0, COLOUR_1, COLOUR_2, COLOUR_COUNT } colour;
if ( COLOUR_0 == colour ) { ... }
if ( ( COLOUR_0 + COLOUR_1 ) == colour ) { ... } // Noncompliant, arithmetic used
if ( colour < COLOUR_COUNT ) { ... }

See

  • MISRA C++:2008, 4-5-2 - Expressions with type enum shall not be used as operands to builtin operators other than the subscript operator [ ], the assignment operator =, the equality operators == and !=, the unary & operator, and the relational operators <, <=, >, >=
objc:S872

The use of bool operands with other operators is unlikely to be meaningful (or intended). Best case it will be confusing to maintainers, worst case it will not have the intended effect. Either way, it is highly recommended to stick to boolean operators when dealing with bool operands.

This rule allows the detection of such uses, which often occur because the logical operators (&&, || and !) can be easily confused with the bitwise operators (&, | and ~).

Noncompliant Code Example

bool b1 = true;
bool b2 = false;
int8_t s8a;
if ( b1 & b2 ) // Noncompliant
if ( ~b1 ) // Noncompliant
if ( b1 < b2 ) // Noncompliant
if ( b1 ^ b2 ) // Noncompliant

Compliant Solution

if ( b1 && b2 )
if ( !b1 )
if ( b1 == false )
if ( b1 == b2 )
if ( b1 != b2 )
s8a = b1 ? 3 : 7;

Exceptions

Operators |= and &= are ignored when used with bool operands. Operator ++ is also ignored with a bool operand because it is covered by rule S2668.

void test(bool b1, bool b2, int i1) {
  b1 |= b2; // ignored
  b1++; // ignored here, handled by S2668
  b1 &= b2; // ignored
  b1 &= i1; // Noncompliant; right operand is not a bool
}

See

  • MISRA C++:2008, 4-5-1 - Expressions with type bool shall not be used as operands to built-in operators other than the assignment operator =, the logical operators &&, ||, !, the equality operators == and !=, the unary & operator, and the conditional operator.
objc:S995

This rule leads to greater precision in the definition of the function interface. The const qualification shall be applied to the object pointed to, not to the pointer, since it is the object itself that is being protected.

Noncompliant Code Example

void myfunc (      int * param1,  // object is modified
             const int * param2,
                   int * param3, // Noncompliant
                   int * param4) // Noncompliant
{
  *param1 = *param2 + *param3 + *param4;
}

int main (int argc,
          const char * * argv) // Noncompliant
{
  return argc;
}

Compliant Solution

void myfunc (      int * param1,  // object is modified
             const int * param2,
             const int * param3,
             const int * param4)
{
  *param1 = *param2 + *param3 + *param4;
}

int main (int argc,
          const char * const * argv)
{
  return argc;
}

See

  • MISRA C:2004, 16.7 - A pointer parameter in a function prototype should be declared as pointer to const if the pointer is not used to modify the addressed object.
  • MISRA C++:2008, 7-1-2 - A pointer or reference parameter in a function shall be declared as pointer to const or reference to const if the corresponding object is not modified.
  • MISRA C:2012, 8.13 - A pointer should point to a const-qualified type whenever possible
objc:S874

Most bitwise operators (~, >>, >>=, &, &=, ^, ^=, |, and |=) have implementation-dependent results when performed on signed operands, and bitwise left shift (<< and <<=) has undefined behavior when performed on negative operands. Therefore bitwise operations should not be performed on signed operands.

Noncompliant Code Example

if ( ( uint16_a & int16_b ) == 0x1234U )
if ( ~int16_a == 0x1234U )

Compliant Solution

if ( ( uint16_a | uint16_b ) == 0x1234U )
if ( ~uint16_a == 0x1234U )

Exceptions

When used as bit flags, it is acceptable to use preprocessor macros as arguments to the & and | operators even if the value is not explicitly declared as unsigned.

fd = open(file_name, UO_WRONLY | UO_CREAT | UO_EXCL | UO_TRUNC, 0600);

If the right-side operand to a shift operator is known at compile time, it is acceptable for the value to be represented with a signed type provided it is positive.

#define SHIFT 24
foo = 15u >> SHIFT;

See

  • MISRA C:2004, 12.7 - Bitwise operators shall not be applied to operands whose underlying type is signed
  • MISRA C++:2008, 5-0-21 - Bitwise operators shall only be applied to operands of unsigned underlying type
  • MISRA C:2012, 10.1 - Operands shall not be of an inappropriate essential type
  • CERT, INT13-C. - Use bitwise operators only on unsigned operands
  • MITRE, CWE-682 - Incorrect Calculation
objc:S876

Applying the unary minus operator to an unsigned variable or expression will always yield another unsigned expression. More plainly, in some cases the operation itself is meaningless, and in some other cases the result will be unexpected. In all cases it is bad practice. Therefore the unary minus operator should not be applied to unsigned variables or expressions.

Noncompliant Code Example

uint8_t a = -1U;
int32_t b = -a; // Noncompliant; b is assigned -255
uint32_t c = 1U;
int64_t d = -c; // Noncompliant; d is assigned MAX_UINT

Exceptions

This rule ignores -1U because it is commonly used as shorthand for MAX_UINT.

See

  • MISRA C:2004, 12.9 - The unary minus operator shall not be applied to an expression whose underlying type is unsigned.
  • MISRA C++:2008, 5-3-2 - The unary minus operator shall not be applied to an expression whose underlying type is unsigned.
  • MISRA C:2012, 10.1 - Operands shall not be of an inappropriate essential type
objc:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

objc:S878

The comma operator takes two expressions, executes them from left to right and returns the result of the second one. Use of this operator is generally detrimental to the readability and reliability of code, and the same effect can be achieved by other means.

Noncompliant Code Example

i = a += 2, a + b;  // What's the value of i ?

Compliant Solution

a +=  2;
i = a + b;

Exceptions

Use of comma operator is tolerated in initialization and increment expressions of for loops.

for(i = 0, j = 5; i < 6; i++, j++) { ... }

See

  • MISRA C:2004, 12.10 - The comma operator shall not be used.
  • MISRA C++:2008, 5-18-1 - The comma operator shall not be used.
  • MISRA C:2012, 12.3 - The comma operator should not be used
objc:S2324

Flexible array members are most likely to be used in conjunction with dynamic memory allocation.

The presence of flexible array members modifies the behaviour of the sizeof operator in ways that might not be expected by a programmer. The assignment of a structure that contains a flexible array member to another structure of the same type may not behave in the expected manner as it copies only those elements up to but not including the start of the flexible array member.

Noncompliant Code Example

#include <stdlib.h>
struct s
{
  uint16_t len;
  uint32_t data[ ]; // Noncompliant - flexible array member
} str;

struct s *copy ( struct s *s1 )
{
  struct s *s2 = malloc ( sizeof ( struct s ) + ( s1->len * sizeof ( uint32_t ) ) );
  /* Omit malloc ( ) return check for brevity */
  *s2 = *s1; /* Only copies s1->len */
  return s2;
}

See

  • MISRA C:2012, 18.7 - Flexible array members shall not be declared.
objc:S2323

Line-splicing occurs when the \ character is immediately followed by a new-line character. If the source line containing a // comment ends with a '\', the next line becomes part of the comment. This may result in unintentional removal of code.

Noncompliant Code Example

void f ( void )
{
  int x = 0; // comment \
  if (x)
  {
    ++x; /* This is always executed */
  }
}

See

  • MISRA C:2012, 3.2 - Line-splicing shall not be used in // comments
objc:S1117

Overriding or shadowing a variable declared in an outer scope can strongly impact the readability, and therefore the maintainability, of a piece of code. Further, it could lead maintainers to introduce bugs because they think they're using one variable but are really using another.

Noncompliant Code Example

class Foo
{
public:
  void doSomething();

private:
  int myField;
};

void Foo::doSomething()
{
    int myField = 0; // Noncompliant
    // ...
}
void f(int x, bool b) {
  int y = 4;
  if (b) {
    int x = 7; // Noncompliant
    int y = 9; // Noncompliant
    // ...
  }
}

Compliant Solution

class Foo
{
public:
  void doSomething();

private:
  int myField;
};

void Foo::doSomething()
{
    int myInternalField = 0; // Compliant
    // ...
}
void f(int x, bool b) {
  int y = 4;
  if (b) {
    int z = 7; // Better yet: Use meaningful names
    int w = 9;
    // ...
  }
}

Exceptions

It is common in a constructor to have constructor arguments shadowing the fields that they will initialize. This pattern avoids the need to select new names for the constructor arguments, and will not be reported by this rule:

class Point{
public:
  Point(int x, int y) : x(x), y(y) {} // Compliant by exception
private:
  int x;
  int y;
};

See

  • MISRA C:2004, 5.2 - Identifiers in an inner scope shall not use the same name as an identifier in an outer scope, and therefore hide that identifier
  • MISRA C++:2008, 2-10-2 - Identifiers declared in an inner scope shall not hide an identifier declared in an outer scope
  • MISRA C:2012, 5.3 - An identifier declared in an inner scope shall not hide an identifier declared in an outer scope
  • CERT, DCL01-C. - Do not reuse variable names in subscopes
  • CERT, DCL51-J. - Do not shadow or obscure identifiers in subscopes
objc:S1116

Empty statements, i.e. ;, are usually introduced by mistake, for example because:

  • It was meant to be replaced by an actual statement, but this was forgotten.
  • There was a typo which lead the semicolon to be doubled, i.e. ;;.

Noncompliant Code Example

void doSomething() {
  ;                                                       // Noncompliant - was used as a kind of TODO marker
}

Compliant Solution

void doSomething() {
}

Exceptions

In the case of empty expanded macro and in the case of 2 consecutive semi-colons when one of the two is part of a macro-definition then the issue is not raised.

Example:

#define A(x) x;
#define LOG(x)

void fun() {
  A(5);
  LOG(X);
}

See

  • MISRA C:2004, 14.3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment provided that the first character following the null statement is a white-space character.
  • MISRA C++:2008, 6-2-3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment, provided that the first character following the null statement is a white-space character.
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • CERT, MSC51-J. - Do not place a semicolon immediately following an if, for, or while condition
  • CERT, EXP15-C. - Do not place a semicolon on the same line as an if, for, or while statement
objc:S969

The defined preprocessing directive is used in the context of #if and #elif expressions to see whether a given identifier has been defined as a macro. It returns a value of 0 (false) or 1 (true), and has two valid forms, defined IDENTIFIER and defined ( IDENTIFIER ). Since it is essentially a macro existence check, it cannot take expressions as arguments.

Note that since

#if defined AN_IDENTIFIER

is equivalent to

#ifdef AN_IDENTIFIER

defined is most useful when there are multiple arguments to check, E.G.

#if defined AAA || defined BBB

Noncompliant Code Example

#if defined ( X > Y ) // Noncompliant; expressions not allowed

Compliant Solution

#if defined X && defined Y && X > Y

See

  • MISRA C:2004, 19.14 - The defined preprocessor operator shall only be used in one of the two standard forms.
  • MISRA C++:2008, 16-1-1 - The defined preprocessor operator shall only be used in one of the two standard forms.
objc:LogicalExpressionOperands

The effect of this rule is to require that operands are appropriately parenthesized. Parentheses are important in this situation both for readability of code and for ensuring that the behavior is as the developer intended.

Where an expression consists of either a sequence of only logical && or a sequence of logical ||, extra parentheses are not required.

Noncompliant Code Example

if (x == 0 && ishigh);                   // Noncompliant
if (x || y || z);
if (x || y && z);                        // Noncompliant
if (x && !y);                            // Noncompliant
if (is_odd(y) && x);
if ((x > c1) && (y > c2) && (z > c3));
if ((x > c1) && (y > c2) || (z > c3));   // Noncompliant

Compliant Solution

if ((x == 0) && ishigh);
if (x || y || z);
if (x || (y && z));
if (x && (!y));
if (is_odd(y) && x);
if ((x > c1) && (y > c2) && (z > c3));
if ((x > c1) && ((y > c2) || (z > c3)));

See

  • MISRA C:2004, 12.5 - The operands of a logical && or || shall be primary-expressions.
  • MISRA C++:2008, 5-2-1 - Each operand of a logical && or || shall be a postfix-expression.
objc:S961

This is a constraint error, but preprocessors have been known to ignore this problem. Each argument in a function-like macro must consist of at least one preprocessing token otherwise the behaviour is undefined.

See

  • MISRA C:2004, 19.8 - A function-like macro shall not be invoked without all of its arguments.
  • MITRE, CWE-628 - Function Call with Incorrectly Specified Arguments
objc:S960

It is tempting to treat function-like macros as functions, but the two things work differently. For instance, the use of functions offers parameter type-checking, while the use of macros does not. Additionally, with macros, there is the potential for a macro to be evaluated multiple times. In general, functions offer a safer, more robust mechanism than function-like macros, and that safety usually outweighs the speed advantages offered by macros. Therefore functions should be used instead when possible.

Noncompliant Code Example

#define CUBE (X) ((X) * (X) * (X)) // Noncompliant

void func(void) {
  int i = 2;
  int a = CUBE(++i); // Noncompliant. Expands to: int a = ((++i) * (++i) * (++i))
  // ...
}

Compliant Solution

inline int cube(int i) {
  return i * i * i;
}

void func(void) {
  int i = 2;
  int a = cube(++i); // yields 27
  // ...
}

See

  • MISRA C:2004, 19.7 - A function should be used in preference to a function-like macro.
  • MISRA C++:2008, 16-0-4 - Function-like macros shall not be defined.
  • MISRA C:2012, Dir. 4.9 - A function should be used in preference to a function-like macro where they are interchangeable
  • CERT, PRE00-C. - Prefer inline or static functions to function-like macros
objc:S966

An attempt to use an undefined identifier may elicit a warning from the preprocessor. Or it may not; the preprocessor may simply assume that the undefined token has a value of 0.

Therefore macro identifiers should not be used in preprocessor directives until after they have been defined, and this limited usage should be enforced with the use of definition tests.

Noncompliant Code Example

#if x > 0  /* x assumed to be zero if not defined */
#include SOMETHING_IMPORTANT
#endif

#ifdef y  /* Okay; y is not evaluated */
#if y > 0 /* Okay; y must be defined to reach this point */
...
#endif
#endif

Compliant Solution

#define x 10
...
#if x > 0
#include SOMETHING_IMPORTANT
#endif

#if defined ( y ) && ( y > 0 )  /* more compact form, same result as before */
...
#endif

See

  • MISRA C:2004, 19.11 - All macro identifiers in preprocessor directives shall be defined before use, except in #ifdef and #ifndef preprocessor directives and the defined() operator.
  • MISRA C:2012, 20.9 - All identifiers used in the controlling expression of #if or #elif preprocessing directives shall be #define’d before evaluation
objc:S967

Because the evaluation order of # and ## are not specified, the results of using them both in the same macro could be unpredictable. Therefore macros should contain at most once instance of either # or ##.

Noncompliant Code Example

#define PRINT_FIELD(field) printf (#field " = " ##field);

Compliant Solution

#define FIELD_VAL(field) ##field
#define PRINT_FIELD(field) printf(#field " = " FIELD_VAL(field))

See

  • MISRA C:2004, 19.12
  • MISRA C++ 2008, 16-3-1
  • Related: MISRA C:2012, 20.11
objc:S2335

There is potential for confusion if an octal or hexadecimal escape sequence is immediately followed by other characters. Instead, such sequences shall be terminated by either:

  • The start of another escape sequence.
  • The end of the character constant or the end of a string literal.

Noncompliant Code Example

const char *s1 = "\x41g";  // Noncompliant
int c1 = '\141t'; // Noncompliant

Compliant Solution

const char *s2 = "\x41" "g"; // Compliant - terminated by end of literal
const char *s3 = "\x41\x67"; // Compliant - terminated by another escape
int c2 = '\141\t'; // Compliant - terminated by another escape

See

  • MISRA C:2012, 4.1 - Octal and hexadecimal escape sequences shall be terminated
objc:S1244

Floating point math is imprecise because of the challenges of storing such values in a binary representation. Even worse, floating point math is not associative; push a float or a double through a series of simple mathematical operations and the answer will be different based on the order of those operation because of the rounding that takes place at each step.

Even simple floating point assignments are not simple:

float f = 0.1; // 0.100000001490116119384765625
double d = 0.1; // 0.1000000000000000055511151231257827021181583404541015625

(Results will vary based on compiler and compiler settings.)

Therefore, the use of the equality (==) and inequality (!=) operators on float or double values is almost always an error.

The accepted solution is to use or write a float comparison library that takes floating-point granularity (FLT_EPSILON) and the magnitude of the numbers being compared into account.

This rule checks for the use of direct and indirect equality/inequailty tests on floats and doubles.

Noncompliant Code Example

float myNumber = 3.146;
if ( myNumber == 3.146 ) {  //Noncompliant. Because of floating point imprecision, this will be false
  // ...
}

if (myNumber <= 3.146 && mNumber >= 3.146) { // Noncompliant indirect equality test
  // ...
}

if (myNumber < 4 || myNumber > 4) { // Noncompliant indirect inequality test
  // ...
}

See

  • MISRA C:2004, 13.3 - Floating-point expressions shall not be tested for equality or inequality.
  • MISRA C++:2008, 6-2-2 - Floating-point expressions shall not be directly or indirectly tested for equality or inequality
objc:S860

Converting an integer type to a pointer generally leads to unspecified behavior. There are several cases where it might be legitimate:

- Converting the integral literal 0 to the null pointer (but you should use nullptr instead, see S4962),

- Converting back to a pointer a pointer value that was converted to a large enough integer (see S1767),

- On embedded devices, device drivers... converting a hard-coded address to a pointer to read some specific memory (this often goes together with the use of volatile, since such memory values can change from the outside of the program).

Since even legitimate cases are corner cases that require to be reviewed carefully, this rule simply reports all places where an integer is cast into a pointer (except the literal 0).

Noncompliant Code Example

struct S {
  int i;
  int j;
};

void f(void* a);

void g(int i) {
  S* s1 = (S*)i; // Noncompliant
  f((void*)i); // Noncompliant
}

See

  • MISRA C++ 2008, 5-2-8 - An object with integer type or pointer to void type shall not be converted to an object with pointer type.
  • CERT, INT36-C. - Converting a pointer to integer or integer to pointer
objc:InvalidEscapeSequence

The use of an undefined escape sequence leads to undefined behavior. The defined escape sequences (ISO/IEC 14882:2003 [1] §2.13.2) are: \n, \t, \v, \b, \r, \f, \a, \\, ?, \', \", \<Octal Number>, and \x<Hexadecimal Number>.

Noncompliant Code Example

const char_t a[ 2 ] = "\k";   // Noncompliant
const char_t b[ 2 ] = "\b";   // Compliant

See

  • MISRA C:2004, 4.1 - Only those escape sequences that are defined in ISO C standard shall be used.
  • MISRA C++:2008, 2-13-1 - Only those escape sequences that are defined in ISO/IEC 14882:2003 shall be used.
objc:S2216

The values that can be represented by a signed bit field with a length of one bit may not meet developer expectations. For example according to the C99 Standard, Section 6.2.6.2, a single-bit signed bit-field has a single (one) sign bit and no (zero) value bits.

This rule does not apply to unnamed bit fields, as their values cannot be accessed.

Noncompliant Code Example

signed int f:1;  // Noncompliant; there's only room here for the sign

Compliant Solution

unsigned int f:1;

or

signed int:1; // unnamed

or

signed int f:2;

See

  • MISRA C:2004, 6.5 - Bit fields of type signed int shall be at least 2 bits long
  • MISRA C:2012, 6.2 - Single-bit named bit fields shall not be of a signed type
  • MISRA C++:2008, 9-6-4 - Named bit-fields with signed integer type shall have a length of more than one bit
objc:OctalConstantAndSequence

Integer literals starting with a zero are octal rather than decimal values. While using octal values is fully supported, most developers do not have experience with them. They may not recognize octal values as such, mistaking them instead for decimal values.

Noncompliant Code Example

int myNumber = 010;   // Noncompliant. myNumber will hold 8, not 10 - was this really expected?

Compliant Solution

int myNumber = 8;

See

  • MISRA C:2004, 7.1 - Octal constants (other than zero) and octal escape sequences shall not be used.
  • MISRA C++:2008, 2-13-2 - Octal constants (other than zero) and octal escape sequences (other than "\0") shall not be used
  • MISRA C:2012, 7.1 - Octal constants shall not be used
  • CERT, DCL18-C. - Do not begin integer constants with 0 when specifying a decimal value
  • CERT, DCL50-J. - Use visually distinct identifiers
objc:S851

If a cast is to be used on any complex expression, the type of cast that may be applied is severely restricted. As explained in MISRA C 2004, section 6.10, conversions on complex expressions are often a source of confusion and it is therefore wise to be cautious. In order to comply with these rules, it may be necessary to use a temporary variable and introduce an extra statement.

Noncompliant Code Example

  ... (float32_t)(f64a + f64b)
  ... (float64_t)(f32a + f32b) // Noncompliant
  ... (float64_t)f32a
  ... (float64_t)(s32a / s32b) // Noncompliant
  ... (float64_t)(s32a > s32b) // Noncompliant
  ... (float64_t)s32a / (float32_t)s32b
  ... (uint32_t)(u16a + u16b) // Noncompliant
  ... (uint32_t)u16a + u16b
  ... (uint32_t)u16a + (uint32_t)u16b
  ... (int16_t)(s32a - 12345)
  ... (uint8_t)(u16a * u16b)
  ... (uint16_t)(u8a * u8b) // Noncompliant
  ... (int16_t)(s32a * s32b)
  ... (int32_t)(s16a * s16b) // Noncompliant
  ... (uint16_t)(f64a + f64b) // Noncompliant
  ... (float32_t)(u16a + u16b) // Noncompliant
  ... (float64_t)foo1(u16a + u16b)
  ... (int32_t)buf16a[u16a + u16b]

See

  • MISRA C:2004, 10.3 - The value of a complex expression of integer type may only be cast to a type that is narrower and of the same signedness as the underlying type of the expression.
  • MISRA C:2004, 10.4 - The value of a complex expression of floating type may only be cast to a narrower floating type.

See Also

  • MISRA C:2004, section 6.10
objc:S855

Conversion of a function pointer to a different type of pointer results in undefined behaviour. This means, for example, that a pointer to a function cannot be converted to a pointer to a different type of function.

Noncompliant Code Example

int f(int a)
{
  float (*p)(float) = (float (*)(float)) & f; // Noncompliant
}

See

  • MISRA C:2004, 11.1 - Conversions shall not be performed between a pointer to a function and any type other than an integral type.
  • MISRA C++:2008, 5-2-6 - A cast shall not convert a pointer to a function to any other pointer type, including a pointer to function type.
  • MISRA C:2012, 11.1 - Conversions shall not be performed between a pointer to a function and any other type
objc:S854

The type of an integer is dependent on a complex combination of factors including:

  • The magnitude of the constant;
  • The implemented sizes of the integer types;
  • The presence of any suffixes;
  • The number base in which the value is expressed (i.e. decimal, octal or hexadecimal).

For example, the value 0x8000 is of type unsigned int in a 16-bit environment, but of type (signed) int in a 32-bit environment.

Note:

  • Any value with a "U" suffix is of unsigned type;
  • An unsuffixed decimal value less than 2^31 is of signed type.

But:

  • An unsuffixed hexadecimal value greater than or equal to 2^15 may be of signed or unsigned type;
  • For C90, an unsuffixed decimal value greater than or equal to 2^31 may be of signed or unsigned type.

In C++, if an overload set includes candidates for an unsigned int and an int, then the overload that would be matched by 0x8000 is therefore dependent on the implemented integer size. Adding a "U" suffix to the value specifies that it is unsigned.

See

  • MISRA C:2004, 10.6 - A "U" suffix shall be applied to all constants of unsigned type.
  • MISRA C++:2008, 2-13-3 - A "U" suffix shall be applied to all octal or hexadecimal integer literals of unsigned type.
  • MISRA C:2012, 7.2 - A "u" or "U" suffix shall be applied to all integer constants that are represented in an unsigned type.
objc:S978

Defining or declaring identifiers with reserved names may lead to undefined behavior. Similarly, defining macros, variables or functions/methods with the same names as functions from the standard library is likely to lead to unexpected results.

Additionally, such identifiers have the potential to thoroughly confuse people who are unfamiliar with the code base, possibly leading them to introduce additional errors. Therefore reserved words and the names of standard library functions should not be used as identifiers.

This rule applies to:

  • defined
  • standard library function names
  • identifiers that begin with two underscores
  • identifiers that begin with an underscore, followed by an uppercase letter
  • identifiers in the global namespace that start with an underscore

Noncompliant Code Example

#ifndef _MY_FILE
#define _MY_FILE   // Noncompliant: starts with '_'

int free(void *pArg, int len) {  // Noncompliant: free is a standard function
  int __i; // Noncompliant: starts with "__"
  //...
}
#endif

Compliant Solution

#ifndef MY_FILE
#define MY_FILE

int clean(void *pArg, int len) {
  int i;
  //...
}
#endif

See

  • MISRA C:2004, 20.1 - Reserved identifiers, macros and functions in the standard library, shall not be defined redefined or undefined.
  • MISRA C++:2008, 17-0-1 - Reserved identifiers, macros and functions in the standard library shall not be defined, redefined, or undefined.
  • MISRA C:2012, 21.2 - A reserved identifier or macro name shall not be declared
  • CERT, DCL37-C. - Do not declare or define a reserved identifier
  • CERT, DCL51-CPP. - Do not declare or define a reserved identifier
objc:S856

Casting an object pointer can very easily lead to undefined behavior. Only a few cases are supported, for instance casting an object pointer to a large enough integral type (and back again), casting an object pointer to a pointer to void (and back again)... Using a pointer cast to access an object as if it was of another type than its real type is not supported in general.

This rule detect casts between object pointers and incompatible types.

Noncompliant Code Example

struct S1 *p1;
struct S2;
void f ()
{
  (float) p1; // Noncompliant, conversion to floating point type
  (int *) p1; // Noncompliant
  float f;
  int *i = (int *)&f; // Noncompliant, undefined behavior even if sizeof(int) == sizeof(float)
  (int) p1; // Compliant, but might be undefined behavior if 'int' is not large enough to hold the value of p1.
  (void *) p1; // Compliant, conversion to 'void *'
  (struct S2 *)p1; // Noncompliant, conversion to another type.
}

Exceptions

In C, it is allowed to cast an object pointer to a character pointer to access the byte representation of the object. This rule ignores this case.

Anything can be safely cast to void (since nothing can be done with a result of this cast), and doing so is a common pattern to silence compiler warnings about unused variables. This rule ignores such casts.

void f(int *p) {
  (void)p;
}

See

  • MISRA C:2004, 11.2 - Conversions shall not be performed between a pointer to object and any type other than an integral type, another pointer to object type or a pointer to void.
  • MISRA C:2012, 11.3 - A cast shall not be performed between a pointer to object type and a pointer to a different object type.
objc:S977

Preprocessing directives (lines that start with #) can be used to conditionally include or exclude code from compilation. Malformed preprocessing directives could lead to the exclusion or inclusion of more code than was intended. Therefore all preprocessing directives should be syntactically meaningful.

Noncompliant Code Example

#define AAA 2
...
int foo(void)
{
  int x = 0;
  ...

#ifndef AAA
  x = 1;
#else1  /* Noncompliant */
  x = AAA;
#endif

  ...
  return x;
}

Compliant Solution

#define AAA 2
...
int foo(void)
{
  int x = 0;
  ...

#ifndef AAA
  x = 1;
#else
  x = AAA;
#endif

  ...
  return x;
}

See

  • MISRA C:2004, 19.16 - Preprocessing directives shall be syntactically meaningful even when excluded by preprocessor.
  • MISRA C++:2008, 16-0-8 - If the # token appears as the first token on a line, then it shall be immediately followed by a preprocessing token.
  • MISRA C:2012, 20.13 - A line whose first token is # shall be a valid preprocessing directive
objc:GotoLabelInNestedBlock

Use of goto can lead to programs that are extremely difficult to comprehend and analyse, and possibly to unspecified behavior.

Unfortunately, removing goto from some code can lead to a rewritten version that is even more difficult to understand than the original. Therefore, limited use of goto is sometimes advised.

However, the use of goto to jump into or out of a sub-block of code, such as into the body of a for loop is never acceptable, because it is extremely difficult to understand and will likely yield results other than what is intended.

Noncompliant Code Example

void f1 (int a) {
  if (a <=0) {
    goto L2;  // Noncompliant; jumps into a different block
  }

  if (a == 0) {
  {
    goto L1; // Compliant
  }
  goto L2;  // Noncompliant; jumps into a block

L1:
  for (int i = 0; i < a; i++) {
  L2:
    //...  Should only have come here with a >=0. Loop is infinite if a < 0
  }
}

Compliant Solution

void f1 (int a) {
  if (a <=0) {
    // ...
  }

  if (a == 0) {
  {
    goto L1; // Compliant
  }

L1:
  for (int i = 0; i < a; i++) {
  L2:
    //...
  }
}

See

  • MISRA C++:2008, 6-6-1 - Any label referenced by a goto statement shall be declared in the same block, or in a block enclosing the goto statement
  • MISRA C:2012, 15.3 - Any label referenced by a goto statement shall be declared in the same block, or in a block enclosing the goto statement
objc:S946

If the address of an automatic object is assigned to another automatic object of larger scope, or to a static object, or returned from a function then the object containing the address may exist beyond the time when the original object ceases to exist (and its address becomes invalid).

Noncompliant Code Example

int* f(void) {
  int local_auto;
  return &local_auto; // Noncompliant, returning address of an object allocated on the stack.
}

See

  • MISRA C:2004, 17.6
  • MISRA C++:2008, 7-5-2
  • MISRA C:2012, 18.6
  • CERT, DCL30-C. - Declare objects with appropriate storage durations
objc:AssignmentInSubExpression

Assignments within sub-expressions are hard to spot and therefore make the code less readable. Ideally, sub-expressions should not have side-effects.

Noncompliant Code Example

if ((str = cont.substring(pos1, pos2)).isEmpty()) {  // Noncompliant
  //...

Compliant Solution

str = cont.substring(pos1, pos2);
if (str.isEmpty()) {
  //...

Exceptions

Assignments explicitly enclosed in parentheses are ignored.

while ((run = keepRunning())) {
  //...
}

See

  • MISRA C:2004, 13.1 - Assignment operators shall not be used in expressions that yield a Boolean value
  • MISRA C++:2008, 6-2-1 - Assignment operators shall not be used in sub-expressions
  • MISRA C:2012, 13.4 - The result of an assignment operator should not be used
  • MITRE, CWE-481 - Assigning instead of Comparing
  • CERT, EXP45-C. - Do not perform assignments in selection statements
  • CERT, EXP51-J. - Do not perform assignments in conditional expressions
objc:S1172

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

In case of Objective-C it is acceptable to have unused parameters if the method is supposed to be overridden.

Noncompliant Code Example

void doSomething(int a, int b) { // Noncompliant, "b" is unused
  compute(a);
}

Compliant Solution

void doSomething(int a) {
  compute(a);
}

See

  • MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions.
  • MISRA C:2012, 2.7 - There should be no unused parameters in functions
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
objc:S820

The C90 standard allows implicit typing of variables and functions, and some C compilers still support legacy code by allowing implicit typing. But it should not be used for new code because it might lead to confusion.

Noncompliant Code Example

extern x;
const x;
static fun(void);
typedef ( *pfi ) ( void );

Compliant Solution

extern int16_t x;
const int16_t x;
static int16_t fun(void);
typedef int16_t ( *pfi ) ( void );

See

  • MISRA C:2004, 8.2 - Whenever an object or function is declared or defined, its type shall be explicitly stated
  • MISRA C:2012, 8.1 - Types shall be explicitly specified
  • CERT, DCL31-C. - Declare identifiers before using them
objc:GlobalMainFunction

A global function named main is the entry point to the program, and is the only identifier which must be in the global namespace. The use of main for other functions may not meet developer expectations.

Noncompliant Code Example

int main() {       // Compliant
}

namespace {
  int main() {     // Noncompliant
  }
}
namespace NS {
  int main() {     // Noncompliant
  }
}

See

  • MISRA C++:2008, 7-3-2 - The identifier main shall not be used for a function other than global function main.
objc:S824

A function declared at block scope will refer to a member of the enclosing namespace, and so the declaration should be explicitly placed at the namespace level.

Additionally, where a declaration statement could either declare a function or an object, the compiler will choose to declare the function. To avoid potential developer confusion over the meaning of a declaration, functions should not be declared at block scope.

Noncompliant Code Example

class A {
};

void fun() {
  void nestedFun();  // Noncompliant; declares a function in block scope

  A a();      // Noncompliant; declares a function at block scope, not an object
}

See

  • MISRA C:2004, 8.6 - Functions shall be declared at file scope
  • MISRA C++:2008, 3-1-2 - Functions shall not be declared at block scope
objc:S943

While they are extraordinarily useful, pointers are not the most intuitive concept in the world. Pointers to pointers are even harder to understand and use correctly. And with each additional level of indirection, pointer variables become more difficult to use correctly. Therefore pointer declarators should be limited to no more than two levels of nesting.

Noncompliant Code Example

typedef int * INTPTR;
struct s {
 int ** s1;
 int *** s2; // Noncompliant
};

struct s ** ps1;
struct s *** ps2; // Noncompliant

int ** ( *pfunc1)();
int ** ( **pfunc2)();
int ** (***pfunc3)(); // Noncompliant
int *** ( **pfunc4)(); // Noncompliant

void function( int ** par1,
               int *** par2, // Noncompliant
               INTPTR * par3,
               int * par4[],
               int ** par5[]) // Noncompliant
{
  int ** ptr1;
  int *** ptr2; // Noncompliant
  INTPTR * ptr3;
  int * ptr4[ 10 ];
  int ** ptr5[ 10 ]; //Noncompliant
}

Compliant Solution

typedef int * INTPTR;
struct s {
 int ** s1;
 int ** s2;
};

struct s ** ps1;
struct s ** ps2;

int ** (*pfunc1)();
int ** (**pfunc2)();
int ** (**pfunc3)();
int ** (**pfunc4)();

void function( int ** par1,
               int ** par2,
               INTPTR * par3,
               int * par4[],
               int * par5[])
{
  int ** ptr1;
  int ** ptr2;
  INTPTR * ptr3;
  int * ptr4[ 10 ];
  int * ptr5[ 10 ];
}

See

  • MISRA C:2004, 17.5 - The declaration of objects should contain no more than 2 levels of pointer indirection
  • MISRA C++:2008, 5-0-19 - The declaration of objects shall contain no more than two levels of pointer indirection
  • MISRA C:2012, 18.5 - Declarations should contain no more than two levels of pointer nesting
objc:S1065

If a label is declared but not used in the program, it can be considered as dead code and should therefore be removed.

This will improve maintainability as developers will not wonder what this label is used for.

Noncompliant Code Example

void fun() {
  label: doSomething();
}

Compliant Solution

void fun() {
  doSomething();
}

See

  • MISRA C:2012, 2.6 - A function should not contain unused label declarations
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
objc:LiteralSuffix

Using upper case literal suffixes removes the potential ambiguity between "1" (digit 1) and "l" (letter el) for declaring literals.

Noncompliant Code Example

const int        a = 0u;      // Noncompliant
const int        b = 0l;      // Noncompliant
const int        c = 0Ul;     // Noncompliant
const int        d = 0x12bu;  // Noncompliant
const float      m = 1.2f;    // Noncompliant
const float      n = 1.2l;    // Noncompliant

Compliant Solution

const int        a = 0U;
const int        b = 0L;
const int        c = 0UL;
const int        d = 0x12bU;
const float      m = 1.2F;
const float      n = 1.2L;

See

  • MISRA C++:2008, 2-13-4 - Literal suffixes shall be upper case
  • MISRA C:2012, 7.3 - The lowercase character "l" shall not be used in a literal suffix
  • CERT DCL16-C. - Use "L," not "l," to indicate a long value
  • CERT, DCL50-J. - Use visually distinct identifiers
objc:PPDefineOrUndefFromBlock

While it is legal to place #define and #undef directives anywhere in a source file, placing them outside of the global namespace is misleading since their scope is not actually restricted. This may be inconsistent with developer expectations.

Noncompliant Code Example

namespace NS
{
  #ifndef MY_HDR
  #define MY_HDR    /* Noncompliant */
  #undef FOO        /* Noncompliant */
  #endif
}

Compliant Solution

#ifndef MY_HDR
#define MY_HDR
#undef FOO
#endif

See

  • MISRA C:2004, 19.5 - Macros shall not be #define'd or #undef'd within a block.
  • MISRA C++:2008, 16-0-2 - Macros shall only be #define'd or #undef'd in the global namespace.
objc:S2393

The identifiers bsearch and qsort shall not be used and no macro with one of these names shall be expanded.

These two functions take as arguments a caller-defined comparison function. If the comparison function does not behave consistently when comparing elements, or if it modifies any of the elements, the behavior is undefined.

Note: the unspecified behavior, which relates to the treatment of elements that compare as equal, can be avoided by ensuring that the comparison function never returns 0. When two elements are otherwise equal, the comparison function could return a value that indicates their relative order in the initial array.

Further, the implementation of qsort is likely to be recursive and will therefore place unknown demands on stack resources. This is of concern in embedded systems because the stack is likely to have a fixed, often small, size.

See

  • MISRA C:2012, 21.9 - The library functions bsearch and qsort of <stdlib.h> shall not be used.
objc:S950

A complete declaration of the structure or union shall be included within any translation unit that refers to that structure. See section 6.1.2.5 of ISO 9899:1990 [2] for a full description of incomplete types.

Noncompliant Code Example

struct tnode * pt; // tnode is incomplete

Compliant Solution

struct tnode * pt; // tnode is incomplete at this point
struct tnode
{
  int count;
  struct tnode * left;
  struct tnode * right;
}; // type tnode is now complete

See

  • MISRA C:2004, 18.1 - All structure and union types shall be complete at the end of a translation unit.
objc:S834

It is possible to declare an array without explicitly specifying its size, but using an explicit size declaration is clearer, and is therefore preferred.

Noncompliant Code Example

int arr1 [ ];  // Noncompliant; nothing specified
int arr2 [ ] = { [0] = 1, [12] = 36, [4] = 93 }; // Noncompliant; highest index determines size. May be difficult to spot
int pirate [ ] = { 2, 4, 8, 42, 501, 90210, 7, 1776 }; // Noncompliant; size is implicit, not explicit

Compliant Solution

int arr1 [10];
int arr2 [13] = { [0] = 1, [12] = 36, [4] = 93 };
int pirate [10] = { 2, 4, 8, 42, 501, 90210, 7, 1776 }; // Implicitly-assigned size was 8. Desired size was 10.

See

  • MISRA C:2004, 8.12 - When an array is declared with external linkage, its size shall be stated explicitly or defined implicitly by initialisation
  • MISRA C++:2008, 3-1-3 - When an array is declared, its size shall either be stated explicitly or defined implicitly by initialization
  • MISRA C:2012, 8.11 - When an array with external linkage is declared, its size should be explicitely specified
  • MISRA C:2012, 9.5 - Where designated initializers are used to initialize an array object the size of the array shall be specified explicitly
  • CERT, ARR02-C. - Explicitly specify array bounds, even if implicitly defined by an initializer
objc:S835

ISO/IEC 14882:2003 [1] requires initializer lists for arrays, structures and union types to be enclosed in a single pair of braces (though the behaviour if this is not done is undefined). The rule given here goes further in requiring the use of additional braces to indicate nested structures.

This forces the developer to explicitly consider and demonstrate the order in which elements of complex data types are initialized (e.g. multi-dimensional arrays).

The zero initialization of arrays or structures shall only be applied at the top level.

The non-zero initialization of arrays or structures requires an explicit initializer for each element.

A similar principle applies to structures, and nested combinations of structures, arrays and other types.

Note also that all the elements of arrays or structures can be initialized (to zero or NULL) by giving an explicit initializer for the first element only. If this method of initialization is chosen then the first element should be initialized to zero (or NULL), and nested braces need not be used.

Noncompliant Code Example

int a1[3][2] = { 1, 2, 3, 4, 5, 6 }; // Noncompliant
int a2[5] = { 1, 2, 3 }; // Noncompliant, partial initialization
int a3[2][2] = { { }, { 1, 2 } }; // Noncompliant, zero initialization at sub-level

Compliant Solution

int a1[3][2] = { { 1, 2 }, { 3, 4 }, { 5, 6 } }; // Compliant
int a2[5] = { 1, 2, 3, 0, 0 }; // Compliant, Non-zero initialization
int a2[5] = { 0 }; // Compliant, zero initialization
int a3[2][2] = { }; // Compliant, zero initialization

See

  • MISRA C:2004, 9.2 - Braces shall be used to indicate and match the structure in the non-zero initialization of arrays and structures.
  • MISRA C++:2008, 8-5-2 - Braces shall be used to indicate and match the structure in the nonzero initialization of arrays and structures.
  • MISRA C:2012, 9.2 - The initializer of an aggregate or union shall be enclosed in braces.
objc:S1036

Having a switch and its cases wholly encompassed by a control structure such as a try, @try, catch, @catch, or a loop is perfectly acceptable. (try and catch are used hereafter to refer to both variants.) It is also acceptable to have a goto and its target label wholly encompassed in a control structure.

What is not acceptable is using a goto or case to suddenly jump into the body of a try, catch, Objective-C @finally, or loop structure. Tangling labels or switch blocks with other control structures results in code that is difficult, if not impossible to understand. More importantly, when it compiles (some of these constructs won't compile under ISO-conformant compilers), it can lead to unexpected results. Therefore this usage should be strictly avoided.

This C++ code sample, which is also applicable to Objective-C if try and catch are converted to @try and @catch, demonstrates jumping into a switch and into a try and catch :

Noncompliant Code Example

void f ( int32_t i )
{
  if ( 10 == i )
  {
    goto Label_10; // Noncompliant; goto transfers control into try block
  }

  if ( 11 == i )
  {
    goto Label_11; // Noncompliant; goto transfers control into catch block
  }

  switch ( i )
  {
    case 1:
      try
      {
        Label_10:
        case 2:  // Noncompliant; switch transfers control into try block
          // Action
          break;
      }
      catch ( ... )
      {
        Label_11:
        case 3: // Noncompliant; switch transfers control into catch block
          // Action
          break;
      }
      break;
    default:
    {
      // Default Action
      break;
    }
  }
}

Compliant Solution

void f ( int32_t i )
{
  switch ( i )
  {
    case 1:
    case 2:
      // Action
      break;
    case 3:
      // Action
      break;
    case 10:

    default:
    {
      // Default Action
      break;
    }
  }

  try
  {
    if ( 2 == i || 10 == i)
    {
      // Action
    }
  }
  catch ( ... )
  {
    if (3 == i || 11 == i)
    {
      // Action
    }
  }
}

See

  • MISRA C++:2008, 15-0-3 - Control shall not be transferred into a try or catch block using goto or switch statement
  • CERT, MSC20-C. - Do not use a switch statement to transfer control into a complex block
objc:S2486

When exceptions occur, it is usually a bad idea to simply ignore them. Instead, it is better to handle them properly, or at least to log them.

Noncompliant Code Example

void save() {
  try {
    saveDocument();
  } catch (const std::exception& ex) {
  }
}

Compliant Solution

void save() {
  try {
    saveDocument();
  } catch (const std::exception& ex) {
    log << "Exception while saving the document: " << ex.what();
  }
}

See

objc:S1836

The restrict type qualifier is a guarantee by the programmer that there are no other pointers with access to the referenced object, and that the object does not overlap with any other object in memory. Its use may allow the compiler to generate more efficient byte code.

However, this is a tricky language feature to use correctly, and there is significant risk of unexpected program behavior if restrict is misused. Therefore, restrict should not be used.

Noncompliant Code Example

void user_copy (
  void * restrict p,  // Noncompliant parameter
  void * restrict q,  // Noncompliant parameter
  size_t n
) {
  // ...
}

See

  • MISRA C:2012, 8.14 - The restrict type qualifier shall not be used
  • CERT, EXP43-C. - Avoid undefined behavior when using restrict-qualified pointers
objc:DigraphUsage

The use of digraphs may not meet developer expectations.

The digraphs are:

  • <%
  • %>
  • <:
  • :>
  • %:
  • %:%:

Noncompliant Code Example

template <typename T>
class A
{
  public:
    template<int32_t i>
    void f2();
};

void f(A<int32_t> * a<:10:>)    /* Noncompliant - usage of '<:' instead of '[' and ':>' instead of ']' */
<%                              /* Noncompliant - usage of '<%' instead of '{' */
  a<:0:>->f2<20>();             /* Noncompliant - usage of '<:' and ':>' */
%>                              /* Noncompliant - usage of '%>' instead of '}' */

Compliant Solution

/* ... */

void f(A<int32_t> * a[10])      /* Compliant */
{                               /* Compliant */
  a[0]->f2<20>();               /* Compliant */
}                               /* Compliant */

See

  • MISRA C++:2008, 2-5-1 - Digraphs should not be used.
objc:S1831

Theoretically, the use of the static keyword on the size of an array parameter means you can assume that only arrays of at least that size will be passed as arguments to the function. I.e. a function parameter of int my_array[static 10] means that my_array will always be at least 10 elements long. If it is not, the behavior is undefined.

In practice, the use of static on the size of an array parameter means the compiler might issue a warning if a noncompliant array is passed to the function - a warning that might or might not be ignored. Therefore, in practice the use of static on an array parameter's size merely lends a false sense of security, and static should not be used in this context.

Note that for some compiler/processor combinations, more efficient code can be generated when static is used, but these combinations are limited, and the benefit does not outweigh the cost.

Noncompliant Code Example

int total (int size, int my_array[static 10]) {...}

Compliant Solution

int total (int size, int my_array[10]) {...}

See

  • MISRA C:2012, 17.6 - The declaration of an array parameter shall not contain the static keyword between the []
objc:PPIncludeTime

Includes time, strftime. This library is associated with clock times. Various aspects are implementation dependent or unspecified, such as the formats of times. If any of the facilities of time.h are used, then the exact implementation for the compiler being used must be determined, and a deviation raised.

Noncompliant Code Example

#include <time.h>  /* Noncompliant */

See

  • MISRA C:2004, 20.12 - The time handling functions of library <time.h> shall not be used.
  • MISRA C:2012, 21.10 - The Standard Library time and date functions shall not be used
objc:S925

Recursion is a powerful tool, but it can be tricky to get right. Getting it wrong can lead to stack overflow errors and cause system problems. Even when you do get it right, recursive code can be difficult to understand, perhaps leading to maintenance problems in the future. Therefore recursion should be avoided in general and used only with due deliberation and caution when it is strictly necessary.

This rule checks for direct recursion (when a function calls itself).

Noncompliant Code Example

int pow(int num, int exponent) {
  if (exponent > 1) {
    num = num * pow(num, exponent-1);  // Noncompliant; direct recursion
  }
  return num;
}

Compliant Solution

int pow(int num, int exponent) {
  int val = num;
  while (exponent > 0) {
    val *= num;
    --exponent;
  }
  return val;
}

See

  • MISRA C:2004, 16.2 - Functions shall not call themselves, either directly or indirectly.
  • MISRA C++:2008, 7-5-4 - Functions should not call themselves, either directly or indirectly.
  • MISRA C:2012, 17.2 - Functions shall not call themselves, either directly or indirectly
objc:CommentedCode

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
objc:S926

Naming the parameters in a function prototype helps identify how they'll be used by the function, thereby acting as a thin layer of documentation for the function.

Noncompliant Code Example

void divide (int, int);

Compliant Solution

void divide (int numerator, int denominator);

See

  • MISRA C:2004, 16.3 - Identifiers shall be given for all of the parameters in a function prototype declaration
  • MISRA C:2012, 8.2 - Function types shall be in prototype form with named parameters
objc:S929

There is a real, functional difference between a function with an empty parameter list and one with an explicitly void parameter list: It is possible to pass parameters to a function with an empty list; the compiler won't complain. That is not the case for a function with a void list. Thus, it is possible, and even easy to invoke empty-list functions incorrectly without knowing it, and thereby introduce the kind of subtle bug that can be very difficult to track down.

Noncompliant Code Example

void myfunc ();  // Noncompliant

//...

void otherFunc() {
  int a = 4;
  //...
  myfunc(a); // Compiler allows this
}

Compliant Solution

void myfunc ( void );

//...

void otherFunc() {
  int a = 4;
  //...
  myfunc(a); // Compiler error!
}

See

  • MISRA C:2004, 16.5 - Functions with no parameters shall be declared with parameter type void
  • CERT, DCL20-C. - Explicitly specify void when a function accepts no arguments
objc:S127

A for loop stop condition should test the loop counter against an invariant value (i.e. one that is true at both the beginning and ending of every loop iteration). Ideally, this means that the stop condition is set to a local variable just before the loop begins.

Stop conditions that are not invariant are slightly less efficient, as well as being difficult to understand and maintain, and likely lead to the introduction of errors in the future.

This rule tracks three types of non-invariant stop conditions:

  • When the loop counters are updated in the body of the for loop
  • When the stop condition depend upon a method call
  • When the stop condition depends on an object property, since such properties could change during the execution of the loop.

Noncompliant Code Example

for (int i = 0; i < 10; i++) {
  ...
  i = i - 1; // Noncompliant
  ...
}
for (int i = 0; i < getMaximumNumber(); i++) {
}

Compliant Solution

for (int i = 0; i < 10; i++) {
  ...
}
int stopCondition = getMaximumNumber();
for (int i = 0; i < stopCondition; i++) {
}

See

  • MISRA C:2004, 13.6 - Numeric variables being used within a for loop for iteration counting shall not be modified in the body of the loop.
  • MISRA C++:2008, 6-5-3 - The loop-counter shall not be modified within condition or statement.
objc:S802

Reusing a typedef name either as another typedef name or for any other purpose may lead to developer confusion.

The same typedef shall not be duplicated anywhere in the project, even if the declarations are identical.

Note that where the type definition is made in a header file, and that header file is included in multiple source files, this rule is not violated.

Noncompliant Code Example

{
  typedef unsigned char uint8_t;
}

{
  typedef unsigned char uint8_t; // Noncompliant, redefinition
}

{
  unsigned char uint8_t; // Noncompliant, reuse of uint8_t for another purpose
}

Compliant Solution

typedef unsigned char uint8_t;
{
}

{
}

{
  unsigned char myChar;
}

See

  • MISRA C:2004, 5.3 - A typedef name shall be a unique identifier.
  • MISRA C++:2008, 2-10-3 - A typedef name (including qualification, if any) shall be a unique identifier.
objc:S920

When there is only a single condition to test, you have the option of using either a switch statement or an if-else if-else statement. For a larger set of potential values, a switch can be easier to read, but when the condition being tested is essentially boolean, then an if/else statement should be used instead.

Noncompliant Code Example

_Bool b = p > 0;
switch (b) { // Noncompliant
...
}
switch (x == 0) { // Noncompliant
...
}

Compliant Solution

_Bool b = p > 0;
if (b) {
...
} else {
...
}
if (x == 0) {
...
} else {
...
}

See

  • MISRA C:2004, 15.4 - A switch expression shall not represent a value that is effectively Boolean
  • MISRA C++ 2008, 6-4-7 - The condition of a switch statement shall not have bool type
  • MISRA C:2012, 16.7 - A switch-expression shall not have essentially Boolean type
objc:FunctionEllipsis

Passing arguments via an ellipsis bypasses the type checking performed by the compiler. Additionally, passing an argument with non-POD class type leads to undefined behavior. Note that the rule specifies "defined" (and not "declared") so as to permit the use of existing library functions.

Noncompliant Code Example

void MyPrintf ( char_t * pFormat, ... )	// Noncompliant
{
  // ...
}

See

  • MISRA C:2004, 16.1 - Functions shall not be defined with a variable number of arguments.
  • MISRA C++:2008, 8-4-1 - Functions shall not be defined using the ellipsis notation.
  • CERT, DCL50-CPP. - Do not define a C-style variadic function
objc:S935

Every call to a function with a non-void return type is expected to return some value. Including a return path in a non-void function that does not explicitly return a value results in undefined behavior.

Conversely, every call to a function with a void return type is expected to not return any value. Returning a value from a void function probably indicates a programming error.

Noncompliant Code Example

int my_func (int a)
{
  if (a > 100)
  {
    return; // Noncompliant
  }

  if (a > 80)
  {
    throw new Exception(); // Compliant
  }

  // Noncompliant
}

Compliant Solution

int my_func (int a)
{
  if (a > 100)
  {
    return 12;
  }

  if (a > 80)
  {
    throw new Exception();
  }

  return a;
}

See

  • MISRA C:2004, 16.8 - All exit paths from a function with non-void return type shall have an explicit return statement with an expression
  • MISRA C++:2008, 8-4-3 - All exit paths from a function with non-void return type shall have an explicit return statement with an expression
  • MISRA C:2012, 17.4 - All exit paths from a function with non-void return type shall have an explicit return statement with an expression
  • MITRE, CWE-394 - Unexpected Status Code or Return Value
  • CERT, MSC37-C. - Ensure that control never reaches the end of a non-void function
  • CERT, MSC52-CPP. - Value-returning functions must return a value from all exit paths
  • CERT, MSC53-CPP. - Do not return from a function declared [[noreturn]]
objc:S936

Using a "bald" function name is likely a bug. Rather than testing the return value of a function with a void parameter list, it implicitly retrieves the address of that function in memory. If that's truly what's intended, then it should be made explicit with the use of the & (address-of) operator. If it's not, then a parameter list (even an empty one) should be added after the function name.

Noncompliant Code Example

int func(void) {
  // ...
}

void f2(int a, int b) {
  // ...
  if (func) {  // Noncompliant - tests that the memory address of func() is non-null
    //...
  }
  // ...
}

Compliant Solution

void f2(int a, int b) {
  // ...
  if (func()) {  // tests that the return value of func() > 0
    //...
  }
  // ...
}

Exceptions

Callback functions are a common occurrence and are usually not passed with a preceding &. There is however little ambiguity so this rule ignores function identifiers when used as a parameter of a function call.

void foo() {
  // ...
}

registerEvent(AnEvent, foo);

See

  • MISRA C:2004, 16.9 - A function identifier shall only be used with either a preceding &, or with a parenthesized parameter list, which may be empty.
  • MISRA C++:2008, 8-4-4 - A function identifier shall only be used to call the function or it shall be preceded by &.
objc:S814

The use of any type other than signed short, unsigned short, signed char, unsigned char, signed int, unsigned int or _Bool for a bit field is implementation-defined, and therefore not portable.

Noncompliant Code Example

int b:3; // Noncompliant - may have the range of values 0..7 or -4..3

Compliant Solution

unsigned int b:3;

See

  • MISRA C:2004, 6.4 - Bit fields shall only be defined to be of type unsigned int or signed int.
  • MISRA C++:2008, 9-6-2 - Bit-fields shall be either bool type or an explicitly unsigned or signed integral type.
  • MISRA C:2012, 6.1 - Bit-fields shall only be declared with an appropriate type
  • CERT, INT12-C. - Do not make assumptions about the type of a plain int bit-field when used in an expression
objc:S819

The use of prototypes enables the compiler to check the integrity of function definitions and calls. Without prototypes the compiler is not obliged to pick up certain errors in function calls (e.g. different number of arguments from the function body, mismatch in types of arguments between call and definition). Function interfaces have been shown to be a cause of considerable problems, and therefore this rule is considered very important.

The recommended method of implementing function prototypes for external functions is to declare the function (i.e. give the function prototype) in a header file, and then include the header file in all those code files that need the prototype (see MISRA C 2004, Rule 8.8).

Noncompliant Code Example

void example() {
  fun(); // Noncompliant
}

void fun() {
}

Compliant Solution

void fun();

void example() {
  fun();
}

void fun() {
}

See

  • MISRA C:2004, 8.1 - Functions shall have prototype declarations and the prototype shall be visible at both the function definition and call
  • MISRA C:2012, 17.3 - A function shall not be declared implicitly
  • CERT, DCL07-C. - Include the appropriate type information in function declarators
  • CERT, DCL31-C. - Declare identifiers before using them

See Also

  • MISRA C:2004, 8.8 - An external object or function shall be declared in one and only one file
objc:S930

This problem is completely avoided by the use of function prototypes. See MISRA C:2004 Rule 8.1. This rule is retained since compilers may not flag this constraint error.

See

  • MISRA C:2004, 16.6 - The number of arguments passed to a function shall match the number of parameters.
  • MITRE, CWE-628 - Function Call with Incorrectly Specified Arguments
  • CERT, DCL07-C. - Include the appropriate type information in function declarators
  • CERT, EXP37-C. - Call functions with the correct number and type of arguments
objc:S810

There are three distinct char types, (plain) char, signed char and unsigned char. signed char and unsigned char should only be used for numeric data, and plain char should only be used for character data. Since it is implementation-defined, the signedness of the plain char type should not be assumed.

Noncompliant Code Example

signed char a = 'a'; // Noncompliant, explicitly signed
unsigned char b = '\r'; // Noncompliant, explicitly unsigned
char c = 10; // Noncompliant

unsigned char d = c; // Noncompliant, d is explicitly signed while c is not
char e = a; // Noncompliant, a is explicitly signed while e is not

Compliant Solution

char a = 'a';
char b = '\r';
unsigned char c = 10;
signed char c = 10;

Exceptions

  • Since the integer value 0 is used as a sentinel for the end of a string, converting this value to char is ignored.

See

  • MISRA C:2004, 6.1 - The plain char type shall be used only for the storage and use of character values
  • MISRA C:2004, 6.2 - signed and unsigned char type shall be used only for the storage and use of number values
  • MISRA C++:2008, 5-0-11 - The plain char type shall only be used for the storage and use of character values
  • MISRA C++:2008, 5-0-12 - signed char and unsigned char type shall only be used for the storage and use of numeric values
  • CERT, INT07-C. - Use only explicitly signed or unsigned char type for numeric values
  • CERT, STR00-C. - Represent characters using an appropriate type
  • CERT, STR04-C. - Use plain char for characters in the basic character set
objc:S813

The basic numeric types char, int, short, long, float, double, and long double should not be used. Instead, specific-length typedefs should be. This rule helps to clarify the size of the storage, but does not guarantee portability because of the asymmetric behavior of integral promotion.

Note that it is still important to understand the integer size of the implementation, and developers should be aware of the actual implementation of the typedefs under these definitions.

Noncompliant Code Example

int function(unsigned short a) // Noncompliant
{
  // ...
}

Compliant Solution

#include <stdint.h>
int32_t function(uint16_t a) // Compliant
{
  // ...
}

See

  • MISRA C:2004, 6.3 - typedefs that indicate size and signedness should be used in place of the basic types
  • MISRA C++:2008, 3-9-2 - typedefs that indicate size and signedness should be used in place of the basic numerical types

See Also

  • MISRA C++ 2008 Section 6.5.0 on integral promotion
objc:EllipsisHandlerNotLast

The catch-all handler should come last in a chain of catch or @catch statements because it catches everything, and any more-specific catch/@catch that comes after it will never be used, even when the relevant condition occurs.

This C++ code sample also applies to Objective-C.

Noncompliant Code Example

void f1()
{
  try
  {
    // ...
  }
  catch (...)
  {
    // Handle all exception types
  }
  catch (int32_t i)  // Noncompliant - handler will never be called
  {
  }
}

Compliant Solution

void f1()
{
  try
  {
    // ...
  }
  catch (int32_t i)  // Compliant - int handler
  {
    // Handle int exceptions
  }
  catch (...)        // Compliant - catch-all handler
  {
    // Handle all other exception types
  }
}

See

  • MISRA C++:2008, 15-3-7 - Where multiple handlers are provided in a single try-catch statement or function-try-block, any ellipsis (catch-all) handler shall occur last.
objc:IdentifierLongerThan31

In addition to being difficult to use, too-long variable names can limit code portability. The ISO standard requires that variable, type, function and label names be no more than 31 characters long.

Note that 31 characters is an upper bound, rather than a length recommendation. Shorter names are better, as long as they're still communicative.

Noncompliant Code Example

int this_is_a_very_long_identifier_that_definitely_should_be_renamed = 0;

Compliant Solution

int reasonable_identifier = 0;

See

  • MISRA C:2004, 5.1 - Identifiers (internal and external) shall not rely on the significance of more than 31 character.
  • CERT, DCL23-C. - Guarantee that mutually visible identifiers are unique
objc:S905

Any statement (other than a null statement, which means a statement containing only a semicolon ;) which has no side effect and does not result in a change of control flow will normally indicate a programming error, and therefore should be refactored.

Noncompliant Code Example

int func(int a, int b) {
  int result = 0;
  a + b; // Noncompliant, no side effect.
  return result;
}

Compliant Solution

int func(int a, int b) {
  int result = a + b; // Compliant
  return result;
}

See

  • MITRE, CWE-482 - Comparing instead of Assigning
  • MISRA C:2004, 14.2 - All non-null statements shall either have at least one side-effect however executed, or cause control flow to change.
objc:S1301

switch statements are useful when there are many different cases depending on the value of the same expression.

For just one or two cases however, the code will be more readable with if statements.

Moreover, if statements are obviously more suitable when the condition of the switch is boolean.

Noncompliant Code Example

switch (variable) {
  case 0:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Compliant Solution

if (variable == 0) {
  doSomething();
} else {
  doSomethingElse();
}

See

  • MISRA C:2012, 16.6 - Every switch statement shall have at least two switch-clauses
objc:SideEffectInRightHandSideOfLogical

There are some situations in C++ where certain parts of expressions may not be evaluated. If these sub-expressions contain side effects then those side effects may or may not occur, depending on the values of other sub expressions. The operators which can lead to this problem are && and ||, where the evaluation of the right-hand operand is conditional on the value of the left-hand operand. The conditional evaluation of the right-hand operand of one of the logical operators can easily cause problems if the developer relies on a side effect occurring.

Operations that cause side effects are:

  • accessing a volatile object
  • modifying an object
  • modifying a file
  • calling a function that performs any operations that cause changes in the state of the execution environment of the calling function.

This rule raises an issue when there is assignment or the use of the increment/decrement operators in right-hand operands.

Noncompliant Code Example

if ( ishigh && ( x == i++ ) ) // Noncompliant
...
if ( ishigh && ( x ==  getX() ) ) // Only acceptable if getX() is known to have no side effects

The operations that cause side effects are accessing a volatile object, modifying an object, modifying a file, or calling a function

that does any of those operations, which cause changes in the state of the execution environment of the calling function.

For the time being, this rule only check that there is no assignment or no use of increment/decrement operators made in right hand operands.

See

  • MISRA C:2004, 12.4 - The right-hand operand of a logical && or || operator shall not contain side effects.
  • MISRA C++:2008, 5-14-1 - The right hand operand of a logical && or || operator shall not contain side effects.
  • MISRA C:2012, 13.5 - The right hand operand of a logical && or || operator shall not contain persistent side effects
  • CERT, EXP02-C. - Be aware of the short-circuit behavior of the logical AND and OR operators
objc:S121

While not technically incorrect, the omission of curly braces can be misleading, and may lead to the introduction of errors during maintenance.

Noncompliant Code Example

if (condition)  // Noncompliant
  executeSomething();

Compliant Solution

if (condition) {
  executeSomething();
}

See

  • MISRA C:2004, 14.8 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C:2004, 14.9 - An if (expression) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C++:2008, 6-3-1 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C++:2008, 6-4-1 - An if (condition) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C:2012, 15.6 - The body of an iteration-statement or a selection-statement shall be a compound-statement
  • CERT, EXP19-C. - Use braces for the body of an if, for, or while statement
  • CERT, EXP52-J. - Use braces for the body of an if, for, or while statement
objc:PPUndefUsage

#undef should not normally be needed. Its use can lead to confusion with respect to the existence or meaning of a macro when it is used in the code.

Noncompliant Code Example

#ifndef MY_HDR
#define MY_HDR
#endif
...
#undef MY_HDR    /* Noncompliant */

See

  • MISRA C:2004, 19.6 - #undef shall not be used.
  • MISRA C++:2008, 16-0-3 - #undef shall not be used.
  • MISRA C:2012, 20.5 - #undef should not be used
objc:SwitchLabelPlacement

A switch-label can be placed anywhere within the statements that form the body of a switch statement, potentially leading to unstructured code. To prevent this from happening, the scope of a case-label or default-label shall be the statement forming the body of a switch statement. All case-clauses and the default-clause shall be at the same scope.

Noncompliant Code Example

switch (x) {
  case 1: // Compliant
    if (foo) {
      case 2: // Noncompliant
        break;
      default: // Noncompliant
        break;
    }
    break;
  default: // Compliant
    break;
}

See

  • MISRA C 2004, 15.1 - A switch label shall only be used when the most closely-enclosing compound statement is the body of a switch statement.
  • MISRA C++ 2008, 6-4-4 - A switch-label shall only be used when the most closely-enclosing compound statement is the body of a switch statement.
  • MISRA C 2012, 16.2 - A switch label shall only be used when the most closely-enclsoing compound statement is the body of a switch statement
objc:EnumPartialInitialization

If an enumerator list is given with no explicit initialization of members, then C/C++ allocates a sequence of integers starting at zero for the first element and increasing by one for each subsequent element.

An explicit initialization of the first element, as permitted by this rule, forces the allocation of integers to start at the given value. When adopting this approach it is essential to ensure that the initialization value used is small enough that no subsequent value in the list will exceed the int storage used by enumeration constants.

Explicit initialization of all items in the list, which is also permissible, prevents the mixing of automatic and manual allocation, which is error prone.

However, it is then the responsibility of the developer to ensure that all values are in the required range, and that values are not unintentionally duplicated.

Noncompliant Code Example

enum color { red = 3, blue, green, yellow = 5 }; // Noncompliant; both green and yellow = 5

Compliant Solution

enum color { red = 3, blue = 4, green = 5, yellow = 5 }; // Compliant

See

  • MISRA C:2004, 9.3 - In an enumerator list, the "=" construct shall not be used to explicitly initialize members other than the first, unless all items are explicitly initialized.
  • MISRA C++:2008, 8-5-3 - In an enumerator list, the = construct shall not be used to explicitly initialize members other than the first, unless all items are explicitly initialized.
objc:S2193

When using a floating-point for loop counter, an accumulation of rounding errors may result in a mismatch between the expected and actual number of iterations.

Even if floating-point loop counters appears to behave correctly on one implementation, it may give a different number of iterations on another implementation.

Noncompliant Code Example

for (float counter = 0.0f; counter < 1.0f; counter += 0.001f) {
  ...
}

Compliant Solution

for (int counter = 0; counter < 1000; ++counter) {
  ...
}

See

  • MISRA C:2004, 13.4 - The controlling expression of a for statement shall not contain any objects of floating type.
  • MISRA C++:2008, 6-5-1 - A for loop shall contain a single loop-counter which shall not have floating type.
  • MISRA C:2012, 14.1 - A loop counter shall not have essentially floating type.
  • CERT, NUM09-J. - Do not use floating-point variables as loop counters
  • CERT, FLP30-C. - Do not use floating-point variables as loop counters
objc:SingleDeclarationPerStatement

Where multiple declarators appear in the same declaration the type of an identifier may not meet developer expectations.

Noncompliant Code Example

int i1; int j1; // Compliant, but not preferred
int i2, *j2; // Noncompliant
int *i3,
&j3 = i2; // Noncompliant

Compliant Solution

int i1;
int j1;
int i2;
int *j2;
int *i3;
int &j3 = i2;

See

  • MISRA C++:2008, 8-0-1 - An init-declarator-list or a member-declarator-list shall consist of a single init-declarator or member-declarator respectively
  • CERT, DCL52-J. - Do not declare more than one variable per declaration
  • CERT, DCL04-C. - Do not declare more than one variable per declaration
objc:S1763

Jump statements (return, break, continue, goto) and throw expressions move control flow out of the current code block. So any unlabelled statements that come after a jump are dead code.

Noncompliant Code Example

int fun(int a) {
  int i = 10;
  return i + a;       // Noncompliant
  i++;             // dead code
}

Compliant Solution

int fun(int a) {
  int i = 10;
  return i + a;
}

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code
  • MISRA C++:2008, 0-1-9 - There shall be no dead code
  • MISRA C:2012, 2.1 - A project shall not contain unreachable code
  • MISRA C:2012, 2.2 - There shall be no dead code
  • MITRE, CWE-561 - Dead Code
  • CERT, MSC56-J. - Detect and remove superfluous code and values
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
objc:PPStringifyAndPastingUsage

The evaluation order of both the # and ## preprocessor operators is unspecified. Compilers have been known to implement these operators inconsistently, therefore, to avoid these problems, do not use them.

Noncompliant Code Example

#define A(Y)   #Y    /* Noncompliant */
#define A(X,Y) X##Y  /* Noncompliant */

See

  • MISRA C:2004, 19.13 - The # and ## preprocessor operators should not be used.
  • MISRA C++:2008, 16-3-2 - The # and ## operators should not be used.
  • MISRA C:2012, 20.10 - The # and ## preprocessor operators should not be used
objc:S1761

The standard, predefined macros, such as __FILE__ and __LINE__, are primarily intended for use by the implementation, and changing them could result in undefined behavior.

This rule checks that the following predefined macros are not defined, undefined, or redefined: assert, errno, __FILE__, __LINE__, __TIME__, __DATE__, __TIMESTAMP__, __COUNTER__, __INCLUDE_LEVEL__, __BASE_FILE__, and _Pragma.

Noncompliant Code Example

#undef __LINE__

See

  • MISRA C:2004, 20.1 - Reserved identifiers, macros and functions in the standard library shall not be defined, redefined, or undefined
  • MISRA C++:2008, 17-0-1 - Reserved identifiers, macros and functions in the standard library shall not be defined, redefined, or undefined
  • MISRA C:2012, 21.1 - #define and #undef shall not be used on a reserved identifier or reserved macro name
objc:S3949

Numbers are infinite, but the types that hold them are not. Each numeric type has hard upper and lower bounds. Try to calculate or assign numbers beyond those bounds, and the result will be surprising:

- For unsigned types, it will be a value that has silently wrapped around from the expected positive value to another one, following the rules of modular arithmetic (if the maximum unsigned char is 255, adding 10 to an unsigned char equals to 250 will yield the value 4)

- For signed type, this is undefined behavior.

Noncompliant Code Example

void test(char c) {
  switch (c) {
    case 2000: // Noncompliant
      // ...
      break;
  }

  int a = 4608 * 1024 * 1024; // Noncompliant
}
objc:S1767

The size of integer required to hold a memory address is implementation-dependent. Therefore, casting a pointer (i.e. a memory address) to any integral data type may result in data loss because the integral type is too small to hold the full address value.

When treating a memory address as integer type is absolutely required, you should be sure to use a large enough type to hold all the data.

Noncompliant Code Example

int *p;
int addr = ( int ) &p;

See

  • MISRA C:2004, 11.3 - A cast should not be performed between a pointer type and an integral type.
  • MISRA C++:2008, 5-2-9 - A cast should not convert a pointer type to an integral type.
  • MISRA C:2012, 11.4 - A conversion should not be performed between a pointer to object and an integer type
  • CERT, INT36-C. - Converting a pointer to integer or integer to pointer
objc:PPIncludeStdio

This includes file and I/O functions fgetpos, fopen, ftell, gets, perror, remove, rename and ungetc.

Streams and file I/O have a large number of unspecified, undefined and implementation-defined behaviors associated with them. It is assumed within MISRA C that they will not normally be needed in production code in embedded systems.

If any of the features of stdio.h need to be used in production code, then the issues associated with the features need to be understood.

Noncompliant Code Example

#include <stdio.h> /* Noncompliant */

See

  • MISRA C:2004, 20.9 - The input/output library <stdio.h> shall not be used in production code.
  • MISRA C++:2008, 27-0-1 - The stream input/output library <cstdio> shall not be used.
  • MISRA C:2012, 21.6 - The Standard Library input/output functions shall not be used
objc:S1081

When using legacy C functions, it's up to the developer to make sure the size of the buffer to be written to is large enough to avoid buffer overflows. Buffer overflows can cause the program to crash at a minimum. At worst, a carefully crafted overflow can cause malicious code to be executed.

This rule reports use of the following insecure functions: strcpy(), strcat(), sprintf(), gets() and getpw().

In such cases, it's better to use an alternate, secure function which allows you to define the maximum number of characters to be written to the buffer:

  • strlcpy (BSD library) or strncpy
  • strlcat (BSD library) or strncat
  • snprintf
  • fgets
  • getpwuid

(Be aware that strncpy and strncat don't guarantee the string will be null-terminated.)

Noncompliant Code Example

sprintf(str, "%s", message);   // Noncompliant
strcpy(str, message); // Noncompliant

Compliant Solution

snprintf(str, sizeof(str), "%s", message);
strlcpy(str, message, sizeof(str));

strncpy(str, message, sizeof(str) -1); // Leave room for null
str[sizeof(str) - 1] = '\0'; // Make sure the string is null-terminated

See

objc:S1219

Even if it is legal, mixing case and non-case labels in the body of a switch statement is very confusing and can even be the result of a typing error.

Noncompliant Code Example

Case 1, the code is syntactically correct but the behavior is not the expected one

switch (day) {
  case MONDAY:
  case TUESDAY:
  WEDNESDAY:   // instead of "case WEDNESDAY"
    doSomething();
    break;
  ...
}

Case 2, the code is correct and behaves as expected but is hardly readable

switch (day) {
  case MONDAY:
    break;
  case TUESDAY:
    foo:for(int i = 0 ; i < X ; i++) {
         /* ... */
        break foo;  // this break statement doesn't relate to the nesting case TUESDAY
         /* ... */
    }
    break;
    /* ... */
}

Compliant Solution

Case 1

switch (day) {
  case MONDAY:
  case TUESDAY:
  case WEDNESDAY:
    doSomething();
    break;
  ...
}

Case 2

switch (day) {
  case MONDAY:
    break;
  case TUESDAY:
    compute(args); // put the content of the labelled "for" statement in a dedicated method
    break;

    /* ... */
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
objc:S793

The #pragma directive is implementation-defined, hence it is important both to demonstrate that all uses are correct, and to minimize, localize and encapsulate any use of pragmas within dedicated functions whenever possible.

The meaning of each pragma shall be documented.

There shall be sufficient supporting description to demonstrate that the behavior of the pragma and its implications for the application, have been fully understood.

This rule flags all instances of #pragma directives, and leaves it to the user to determine whether they have been properly documented.

See

  • MISRA C:2004, 3.4 - All uses of the #pragma directive shall be documented and explained
  • MISRA C++:2008, 16-6-1 - All uses of the #pragma directive shall be documented
  • CERT, MSC00-C - Compile cleanly at high warning levels
objc:S784

Ensuring that assembly language code is encapsulated and isolated aids portability. Where assembly language instructions are needed, they shall be encapsulated and isolated in either assembler functions or C++ functions.

Noncompliant Code Example

void fn ( void )
{
  DoSomething ( );
  asm ( "NOP" ); // Noncompliant, asm mixed with C/C++ statements
  DoSomething ( );
}

Compliant Solution

void Delay ( void )
{
  asm ( "NOP" ); // Compliant, asm not mixed with C/C++ statements
}

void fn ( void )
{
  DoSomething ( );
  Delay ( ); // Compliant, Assembler is encapsulated
  DoSomething ( );
}

See

  • MISRA C 2004, 2.1 - Assembly language shall be encapsulated and isolated.
  • MISRA C++ 2008, 7-4-3 - Assembly language shall be encapsulated and isolated.
objc:C99CommentUsage

This excludes the use of // C99 style comments and C++ style comments, since these are not permitted in C90. Many compilers support the // style of comments as an extension to C90. The use of // in preprocessor directives (e.g. #define) can vary. Also the mixing of /* ... */ and // is not consistent. This is more than a style issue, since different (pre C99) compilers may behave differently.

Noncompliant Code Example

int main(int argc, char* argv[])
{
  // Do nothing - Noncompliant
  return 0;
}

Compliant Solution

int main(int argc, char* argv[])
{
  /* Do nothing - Compliant */
  return 0;
}

See

  • MISRA C:2004, 2.2 - Source code shall only use /* ... */ style comments.
objc:S1103

Defining a nested single-line comment within a multi-line comment invites errors. It may lead a developer to wrongly think that the lines located after the single-line comment are not part of the comment.

If a comment starting sequence, /* or //, occurs within a /* comment, is it quite likely to be caused by a missing */ comment ending sequence.

If a comment starting sequence occurs within a // comment, it is probably because a region of code has been commented-out using //.

Noncompliant Code Example

/* some comment, end comment marker accidentally omitted
// Make sure this function is called in a thread safe context
Perform_Critical_Safety_Function(X);
...
/* this comment is non-compliant */

Exceptions

The sequence // is permitted within a // comment.

See

  • CERT, MSC04-C. - Use comments consistently and in a readable fashion
  • MISRA C:2004, 2.3 - The character sequence /* shall not be used within a comment.
  • MISRA C++:2008, 2-7-1 - The character sequence /* shall not be used within a C-style comment.
  • MISRA C:2012, 3.1 - The character sequences /* and // shall not be used within a comment
objc:S5266

In programming languages keywords have a special meaning and are reserved to the language. It is hence a bad idea to define macros with keywords as macro identifier as it can easily lead to undefined behavior:

  • The same object might be defined differently in different places, which violates the One Definition Rule
  • If you include any header from the standard library, it is undefined behavior to define such macros

Additionally, it is very awkward for anyone reading the code to have a keyword that means something different.

Noncompliant Code Example

#define int some_other_type // Noncompliant
#include <stdlib.h>;

See

* MISRA C:2012, 20.4 - A macro shall not be defined with the same name as a keyword

objc:PPBadIncludeForm

These are the only forms for the #include directive permitted by the standard. The behavior is undefined when other forms are used.

Noncompliant Code Example

#include filename.h        // Noncompliant

Compliant Solution

#include "filename.h"        // Compliant
#include <filename.h>

#define HEADER "filename.h"
#include HEADER

See

  • MISRA C:2004, 19.3 - The #include directive shall be followed by either a <filename> or "filename" sequence.
  • MISRA C++:2008, 16-2-6 - The #include directive shall be followed by either a <filename> or "filename" sequence.
  • MISRA C:2012, 20.3 - The #include directive shall be followed by either a <filename> or "filename" sequence
objc:S1226

While it is technically correct to assign to parameters from within function bodies, it is better to use temporary variables to store intermediate results.

Allowing parameters to be assigned to also reduces the code readability as developers will not be able to know whether the original parameter or some temporary variable is being accessed without going through the whole function.

Noncompliant Code Example

int glob = 0;
void function (int a) {
  a = glob; // Noncompliant
  ...
}

Compliant Solution

int glob = 0;
void function (int a) {
  int b = glob;
  ...
}

See

  • MISRA C:2012, 17.8 - A function parameter should not be modified
objc:Union

The use of unions to access an object in different ways may result in the data being misinterpreted. Therefore, this rule prohibits the use of unions for any purpose.

Noncompliant Code Example

union U1 { // Noncompliant
    float j;
    int i;
};

See

  • MISRA C:2004, 18.4 - Unions shall not be used.
  • MISRA C++:2008, 9-5-1 - Unions shall not be used.
  • MISRA C:2012, 19.2 - The union keyword should not be used
objc:ContinueUsage

continue is an unstructured control flow statement. It makes code less testable, less readable and less maintainable. Structured control flow statements such as if should be used instead.

Noncompliant Code Example

int i;
for (i = 0; i < 10; i++) {
  if (i == 5) {
    continue;  /* Noncompliant */
  }
  printf("i = %d\n", i);
}

Compliant Solution

int i;
for (i = 0; i < 10; i++) {
  if (i != 5) {
    printf("i = %d\n", i);
  }
}

See

  • MISRA C:2004, 14.5 - The continue statement shall not be used.
objc:PPIncludeNonStandardCharacters

If the ', \, " or /* characters are used between < and > delimiters or the ', \ or /* characters are used between the " delimiters in a header name preprocessing token, then the behavior is undefined.

Noncompliant Code Example

#include <"foo">     // Noncompliant
#include "dir\foo.h" // Noncompliant

See

  • MISRA C:2004, 19.2 - Non-standard characters should not occur in header file names in #include directives.
  • MISRA C++:2008, 16-2-4 - The ', ", /* or // characters shall not occur in a header file name.
  • MISRA C++:2008, 16-2-5 - The \ character should not occur in a header file name.
  • MISRA C:2012, 20.2 - The ', " or \ characters and the /* or // character sequences shall not occur in a header file name
objc:FunctionSinglePointOfExit

This is required by IEC 61508, under good programming style.

Noncompliant Code Example

int function1()
{
  return 3;
}

void function2()
{
  function1();
}

int function3(char* ptr) /* Noncompliant; two explicit returns */
{
  if (ptr == NULL) return -1;

  return 7;
}

void function4(char *ptr) /* Noncompliant; two returns, one explicit and one implicit */
{
  if (1) return;

  printf("hello world!\n");
}

See

  • MISRA C:2004, 14.7 - A function shall have a single point of exit at the end of the function.
  • MISRA C++:2008, 6-6-5 - A function shall have a single point of exit at the end of the function
  • MISRA C:2012, 15.5 - A function should have a single point of exit at the end
objc:SwitchWithoutDefault

The requirement for a final default clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken. When the switch covers all current values of an enum - and especially when it doesn't - a default case should still be used because there is no guarantee that the enum won't be extended.

Noncompliant Code Example

switch (param) { // Noncompliant - default clause is missing
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
}

Compliant Solution

switch (param) {
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
  default:
    doDefault();
    break;
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
  • MITRE, CWE-478 - Missing Default Case in Switch Statement
  • CERT, MSC01-C. - Strive for logical completeness

See also

objc:ElseIfWithoutElse

This rule applies whenever an if statement is followed by one or more else if statements; the final else if should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch statement.

Noncompliant Code Example

if (x == 0) {
  doSomething();
} else if (x == 1) {
  doSomethingElse();
}

Compliant Solution

if (x == 0) {
  doSomething();
} else if (x == 1) {
  doSomethingElse();
} else {
  error();
}

Exceptions

When all branches of an if-else if end with return, break or throw, the code that comes after the if implicitly behaves as if it was in an else clause. This rule will therefore ignore that case.

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
objc:PPIncludeNotAtTop

To aid code readability, all the #include directives in a particular code file should be grouped together near the top of the file. The only items which may precede an #include in a file are other preprocessor directives or comments.

Noncompliant Code Example

#include <h1.h> /* Compliant */
int32_t i;
#include <f2.h> /* Noncompliant */

Compliant Solution

#include <h1.h>
#include <f2.h>

int32_t i;

See

  • MISRA C:2004, 19.1 - #include statements in a file should only be preceded by other preprocessor directives or comments.
  • MISRA C++:2008, 16-0-1 - #include directives in a file shall only be preceded by other preprocessor directives or comments.
  • MISRA C:2012, 20.1 - #include directives should only be preceded by preprocessor directives or comments
objc:NonEmptyCaseWithoutBreak

When the execution is not explicitly terminated at the end of a switch case, it continues to execute the statements of the following case. While this is sometimes intentional, it often is a mistake which leads to unexpected behavior.

Noncompliant Code Example

switch (myVariable) {
  case 1:
    foo();
    break;
  case 2:  // Both 'doSomething()' and 'doSomethingElse()' will be executed. Is it on purpose ?
    doSomething();
  default:
    doSomethingElse();
    break;
}

Compliant Solution

switch (myVariable) {
  case 1:
    foo();
    break;
  case 2:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Exceptions

This rule is relaxed in the following cases:

switch (myVariable) {
  case 0:                                // Empty case used to specify the same behavior for a group of cases.
  case 1:
    doSomething();
    break;
  case 2:                                // Use of return statement
    return;
  case 3:                                // Use of throw statement
    throw 1;
  case 4:                                // Use of continue statement
    continue;
  default:                               // For the last case, use of break statement is optional
    doSomethingElse();
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.2 - An unconditional break statement shall terminate every non-empty switch clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-5 - An unconditional throw or break statement shall terminate every non-empty switch-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.3 - An unconditional break statement shall terminate every switch-clause
  • MITRE, CWE-484 - Omitted Break Statement in Switch
  • CERT, MSC17-C. - Finish every set of statements associated with a case label with a break statement
  • CERT, MSC52-J. - Finish every set of statements associated with a case label with a break statement
objc:S883

Where a data value is to be tested against zero then the test should be made explicit. The exception to this rule is when data represents a Boolean value, even though in C this will in practice be an integer.

This rule is in the interests of clarity, and makes clear the distinction between integers and logical values.

Noncompliant Code Example

if ( x ) // Noncompliant, unless x is effectively Boolean data

Compliant Solution

if ( x == 0) // Compliant solution

See

  • MISRA C:2004, 13.2 - Tests of a value against zero should be made explicit, unless the operand is effectively Boolean.
objc:BackJumpWithGoto

Unconstrained use of goto can lead to programs that are extremely difficult to comprehend and analyse. For C++, it can also lead to the program exhibiting unspecified behavior.

However, in many cases a total ban on goto requires the introduction of flags to ensure correct control flow, and it is possible that these flags may themselves be less transparent than the goto they replace.

Therefore, the restricted use of goto is allowed where that use will not lead to semantics contrary to developer expectations. "Back" jumps are prohibited, since they can be used to create iterations without using the well-defined iteration statements supplied by the core language.

Noncompliant Code Example

int f() {
  int j = 0;
L1:
  ++j;
  if (10 == j) {
    goto L2;         // forward jump ignored
  }
  // ...
  goto L1;           // Noncompliant
L2:
  return ++j;
}

Compliant Solution

int f() {
  for (int j = 0; j < 11; j++) {
    // ...
  }
  return ++j;
}

See

  • MISRA C++:2008, 6-6-2 - The goto statement shall jump to a label declared later in the same function body
  • MISRA C:2012, 15.2 - The goto statement shall jump to a label declared later in the same function
objc:S886

The for statement provides a general-purpose looping facility. Using a restricted form of loop makes code easier to review and to analyse.

The three clauses of a for statement are the:

  • First clause which should
    • be empty, or
    • assign a value to the loop counter, or
    • define and initialize the loop counter (C99).
  • Second clause which should
    • be an expression that has no persistent side effects, and
    • not use objects that are modified in the for loop body.
  • Third clause which should
    • be an expression whose only persistent side effect is to modify the value of the loop counter, and
    • not use objects that are modified in the for loop body.

Noncompliant Code Example

for( int i = 0 ; i++ < 10 ; i += 1 ) { // Noncompliant, loop counter is updated in the condition
}

for( int i = 0 ; ; ) { // Noncompliant, initialized variable i is not used in the condition
}

for( int i = 0 , j = 0 ; i < 10 ; i += j) { // Noncompliant, j is modified in the body
  j = i + 1;
}

See

  • MISRA C:2004, 13.5 - The three expressions of a for statement shall be concerned only with loop control.
  • MISRA C++:2008, 6-5-5 - A loop-control-variable other than the loop-counter shall not be modified within condition or expression.
  • MISRA C:2012, 14.2 - A for loop shall be well-formed
objc:IncAndDecMixedWithOtherOperators

The use of increment and decrement operators in method calls or in combination with other arithmetic operators is not recommended, because:

  • It can significantly impair the readability of the code.
  • It introduces additional side effects into a statement, with the potential for undefined behavior.
  • It is safer to use these operators in isolation from any other arithmetic operators.

Noncompliant Code Example

u8a = ++u8b + u8c--;
foo = bar++ / 4;

Compliant Solution

The following sequence is clearer and therefore safer:

++u8b;
u8a = u8b + u8c;
u8c--;
foo = bar / 4;
bar++;

See

  • MISRA C:2004, 12.1 - Limited dependence should be placed on the C operator precedence rules in expressions.
  • MISRA C:2004, 12.13 - The increment (++) and decrement (--) operators should not be mixed with other operators in an expression.
  • MISRA C++:2008, 5-2-10 - The increment (++) and decrement (--) operator should not be mixed with other operators in an expression.
  • MISRA C:2012, 12.1 - The precedence of operators within expressions should be made explicit
  • MISRA C:2012, 13.3 - A full expression containing an increment (++) or decrement (--) operator should have no other potential side effects other than that cause by the increment or decrement operator
  • CERT, EXP30-C. - Do not depend on the order of evaluation for side effects
  • CERT, EXP50-CPP. - Do not depend on the order of evaluation for side effects
  • CERT, EXP05-J. - Do not follow a write by a subsequent write or read of the same object within an expression
objc:S897

If a type is declared but not used, then it is unclear to a reviewer if the type is redundant or it has been left unused by mistake.

Noncompliant Code Example

void unusedtype()
{
  typedef int local_Type; // Noncompliant, unused
}

See

  • MISRA C++:2008, 0-1-5 - A project shall not contain unused type declarations.
php:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

Noncompliant Code Example

$uname = "steve";
$password = "blue";
connect($uname, $password);

Compliant Solution

$uname = getEncryptedUser();
$password = getEncryptedPass();
connect($uname, $password);

See

php:S4524

switch can contain a default clause for various reasons: to handle unexpected values, to show that all the cases were properly considered.

For readability purpose, to help a developer to quickly find the default behavior of a switch statement, it is recommended to put the default clause at the end of the switch statement. This rule raises an issue if the default clause is not the first or the last one of the switch's cases.

Noncompliant Code Example

switch ($param) {
  case 0:
    doSomething();
    break;
  default: // default clause should be the first or last one
    error();
    break;
  case 1:
    doSomethingElse();
    break;
}

Compliant Solution

switch ($param) {
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
  default:
    error();
    break;
}

See

  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
php:S112

If you throw a general exception type, such as ErrorException, RuntimeException, or Exception in a library or framework, it forces consumers to catch all exceptions, including unknown exceptions that they do not know how to handle.

Instead, either throw a subtype that already exists in the Standard PHP Library, or create your own type that derives from Exception.

Noncompliant Code Example

throw new Exception();  // Noncompliant

Compliant Solution

throw new InvalidArgumentException();
// or
throw new UnexpectedValueException();

See

php:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

public function setName($name) {
    $name = $name;
}

Compliant Solution

public function setName($name) {
    $this->name = $name;
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
php:S905

Any statement (other than a null statement, which means a statement containing only a semicolon ;) which has no side effect and does not result in a change of control flow will normally indicate a programming error, and therefore should be refactored.

Noncompliant Code Example

$a == 1; // Noncompliant; was assignment intended?
$a < $b; // Noncompliant; have we forgotten to assign the result to a variable?
{code}

See

php:S907

goto is an unstructured control flow statement. It makes code less readable and maintainable. Structured control flow statements such as if, for, while, continue or break should be used instead.

Noncompliant Code Example

$i = 0;
loop:
  echo("i = $i");
  $i++;
  if ($i < 10){
    goto loop;
  }

Compliant Solution

for ($i = 0; $i < 10; $i++){
  echo("i = $i");
}
php:S1301

switch statements are useful when there are many different cases depending on the value of the same expression.

For just one or two cases however, the code will be more readable with if statements.

Noncompliant Code Example

switch ($variable) {
  case 0:
    do_something();
    break;
  default:
    do_something_else();
    break;
}

Compliant Solution

if ($variable == 0) {
  do_something();
} else {
  do_something_else();
}
php:S1145

if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.

There are three possible causes for the presence of such code:

  • An if statement was changed during debugging and that debug code has been committed.
  • Some value was left unset.
  • Some logic is not doing what the programmer thought it did.

In any of these cases, unconditional if statements should be removed.

Noncompliant Code Example

if (true) {  // Noncompliant
  doSomething();
}
...
if (false) {  // Noncompliant
  doSomethingElse();
}

Compliant Solution

doSomething();

See

php:S121

While not technically incorrect, the omission of curly braces can be misleading, and may lead to the introduction of errors during maintenance.

Noncompliant Code Example

if (condition)  // Noncompliant
  executeSomething();

Compliant Solution

if (condition) {
  executeSomething();
}

See

  • CERT, EXP19-C. - Use braces for the body of an if, for, or while statement
  • CERT, EXP52-J. - Use braces for the body of an if, for, or while statement
php:S2077

Formatting strings used as SQL queries is security-sensitive. It has led in the past to the following vulnerabilities:

SQL queries often need to use a hardcoded SQL string with a dynamic parameter coming from a user request. Formatting a string to add those parameters to the request is a bad practice as it can result in an SQL injection. The safe way to add parameters to a SQL query is to use SQL binding mechanisms.

This rule flags the execution of SQL queries which are built using formatting of strings, even if there is no injection. This rule does not detect SQL injections. The goal is to guide security code reviews and to prevent a common bad practice.

The following functions are detected as SQL query execution:

  • mysql_query
  • mysql_db_query
  • mysql_unbuffered_query
  • pg_query
  • pg_send_query
  • mssql_query
  • mysqli_query and mysqli::query
  • mysqli_real_query and mysqli::real_query
  • mysqli_multi_query and mysqli::multi_query
  • mysqli_send_query and mysqli::send_query
  • PDO::query
  • PDO::exec
  • PDO::prepare

Ask Yourself Whether

  • the SQL query is built using string formatting technics, such as concatenating variables.
  • some of the values are coming from an untrusted source and are not sanitized.

You may be at risk if you answered yes to this question.

Recommended Secure Coding Practices

  • Avoid building queries manually using formatting technics. If you do it anyway, do not include user input in this building process.
  • Use parameterized queries, prepared statements, or stored procedures whenever possible.
  • PHP Data Objects (PDO) prepared statement with bound parameters should be preferred to native database functions.
  • Avoid executing SQL queries containing unsafe input in stored procedures or functions.
  • Sanitize every unsafe input.

You can also reduce the impact of an attack by using a database account with low privileges.

Sensitive Code Example

$id = $_GET['id'];
mysql_connect('localhost', $username, $password) or die('Could not connect: ' . mysql_error());
mysql_select_db('myDatabase') or die('Could not select database');

$result = mysql_query("SELECT * FROM myTable WHERE id = " . $id);  // Sensitive, could be susceptible to SQL injection

while ($row = mysql_fetch_object($result)) {
    echo $row->name;
}

Compliant Solution

$id = $_GET['id'];
try {
    $conn = new PDO('mysql:host=localhost;dbname=myDatabase', $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $conn->prepare('SELECT * FROM myTable WHERE id = :id');
    $stmt->execute(array('id' => $id));

    while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
        echo $row->name;
    }
} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}

Exceptions

No issue will be raised if one of the functions is called with hard-coded string (no concatenation) and this string does not contain a "$" sign.

$result = mysql_query("SELECT * FROM myTable WHERE id = 42") or die('Query failed: ' . mysql_error());  // Compliant

The current implementation does not follow variables. It will only detect SQL queries which are concatenated or contain a $ sign directly in the function call.

$query = "SELECT * FROM myTable WHERE id = " . $id;
$result = mysql_query($query);  // No issue will be raised even if it is Sensitive

See

php:S881

The use of increment and decrement operators in method calls or in combination with other arithmetic operators is not recommended, because:

  • It can significantly impair the readability of the code.
  • It introduces additional side effects into a statement, with the potential for undefined behavior.
  • It is safer to use these operators in isolation from any other arithmetic operators.

Noncompliant Code Example

$u8a = ++$u8b + $u8c--;
$foo = $bar++ / 4;

Compliant Solution

The following sequence is clearer and therefore safer:

++$u8b;
$u8a = $u8b + $u8c;
$u8c--;
$foo = $bar / 4;
$bar++;

See

  • CERT, EXP30-C. - Do not depend on the order of evaluation for side effects
  • CERT, EXP50-CPP. - Do not depend on the order of evaluation for side effects
  • CERT, EXP05-J. - Do not follow a write by a subsequent write or read of the same object within an expression
php:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

php:S2201

When the call to a function doesn't have any side effect, what is the point of making the call if the results are ignored? In such cases, either the function call is useless and should be dropped, or the source code doesn't behave as expected.

Noncompliant Code Example

strlen($name); // Noncompliant; "strlen" has no side effect

Compliant Solution

$length = strlen($name);

See

php:S2681

Curly braces can be omitted from a one-line block, such as with an if statement or for loop, but doing so can be misleading and induce bugs.

This rule raises an issue when the whitespacing of the lines after a one line block indicates an intent to include those lines in the block, but the omission of curly braces means the lines will be unconditionally executed once.

Noncompliant Code Example

if ($condition)
  firstActionInBlock();
  secondAction();  // Noncompliant; executed unconditionally
thirdAction();

if($condition) firstActionInBlock(); secondAction();  // Noncompliant; secondAction executed unconditionally

if($condition) firstActionInBlock();  // Noncompliant
  secondAction();  // Executed unconditionally

$str = null;
for ($i = 0; $i < count($array); $i++)
  $str = $array[$i];
  doTheThing($str);  // Noncompliant; executed only on last array element

Compliant Solution

if ($condition) {
  firstActionInBlock();
  secondAction();
}
thirdAction();

if($condition) { firstActionInBlock(); secondAction(); }

if($condition) {
  firstActionInBlock();
  secondAction();
}

$str = null;
for ($i = 0; $i < count($array); $i++) {
  $str = $array[$i];
  doTheThing($str);
}

See

php:S3011

Changing or bypassing accessibility is security-sensitive. For example, it has led in the past to the following vulnerability:

private methods were made private for a reason, and the same is true of every other visibility level. Altering or bypassing the accessibility of classes, methods, or fields violates the encapsulation principle and could introduce security holes.

This rule raises an issue when reflection is used to change the visibility of a class, method or field, and when it is used to directly update a field value.

Ask Yourself Whether

  • there is a good reason to override the existing accessibility level of the method/field. This is very rarely the case. Accessing hidden fields and methods will make your code unstable as they are not part of the public API and may change in future versions.
  • this method is called by untrusted code. *
  • it is possible to modify or bypass the accessibility of sensitive methods or fields using this code. *

* You are at risk if you answered yes to those questions.

Recommended Secure Coding Practices

Don't change or bypass the accessibility of any method or field if possible.

If untrusted code can execute this method, make sure that it cannot decide which method or field's accessibility can be modified or bypassed.

Questionable Code Example

class MyClass
{
    public static $publicstatic = 'Static';
    private static $privatestatic = 'private Static';
    private $private = 'Private';
    private const CONST_PRIVATE = 'Private CONST';
    public $myfield = 42;

    private function __construct() {}
    private function privateMethod() {}
    public function __set($property, $value)  {}
    public function __get($property) {}
}

$clazz = new ReflectionClass('MyClass');

$clazz->getstaticProperties(); // Questionable. This gives access to private static properties

$clazz->setStaticPropertyValue('publicstatic', '42'); // OK as there is no overloading to bypass and it respects access control.
$clazz->getStaticPropertyValue('publicstatic'); // OK as there is no overloading to bypass and it respects access control.

// The following calls can access private or protected constants.
$clazz->getConstant('CONST_PRIVATE'); // Questionable.
$clazz->getConstants(); // Questionable.
$clazz->getReflectionConstant('CONST_PRIVATE'); // Questionable.
$clazz->getReflectionConstants(); // Questionable.

$obj = $clazz->newInstanceWithoutConstructor(); // Questionable. Bypassing private constructor.

$constructor = $clazz->getConstructor();
$constructorClosure = $constructor->getClosure($obj); // Questionable. It is possible to call private methods with closures.
$constructor->setAccessible(true); // Questionable. Bypassing constructor accessibility.

$prop = new ReflectionProperty('MyClass', 'private');
$prop->setAccessible(true); // Questionable. Change accessibility of a property.
$prop->setValue($obj, "newValue"); // Questionable. Bypass of the __set method.
$prop->getValue($obj); // Questionable. Bypass of the __get method.

$prop2 = $clazz->getProperties()[2];
$prop2->setAccessible(true); // Questionable. Change accessibility of a property.
$prop2->setValue($obj, "newValue"); // Questionable. Bypass of the __set method.
$prop2->getValue($obj); // Questionable. Bypass of the __get method.

$meth = new ReflectionMethod('MyClass', 'privateMethod');
$clos = $meth->getClosure($obj); // Questionable. It is possible to call private methods with closures.
$meth->setAccessible(true); // Questionable. Change accessibility of a method.

$meth2 = $clazz->getMethods()[0];
$clos2 = $meth2->getClosure($obj); // Questionable. It is possible to call private methods with closures.
$meth2->setAccessible(true); // Questionable. Change accessibility of a method.

// Using a ReflectionObject instead of the class

$objr = new ReflectionObject($obj);
$objr->newInstanceWithoutConstructor(); // Questionable. Bypassing private constructor.

$objr->getStaticPropertyValue("publicstatic"); // OK as there is no overloading to bypass and it respects access control.
$objr->setStaticPropertyValue("publicstatic", "newValue"); // OK as there is no overloading to bypass and it respects access control.

$objr->getStaticProperties(); // Questionable. This gives access to private static properties

// The following calls can access private or protected constants.
$objr->getConstant('CONST_PRIVATE'); // Questionable.
$objr->getConstants(); // Questionable.
$objr->getReflectionConstant('CONST_PRIVATE'); // Questionable.
$objr->getReflectionConstants(); // Questionable.

$constructor = $objr->getConstructor();
$constructorClosure = $constructor->getClosure($obj); // Questionable. It is possible to call private methods with closures.
$constructor->setAccessible(true); // Questionable. Bypassing constructor accessibility.

$prop3 = $objr->getProperty('private');
$prop3->setAccessible(true); // Questionable. Change accessibility of a property.
$prop3->setValue($obj, "newValue"); // Questionable. Bypass of the __set method.
$prop3->getValue($obj); // Questionable. Bypass of the __get method.

$prop4 = $objr->getProperties()[2];
$prop4->setAccessible(true); // Questionable. Change accessibility of a property.
$prop4->setValue($obj, "newValue"); // Questionable. Bypass of the __set method.
$prop4->getValue($obj); // Questionable. Bypass of the __get method.

$meth3 = $objr->getMethod('privateMethod');
$clos3 = $meth3->getClosure($obj); // Questionable. It is possible to call private methods with closures.
$meth3->setAccessible(true); // Questionable. Change accessibility of a method.

$meth4 = $objr->getMethods()[0];
$clos4 = $meth4->getClosure($obj); // Questionable. It is possible to call private methods with closures.
$meth4->setAccessible(true); // Questionable. Change accessibility of a method.

See

php:S1075

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.

See

php:S1117

Overriding or shadowing a variable declared in an outer scope can strongly impact the readability, and therefore the maintainability, of a piece of code. Further, it could lead maintainers to introduce bugs because they think they're using one variable but are really using another.

Noncompliant Code Example

class Foo {
  public $myField;

  public function doSomething() {
    $myField = 0;
    ...
  }
}

See

php:S1116

Empty statements, i.e. ;, are usually introduced by mistake, for example because:

  • It was meant to be replaced by an actual statement, but this was forgotten.
  • There was a typo which lead the semicolon to be doubled, i.e. ;;.

Noncompliant Code Example

function doSomething() {
  ;                                              // Noncompliant - was used as a kind of TODO marker
}

function doSomethingElse($p) {
  echo $p;;                                      // Noncompliant - double ;
}

for ($i = 1; $i <= 10; doSomething($i), $i++);   // Noncompliant - Rarely, they are used on purpose as the body of a loop. It is a bad practice to have side-effects outside of the loop body

Compliant Solution

function doSomething() {}

function doSomethingElse($p) {
  echo $p;

  for ($i = 1; $i <= 10; $i++) {
    doSomething($i);
  }
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • CERT, MSC51-J. - Do not place a semicolon immediately following an if, for, or while condition
  • CERT, EXP15-C. - Do not place a semicolon on the same line as an if, for, or while statement
php:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Noncompliant Code Example

if ( $a == $a ) { // always true
  doZ();
}
if ( $a != $a ) { // always false
  doY();
}
if ( $a == $b && $a == $b ) { // if the first one is true, the second one is too
  doX();
}
if ( $a == $b || $a == $b ) { // if the first one is true, the second one is too
  doW();
}

$j = 5 / 5; //always 1
$k = 5 - 5; //always 0

Exceptions

Left-shifting 1 onto 1 is common in the construction of bit masks, and is ignored.

$i = 1 << 1; // Compliant
$j = $a << $a; // Noncompliant

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
php:S1763

Jump statements (return, break, continue, goto) and throw expressions move control flow out of the current code block. So any unlabelled statements that come after a jump are dead code.

Noncompliant Code Example

function fun($a) {
  $i = 10;
  return $i + $a;
  $i++;             // dead code
}

Compliant Solution

function fun($a) {
  $i = 10;
  return $i + $a;
}

See

php:S5328

Setting session IDs is security-sensitive. Dynamically setting session IDs with client-supplied data or insecure hashes may lead to session fixation attacks and may allow an attacker to hijack another user's session.

Ask Yourself Whether

  • the session ID is not unique
  • the session ID is set from an hidden field of a web form
  • the session ID is relying on a non secure cryptographically hash

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

  • Don't manually generate session IDs, use instead PHP's native functionality such as session_regenerate_id().
  • If you must generate your own IDs, use a cryptographically secure method, like bin2hex(random_bytes(16))

Sensitive Code Example

session_id(customHash($user));
// or
session_id($_POST["hidden_session_id"]);

Compliant Solution

session_regenerate_id();
// or
$sessionId = bin2hex(random_bytes(16));
session_id($sessionId);

See

php:S1121

Assignments within sub-expressions are hard to spot and therefore make the code less readable. Ideally, sub-expressions should not have side-effects.

Noncompliant Code Example

if ($val = value() && check()) { // Noncompliant
}

Compliant Solution

$val = value();
if ($val && check()) {
}

or

if ($val == value() && check()) { // Perhaps in fact the assignment operator was expected
}

Exceptions

Assignments in while statement conditions, and assignments enclosed in relational expressions are allowed.

while (($line = next_line()) != NULL) {...}

while ($line = next_line()) {...}

See

  • MISRA C:2004, 13.1 - Assignment operators shall not be used in expressions that yield a Boolean value
  • MISRA C++:2008, 6-2-1 - Assignment operators shall not be used in sub-expressions
  • MISRA C:2012, 13.4 - The result of an assignment operator should not be used
  • MITRE, CWE-481 - Assigning instead of Comparing
  • CERT, EXP45-C. - Do not perform assignments in selection statements
  • CERT, EXP51-J. - Do not perform assignments in conditional expressions
php:S1523

Executing code dynamically is security-sensitive. It has led in the past to the following vulnerabilities:

Some APIs enable the execution of dynamic code by providing it as strings at runtime. These APIs might be useful in some very specific meta-programming use-cases. However most of the time their use is frowned upon as they also increase the risk of Injected Code. Such attacks can either run on the server or in the client (exemple: XSS attack) and have a huge impact on an application's security.

This rule marks for review each occurrence of the eval function. This rule does not detect code injections. It only highlights the use of APIs which should be used sparingly and very carefully. The goal is to guide security code reviews.

Ask Yourself Whether

  • the executed code may come from an untrusted source and hasn't been sanitized.
  • you really need to run code dynamically.

You are at risk if you answered yes to the first question. You are increasing the security risks for no reason if you answered yes to the second question.

Recommended Secure Coding Practices

Regarding the execution of unknown code, the best solution is to not run code provided by an untrusted source. If you really need to do it, run the code in a sandboxed environment. Use jails, firewalls and whatever means your operating system and programming language provide (example: Security Managers in java, iframes and same-origin policy for javascript in a web browser).

Do not try to create a blacklist of dangerous code. It is impossible to cover all attacks that way.

Avoid using dynamic code APIs whenever possible. Hard-coded code is always safer.

Noncompliant Code Example

eval($code_to_be_dynamically_executed)

See

php:S1854

A dead store happens when a local variable is assigned a value that is not read by any subsequent instruction. Calculating or retrieving a value only to then overwrite it or throw it away, could indicate a serious error in the code. Even if it's not an error, it is at best a waste of resources. Therefore all calculated values should be used.

Noncompliant Code Example

$i = $a + $b; // Noncompliant; calculation result not used before value is overwritten
$i = compute();

Compliant Solution

$i = $a + $b;
$i += compute();

Exceptions

This rule ignores initializations to -1, 0, 1, null, true, false, "", [] and array().

See

php:S1172

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

Noncompliant Code Example

function doSomething($a, $b) { // "$a" is unused
  return compute($b);
}

Compliant Solution

function doSomething($b) {
  return compute($b);
}

Exceptions

Functions in classes that override a class or implement interfaces are ignored.

class C extends B {

  function doSomething($a, $b) {     // no issue reported on $b
    compute($a);
  }

}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
php:S1862

A switch and a chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

For a switch, if the first case ends with a break, the second case will never be executed, rendering it dead code. Worse there is the risk in this situation that future maintenance will be done on the dead case, rather than on the one that's actually used.

On the other hand, if the first case does not end with a break, both cases will be executed, but future maintainers may not notice that.

Noncompliant Code Example

if ($param == 1)
  openWindow();
else if ($param == 2)
  closeWindow();
else if ($param == 1)  // Noncompliant
  moveWindowToTheBackground();


switch($i) {
  case 1:
    //...
    break;
  case 3:
    //...
    break;
  case 1:  // Noncompliant
    //...
    break;
  default:
    // ...
    break;
}

Compliant Solution

if ($param == 1)
  openWindow();
else if ($param == 2)
  closeWindow();
else if ($param == 3)
  moveWindowToTheBackground();

switch($i) {
  case 1:
    //...
    break;
  case 3:
    //...
    break;
  default:
    // ...
    break;
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
php:S2036

Files that define symbols such as classes and variables may be included into many files. Simply performing that inclusion should have no effect on those files other than declaring new symbols. For instance, a file containing a class definition should not also contain side-effects such as print statements that will be evaluated automatically on inclusion. Logic should be segregated into symbol-only files and side-effect-only files. The type of operation which is not allowed in a symbol-definition file includes but is not limited to:

  • generating output
  • modifying ini settings
  • emitting errors or exceptions
  • modifying global or static variables
  • reading/writing files

Noncompliant Code Example

<?php

print "Include worked!";

class foo {
  // ...
}

Compliant Solution

<?php

class foo {

  public function log() {
    print "Include worked!";
  }

}

See

php:S2278

According to the US National Institute of Standards and Technology (NIST), the Data Encryption Standard (DES) is no longer considered secure:

Adopted in 1977 for federal agencies to use in protecting sensitive, unclassified information, the DES is being withdrawn because it no longer provides the security that is needed to protect federal government information.

Federal agencies are encouraged to use the Advanced Encryption Standard, a faster and stronger algorithm approved as FIPS 197 in 2001.

For similar reasons, RC2 should also be avoided.

Noncompliant Code Example

<?php
  $ciphertext = mcrypt_encrypt(MCRYPT_DES, $key, $plaintext, $mode); // Noncompliant
  // ...
  $ciphertext = mcrypt_encrypt(MCRYPT_DES_COMPAT, $key, $plaintext, $mode); // Noncompliant
  // ...
  $ciphertext = mcrypt_encrypt(MCRYPT_TRIPLEDES, $key, $plaintext, $mode); // Noncompliant
  // ...
  $ciphertext = mcrypt_encrypt(MCRYPT_3DES, $key, $plaintext, $mode); // Noncompliant

  $cipher = "des-ede3-cfb";  // Noncompliant
  $ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
?>

Compliant Solution

<?php
  $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);
?>

See

php:S836

When a variable is not initialized before its use, it's a sign that the developer made a mistake.

Noncompliant Code Example

function fun($condition) {
  $res = 1;
  if ($condition) {
    $res++;
  }
  return $result; // Noncompliant, "$result" instead of "$res"
}

Compliant Solution

function fun($condition) {
  $res = 1;
  if ($condition) {
    $res++;
  }
  return $res;
}

See

php:S1313

Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:

Today's services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery and deployment:

  • The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
  • It forces the same address to be used in every environment (dev, sys, qa, prod).

Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service at this address or spoof the IP address. Such an attack is always possible, but in the case of a hardcoded IP address the fix will be much slower, which will increase an attack's impact.

Recommended Secure Coding Practices

  • make the IP address configurable.

Noncompliant Code Example

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, '8.8.8.8', 23);  // Noncompliant

Exceptions

No issue is reported for the following cases because they are not considered sensitive:

  • Loopback addresses 127.0.0.0/8 in CIDR notation (from 127.0.0.0 to 127.255.255.255)
  • Broadcast address 255.255.255.255
  • Non routable address 0.0.0.0
  • Strings of the form 2.5.<number>.<number> as they often match Object Identifiers (OID).

See

php:S2245

Using pseudorandom number generators (PRNGs) is security-sensitive. For example, it has led in the past to the following vulnerabilities:

When software generates predictable values in a context requiring unpredictability, it may be possible for an attacker to guess the next value that will be generated, and use this guess to impersonate another user or access sensitive information.

As the rand() and mt_rand functions rely on a pseudorandom number generator, it should not be used for security-critical applications or for protecting sensitive data.

Ask Yourself Whether

  • the code using the generated value requires it to be unpredictable. It is the case for all encryption mechanisms or when a secret value, such as a password, is hashed.
  • the function you use generates a value which can be predicted (pseudo-random).
  • the generated value is used multiple times.
  • an attacker can access the generated value.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

  • Use functions which rely on a cryptographically strong random number generator such as random_int() or random_bytes() or openssl_random_pseudo_bytes()
  • When using openssl_random_pseudo_bytes(), provide and check the crypto_strong parameter
  • Use the generated random values only once.
  • You should not expose the generated random value. If you have to store it, make sure that the database or file is secure.

Questionable Code Example

$random = rand();
$random2 = mt_rand(0, 99);

Compliant Solution

$randomInt = random_int(0,99); // Compliant; generates a cryptographically secure random integer

See

php:S131

The requirement for a final case default clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken. Even when the switch covers all current values of an enum, a default case should still be used because there is no guarantee that the enum won't be extended.

Noncompliant Code Example

switch ($param) {  //missing default clause
  case 0:
    do_something();
    break;
  case 1:
    do_something_else();
    break;
}

Compliant Solution

switch ($param) {
  case 0:
    do_something();
    break;
  case 1:
    do_something_else();
    break;
  default:
    error();
    break;
}

See

php:S4784

Using regular expressions is security-sensitive. It has led in the past to the following vulnerabilities:

Evaluating regular expressions against input strings is potentially an extremely CPU-intensive task. Specially crafted regular expressions such as /(a+)+s/ will take several seconds to evaluate the input string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaabs. The problem is that with every additional a character added to the input, the time required to evaluate the regex doubles. However, the equivalent regular expression, a+s (without grouping) is efficiently evaluated in milliseconds and scales linearly with the input size.

Evaluating such regular expressions opens the door to Regular expression Denial of Service (ReDoS) attacks. In the context of a web application, attackers can force the web server to spend all of its resources evaluating regular expressions thereby making the service inaccessible to genuine users.

This rule flags any execution of a hardcoded regular expression which has at least 3 characters and contains at at least two instances of any of the following characters *+{.

Example: (a+)*

The following functions are detected as executing regular expressions:

Note that ereg* functions have been removed in PHP 7 and PHP 5 end of life date is the 1st of January 2019. Using PHP 5 is dangerous as there will be no security fix.

This rule's goal is to guide security code reviews.

Ask Yourself Whether

  • the executed regular expression is sensitive and a user can provide a string which will be analyzed by this regular expression.
  • your regular expression engine performance decrease with specially crafted inputs and regular expressions.

You may be at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Do not set the constant pcre.backtrack_limit to a high value as it will increase the resource consumption of PCRE functions.

Check the error codes of PCRE functions via preg_last_error.

Check whether your regular expression engine (the algorithm executing your regular expression) has any known vulnerabilities. Search for vulnerability reports mentioning the one engine you're are using. Do not run vulnerable regular expressions on user input.

Use if possible a library which is not vulnerable to Redos Attacks such as Google Re2.

Remember also that a ReDos attack is possible if a user-provided regular expression is executed. This rule won't detect this kind of injection.

Avoid executing a user input string as a regular expression or use at least preg_quote to escape regular expression characters.

Exceptions

An issue will be created for the functions mb_ereg_search_pos, mb_ereg_search_regs and mb_ereg_search if and only if at least the first argument, i.e. the $pattern, is provided.

The current implementation does not follow variables. It will only detect regular expressions hard-coded directly in the function call.

$pattern = "/(a+)+/";
$result = eregi($pattern, $input);  // No issue will be raised even if it is Sensitive

Some corner-case regular expressions will not raise an issue even though they might be vulnerable. For example: (a|aa)+, (a|a?)+.

It is a good idea to test your regular expression if it has the same pattern on both side of a "|".

See

php:S125

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

php:S127

A for loop stop condition should test the loop counter against an invariant value (i.e. one that is true at both the beginning and ending of every loop iteration). Ideally, this means that the stop condition is set to a local variable just before the loop begins.

Stop conditions that are not invariant are slightly less efficient, as well as being difficult to understand and maintain, and likely lead to the introduction of errors in the future.

This rule tracks three types of non-invariant stop conditions:

  • When the loop counters are updated in the body of the for loop
  • When the stop condition depend upon a method call
  • When the stop condition depends on an object property, since such properties could change during the execution of the loop.

Noncompliant Code Example

for ($i = 0; $i < 10; $i++) {
  echo $i;
  if(condition) {
    $i = 20;
  }
}

Compliant Solution

for ($i = 0; $i < 10; $i++) {
  echo $i;
}

php:S126

This rule applies whenever an if statement is followed by one or more else if statements; the final else if should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch statement.

Noncompliant Code Example

if (condition1) {
  do_something();
} else if (condition2) {
  do_something_else();
}

Compliant Solution

if (condition1) {
  do_something();
} else if (condition2) {
  do_something_else();
} else {
  throw new InvalidArgumentException('message');
}

Exceptions

When all branches of an if-else if end with return, break or throw, the code that comes after the if implicitly behaves as if it was in an else clause. This rule will therefore ignore that case.

See

php:S128

When the execution is not explicitly terminated at the end of a switch case, it continues to execute the statements of the following case. While this is sometimes intentional, it often is a mistake which leads to unexpected behavior.

Noncompliant Code Example

switch ($myVariable) {
  case 1:
    foo();
    break;
  case 2:  // Both 'doSomething()' and 'doSomethingElse()' will be executed. Is it on purpose ?
    do_something();
  default:
    do_something_else();
   break;
}

Compliant Solution

switch ($myVariable) {
  case 1:
    foo();
    break;
  case 2:
    do_something();
    break;
  default:
    do_something_else();
   break;
}

Exceptions

This rule is relaxed in following cases:

switch ($myVariable) {
  case 0:                  // Empty case used to specify the same behavior for a group of cases.
  case 1:
    do_something();
    break;
  case 2:                  // Use of continue statement
    continue;
  case 3:                  // Case includes a jump statement (exit, return, break &etc)
    exit(0);
  case 4:
    echo 'Second case, which falls through';
    // no break        <- comment is used when fall-through is intentional in a non-empty case body
  default:                 // For the last case, use of break statement is optional
    doSomethingElse();
}

See

  • MITRE, CWE-484 - Omitted Break Statement in Switch
  • CERT, MSC17-C. - Finish every set of statements associated with a case label with a break statement
  • CERT, MSC52-J. - Finish every set of statements associated with a case label with a break statement
php:S2255

Using cookies is security-sensitive. It has led in the past to the following vulnerabilities:

Attackers can use widely-available tools to read cookies, sensitive information written by the server will be exposed.

This rule flags code that writes cookies.

Ask Yourself Whether

  • sensitive information is stored inside the cookie.

You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

Cookies should only be used to manage the user session. The best practice is to keep all user-related information server-side and link them to the user session, never sending them to the client. In a very few corner cases, cookies can be used for non-sensitive information that need to live longer than the user session.

Do not try to encode sensitive information in a non human-readable format before writing them in a cookie. The encoding can be reverted and the original information will be exposed.

Using cookies only for session IDs doesn't make them secure. Follow OWASP best practices when you configure your cookies.

As a side note, every information read from a cookie should be Sanitized.

Sensitive Code Example

$value = "1234 1234 1234 1234";

// Review this cookie as it seems to send sensitive information (credit card number).
setcookie("CreditCardNumber", $value, $expire, $path, $domain, true, true); // Sensitive
setrawcookie("CreditCardNumber", $value, $expire, $path, $domain, true, true); // Sensitive

See

php:S4433

An un-authenticated LDAP connection can lead to transactions without access control. Authentication, and with it, access control, are the last line of defense against LDAP injections and should not be disabled.

This rule raises an issue when an anonymous LDAP connection is created.

Noncompliant Code Example

$ldapconn = ldap_connect("ldap.example.com");

if ($ldapconn) {
    $ldapbind = ldap_bind($ldapconn); // Noncompliant; anonymous authentication, no user/password provided
}

Compliant Solution

$ldaprdn  = 'uname';
$ldappass = 'password';

$ldapconn = ldap_connect("ldap.example.com");

if ($ldapconn) {
    $ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass); // Compliant
}

See

php:S2251

A for loop with a counter that moves in the wrong direction is not an infinite loop. Because of wraparound, the loop will eventually reach its stop condition, but in doing so, it will run many, many more times than anticipated, potentially causing unexpected behavior.

Noncompliant Code Example

for ($i = 0; $i < $length; $i--) { // Noncompliant
  //...
}

Compliant Solution

for ($i = 0; $i < $length; $i++) {
  //...
}

See

php:S2092

The "secure" attribute prevents cookies from being sent over plaintext connections such as HTTP, where they would be easily eavesdropped upon. Instead, cookies with the secure attribute are only sent over encrypted HTTPS connections.

Recommended Secure Coding Practices

  • set the last parameter of the setcookie function to "true"
  • set session.cookie_secure = 1 in the php.ini file

Noncompliant Code Example

; php.ini
session.cookie_secure = 0; Noncompliant

// in PHP code
session_set_cookie_params($lifetime, $path, $domain, false); // Noncompliant, the last parameter means that the session cookie should not be secure

setcookie($name, $value, $expire, $path, $domain, false); // Noncompliant, the last parameter means that the cookie should not be secure

See

c:S2589

If a boolean expression doesn't change the evaluation of the condition, then it is entirely unnecessary, and can be removed. If it is gratuitous because it does not match the programmer's intent, then it's a bug and the expression should be fixed.

Noncompliant Code Example

a = true;
if (a) { // Noncompliant
  doSomething();
}

if (b && a) { // Noncompliant; "a" is always "true"
  doSomething();
}

if (c || !a) { // Noncompliant; "!a" is always "false"
  doSomething();
}

Compliant Solution

a = true;
if (foo(a)) {
  doSomething();
}

if (b) {
  doSomething();
}

if (c) {
  doSomething();
}

See

  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
  • MITRE, CWE-571 - Expression is Always True
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-489 - Leftover Debug Code
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
c:S990

<stdlib.h>'s abort, exit, getenv, and system have undefined, and implementation-defined behaviors, and should therefore be used.

Noncompliant Code Example

#include <stdlib.h>

void f( ) {
  exit(0); // Noncompliant
}

See

  • MISRA C:2004, 20.11 - The library functions abort, exit, getenv and system from library <stdlib.h> shall not be used.
  • MISRA C++:2008, 18-0-3 - The library functions abort, exit, getenv and system from library <cstdlib> shall not be used.
  • MISRA C:2012, 21.8 - The library functions abort, exit, getenv and system of <stdlib.h> shall not be used
  • CERT, ENV33-C. - Do not call system()
  • CERT, ERR50-CPP. - Do not abruptly terminate the program
c:PPIncludeSignal

Signal handling contains implementation-defined and undefined behavior.

Noncompliant Code Example

#include <signal.h> /* Noncompliant */

See

  • MISRA C:2004, 20.8 - The signal handling facilities of <signal.h> shall not be used.
  • MISRA C:2012, 21.5 - The standard header file <signal.h> shall not be used
c:S2583

Conditional expressions which are always true or false can lead to dead code. Such code is always buggy and should never be used in production.

Noncompliant Code Example

a = false;
if (a) { // Noncompliant
  doSomething(); // never executed
}

if (!a || b) { // Noncompliant; "!a" is always "true", "b" is never evaluated
  doSomething();
} else {
  doSomethingElse(); // never executed
}

Exceptions

This rule will not raise an issue when the condition is an integer constant or a const variable of integer type.

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

See

  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
c:TrigraphUsage

Trigraphs are denoted by a sequence of 2 question marks followed by a specified third character (e.g. ??- represents a '~' (tilde) character and ??) represents a ']'). They can cause accidental confusion with other uses of two question marks.

Noncompliant Code Example

static const char str[] = "(Date should be in the form ??-??-??)"; // Noncompliant. Evaluates to "(Date should be in the form ~~]"

Compliant Solution

static const char str[] = "(Date should be in the form ?" "?-?" "?-?" ?)";  // adjacent string literals concatenated at compile time
static const char str2[] = "(Date should be in the form ?-?-?)"; // problem avoided by eliminating 2nd '?' in each sequence
static const char str3[] = "(Date should be in the form ? ?-? ?-? ?)"; // problem avoided by spacing '?'s out

See

  • MISRA C:2004, 4.2 - Trigraphs shall not be used
  • MISRA C++:2008, 2-3-1 - Trigraphs shall not be used
  • MISRA C:2012, 4.2 - Trigraphs shall not be used
  • CERT, PRE07-C. - Avoid using repeated question marks
c:S982

setjmp.h functions allow the normal function mechanisms to be bypassed and should be used only with extreme caution, if at all.

Calling setjmp saves the program environment into the buffer passed into the call. Later calling longjmp returns execution to the point at which setjmp was called and restores the context that was saved into the buffer. But the values of non-volatile local variables after longjmp are indeterminate. Additionally invoking longjmp from a nested signal handler is undefined, as is longjmping back to a method that has already completed execution.

This rule flags all instances of setjmp, _setjmp, longjmp, _longjmp, sigsetjmp, siglongjmp and <setjmp.h>.

Noncompliant Code Example

#include <setjmp.h>  // Noncompliant

jmp_buf buf;

int main(int argc, char* argv[]) {
  int i = setjmp(buf);  // Noncompliant
  if (i == 0) { // value of i was assigned after env was saved & will be indeterminate after longjmp();
    // normal execution
  } else {
    // recover
  }
}

//...

void fun() {
  //...
  longjmp(buf, 1);  // Noncompliant
}

Compliant Solution

int main(int argc, char* argv[]) {
  // normal execution
}

//...

void fun() {
  //...
}

See

  • MISRA C:2004, 20.7 - The setjmp macro and the longjmp function shall not be used.
  • MISRA C++:2008, 17-0-5 - The setjmp macro and the longjmp function shall not be used.
  • MISRA C:2012, 21.4 - The standard header file <setjmp.h> shall not be used
  • CERT, MSC22-C. - Use the setjmp(), longjmp() facility securely
  • CERT, ERR52-CPP. - Do not use setjmp() or longjmp()
c:S985

errno is a facility of C++ which should in theory be useful, but which in practice is poorly defined by ISO/IEC 14882:2003. A non-zero value may or may not indicate that a problem has occurred; therefore errno shall not be used.

Even for those functions for which the behaviour of errno is well defined, it is preferable to check the values of inputs before calling the function rather than relying on using errno to trap errors.

Noncompliant Code Example

#include <cstdlib>
#include <cerrno>

void f1 ( const char_t * str )
{
  errno = 0; // Noncompliant
  int32_t i = atoi ( str );
  if ( 0 != errno ) // Noncompliant
  {
    // handle error case???
  }
}

See

  • MISRA C:2004, 20.5 - The error indicator errno shall not be used.
  • MISRA C++:2008, 19-3-1 - The error indicator errno shall not be used.

See Also

  • ISO/IEC 14882:2003
c:S864

The rules of operator precedence are complicated and can lead to errors. For this reason, parentheses should be used for clarification in complex statements. However, this does not mean that parentheses should be gratuitously added around every operation.

Parentheses are not needed:

  • with a unary operator, except when ! is used as left operand in comparison expressions
  • when all the operators in an expression are the same
  • when only a single operator is involved
  • around the right-hand side of an assignment operator unless the right-hand side itself contains an assignment

Parentheses are needed:

  • in the condition of a ternary operator if it uses operators
  • when overloaded shift operator << or >> is used in an expression with comparison operators

Noncompliant Code Example

x = a + b;
x = a * -1;
x = a + b + c;
x = f ( a + b, c );

x = a == b ? a : a - b; // Noncompliant
x = a + b - c + d; // Noncompliant
x = a * 3 + c + d; // Noncompliant

if (a = f(b,c) == true) { ... } // Noncompliant; == evaluated first
x - b ? a : c; // Noncompliant; "-" evaluated first
s << 5 == 1; // Noncompliant; "<<" evaluated first

Compliant Solution

x = a + b;
x = a * -1;
x = a + b + c;
x = f ( a + b, c );

x = ( a == b ) ? a : ( a - b );
x = ( a + b ) - ( c + d );
x = ( a * 3 ) + c + d;

if ( (a = f(b,c)) == true) { ... }
(x - b) ? a : c; // Compliant
(s << 5) == 1; // Compliant

See

  • MISRA C:2004, 12.1 - Limited dependence should be placed on C's operator precedence rules in expressions
  • MISRA C:2004, 12.2 - The value of an expression shall be the same under any order of evaluation that the standard permits.
  • MISRA C:2004, 12.5 - The operands of a logical && or || shall be primary-expressions.
  • MISRA C++:2008, 5-0-1 - The value of an expression shall be the same under any order of evaluation that the standard permits.
  • MISRA C++:2008, 5-0-2 - Limited dependence should be placed on C++ operator precedence rules in expressions
  • MISRA C++:2008, 5-2-1 - Each operand of a logical && or || shall be a postfix-expression.
  • MISRA C:2012, 12.1 - The precedence of operators within expressions should be made explicit
  • CERT, EXP00-C. - Use parentheses for precedence of operation
  • CERT, EXP53-J. - Use parentheses for precedence of operation
  • MITRE, CWE-783 - Operator Precedence Logic Error
c:GotoUsage

goto is an unstructured control flow statement. It makes code less readable and maintainable. Structured control flow statements such as if, for, while, continue or break should be used instead.

Noncompliant Code Example

int i = 0;
loop:
  printf("i = %d\n", i);
  i++;
  if (i < 10){
    goto loop; // Noncompliant
  }

Compliant Solution

for (int i = 0; i < 10; i++) {
  printf("i = %d\n", i);
}

See

  • MISRA C:2004, 14.4 - The goto statement shall not be used.
  • MISRA C:2012, 15.1 - The goto statement should not be used
c:S984

The use of dynamic memory can lead to out-of-storage run-time failures, which are undesirable.

The built-in new and delete operators, other than the placement versions, use dynamic heap memory. The functions calloc, malloc, realloc and free also use dynamic heap memory.

There is a range of unspecified, undefined and implementation-defined behaviour associated with dynamic memory allocation, as well as a number of other potential pitfalls. Dynamic heap memory allocation may lead to memory leaks, data inconsistency, memory exhaustion, non-deterministic behaviour, etc.

Note that some implementations may use dynamic heap memory allocation to implement other functions (for example, functions in the library cstring). If this is the case, then these functions shall also be avoided.

Noncompliant Code Example

int *b;
void initialize()
{
  b = (int *b) alloc ( 1024 * sizeof ( int ) ); // Noncompliant, could lead to an out-of-storage run-time failure.
  if( b == 0 )
  {
    // handle case when dynamic allocation failed.
  }
}

Compliant Solution

int b[1024]; // Compliant solution.

See

  • MISRA C:2004, 20.4 - Dynamic heap memory allocation shall not be used.
  • MISRA C++ 2008, 18-4-1 - Dynamic heap memory allocation shall not be used.
  • MISRA C:2012, 21.3 The memory allocation and deallocation functions of <stdlib.h> shall not be used
c:S986

offsetof can lead to undefined behavior when the argument types are incompatible or when bit fields are used. Therefore offsetof should be avoided.

Noncompliant Code Example

#include <stddef.h>

struct A
{
  int32_t i;
};

void f1 ( )
{
  offsetof ( A, i ); // Noncompliant
}

See

  • MISRA C:2004, 20.6 - The macro offsetof, in library <stddef.h>, shall not be used.
  • MISRA C++ 2008, 18-2-1 - The macro offsetof, in library <stddef.h>, shall not be used.
c:S989

<stdlib.h>'s atof, atoi, and atol functions, which convert strings to numbers, have undefined behavior when the strings cannot be converted, and should therefore be avoided.

Noncompliant Code Example

int converter (const char * numstr) {
  return atoi(numstr); // Noncompliant
}

Compliant Solution

int converter (const char * numstr) {
  return strtol(numstr, NULL, 10);
}

See

  • MISRA C:2004, 20.10 - The library functions atof, atoi and atol from library <stdlib.h> shall not be used.
  • MISRA C++:2008, 18-0-2 - The library functions atof, atoi and atol from library <cstdlib> shall not be used.
  • MISRA C:2012, 21.7 - The atof, atoi, atol and atoll functions of <stdlib.h> shall not be used
  • CERT, ERR34-C. - Detect errors when converting a string to a number
c:S867

The use of operands with types other than bool with these operators is unlikely to be meaningful (or intended). This rule allows the detection of such uses, which often occur because the logical operators (&&, || and !) can be easily confused with the bitwise operators (&, | and ~).

Noncompliant Code Example

if ( 1 && ( c < d ) ) // Noncompliant
if ( ( a < b ) && ( c + d ) ) // Noncompliant
if ( u8_a && ( c + d ) ) // Noncompliant
if ( !0 ) // Noncompliant, always true
if ( !ptr ) // Noncompliant
if ( ( a < b ) && ( c < d ) ) // Compliant
if ( !false ) // Compliant

Compliant Solution

if ( 1 != 0 && ( c < d ) ) // Compliant, but left operand is always true
if ( ( a < b ) && ( c + d ) != 0 ) // Compliant
if ( u8_a != 0 && ( c + d ) != 0) // Compliant
if ( 0 == 0 ) // Compliant, always true
if ( ptr != NULL ) // Compliant

See

  • MISRA C:2004, 12.6 - The operands of logical operators (&&, || and !) should be effectively Boolean. Expressions that are effectively Boolean should not be used as operands to operators other than (&&, || and !).
  • MISRA C++:2008, 5-3-1 - Each operand of the ! operator, the logical && or the logical || operators shall have type bool.
  • CERT, EXP54-J. - Understand the differences between bitwise and logical operators
c:SingleGotoOrBreakPerIteration

Restricting the number of exits from a loop is done in the interests of good structured programming. One break or goto statement is acceptable in a loop since this allows, for example, for dual-outcome loops or optimal coding.

Noncompliant Code Example

With the default threshold of 1:

for (int i = 0; i < 10; i++) {
  if (...) {
    break;      //  Compliant
  }
  else if (...) {
    break;      //  Non-compliant - second jump from loop
  }
  else {
    ...
  }
}
while (...) {
  if (...) {
    break;      // Compliant
  }
  if (...) {
    break;      // Non-compliant - second jump from loop
  }
}

Compliant Solution

for (int i = 0; i < 10; i++) {
  if (...) {
    break;      //  Compliant
  }
}
while (...) {
  if (...) {
    break;    // Compliant
  }
}

See

  • MISRA C:2004, 14.6 - For any iteration statement there shall be at most one break statement used for loop termination.
  • MISRA C++:2008, 6-6-4 - For any iteration statement there shall be no more than one break or goto statement used for loop termination.
  • MISRA C:2012, 15.4 - There should be no more than one break or goto statement used to terminate any iteration statement
c:S1144

private methods that are never executed are dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.

Noncompliant Code Example

static void unusedStaticFunction() { // Noncompliant
}

class Server {
public:
  void start() { // Compliant, the member function "start()" is public
    log("start");
  }
private:
  void clear() { // Noncompliant, the member function "clear()" is unused
  }
  void log(const char * msg) { // Compliant, the member function "log()" is used in "start() { ... }"
    printf(msg);
  }
};

See

* MISRA C++:2008, 0-1-10 - Every defined function shall be called at least once.

c:NarrowAndWideStringConcat

Concatenation of wide and narrow string literals leads to undefined behavior.

Noncompliant Code Example

wchar_t n_array[] = "Hello" L"World";     // Noncompliant
wchar_t w_array[] = L"Hello" "World";     // Noncompliant

Compliant Solution

char_t n_array[] = "Hello" "World";     // Compliant
wchar_t w_array[] = L"Hello" L"World";	// Compliant

See

  • MISRA C++:2008, 2-13-5 - Narrow and wide string literals shall not be concatenated.
  • CERT STR10-C. - Do not concatenate different type of string literals
c:S872

The use of bool operands with other operators is unlikely to be meaningful (or intended). Best case it will be confusing to maintainers, worst case it will not have the intended effect. Either way, it is highly recommended to stick to boolean operators when dealing with bool operands.

This rule allows the detection of such uses, which often occur because the logical operators (&&, || and !) can be easily confused with the bitwise operators (&, | and ~).

Noncompliant Code Example

bool b1 = true;
bool b2 = false;
int8_t s8a;
if ( b1 & b2 ) // Noncompliant
if ( ~b1 ) // Noncompliant
if ( b1 < b2 ) // Noncompliant
if ( b1 ^ b2 ) // Noncompliant

Compliant Solution

if ( b1 && b2 )
if ( !b1 )
if ( b1 == false )
if ( b1 == b2 )
if ( b1 != b2 )
s8a = b1 ? 3 : 7;

Exceptions

Operators |= and &= are ignored when used with bool operands. Operator ++ is also ignored with a bool operand because it is covered by rule S2668.

void test(bool b1, bool b2, int i1) {
  b1 |= b2; // ignored
  b1++; // ignored here, handled by S2668
  b1 &= b2; // ignored
  b1 &= i1; // Noncompliant; right operand is not a bool
}

See

  • MISRA C++:2008, 4-5-1 - Expressions with type bool shall not be used as operands to built-in operators other than the assignment operator =, the logical operators &&, ||, !, the equality operators == and !=, the unary & operator, and the conditional operator.
c:S873

Enumerations have implementation-defined representation and so should not be used in arithmetic contexts.

Noncompliant Code Example

enum { COLOUR_0, COLOUR_1, COLOUR_2, COLOUR_COUNT } colour;
if ( COLOUR_0 == colour ) { ... }
if ( ( COLOUR_0 + COLOUR_1 ) == colour ) { ... } // Noncompliant, arithmetic used
if ( colour < COLOUR_COUNT ) { ... }

See

  • MISRA C++:2008, 4-5-2 - Expressions with type enum shall not be used as operands to builtin operators other than the subscript operator [ ], the assignment operator =, the equality operators == and !=, the unary & operator, and the relational operators <, <=, >, >=
c:S874

Most bitwise operators (~, >>, >>=, &, &=, ^, ^=, |, and |=) have implementation-dependent results when performed on signed operands, and bitwise left shift (<< and <<=) has undefined behavior when performed on negative operands. Therefore bitwise operations should not be performed on signed operands.

Noncompliant Code Example

if ( ( uint16_a & int16_b ) == 0x1234U )
if ( ~int16_a == 0x1234U )

Compliant Solution

if ( ( uint16_a | uint16_b ) == 0x1234U )
if ( ~uint16_a == 0x1234U )

Exceptions

When used as bit flags, it is acceptable to use preprocessor macros as arguments to the & and | operators even if the value is not explicitly declared as unsigned.

fd = open(file_name, UO_WRONLY | UO_CREAT | UO_EXCL | UO_TRUNC, 0600);

If the right-side operand to a shift operator is known at compile time, it is acceptable for the value to be represented with a signed type provided it is positive.

#define SHIFT 24
foo = 15u >> SHIFT;

See

  • MISRA C:2004, 12.7 - Bitwise operators shall not be applied to operands whose underlying type is signed
  • MISRA C++:2008, 5-0-21 - Bitwise operators shall only be applied to operands of unsigned underlying type
  • MISRA C:2012, 10.1 - Operands shall not be of an inappropriate essential type
  • CERT, INT13-C. - Use bitwise operators only on unsigned operands
  • MITRE, CWE-682 - Incorrect Calculation
c:S995

This rule leads to greater precision in the definition of the function interface. The const qualification shall be applied to the object pointed to, not to the pointer, since it is the object itself that is being protected.

Noncompliant Code Example

void myfunc (      int * param1,  // object is modified
             const int * param2,
                   int * param3, // Noncompliant
                   int * param4) // Noncompliant
{
  *param1 = *param2 + *param3 + *param4;
}

int main (int argc,
          const char * * argv) // Noncompliant
{
  return argc;
}

Compliant Solution

void myfunc (      int * param1,  // object is modified
             const int * param2,
             const int * param3,
             const int * param4)
{
  *param1 = *param2 + *param3 + *param4;
}

int main (int argc,
          const char * const * argv)
{
  return argc;
}

See

  • MISRA C:2004, 16.7 - A pointer parameter in a function prototype should be declared as pointer to const if the pointer is not used to modify the addressed object.
  • MISRA C++:2008, 7-1-2 - A pointer or reference parameter in a function shall be declared as pointer to const or reference to const if the corresponding object is not modified.
  • MISRA C:2012, 8.13 - A pointer should point to a const-qualified type whenever possible
c:S876

Applying the unary minus operator to an unsigned variable or expression will always yield another unsigned expression. More plainly, in some cases the operation itself is meaningless, and in some other cases the result will be unexpected. In all cases it is bad practice. Therefore the unary minus operator should not be applied to unsigned variables or expressions.

Noncompliant Code Example

uint8_t a = -1U;
int32_t b = -a; // Noncompliant; b is assigned -255
uint32_t c = 1U;
int64_t d = -c; // Noncompliant; d is assigned MAX_UINT

Exceptions

This rule ignores -1U because it is commonly used as shorthand for MAX_UINT.

See

  • MISRA C:2004, 12.9 - The unary minus operator shall not be applied to an expression whose underlying type is unsigned.
  • MISRA C++:2008, 5-3-2 - The unary minus operator shall not be applied to an expression whose underlying type is unsigned.
  • MISRA C:2012, 10.1 - Operands shall not be of an inappropriate essential type
c:S878

The comma operator takes two expressions, executes them from left to right and returns the result of the second one. Use of this operator is generally detrimental to the readability and reliability of code, and the same effect can be achieved by other means.

Noncompliant Code Example

i = a += 2, a + b;  // What's the value of i ?

Compliant Solution

a +=  2;
i = a + b;

Exceptions

Use of comma operator is tolerated in initialization and increment expressions of for loops.

for(i = 0, j = 5; i < 6; i++, j++) { ... }

See

  • MISRA C:2004, 12.10 - The comma operator shall not be used.
  • MISRA C++:2008, 5-18-1 - The comma operator shall not be used.
  • MISRA C:2012, 12.3 - The comma operator should not be used
c:S2324

Flexible array members are most likely to be used in conjunction with dynamic memory allocation.

The presence of flexible array members modifies the behaviour of the sizeof operator in ways that might not be expected by a programmer. The assignment of a structure that contains a flexible array member to another structure of the same type may not behave in the expected manner as it copies only those elements up to but not including the start of the flexible array member.

Noncompliant Code Example

#include <stdlib.h>
struct s
{
  uint16_t len;
  uint32_t data[ ]; // Noncompliant - flexible array member
} str;

struct s *copy ( struct s *s1 )
{
  struct s *s2 = malloc ( sizeof ( struct s ) + ( s1->len * sizeof ( uint32_t ) ) );
  /* Omit malloc ( ) return check for brevity */
  *s2 = *s1; /* Only copies s1->len */
  return s2;
}

See

  • MISRA C:2012, 18.7 - Flexible array members shall not be declared.
c:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

c:S2323

Line-splicing occurs when the \ character is immediately followed by a new-line character. If the source line containing a // comment ends with a '\', the next line becomes part of the comment. This may result in unintentional removal of code.

Noncompliant Code Example

void f ( void )
{
  int x = 0; // comment \
  if (x)
  {
    ++x; /* This is always executed */
  }
}

See

  • MISRA C:2012, 3.2 - Line-splicing shall not be used in // comments
c:S1116

Empty statements, i.e. ;, are usually introduced by mistake, for example because:

  • It was meant to be replaced by an actual statement, but this was forgotten.
  • There was a typo which lead the semicolon to be doubled, i.e. ;;.

Noncompliant Code Example

void doSomething() {
  ;                                                       // Noncompliant - was used as a kind of TODO marker
}

Compliant Solution

void doSomething() {
}

Exceptions

In the case of empty expanded macro and in the case of 2 consecutive semi-colons when one of the two is part of a macro-definition then the issue is not raised.

Example:

#define A(x) x;
#define LOG(x)

void fun() {
  A(5);
  LOG(X);
}

See

  • MISRA C:2004, 14.3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment provided that the first character following the null statement is a white-space character.
  • MISRA C++:2008, 6-2-3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment, provided that the first character following the null statement is a white-space character.
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • CERT, MSC51-J. - Do not place a semicolon immediately following an if, for, or while condition
  • CERT, EXP15-C. - Do not place a semicolon on the same line as an if, for, or while statement
c:LogicalExpressionOperands

The effect of this rule is to require that operands are appropriately parenthesized. Parentheses are important in this situation both for readability of code and for ensuring that the behavior is as the developer intended.

Where an expression consists of either a sequence of only logical && or a sequence of logical ||, extra parentheses are not required.

Noncompliant Code Example

if (x == 0 && ishigh);                   // Noncompliant
if (x || y || z);
if (x || y && z);                        // Noncompliant
if (x && !y);                            // Noncompliant
if (is_odd(y) && x);
if ((x > c1) && (y > c2) && (z > c3));
if ((x > c1) && (y > c2) || (z > c3));   // Noncompliant

Compliant Solution

if ((x == 0) && ishigh);
if (x || y || z);
if (x || (y && z));
if (x && (!y));
if (is_odd(y) && x);
if ((x > c1) && (y > c2) && (z > c3));
if ((x > c1) && ((y > c2) || (z > c3)));

See

  • MISRA C:2004, 12.5 - The operands of a logical && or || shall be primary-expressions.
  • MISRA C++:2008, 5-2-1 - Each operand of a logical && or || shall be a postfix-expression.
c:S969

The defined preprocessing directive is used in the context of #if and #elif expressions to see whether a given identifier has been defined as a macro. It returns a value of 0 (false) or 1 (true), and has two valid forms, defined IDENTIFIER and defined ( IDENTIFIER ). Since it is essentially a macro existence check, it cannot take expressions as arguments.

Note that since

#if defined AN_IDENTIFIER

is equivalent to

#ifdef AN_IDENTIFIER

defined is most useful when there are multiple arguments to check, E.G.

#if defined AAA || defined BBB

Noncompliant Code Example

#if defined ( X > Y ) // Noncompliant; expressions not allowed

Compliant Solution

#if defined X && defined Y && X > Y

See

  • MISRA C:2004, 19.14 - The defined preprocessor operator shall only be used in one of the two standard forms.
  • MISRA C++:2008, 16-1-1 - The defined preprocessor operator shall only be used in one of the two standard forms.
c:S960

It is tempting to treat function-like macros as functions, but the two things work differently. For instance, the use of functions offers parameter type-checking, while the use of macros does not. Additionally, with macros, there is the potential for a macro to be evaluated multiple times. In general, functions offer a safer, more robust mechanism than function-like macros, and that safety usually outweighs the speed advantages offered by macros. Therefore functions should be used instead when possible.

Noncompliant Code Example

#define CUBE (X) ((X) * (X) * (X)) // Noncompliant

void func(void) {
  int i = 2;
  int a = CUBE(++i); // Noncompliant. Expands to: int a = ((++i) * (++i) * (++i))
  // ...
}

Compliant Solution

inline int cube(int i) {
  return i * i * i;
}

void func(void) {
  int i = 2;
  int a = cube(++i); // yields 27
  // ...
}

See

  • MISRA C:2004, 19.7 - A function should be used in preference to a function-like macro.
  • MISRA C++:2008, 16-0-4 - Function-like macros shall not be defined.
  • MISRA C:2012, Dir. 4.9 - A function should be used in preference to a function-like macro where they are interchangeable
  • CERT, PRE00-C. - Prefer inline or static functions to function-like macros
c:S961

This is a constraint error, but preprocessors have been known to ignore this problem. Each argument in a function-like macro must consist of at least one preprocessing token otherwise the behaviour is undefined.

See

  • MISRA C:2004, 19.8 - A function-like macro shall not be invoked without all of its arguments.
  • MITRE, CWE-628 - Function Call with Incorrectly Specified Arguments
c:S967

Because the evaluation order of # and ## are not specified, the results of using them both in the same macro could be unpredictable. Therefore macros should contain at most once instance of either # or ##.

Noncompliant Code Example

#define PRINT_FIELD(field) printf (#field " = " ##field);

Compliant Solution

#define FIELD_VAL(field) ##field
#define PRINT_FIELD(field) printf(#field " = " FIELD_VAL(field))

See

  • MISRA C:2004, 19.12
  • MISRA C++ 2008, 16-3-1
  • Related: MISRA C:2012, 20.11
c:S966

An attempt to use an undefined identifier may elicit a warning from the preprocessor. Or it may not; the preprocessor may simply assume that the undefined token has a value of 0.

Therefore macro identifiers should not be used in preprocessor directives until after they have been defined, and this limited usage should be enforced with the use of definition tests.

Noncompliant Code Example

#if x > 0  /* x assumed to be zero if not defined */
#include SOMETHING_IMPORTANT
#endif

#ifdef y  /* Okay; y is not evaluated */
#if y > 0 /* Okay; y must be defined to reach this point */
...
#endif
#endif

Compliant Solution

#define x 10
...
#if x > 0
#include SOMETHING_IMPORTANT
#endif

#if defined ( y ) && ( y > 0 )  /* more compact form, same result as before */
...
#endif

See

  • MISRA C:2004, 19.11 - All macro identifiers in preprocessor directives shall be defined before use, except in #ifdef and #ifndef preprocessor directives and the defined() operator.
  • MISRA C:2012, 20.9 - All identifiers used in the controlling expression of #if or #elif preprocessing directives shall be #define’d before evaluation
c:S1244

Floating point math is imprecise because of the challenges of storing such values in a binary representation. Even worse, floating point math is not associative; push a float or a double through a series of simple mathematical operations and the answer will be different based on the order of those operation because of the rounding that takes place at each step.

Even simple floating point assignments are not simple:

float f = 0.1; // 0.100000001490116119384765625
double d = 0.1; // 0.1000000000000000055511151231257827021181583404541015625

(Results will vary based on compiler and compiler settings.)

Therefore, the use of the equality (==) and inequality (!=) operators on float or double values is almost always an error.

The accepted solution is to use or write a float comparison library that takes floating-point granularity (FLT_EPSILON) and the magnitude of the numbers being compared into account.

This rule checks for the use of direct and indirect equality/inequailty tests on floats and doubles.

Noncompliant Code Example

float myNumber = 3.146;
if ( myNumber == 3.146 ) {  //Noncompliant. Because of floating point imprecision, this will be false
  // ...
}

if (myNumber <= 3.146 && mNumber >= 3.146) { // Noncompliant indirect equality test
  // ...
}

if (myNumber < 4 || myNumber > 4) { // Noncompliant indirect inequality test
  // ...
}

See

  • MISRA C:2004, 13.3 - Floating-point expressions shall not be tested for equality or inequality.
  • MISRA C++:2008, 6-2-2 - Floating-point expressions shall not be directly or indirectly tested for equality or inequality
c:S2335

There is potential for confusion if an octal or hexadecimal escape sequence is immediately followed by other characters. Instead, such sequences shall be terminated by either:

  • The start of another escape sequence.
  • The end of the character constant or the end of a string literal.

Noncompliant Code Example

const char *s1 = "\x41g";  // Noncompliant
int c1 = '\141t'; // Noncompliant

Compliant Solution

const char *s2 = "\x41" "g"; // Compliant - terminated by end of literal
const char *s3 = "\x41\x67"; // Compliant - terminated by another escape
int c2 = '\141\t'; // Compliant - terminated by another escape

See

  • MISRA C:2012, 4.1 - Octal and hexadecimal escape sequences shall be terminated
c:S2216

The values that can be represented by a signed bit field with a length of one bit may not meet developer expectations. For example according to the C99 Standard, Section 6.2.6.2, a single-bit signed bit-field has a single (one) sign bit and no (zero) value bits.

This rule does not apply to unnamed bit fields, as their values cannot be accessed.

Noncompliant Code Example

signed int f:1;  // Noncompliant; there's only room here for the sign

Compliant Solution

unsigned int f:1;

or

signed int:1; // unnamed

or

signed int f:2;

See

  • MISRA C:2004, 6.5 - Bit fields of type signed int shall be at least 2 bits long
  • MISRA C:2012, 6.2 - Single-bit named bit fields shall not be of a signed type
  • MISRA C++:2008, 9-6-4 - Named bit-fields with signed integer type shall have a length of more than one bit
c:S860

Converting an integer type to a pointer generally leads to unspecified behavior. There are several cases where it might be legitimate:

- Converting the integral literal 0 to the null pointer (but you should use nullptr instead, see S4962),

- Converting back to a pointer a pointer value that was converted to a large enough integer (see S1767),

- On embedded devices, device drivers... converting a hard-coded address to a pointer to read some specific memory (this often goes together with the use of volatile, since such memory values can change from the outside of the program).

Since even legitimate cases are corner cases that require to be reviewed carefully, this rule simply reports all places where an integer is cast into a pointer (except the literal 0).

Noncompliant Code Example

struct S {
  int i;
  int j;
};

void f(void* a);

void g(int i) {
  S* s1 = (S*)i; // Noncompliant
  f((void*)i); // Noncompliant
}

See

  • MISRA C++ 2008, 5-2-8 - An object with integer type or pointer to void type shall not be converted to an object with pointer type.
  • CERT, INT36-C. - Converting a pointer to integer or integer to pointer
c:InvalidEscapeSequence

The use of an undefined escape sequence leads to undefined behavior. The defined escape sequences (ISO/IEC 14882:2003 [1] §2.13.2) are: \n, \t, \v, \b, \r, \f, \a, \\, ?, \', \", \<Octal Number>, and \x<Hexadecimal Number>.

Noncompliant Code Example

const char_t a[ 2 ] = "\k";   // Noncompliant
const char_t b[ 2 ] = "\b";   // Compliant

See

  • MISRA C:2004, 4.1 - Only those escape sequences that are defined in ISO C standard shall be used.
  • MISRA C++:2008, 2-13-1 - Only those escape sequences that are defined in ISO/IEC 14882:2003 shall be used.
c:OctalConstantAndSequence

Integer literals starting with a zero are octal rather than decimal values. While using octal values is fully supported, most developers do not have experience with them. They may not recognize octal values as such, mistaking them instead for decimal values.

Noncompliant Code Example

int myNumber = 010;   // Noncompliant. myNumber will hold 8, not 10 - was this really expected?

Compliant Solution

int myNumber = 8;

See

  • MISRA C:2004, 7.1 - Octal constants (other than zero) and octal escape sequences shall not be used.
  • MISRA C++:2008, 2-13-2 - Octal constants (other than zero) and octal escape sequences (other than "\0") shall not be used
  • MISRA C:2012, 7.1 - Octal constants shall not be used
  • CERT, DCL18-C. - Do not begin integer constants with 0 when specifying a decimal value
  • CERT, DCL50-J. - Use visually distinct identifiers
c:S851

If a cast is to be used on any complex expression, the type of cast that may be applied is severely restricted. As explained in MISRA C 2004, section 6.10, conversions on complex expressions are often a source of confusion and it is therefore wise to be cautious. In order to comply with these rules, it may be necessary to use a temporary variable and introduce an extra statement.

Noncompliant Code Example

  ... (float32_t)(f64a + f64b)
  ... (float64_t)(f32a + f32b) // Noncompliant
  ... (float64_t)f32a
  ... (float64_t)(s32a / s32b) // Noncompliant
  ... (float64_t)(s32a > s32b) // Noncompliant
  ... (float64_t)s32a / (float32_t)s32b
  ... (uint32_t)(u16a + u16b) // Noncompliant
  ... (uint32_t)u16a + u16b
  ... (uint32_t)u16a + (uint32_t)u16b
  ... (int16_t)(s32a - 12345)
  ... (uint8_t)(u16a * u16b)
  ... (uint16_t)(u8a * u8b) // Noncompliant
  ... (int16_t)(s32a * s32b)
  ... (int32_t)(s16a * s16b) // Noncompliant
  ... (uint16_t)(f64a + f64b) // Noncompliant
  ... (float32_t)(u16a + u16b) // Noncompliant
  ... (float64_t)foo1(u16a + u16b)
  ... (int32_t)buf16a[u16a + u16b]

See

  • MISRA C:2004, 10.3 - The value of a complex expression of integer type may only be cast to a type that is narrower and of the same signedness as the underlying type of the expression.
  • MISRA C:2004, 10.4 - The value of a complex expression of floating type may only be cast to a narrower floating type.

See Also

  • MISRA C:2004, section 6.10
c:S854

The type of an integer is dependent on a complex combination of factors including:

  • The magnitude of the constant;
  • The implemented sizes of the integer types;
  • The presence of any suffixes;
  • The number base in which the value is expressed (i.e. decimal, octal or hexadecimal).

For example, the value 0x8000 is of type unsigned int in a 16-bit environment, but of type (signed) int in a 32-bit environment.

Note:

  • Any value with a "U" suffix is of unsigned type;
  • An unsuffixed decimal value less than 2^31 is of signed type.

But:

  • An unsuffixed hexadecimal value greater than or equal to 2^15 may be of signed or unsigned type;
  • For C90, an unsuffixed decimal value greater than or equal to 2^31 may be of signed or unsigned type.

In C++, if an overload set includes candidates for an unsigned int and an int, then the overload that would be matched by 0x8000 is therefore dependent on the implemented integer size. Adding a "U" suffix to the value specifies that it is unsigned.

See

  • MISRA C:2004, 10.6 - A "U" suffix shall be applied to all constants of unsigned type.
  • MISRA C++:2008, 2-13-3 - A "U" suffix shall be applied to all octal or hexadecimal integer literals of unsigned type.
  • MISRA C:2012, 7.2 - A "u" or "U" suffix shall be applied to all integer constants that are represented in an unsigned type.
c:S855

Conversion of a function pointer to a different type of pointer results in undefined behaviour. This means, for example, that a pointer to a function cannot be converted to a pointer to a different type of function.

Noncompliant Code Example

int f(int a)
{
  float (*p)(float) = (float (*)(float)) & f; // Noncompliant
}

See

  • MISRA C:2004, 11.1 - Conversions shall not be performed between a pointer to a function and any type other than an integral type.
  • MISRA C++:2008, 5-2-6 - A cast shall not convert a pointer to a function to any other pointer type, including a pointer to function type.
  • MISRA C:2012, 11.1 - Conversions shall not be performed between a pointer to a function and any other type
c:S978

Defining or declaring identifiers with reserved names may lead to undefined behavior. Similarly, defining macros, variables or functions/methods with the same names as functions from the standard library is likely to lead to unexpected results.

Additionally, such identifiers have the potential to thoroughly confuse people who are unfamiliar with the code base, possibly leading them to introduce additional errors. Therefore reserved words and the names of standard library functions should not be used as identifiers.

This rule applies to:

  • defined
  • standard library function names
  • identifiers that begin with two underscores
  • identifiers that begin with an underscore, followed by an uppercase letter
  • identifiers in the global namespace that start with an underscore

Noncompliant Code Example

#ifndef _MY_FILE
#define _MY_FILE   // Noncompliant: starts with '_'

int free(void *pArg, int len) {  // Noncompliant: free is a standard function
  int __i; // Noncompliant: starts with "__"
  //...
}
#endif

Compliant Solution

#ifndef MY_FILE
#define MY_FILE

int clean(void *pArg, int len) {
  int i;
  //...
}
#endif

See

  • MISRA C:2004, 20.1 - Reserved identifiers, macros and functions in the standard library, shall not be defined redefined or undefined.
  • MISRA C++:2008, 17-0-1 - Reserved identifiers, macros and functions in the standard library shall not be defined, redefined, or undefined.
  • MISRA C:2012, 21.2 - A reserved identifier or macro name shall not be declared
  • CERT, DCL37-C. - Do not declare or define a reserved identifier
  • CERT, DCL51-CPP. - Do not declare or define a reserved identifier
c:S856

Casting an object pointer can very easily lead to undefined behavior. Only a few cases are supported, for instance casting an object pointer to a large enough integral type (and back again), casting an object pointer to a pointer to void (and back again)... Using a pointer cast to access an object as if it was of another type than its real type is not supported in general.

This rule detect casts between object pointers and incompatible types.

Noncompliant Code Example

struct S1 *p1;
struct S2;
void f ()
{
  (float) p1; // Noncompliant, conversion to floating point type
  (int *) p1; // Noncompliant
  float f;
  int *i = (int *)&f; // Noncompliant, undefined behavior even if sizeof(int) == sizeof(float)
  (int) p1; // Compliant, but might be undefined behavior if 'int' is not large enough to hold the value of p1.
  (void *) p1; // Compliant, conversion to 'void *'
  (struct S2 *)p1; // Noncompliant, conversion to another type.
}

Exceptions

In C, it is allowed to cast an object pointer to a character pointer to access the byte representation of the object. This rule ignores this case.

Anything can be safely cast to void (since nothing can be done with a result of this cast), and doing so is a common pattern to silence compiler warnings about unused variables. This rule ignores such casts.

void f(int *p) {
  (void)p;
}

See

  • MISRA C:2004, 11.2 - Conversions shall not be performed between a pointer to object and any type other than an integral type, another pointer to object type or a pointer to void.
  • MISRA C:2012, 11.3 - A cast shall not be performed between a pointer to object type and a pointer to a different object type.
c:S977

Preprocessing directives (lines that start with #) can be used to conditionally include or exclude code from compilation. Malformed preprocessing directives could lead to the exclusion or inclusion of more code than was intended. Therefore all preprocessing directives should be syntactically meaningful.

Noncompliant Code Example

#define AAA 2
...
int foo(void)
{
  int x = 0;
  ...

#ifndef AAA
  x = 1;
#else1  /* Noncompliant */
  x = AAA;
#endif

  ...
  return x;
}

Compliant Solution

#define AAA 2
...
int foo(void)
{
  int x = 0;
  ...

#ifndef AAA
  x = 1;
#else
  x = AAA;
#endif

  ...
  return x;
}

See

  • MISRA C:2004, 19.16 - Preprocessing directives shall be syntactically meaningful even when excluded by preprocessor.
  • MISRA C++:2008, 16-0-8 - If the # token appears as the first token on a line, then it shall be immediately followed by a preprocessing token.
  • MISRA C:2012, 20.13 - A line whose first token is # shall be a valid preprocessing directive
c:GotoLabelInNestedBlock

Use of goto can lead to programs that are extremely difficult to comprehend and analyse, and possibly to unspecified behavior.

Unfortunately, removing goto from some code can lead to a rewritten version that is even more difficult to understand than the original. Therefore, limited use of goto is sometimes advised.

However, the use of goto to jump into or out of a sub-block of code, such as into the body of a for loop is never acceptable, because it is extremely difficult to understand and will likely yield results other than what is intended.

Noncompliant Code Example

void f1 (int a) {
  if (a <=0) {
    goto L2;  // Noncompliant; jumps into a different block
  }

  if (a == 0) {
  {
    goto L1; // Compliant
  }
  goto L2;  // Noncompliant; jumps into a block

L1:
  for (int i = 0; i < a; i++) {
  L2:
    //...  Should only have come here with a >=0. Loop is infinite if a < 0
  }
}

Compliant Solution

void f1 (int a) {
  if (a <=0) {
    // ...
  }

  if (a == 0) {
  {
    goto L1; // Compliant
  }

L1:
  for (int i = 0; i < a; i++) {
  L2:
    //...
  }
}

See

  • MISRA C++:2008, 6-6-1 - Any label referenced by a goto statement shall be declared in the same block, or in a block enclosing the goto statement
  • MISRA C:2012, 15.3 - Any label referenced by a goto statement shall be declared in the same block, or in a block enclosing the goto statement
c:S946

If the address of an automatic object is assigned to another automatic object of larger scope, or to a static object, or returned from a function then the object containing the address may exist beyond the time when the original object ceases to exist (and its address becomes invalid).

Noncompliant Code Example

int* f(void) {
  int local_auto;
  return &local_auto; // Noncompliant, returning address of an object allocated on the stack.
}

See

  • MISRA C:2004, 17.6
  • MISRA C++:2008, 7-5-2
  • MISRA C:2012, 18.6
  • CERT, DCL30-C. - Declare objects with appropriate storage durations
c:S1172

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

In case of Objective-C it is acceptable to have unused parameters if the method is supposed to be overridden.

Noncompliant Code Example

void doSomething(int a, int b) { // Noncompliant, "b" is unused
  compute(a);
}

Compliant Solution

void doSomething(int a) {
  compute(a);
}

See

  • MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions.
  • MISRA C:2012, 2.7 - There should be no unused parameters in functions
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
c:AssignmentInSubExpression

Assignments within sub-expressions are hard to spot and therefore make the code less readable. Ideally, sub-expressions should not have side-effects.

Noncompliant Code Example

if ((str = cont.substring(pos1, pos2)).isEmpty()) {  // Noncompliant
  //...

Compliant Solution

str = cont.substring(pos1, pos2);
if (str.isEmpty()) {
  //...

Exceptions

Assignments explicitly enclosed in parentheses are ignored.

while ((run = keepRunning())) {
  //...
}

See

  • MISRA C:2004, 13.1 - Assignment operators shall not be used in expressions that yield a Boolean value
  • MISRA C++:2008, 6-2-1 - Assignment operators shall not be used in sub-expressions
  • MISRA C:2012, 13.4 - The result of an assignment operator should not be used
  • MITRE, CWE-481 - Assigning instead of Comparing
  • CERT, EXP45-C. - Do not perform assignments in selection statements
  • CERT, EXP51-J. - Do not perform assignments in conditional expressions
c:S820

The C90 standard allows implicit typing of variables and functions, and some C compilers still support legacy code by allowing implicit typing. But it should not be used for new code because it might lead to confusion.

Noncompliant Code Example

extern x;
const x;
static fun(void);
typedef ( *pfi ) ( void );

Compliant Solution

extern int16_t x;
const int16_t x;
static int16_t fun(void);
typedef int16_t ( *pfi ) ( void );

See

  • MISRA C:2004, 8.2 - Whenever an object or function is declared or defined, its type shall be explicitly stated
  • MISRA C:2012, 8.1 - Types shall be explicitly specified
  • CERT, DCL31-C. - Declare identifiers before using them
c:S824

A function declared at block scope will refer to a member of the enclosing namespace, and so the declaration should be explicitly placed at the namespace level.

Additionally, where a declaration statement could either declare a function or an object, the compiler will choose to declare the function. To avoid potential developer confusion over the meaning of a declaration, functions should not be declared at block scope.

Noncompliant Code Example

class A {
};

void fun() {
  void nestedFun();  // Noncompliant; declares a function in block scope

  A a();      // Noncompliant; declares a function at block scope, not an object
}

See

  • MISRA C:2004, 8.6 - Functions shall be declared at file scope
  • MISRA C++:2008, 3-1-2 - Functions shall not be declared at block scope
c:S943

While they are extraordinarily useful, pointers are not the most intuitive concept in the world. Pointers to pointers are even harder to understand and use correctly. And with each additional level of indirection, pointer variables become more difficult to use correctly. Therefore pointer declarators should be limited to no more than two levels of nesting.

Noncompliant Code Example

typedef int * INTPTR;
struct s {
 int ** s1;
 int *** s2; // Noncompliant
};

struct s ** ps1;
struct s *** ps2; // Noncompliant

int ** ( *pfunc1)();
int ** ( **pfunc2)();
int ** (***pfunc3)(); // Noncompliant
int *** ( **pfunc4)(); // Noncompliant

void function( int ** par1,
               int *** par2, // Noncompliant
               INTPTR * par3,
               int * par4[],
               int ** par5[]) // Noncompliant
{
  int ** ptr1;
  int *** ptr2; // Noncompliant
  INTPTR * ptr3;
  int * ptr4[ 10 ];
  int ** ptr5[ 10 ]; //Noncompliant
}

Compliant Solution

typedef int * INTPTR;
struct s {
 int ** s1;
 int ** s2;
};

struct s ** ps1;
struct s ** ps2;

int ** (*pfunc1)();
int ** (**pfunc2)();
int ** (**pfunc3)();
int ** (**pfunc4)();

void function( int ** par1,
               int ** par2,
               INTPTR * par3,
               int * par4[],
               int * par5[])
{
  int ** ptr1;
  int ** ptr2;
  INTPTR * ptr3;
  int * ptr4[ 10 ];
  int * ptr5[ 10 ];
}

See

  • MISRA C:2004, 17.5 - The declaration of objects should contain no more than 2 levels of pointer indirection
  • MISRA C++:2008, 5-0-19 - The declaration of objects shall contain no more than two levels of pointer indirection
  • MISRA C:2012, 18.5 - Declarations should contain no more than two levels of pointer nesting
c:GlobalMainFunction

A global function named main is the entry point to the program, and is the only identifier which must be in the global namespace. The use of main for other functions may not meet developer expectations.

Noncompliant Code Example

int main() {       // Compliant
}

namespace {
  int main() {     // Noncompliant
  }
}
namespace NS {
  int main() {     // Noncompliant
  }
}

See

  • MISRA C++:2008, 7-3-2 - The identifier main shall not be used for a function other than global function main.
c:S1065

If a label is declared but not used in the program, it can be considered as dead code and should therefore be removed.

This will improve maintainability as developers will not wonder what this label is used for.

Noncompliant Code Example

void fun() {
  label: doSomething();
}

Compliant Solution

void fun() {
  doSomething();
}

See

  • MISRA C:2012, 2.6 - A function should not contain unused label declarations
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
c:S836

Variables should be initialized before their use to avoid unexpected behaviors due to garbage values.

Noncompliant Code Example

void function(int flag, int b) {
  int a;
  if (flag) {
    a = b;
  }
  return a; // Noncompliant - "a" has not been initialized in all paths
}

Compliant Solution

void function(int flag, int b) {
  int a = 0;
  if (flag) {
    a = b;
  }
  return a;
}

See

  • MITRE, CWE-457 - Use of Uninitialized Variable
  • MISRA C:2004, 9.1 - All automatic variables shall have been assigned a value before being used.
  • MISRA C++:2008, 8-5-1 - All variables shall have a defined value before they are used.
c:LiteralSuffix

Using upper case literal suffixes removes the potential ambiguity between "1" (digit 1) and "l" (letter el) for declaring literals.

Noncompliant Code Example

const int        a = 0u;      // Noncompliant
const int        b = 0l;      // Noncompliant
const int        c = 0Ul;     // Noncompliant
const int        d = 0x12bu;  // Noncompliant
const float      m = 1.2f;    // Noncompliant
const float      n = 1.2l;    // Noncompliant

Compliant Solution

const int        a = 0U;
const int        b = 0L;
const int        c = 0UL;
const int        d = 0x12bU;
const float      m = 1.2F;
const float      n = 1.2L;

See

  • MISRA C++:2008, 2-13-4 - Literal suffixes shall be upper case
  • MISRA C:2012, 7.3 - The lowercase character "l" shall not be used in a literal suffix
  • CERT DCL16-C. - Use "L," not "l," to indicate a long value
  • CERT, DCL50-J. - Use visually distinct identifiers
c:PPDefineOrUndefFromBlock

While it is legal to place #define and #undef directives anywhere in a source file, placing them outside of the global namespace is misleading since their scope is not actually restricted. This may be inconsistent with developer expectations.

Noncompliant Code Example

namespace NS
{
  #ifndef MY_HDR
  #define MY_HDR    /* Noncompliant */
  #undef FOO        /* Noncompliant */
  #endif
}

Compliant Solution

#ifndef MY_HDR
#define MY_HDR
#undef FOO
#endif

See

  • MISRA C:2004, 19.5 - Macros shall not be #define'd or #undef'd within a block.
  • MISRA C++:2008, 16-0-2 - Macros shall only be #define'd or #undef'd in the global namespace.
c:S2393

The identifiers bsearch and qsort shall not be used and no macro with one of these names shall be expanded.

These two functions take as arguments a caller-defined comparison function. If the comparison function does not behave consistently when comparing elements, or if it modifies any of the elements, the behavior is undefined.

Note: the unspecified behavior, which relates to the treatment of elements that compare as equal, can be avoided by ensuring that the comparison function never returns 0. When two elements are otherwise equal, the comparison function could return a value that indicates their relative order in the initial array.

Further, the implementation of qsort is likely to be recursive and will therefore place unknown demands on stack resources. This is of concern in embedded systems because the stack is likely to have a fixed, often small, size.

See

  • MISRA C:2012, 21.9 - The library functions bsearch and qsort of <stdlib.h> shall not be used.
c:S950

A complete declaration of the structure or union shall be included within any translation unit that refers to that structure. See section 6.1.2.5 of ISO 9899:1990 [2] for a full description of incomplete types.

Noncompliant Code Example

struct tnode * pt; // tnode is incomplete

Compliant Solution

struct tnode * pt; // tnode is incomplete at this point
struct tnode
{
  int count;
  struct tnode * left;
  struct tnode * right;
}; // type tnode is now complete

See

  • MISRA C:2004, 18.1 - All structure and union types shall be complete at the end of a translation unit.
c:S833

See

  • MISRA C++ 2008, 3-3-2
  • MISRA C 2004, 8.11
  • MISRA C 2012, 8.8
c:S834

It is possible to declare an array without explicitly specifying its size, but using an explicit size declaration is clearer, and is therefore preferred.

Noncompliant Code Example

int arr1 [ ];  // Noncompliant; nothing specified
int arr2 [ ] = { [0] = 1, [12] = 36, [4] = 93 }; // Noncompliant; highest index determines size. May be difficult to spot
int pirate [ ] = { 2, 4, 8, 42, 501, 90210, 7, 1776 }; // Noncompliant; size is implicit, not explicit

Compliant Solution

int arr1 [10];
int arr2 [13] = { [0] = 1, [12] = 36, [4] = 93 };
int pirate [10] = { 2, 4, 8, 42, 501, 90210, 7, 1776 }; // Implicitly-assigned size was 8. Desired size was 10.

See

  • MISRA C:2004, 8.12 - When an array is declared with external linkage, its size shall be stated explicitly or defined implicitly by initialisation
  • MISRA C++:2008, 3-1-3 - When an array is declared, its size shall either be stated explicitly or defined implicitly by initialization
  • MISRA C:2012, 8.11 - When an array with external linkage is declared, its size should be explicitely specified
  • MISRA C:2012, 9.5 - Where designated initializers are used to initialize an array object the size of the array shall be specified explicitly
  • CERT, ARR02-C. - Explicitly specify array bounds, even if implicitly defined by an initializer
c:S835

ISO/IEC 14882:2003 [1] requires initializer lists for arrays, structures and union types to be enclosed in a single pair of braces (though the behaviour if this is not done is undefined). The rule given here goes further in requiring the use of additional braces to indicate nested structures.

This forces the developer to explicitly consider and demonstrate the order in which elements of complex data types are initialized (e.g. multi-dimensional arrays).

The zero initialization of arrays or structures shall only be applied at the top level.

The non-zero initialization of arrays or structures requires an explicit initializer for each element.

A similar principle applies to structures, and nested combinations of structures, arrays and other types.

Note also that all the elements of arrays or structures can be initialized (to zero or NULL) by giving an explicit initializer for the first element only. If this method of initialization is chosen then the first element should be initialized to zero (or NULL), and nested braces need not be used.

Noncompliant Code Example

int a1[3][2] = { 1, 2, 3, 4, 5, 6 }; // Noncompliant
int a2[5] = { 1, 2, 3 }; // Noncompliant, partial initialization
int a3[2][2] = { { }, { 1, 2 } }; // Noncompliant, zero initialization at sub-level

Compliant Solution

int a1[3][2] = { { 1, 2 }, { 3, 4 }, { 5, 6 } }; // Compliant
int a2[5] = { 1, 2, 3, 0, 0 }; // Compliant, Non-zero initialization
int a2[5] = { 0 }; // Compliant, zero initialization
int a3[2][2] = { }; // Compliant, zero initialization

See

  • MISRA C:2004, 9.2 - Braces shall be used to indicate and match the structure in the non-zero initialization of arrays and structures.
  • MISRA C++:2008, 8-5-2 - Braces shall be used to indicate and match the structure in the nonzero initialization of arrays and structures.
  • MISRA C:2012, 9.2 - The initializer of an aggregate or union shall be enclosed in braces.
c:S1036

Having a switch and its cases wholly encompassed by a control structure such as a try, @try, catch, @catch, or a loop is perfectly acceptable. (try and catch are used hereafter to refer to both variants.) It is also acceptable to have a goto and its target label wholly encompassed in a control structure.

What is not acceptable is using a goto or case to suddenly jump into the body of a try, catch, Objective-C @finally, or loop structure. Tangling labels or switch blocks with other control structures results in code that is difficult, if not impossible to understand. More importantly, when it compiles (some of these constructs won't compile under ISO-conformant compilers), it can lead to unexpected results. Therefore this usage should be strictly avoided.

This C++ code sample, which is also applicable to Objective-C if try and catch are converted to @try and @catch, demonstrates jumping into a switch and into a try and catch :

Noncompliant Code Example

void f ( int32_t i )
{
  if ( 10 == i )
  {
    goto Label_10; // Noncompliant; goto transfers control into try block
  }

  if ( 11 == i )
  {
    goto Label_11; // Noncompliant; goto transfers control into catch block
  }

  switch ( i )
  {
    case 1:
      try
      {
        Label_10:
        case 2:  // Noncompliant; switch transfers control into try block
          // Action
          break;
      }
      catch ( ... )
      {
        Label_11:
        case 3: // Noncompliant; switch transfers control into catch block
          // Action
          break;
      }
      break;
    default:
    {
      // Default Action
      break;
    }
  }
}

Compliant Solution

void f ( int32_t i )
{
  switch ( i )
  {
    case 1:
    case 2:
      // Action
      break;
    case 3:
      // Action
      break;
    case 10:

    default:
    {
      // Default Action
      break;
    }
  }

  try
  {
    if ( 2 == i || 10 == i)
    {
      // Action
    }
  }
  catch ( ... )
  {
    if (3 == i || 11 == i)
    {
      // Action
    }
  }
}

See

  • MISRA C++:2008, 15-0-3 - Control shall not be transferred into a try or catch block using goto or switch statement
  • CERT, MSC20-C. - Do not use a switch statement to transfer control into a complex block
c:DigraphUsage

The use of digraphs may not meet developer expectations.

The digraphs are:

  • <%
  • %>
  • <:
  • :>
  • %:
  • %:%:

Noncompliant Code Example

template <typename T>
class A
{
  public:
    template<int32_t i>
    void f2();
};

void f(A<int32_t> * a<:10:>)    /* Noncompliant - usage of '<:' instead of '[' and ':>' instead of ']' */
<%                              /* Noncompliant - usage of '<%' instead of '{' */
  a<:0:>->f2<20>();             /* Noncompliant - usage of '<:' and ':>' */
%>                              /* Noncompliant - usage of '%>' instead of '}' */

Compliant Solution

/* ... */

void f(A<int32_t> * a[10])      /* Compliant */
{                               /* Compliant */
  a[0]->f2<20>();               /* Compliant */
}                               /* Compliant */

See

  • MISRA C++:2008, 2-5-1 - Digraphs should not be used.
c:S1836

The restrict type qualifier is a guarantee by the programmer that there are no other pointers with access to the referenced object, and that the object does not overlap with any other object in memory. Its use may allow the compiler to generate more efficient byte code.

However, this is a tricky language feature to use correctly, and there is significant risk of unexpected program behavior if restrict is misused. Therefore, restrict should not be used.

Noncompliant Code Example

void user_copy (
  void * restrict p,  // Noncompliant parameter
  void * restrict q,  // Noncompliant parameter
  size_t n
) {
  // ...
}

See

  • MISRA C:2012, 8.14 - The restrict type qualifier shall not be used
  • CERT, EXP43-C. - Avoid undefined behavior when using restrict-qualified pointers
c:PPIncludeTime

Includes time, strftime. This library is associated with clock times. Various aspects are implementation dependent or unspecified, such as the formats of times. If any of the facilities of time.h are used, then the exact implementation for the compiler being used must be determined, and a deviation raised.

Noncompliant Code Example

#include <time.h>  /* Noncompliant */

See

  • MISRA C:2004, 20.12 - The time handling functions of library <time.h> shall not be used.
  • MISRA C:2012, 21.10 - The Standard Library time and date functions shall not be used
c:S1831

Theoretically, the use of the static keyword on the size of an array parameter means you can assume that only arrays of at least that size will be passed as arguments to the function. I.e. a function parameter of int my_array[static 10] means that my_array will always be at least 10 elements long. If it is not, the behavior is undefined.

In practice, the use of static on the size of an array parameter means the compiler might issue a warning if a noncompliant array is passed to the function - a warning that might or might not be ignored. Therefore, in practice the use of static on an array parameter's size merely lends a false sense of security, and static should not be used in this context.

Note that for some compiler/processor combinations, more efficient code can be generated when static is used, but these combinations are limited, and the benefit does not outweigh the cost.

Noncompliant Code Example

int total (int size, int my_array[static 10]) {...}

Compliant Solution

int total (int size, int my_array[10]) {...}

See

  • MISRA C:2012, 17.6 - The declaration of an array parameter shall not contain the static keyword between the []
c:CommentedCode

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
c:S925

Recursion is a powerful tool, but it can be tricky to get right. Getting it wrong can lead to stack overflow errors and cause system problems. Even when you do get it right, recursive code can be difficult to understand, perhaps leading to maintenance problems in the future. Therefore recursion should be avoided in general and used only with due deliberation and caution when it is strictly necessary.

This rule checks for direct recursion (when a function calls itself).

Noncompliant Code Example

int pow(int num, int exponent) {
  if (exponent > 1) {
    num = num * pow(num, exponent-1);  // Noncompliant; direct recursion
  }
  return num;
}

Compliant Solution

int pow(int num, int exponent) {
  int val = num;
  while (exponent > 0) {
    val *= num;
    --exponent;
  }
  return val;
}

See

  • MISRA C:2004, 16.2 - Functions shall not call themselves, either directly or indirectly.
  • MISRA C++:2008, 7-5-4 - Functions should not call themselves, either directly or indirectly.
  • MISRA C:2012, 17.2 - Functions shall not call themselves, either directly or indirectly
c:S926

Naming the parameters in a function prototype helps identify how they'll be used by the function, thereby acting as a thin layer of documentation for the function.

Noncompliant Code Example

void divide (int, int);

Compliant Solution

void divide (int numerator, int denominator);

See

  • MISRA C:2004, 16.3 - Identifiers shall be given for all of the parameters in a function prototype declaration
  • MISRA C:2012, 8.2 - Function types shall be in prototype form with named parameters
c:S929

There is a real, functional difference between a function with an empty parameter list and one with an explicitly void parameter list: It is possible to pass parameters to a function with an empty list; the compiler won't complain. That is not the case for a function with a void list. Thus, it is possible, and even easy to invoke empty-list functions incorrectly without knowing it, and thereby introduce the kind of subtle bug that can be very difficult to track down.

Noncompliant Code Example

void myfunc ();  // Noncompliant

//...

void otherFunc() {
  int a = 4;
  //...
  myfunc(a); // Compiler allows this
}

Compliant Solution

void myfunc ( void );

//...

void otherFunc() {
  int a = 4;
  //...
  myfunc(a); // Compiler error!
}

See

  • MISRA C:2004, 16.5 - Functions with no parameters shall be declared with parameter type void
  • CERT, DCL20-C. - Explicitly specify void when a function accepts no arguments
c:S127

A for loop stop condition should test the loop counter against an invariant value (i.e. one that is true at both the beginning and ending of every loop iteration). Ideally, this means that the stop condition is set to a local variable just before the loop begins.

Stop conditions that are not invariant are slightly less efficient, as well as being difficult to understand and maintain, and likely lead to the introduction of errors in the future.

This rule tracks three types of non-invariant stop conditions:

  • When the loop counters are updated in the body of the for loop
  • When the stop condition depend upon a method call
  • When the stop condition depends on an object property, since such properties could change during the execution of the loop.

Noncompliant Code Example

for (int i = 0; i < 10; i++) {
  ...
  i = i - 1; // Noncompliant
  ...
}
for (int i = 0; i < getMaximumNumber(); i++) {
}

Compliant Solution

for (int i = 0; i < 10; i++) {
  ...
}
int stopCondition = getMaximumNumber();
for (int i = 0; i < stopCondition; i++) {
}

See

  • MISRA C:2004, 13.6 - Numeric variables being used within a for loop for iteration counting shall not be modified in the body of the loop.
  • MISRA C++:2008, 6-5-3 - The loop-counter shall not be modified within condition or statement.
c:S802

Reusing a typedef name either as another typedef name or for any other purpose may lead to developer confusion.

The same typedef shall not be duplicated anywhere in the project, even if the declarations are identical.

Note that where the type definition is made in a header file, and that header file is included in multiple source files, this rule is not violated.

Noncompliant Code Example

{
  typedef unsigned char uint8_t;
}

{
  typedef unsigned char uint8_t; // Noncompliant, redefinition
}

{
  unsigned char uint8_t; // Noncompliant, reuse of uint8_t for another purpose
}

Compliant Solution

typedef unsigned char uint8_t;
{
}

{
}

{
  unsigned char myChar;
}

See

  • MISRA C:2004, 5.3 - A typedef name shall be a unique identifier.
  • MISRA C++:2008, 2-10-3 - A typedef name (including qualification, if any) shall be a unique identifier.
c:S920

When there is only a single condition to test, you have the option of using either a switch statement or an if-else if-else statement. For a larger set of potential values, a switch can be easier to read, but when the condition being tested is essentially boolean, then an if/else statement should be used instead.

Noncompliant Code Example

_Bool b = p > 0;
switch (b) { // Noncompliant
...
}
switch (x == 0) { // Noncompliant
...
}

Compliant Solution

_Bool b = p > 0;
if (b) {
...
} else {
...
}
if (x == 0) {
...
} else {
...
}

See

  • MISRA C:2004, 15.4 - A switch expression shall not represent a value that is effectively Boolean
  • MISRA C++ 2008, 6-4-7 - The condition of a switch statement shall not have bool type
  • MISRA C:2012, 16.7 - A switch-expression shall not have essentially Boolean type
c:FunctionEllipsis

Passing arguments via an ellipsis bypasses the type checking performed by the compiler. Additionally, passing an argument with non-POD class type leads to undefined behavior. Note that the rule specifies "defined" (and not "declared") so as to permit the use of existing library functions.

Noncompliant Code Example

void MyPrintf ( char_t * pFormat, ... )	// Noncompliant
{
  // ...
}

See

  • MISRA C:2004, 16.1 - Functions shall not be defined with a variable number of arguments.
  • MISRA C++:2008, 8-4-1 - Functions shall not be defined using the ellipsis notation.
  • CERT, DCL50-CPP. - Do not define a C-style variadic function
c:S936

Using a "bald" function name is likely a bug. Rather than testing the return value of a function with a void parameter list, it implicitly retrieves the address of that function in memory. If that's truly what's intended, then it should be made explicit with the use of the & (address-of) operator. If it's not, then a parameter list (even an empty one) should be added after the function name.

Noncompliant Code Example

int func(void) {
  // ...
}

void f2(int a, int b) {
  // ...
  if (func) {  // Noncompliant - tests that the memory address of func() is non-null
    //...
  }
  // ...
}

Compliant Solution

void f2(int a, int b) {
  // ...
  if (func()) {  // tests that the return value of func() > 0
    //...
  }
  // ...
}

Exceptions

Callback functions are a common occurrence and are usually not passed with a preceding &. There is however little ambiguity so this rule ignores function identifiers when used as a parameter of a function call.

void foo() {
  // ...
}

registerEvent(AnEvent, foo);

See

  • MISRA C:2004, 16.9 - A function identifier shall only be used with either a preceding &, or with a parenthesized parameter list, which may be empty.
  • MISRA C++:2008, 8-4-4 - A function identifier shall only be used to call the function or it shall be preceded by &.
c:S814

The use of any type other than signed short, unsigned short, signed char, unsigned char, signed int, unsigned int or _Bool for a bit field is implementation-defined, and therefore not portable.

Noncompliant Code Example

int b:3; // Noncompliant - may have the range of values 0..7 or -4..3

Compliant Solution

unsigned int b:3;

See

  • MISRA C:2004, 6.4 - Bit fields shall only be defined to be of type unsigned int or signed int.
  • MISRA C++:2008, 9-6-2 - Bit-fields shall be either bool type or an explicitly unsigned or signed integral type.
  • MISRA C:2012, 6.1 - Bit-fields shall only be declared with an appropriate type
  • CERT, INT12-C. - Do not make assumptions about the type of a plain int bit-field when used in an expression
c:S935

Every call to a function with a non-void return type is expected to return some value. Including a return path in a non-void function that does not explicitly return a value results in undefined behavior.

Conversely, every call to a function with a void return type is expected to not return any value. Returning a value from a void function probably indicates a programming error.

Noncompliant Code Example

int my_func (int a)
{
  if (a > 100)
  {
    return; // Noncompliant
  }

  if (a > 80)
  {
    throw new Exception(); // Compliant
  }

  // Noncompliant
}

Compliant Solution

int my_func (int a)
{
  if (a > 100)
  {
    return 12;
  }

  if (a > 80)
  {
    throw new Exception();
  }

  return a;
}

See

  • MISRA C:2004, 16.8 - All exit paths from a function with non-void return type shall have an explicit return statement with an expression
  • MISRA C++:2008, 8-4-3 - All exit paths from a function with non-void return type shall have an explicit return statement with an expression
  • MISRA C:2012, 17.4 - All exit paths from a function with non-void return type shall have an explicit return statement with an expression
  • MITRE, CWE-394 - Unexpected Status Code or Return Value
  • CERT, MSC37-C. - Ensure that control never reaches the end of a non-void function
  • CERT, MSC52-CPP. - Value-returning functions must return a value from all exit paths
  • CERT, MSC53-CPP. - Do not return from a function declared [[noreturn]]
c:S819

The use of prototypes enables the compiler to check the integrity of function definitions and calls. Without prototypes the compiler is not obliged to pick up certain errors in function calls (e.g. different number of arguments from the function body, mismatch in types of arguments between call and definition). Function interfaces have been shown to be a cause of considerable problems, and therefore this rule is considered very important.

The recommended method of implementing function prototypes for external functions is to declare the function (i.e. give the function prototype) in a header file, and then include the header file in all those code files that need the prototype (see MISRA C 2004, Rule 8.8).

Noncompliant Code Example

void example() {
  fun(); // Noncompliant
}

void fun() {
}

Compliant Solution

void fun();

void example() {
  fun();
}

void fun() {
}

See

  • MISRA C:2004, 8.1 - Functions shall have prototype declarations and the prototype shall be visible at both the function definition and call
  • MISRA C:2012, 17.3 - A function shall not be declared implicitly
  • CERT, DCL07-C. - Include the appropriate type information in function declarators
  • CERT, DCL31-C. - Declare identifiers before using them

See Also

  • MISRA C:2004, 8.8 - An external object or function shall be declared in one and only one file
c:S930

This problem is completely avoided by the use of function prototypes. See MISRA C:2004 Rule 8.1. This rule is retained since compilers may not flag this constraint error.

See

  • MISRA C:2004, 16.6 - The number of arguments passed to a function shall match the number of parameters.
  • MITRE, CWE-628 - Function Call with Incorrectly Specified Arguments
  • CERT, DCL07-C. - Include the appropriate type information in function declarators
  • CERT, EXP37-C. - Call functions with the correct number and type of arguments
c:S810

There are three distinct char types, (plain) char, signed char and unsigned char. signed char and unsigned char should only be used for numeric data, and plain char should only be used for character data. Since it is implementation-defined, the signedness of the plain char type should not be assumed.

Noncompliant Code Example

signed char a = 'a'; // Noncompliant, explicitly signed
unsigned char b = '\r'; // Noncompliant, explicitly unsigned
char c = 10; // Noncompliant

unsigned char d = c; // Noncompliant, d is explicitly signed while c is not
char e = a; // Noncompliant, a is explicitly signed while e is not

Compliant Solution

char a = 'a';
char b = '\r';
unsigned char c = 10;
signed char c = 10;

Exceptions

  • Since the integer value 0 is used as a sentinel for the end of a string, converting this value to char is ignored.

See

  • MISRA C:2004, 6.1 - The plain char type shall be used only for the storage and use of character values
  • MISRA C:2004, 6.2 - signed and unsigned char type shall be used only for the storage and use of number values
  • MISRA C++:2008, 5-0-11 - The plain char type shall only be used for the storage and use of character values
  • MISRA C++:2008, 5-0-12 - signed char and unsigned char type shall only be used for the storage and use of numeric values
  • CERT, INT07-C. - Use only explicitly signed or unsigned char type for numeric values
  • CERT, STR00-C. - Represent characters using an appropriate type
  • CERT, STR04-C. - Use plain char for characters in the basic character set
c:S813

The basic numeric types char, int, short, long, float, double, and long double should not be used. Instead, specific-length typedefs should be. This rule helps to clarify the size of the storage, but does not guarantee portability because of the asymmetric behavior of integral promotion.

Note that it is still important to understand the integer size of the implementation, and developers should be aware of the actual implementation of the typedefs under these definitions.

Noncompliant Code Example

int function(unsigned short a) // Noncompliant
{
  // ...
}

Compliant Solution

#include <stdint.h>
int32_t function(uint16_t a) // Compliant
{
  // ...
}

See

  • MISRA C:2004, 6.3 - typedefs that indicate size and signedness should be used in place of the basic types
  • MISRA C++:2008, 3-9-2 - typedefs that indicate size and signedness should be used in place of the basic numerical types

See Also

  • MISRA C++ 2008 Section 6.5.0 on integral promotion
c:IdentifierLongerThan31

In addition to being difficult to use, too-long variable names can limit code portability. The ISO standard requires that variable, type, function and label names be no more than 31 characters long.

Note that 31 characters is an upper bound, rather than a length recommendation. Shorter names are better, as long as they're still communicative.

Noncompliant Code Example

int this_is_a_very_long_identifier_that_definitely_should_be_renamed = 0;

Compliant Solution

int reasonable_identifier = 0;

See

  • MISRA C:2004, 5.1 - Identifiers (internal and external) shall not rely on the significance of more than 31 character.
  • CERT, DCL23-C. - Guarantee that mutually visible identifiers are unique
c:S905

Any statement (other than a null statement, which means a statement containing only a semicolon ;) which has no side effect and does not result in a change of control flow will normally indicate a programming error, and therefore should be refactored.

Noncompliant Code Example

int func(int a, int b) {
  int result = 0;
  a + b; // Noncompliant, no side effect.
  return result;
}

Compliant Solution

int func(int a, int b) {
  int result = a + b; // Compliant
  return result;
}

See

  • MITRE, CWE-482 - Comparing instead of Assigning
  • MISRA C:2004, 14.2 - All non-null statements shall either have at least one side-effect however executed, or cause control flow to change.
c:S1301

switch statements are useful when there are many different cases depending on the value of the same expression.

For just one or two cases however, the code will be more readable with if statements.

Moreover, if statements are obviously more suitable when the condition of the switch is boolean.

Noncompliant Code Example

switch (variable) {
  case 0:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Compliant Solution

if (variable == 0) {
  doSomething();
} else {
  doSomethingElse();
}

See

  • MISRA C:2012, 16.6 - Every switch statement shall have at least two switch-clauses
c:SideEffectInRightHandSideOfLogical

There are some situations in C++ where certain parts of expressions may not be evaluated. If these sub-expressions contain side effects then those side effects may or may not occur, depending on the values of other sub expressions. The operators which can lead to this problem are && and ||, where the evaluation of the right-hand operand is conditional on the value of the left-hand operand. The conditional evaluation of the right-hand operand of one of the logical operators can easily cause problems if the developer relies on a side effect occurring.

Operations that cause side effects are:

  • accessing a volatile object
  • modifying an object
  • modifying a file
  • calling a function that performs any operations that cause changes in the state of the execution environment of the calling function.

This rule raises an issue when there is assignment or the use of the increment/decrement operators in right-hand operands.

Noncompliant Code Example

if ( ishigh && ( x == i++ ) ) // Noncompliant
...
if ( ishigh && ( x ==  getX() ) ) // Only acceptable if getX() is known to have no side effects

The operations that cause side effects are accessing a volatile object, modifying an object, modifying a file, or calling a function

that does any of those operations, which cause changes in the state of the execution environment of the calling function.

For the time being, this rule only check that there is no assignment or no use of increment/decrement operators made in right hand operands.

See

  • MISRA C:2004, 12.4 - The right-hand operand of a logical && or || operator shall not contain side effects.
  • MISRA C++:2008, 5-14-1 - The right hand operand of a logical && or || operator shall not contain side effects.
  • MISRA C:2012, 13.5 - The right hand operand of a logical && or || operator shall not contain persistent side effects
  • CERT, EXP02-C. - Be aware of the short-circuit behavior of the logical AND and OR operators
c:S121

While not technically incorrect, the omission of curly braces can be misleading, and may lead to the introduction of errors during maintenance.

Noncompliant Code Example

if (condition)  // Noncompliant
  executeSomething();

Compliant Solution

if (condition) {
  executeSomething();
}

See

  • MISRA C:2004, 14.8 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C:2004, 14.9 - An if (expression) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C++:2008, 6-3-1 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C++:2008, 6-4-1 - An if (condition) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C:2012, 15.6 - The body of an iteration-statement or a selection-statement shall be a compound-statement
  • CERT, EXP19-C. - Use braces for the body of an if, for, or while statement
  • CERT, EXP52-J. - Use braces for the body of an if, for, or while statement
c:PPUndefUsage

#undef should not normally be needed. Its use can lead to confusion with respect to the existence or meaning of a macro when it is used in the code.

Noncompliant Code Example

#ifndef MY_HDR
#define MY_HDR
#endif
...
#undef MY_HDR    /* Noncompliant */

See

  • MISRA C:2004, 19.6 - #undef shall not be used.
  • MISRA C++:2008, 16-0-3 - #undef shall not be used.
  • MISRA C:2012, 20.5 - #undef should not be used
c:SwitchLabelPlacement

A switch-label can be placed anywhere within the statements that form the body of a switch statement, potentially leading to unstructured code. To prevent this from happening, the scope of a case-label or default-label shall be the statement forming the body of a switch statement. All case-clauses and the default-clause shall be at the same scope.

Noncompliant Code Example

switch (x) {
  case 1: // Compliant
    if (foo) {
      case 2: // Noncompliant
        break;
      default: // Noncompliant
        break;
    }
    break;
  default: // Compliant
    break;
}

See

  • MISRA C 2004, 15.1 - A switch label shall only be used when the most closely-enclosing compound statement is the body of a switch statement.
  • MISRA C++ 2008, 6-4-4 - A switch-label shall only be used when the most closely-enclosing compound statement is the body of a switch statement.
  • MISRA C 2012, 16.2 - A switch label shall only be used when the most closely-enclsoing compound statement is the body of a switch statement
c:EnumPartialInitialization

If an enumerator list is given with no explicit initialization of members, then C/C++ allocates a sequence of integers starting at zero for the first element and increasing by one for each subsequent element.

An explicit initialization of the first element, as permitted by this rule, forces the allocation of integers to start at the given value. When adopting this approach it is essential to ensure that the initialization value used is small enough that no subsequent value in the list will exceed the int storage used by enumeration constants.

Explicit initialization of all items in the list, which is also permissible, prevents the mixing of automatic and manual allocation, which is error prone.

However, it is then the responsibility of the developer to ensure that all values are in the required range, and that values are not unintentionally duplicated.

Noncompliant Code Example

enum color { red = 3, blue, green, yellow = 5 }; // Noncompliant; both green and yellow = 5

Compliant Solution

enum color { red = 3, blue = 4, green = 5, yellow = 5 }; // Compliant

See

  • MISRA C:2004, 9.3 - In an enumerator list, the "=" construct shall not be used to explicitly initialize members other than the first, unless all items are explicitly initialized.
  • MISRA C++:2008, 8-5-3 - In an enumerator list, the = construct shall not be used to explicitly initialize members other than the first, unless all items are explicitly initialized.
c:S2193

When using a floating-point for loop counter, an accumulation of rounding errors may result in a mismatch between the expected and actual number of iterations.

Even if floating-point loop counters appears to behave correctly on one implementation, it may give a different number of iterations on another implementation.

Noncompliant Code Example

for (float counter = 0.0f; counter < 1.0f; counter += 0.001f) {
  ...
}

Compliant Solution

for (int counter = 0; counter < 1000; ++counter) {
  ...
}

See

  • MISRA C:2004, 13.4 - The controlling expression of a for statement shall not contain any objects of floating type.
  • MISRA C++:2008, 6-5-1 - A for loop shall contain a single loop-counter which shall not have floating type.
  • MISRA C:2012, 14.1 - A loop counter shall not have essentially floating type.
  • CERT, NUM09-J. - Do not use floating-point variables as loop counters
  • CERT, FLP30-C. - Do not use floating-point variables as loop counters
c:SingleDeclarationPerStatement

Where multiple declarators appear in the same declaration the type of an identifier may not meet developer expectations.

Noncompliant Code Example

int i1; int j1; // Compliant, but not preferred
int i2, *j2; // Noncompliant
int *i3,
&j3 = i2; // Noncompliant

Compliant Solution

int i1;
int j1;
int i2;
int *j2;
int *i3;
int &j3 = i2;

See

  • MISRA C++:2008, 8-0-1 - An init-declarator-list or a member-declarator-list shall consist of a single init-declarator or member-declarator respectively
  • CERT, DCL52-J. - Do not declare more than one variable per declaration
  • CERT, DCL04-C. - Do not declare more than one variable per declaration
c:S1763

Jump statements (return, break, continue, goto) and throw expressions move control flow out of the current code block. So any unlabelled statements that come after a jump are dead code.

Noncompliant Code Example

int fun(int a) {
  int i = 10;
  return i + a;       // Noncompliant
  i++;             // dead code
}

Compliant Solution

int fun(int a) {
  int i = 10;
  return i + a;
}

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code
  • MISRA C++:2008, 0-1-9 - There shall be no dead code
  • MISRA C:2012, 2.1 - A project shall not contain unreachable code
  • MISRA C:2012, 2.2 - There shall be no dead code
  • MITRE, CWE-561 - Dead Code
  • CERT, MSC56-J. - Detect and remove superfluous code and values
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
c:PPStringifyAndPastingUsage

The evaluation order of both the # and ## preprocessor operators is unspecified. Compilers have been known to implement these operators inconsistently, therefore, to avoid these problems, do not use them.

Noncompliant Code Example

#define A(Y)   #Y    /* Noncompliant */
#define A(X,Y) X##Y  /* Noncompliant */

See

  • MISRA C:2004, 19.13 - The # and ## preprocessor operators should not be used.
  • MISRA C++:2008, 16-3-2 - The # and ## operators should not be used.
  • MISRA C:2012, 20.10 - The # and ## preprocessor operators should not be used
c:S1761

The standard, predefined macros, such as __FILE__ and __LINE__, are primarily intended for use by the implementation, and changing them could result in undefined behavior.

This rule checks that the following predefined macros are not defined, undefined, or redefined: assert, errno, __FILE__, __LINE__, __TIME__, __DATE__, __TIMESTAMP__, __COUNTER__, __INCLUDE_LEVEL__, __BASE_FILE__, and _Pragma.

Noncompliant Code Example

#undef __LINE__

See

  • MISRA C:2004, 20.1 - Reserved identifiers, macros and functions in the standard library shall not be defined, redefined, or undefined
  • MISRA C++:2008, 17-0-1 - Reserved identifiers, macros and functions in the standard library shall not be defined, redefined, or undefined
  • MISRA C:2012, 21.1 - #define and #undef shall not be used on a reserved identifier or reserved macro name
c:S3949

Numbers are infinite, but the types that hold them are not. Each numeric type has hard upper and lower bounds. Try to calculate or assign numbers beyond those bounds, and the result will be surprising:

- For unsigned types, it will be a value that has silently wrapped around from the expected positive value to another one, following the rules of modular arithmetic (if the maximum unsigned char is 255, adding 10 to an unsigned char equals to 250 will yield the value 4)

- For signed type, this is undefined behavior.

Noncompliant Code Example

void test(char c) {
  switch (c) {
    case 2000: // Noncompliant
      // ...
      break;
  }

  int a = 4608 * 1024 * 1024; // Noncompliant
}
c:PPIncludeStdio

This includes file and I/O functions fgetpos, fopen, ftell, gets, perror, remove, rename and ungetc.

Streams and file I/O have a large number of unspecified, undefined and implementation-defined behaviors associated with them. It is assumed within MISRA C that they will not normally be needed in production code in embedded systems.

If any of the features of stdio.h need to be used in production code, then the issues associated with the features need to be understood.

Noncompliant Code Example

#include <stdio.h> /* Noncompliant */

See

  • MISRA C:2004, 20.9 - The input/output library <stdio.h> shall not be used in production code.
  • MISRA C++:2008, 27-0-1 - The stream input/output library <cstdio> shall not be used.
  • MISRA C:2012, 21.6 - The Standard Library input/output functions shall not be used
c:S1767

The size of integer required to hold a memory address is implementation-dependent. Therefore, casting a pointer (i.e. a memory address) to any integral data type may result in data loss because the integral type is too small to hold the full address value.

When treating a memory address as integer type is absolutely required, you should be sure to use a large enough type to hold all the data.

Noncompliant Code Example

int *p;
int addr = ( int ) &p;

See

  • MISRA C:2004, 11.3 - A cast should not be performed between a pointer type and an integral type.
  • MISRA C++:2008, 5-2-9 - A cast should not convert a pointer type to an integral type.
  • MISRA C:2012, 11.4 - A conversion should not be performed between a pointer to object and an integer type
  • CERT, INT36-C. - Converting a pointer to integer or integer to pointer
c:S1081

When using legacy C functions, it's up to the developer to make sure the size of the buffer to be written to is large enough to avoid buffer overflows. Buffer overflows can cause the program to crash at a minimum. At worst, a carefully crafted overflow can cause malicious code to be executed.

This rule reports use of the following insecure functions: strcpy(), strcat(), sprintf(), gets() and getpw().

In such cases, it's better to use an alternate, secure function which allows you to define the maximum number of characters to be written to the buffer:

  • strlcpy (BSD library) or strncpy
  • strlcat (BSD library) or strncat
  • snprintf
  • fgets
  • getpwuid

(Be aware that strncpy and strncat don't guarantee the string will be null-terminated.)

Noncompliant Code Example

sprintf(str, "%s", message);   // Noncompliant
strcpy(str, message); // Noncompliant

Compliant Solution

snprintf(str, sizeof(str), "%s", message);
strlcpy(str, message, sizeof(str));

strncpy(str, message, sizeof(str) -1); // Leave room for null
str[sizeof(str) - 1] = '\0'; // Make sure the string is null-terminated

See

c:S793

The #pragma directive is implementation-defined, hence it is important both to demonstrate that all uses are correct, and to minimize, localize and encapsulate any use of pragmas within dedicated functions whenever possible.

The meaning of each pragma shall be documented.

There shall be sufficient supporting description to demonstrate that the behavior of the pragma and its implications for the application, have been fully understood.

This rule flags all instances of #pragma directives, and leaves it to the user to determine whether they have been properly documented.

See

  • MISRA C:2004, 3.4 - All uses of the #pragma directive shall be documented and explained
  • MISRA C++:2008, 16-6-1 - All uses of the #pragma directive shall be documented
  • CERT, MSC00-C - Compile cleanly at high warning levels
c:S1219

Even if it is legal, mixing case and non-case labels in the body of a switch statement is very confusing and can even be the result of a typing error.

Noncompliant Code Example

Case 1, the code is syntactically correct but the behavior is not the expected one

switch (day) {
  case MONDAY:
  case TUESDAY:
  WEDNESDAY:   // instead of "case WEDNESDAY"
    doSomething();
    break;
  ...
}

Case 2, the code is correct and behaves as expected but is hardly readable

switch (day) {
  case MONDAY:
    break;
  case TUESDAY:
    foo:for(int i = 0 ; i < X ; i++) {
         /* ... */
        break foo;  // this break statement doesn't relate to the nesting case TUESDAY
         /* ... */
    }
    break;
    /* ... */
}

Compliant Solution

Case 1

switch (day) {
  case MONDAY:
  case TUESDAY:
  case WEDNESDAY:
    doSomething();
    break;
  ...
}

Case 2

switch (day) {
  case MONDAY:
    break;
  case TUESDAY:
    compute(args); // put the content of the labelled "for" statement in a dedicated method
    break;

    /* ... */
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
c:S784

Ensuring that assembly language code is encapsulated and isolated aids portability. Where assembly language instructions are needed, they shall be encapsulated and isolated in either assembler functions or C++ functions.

Noncompliant Code Example

void fn ( void )
{
  DoSomething ( );
  asm ( "NOP" ); // Noncompliant, asm mixed with C/C++ statements
  DoSomething ( );
}

Compliant Solution

void Delay ( void )
{
  asm ( "NOP" ); // Compliant, asm not mixed with C/C++ statements
}

void fn ( void )
{
  DoSomething ( );
  Delay ( ); // Compliant, Assembler is encapsulated
  DoSomething ( );
}

See

  • MISRA C 2004, 2.1 - Assembly language shall be encapsulated and isolated.
  • MISRA C++ 2008, 7-4-3 - Assembly language shall be encapsulated and isolated.
c:C99CommentUsage

This excludes the use of // C99 style comments and C++ style comments, since these are not permitted in C90. Many compilers support the // style of comments as an extension to C90. The use of // in preprocessor directives (e.g. #define) can vary. Also the mixing of /* ... */ and // is not consistent. This is more than a style issue, since different (pre C99) compilers may behave differently.

Noncompliant Code Example

int main(int argc, char* argv[])
{
  // Do nothing - Noncompliant
  return 0;
}

Compliant Solution

int main(int argc, char* argv[])
{
  /* Do nothing - Compliant */
  return 0;
}

See

  • MISRA C:2004, 2.2 - Source code shall only use /* ... */ style comments.
c:S1103

Defining a nested single-line comment within a multi-line comment invites errors. It may lead a developer to wrongly think that the lines located after the single-line comment are not part of the comment.

If a comment starting sequence, /* or //, occurs within a /* comment, is it quite likely to be caused by a missing */ comment ending sequence.

If a comment starting sequence occurs within a // comment, it is probably because a region of code has been commented-out using //.

Noncompliant Code Example

/* some comment, end comment marker accidentally omitted
// Make sure this function is called in a thread safe context
Perform_Critical_Safety_Function(X);
...
/* this comment is non-compliant */

Exceptions

The sequence // is permitted within a // comment.

See

  • CERT, MSC04-C. - Use comments consistently and in a readable fashion
  • MISRA C:2004, 2.3 - The character sequence /* shall not be used within a comment.
  • MISRA C++:2008, 2-7-1 - The character sequence /* shall not be used within a C-style comment.
  • MISRA C:2012, 3.1 - The character sequences /* and // shall not be used within a comment
c:S5266

In programming languages keywords have a special meaning and are reserved to the language. It is hence a bad idea to define macros with keywords as macro identifier as it can easily lead to undefined behavior:

  • The same object might be defined differently in different places, which violates the One Definition Rule
  • If you include any header from the standard library, it is undefined behavior to define such macros

Additionally, it is very awkward for anyone reading the code to have a keyword that means something different.

Noncompliant Code Example

#define int some_other_type // Noncompliant
#include <stdlib.h>;

See

* MISRA C:2012, 20.4 - A macro shall not be defined with the same name as a keyword

c:PPBadIncludeForm

These are the only forms for the #include directive permitted by the standard. The behavior is undefined when other forms are used.

Noncompliant Code Example

#include filename.h        // Noncompliant

Compliant Solution

#include "filename.h"        // Compliant
#include <filename.h>

#define HEADER "filename.h"
#include HEADER

See

  • MISRA C:2004, 19.3 - The #include directive shall be followed by either a <filename> or "filename" sequence.
  • MISRA C++:2008, 16-2-6 - The #include directive shall be followed by either a <filename> or "filename" sequence.
  • MISRA C:2012, 20.3 - The #include directive shall be followed by either a <filename> or "filename" sequence
c:S1226

While it is technically correct to assign to parameters from within function bodies, it is better to use temporary variables to store intermediate results.

Allowing parameters to be assigned to also reduces the code readability as developers will not be able to know whether the original parameter or some temporary variable is being accessed without going through the whole function.

Noncompliant Code Example

int glob = 0;
void function (int a) {
  a = glob; // Noncompliant
  ...
}

Compliant Solution

int glob = 0;
void function (int a) {
  int b = glob;
  ...
}

See

  • MISRA C:2012, 17.8 - A function parameter should not be modified
c:Union

The use of unions to access an object in different ways may result in the data being misinterpreted. Therefore, this rule prohibits the use of unions for any purpose.

Noncompliant Code Example

union U1 { // Noncompliant
    float j;
    int i;
};

See

  • MISRA C:2004, 18.4 - Unions shall not be used.
  • MISRA C++:2008, 9-5-1 - Unions shall not be used.
  • MISRA C:2012, 19.2 - The union keyword should not be used
c:ContinueUsage

continue is an unstructured control flow statement. It makes code less testable, less readable and less maintainable. Structured control flow statements such as if should be used instead.

Noncompliant Code Example

int i;
for (i = 0; i < 10; i++) {
  if (i == 5) {
    continue;  /* Noncompliant */
  }
  printf("i = %d\n", i);
}

Compliant Solution

int i;
for (i = 0; i < 10; i++) {
  if (i != 5) {
    printf("i = %d\n", i);
  }
}

See

  • MISRA C:2004, 14.5 - The continue statement shall not be used.
c:PPIncludeNonStandardCharacters

If the ', \, " or /* characters are used between < and > delimiters or the ', \ or /* characters are used between the " delimiters in a header name preprocessing token, then the behavior is undefined.

Noncompliant Code Example

#include <"foo">     // Noncompliant
#include "dir\foo.h" // Noncompliant

See

  • MISRA C:2004, 19.2 - Non-standard characters should not occur in header file names in #include directives.
  • MISRA C++:2008, 16-2-4 - The ', ", /* or // characters shall not occur in a header file name.
  • MISRA C++:2008, 16-2-5 - The \ character should not occur in a header file name.
  • MISRA C:2012, 20.2 - The ', " or \ characters and the /* or // character sequences shall not occur in a header file name
c:FunctionSinglePointOfExit

This is required by IEC 61508, under good programming style.

Noncompliant Code Example

int function1()
{
  return 3;
}

void function2()
{
  function1();
}

int function3(char* ptr) /* Noncompliant; two explicit returns */
{
  if (ptr == NULL) return -1;

  return 7;
}

void function4(char *ptr) /* Noncompliant; two returns, one explicit and one implicit */
{
  if (1) return;

  printf("hello world!\n");
}

See

  • MISRA C:2004, 14.7 - A function shall have a single point of exit at the end of the function.
  • MISRA C++:2008, 6-6-5 - A function shall have a single point of exit at the end of the function
  • MISRA C:2012, 15.5 - A function should have a single point of exit at the end
c:PPIncludeNotAtTop

To aid code readability, all the #include directives in a particular code file should be grouped together near the top of the file. The only items which may precede an #include in a file are other preprocessor directives or comments.

Noncompliant Code Example

#include <h1.h> /* Compliant */
int32_t i;
#include <f2.h> /* Noncompliant */

Compliant Solution

#include <h1.h>
#include <f2.h>

int32_t i;

See

  • MISRA C:2004, 19.1 - #include statements in a file should only be preceded by other preprocessor directives or comments.
  • MISRA C++:2008, 16-0-1 - #include directives in a file shall only be preceded by other preprocessor directives or comments.
  • MISRA C:2012, 20.1 - #include directives should only be preceded by preprocessor directives or comments
c:SwitchWithoutDefault

The requirement for a final default clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken. When the switch covers all current values of an enum - and especially when it doesn't - a default case should still be used because there is no guarantee that the enum won't be extended.

Noncompliant Code Example

switch (param) { // Noncompliant - default clause is missing
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
}

Compliant Solution

switch (param) {
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
  default:
    doDefault();
    break;
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
  • MITRE, CWE-478 - Missing Default Case in Switch Statement
  • CERT, MSC01-C. - Strive for logical completeness

See also

c:ElseIfWithoutElse

This rule applies whenever an if statement is followed by one or more else if statements; the final else if should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch statement.

Noncompliant Code Example

if (x == 0) {
  doSomething();
} else if (x == 1) {
  doSomethingElse();
}

Compliant Solution

if (x == 0) {
  doSomething();
} else if (x == 1) {
  doSomethingElse();
} else {
  error();
}

Exceptions

When all branches of an if-else if end with return, break or throw, the code that comes after the if implicitly behaves as if it was in an else clause. This rule will therefore ignore that case.

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
c:NonEmptyCaseWithoutBreak

When the execution is not explicitly terminated at the end of a switch case, it continues to execute the statements of the following case. While this is sometimes intentional, it often is a mistake which leads to unexpected behavior.

Noncompliant Code Example

switch (myVariable) {
  case 1:
    foo();
    break;
  case 2:  // Both 'doSomething()' and 'doSomethingElse()' will be executed. Is it on purpose ?
    doSomething();
  default:
    doSomethingElse();
    break;
}

Compliant Solution

switch (myVariable) {
  case 1:
    foo();
    break;
  case 2:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Exceptions

This rule is relaxed in the following cases:

switch (myVariable) {
  case 0:                                // Empty case used to specify the same behavior for a group of cases.
  case 1:
    doSomething();
    break;
  case 2:                                // Use of return statement
    return;
  case 3:                                // Use of throw statement
    throw 1;
  case 4:                                // Use of continue statement
    continue;
  default:                               // For the last case, use of break statement is optional
    doSomethingElse();
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.2 - An unconditional break statement shall terminate every non-empty switch clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-5 - An unconditional throw or break statement shall terminate every non-empty switch-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.3 - An unconditional break statement shall terminate every switch-clause
  • MITRE, CWE-484 - Omitted Break Statement in Switch
  • CERT, MSC17-C. - Finish every set of statements associated with a case label with a break statement
  • CERT, MSC52-J. - Finish every set of statements associated with a case label with a break statement
c:S883

Where a data value is to be tested against zero then the test should be made explicit. The exception to this rule is when data represents a Boolean value, even though in C this will in practice be an integer.

This rule is in the interests of clarity, and makes clear the distinction between integers and logical values.

Noncompliant Code Example

if ( x ) // Noncompliant, unless x is effectively Boolean data

Compliant Solution

if ( x == 0) // Compliant solution

See

  • MISRA C:2004, 13.2 - Tests of a value against zero should be made explicit, unless the operand is effectively Boolean.
c:S886

The for statement provides a general-purpose looping facility. Using a restricted form of loop makes code easier to review and to analyse.

The three clauses of a for statement are the:

  • First clause which should
    • be empty, or
    • assign a value to the loop counter, or
    • define and initialize the loop counter (C99).
  • Second clause which should
    • be an expression that has no persistent side effects, and
    • not use objects that are modified in the for loop body.
  • Third clause which should
    • be an expression whose only persistent side effect is to modify the value of the loop counter, and
    • not use objects that are modified in the for loop body.

Noncompliant Code Example

for( int i = 0 ; i++ < 10 ; i += 1 ) { // Noncompliant, loop counter is updated in the condition
}

for( int i = 0 ; ; ) { // Noncompliant, initialized variable i is not used in the condition
}

for( int i = 0 , j = 0 ; i < 10 ; i += j) { // Noncompliant, j is modified in the body
  j = i + 1;
}

See

  • MISRA C:2004, 13.5 - The three expressions of a for statement shall be concerned only with loop control.
  • MISRA C++:2008, 6-5-5 - A loop-control-variable other than the loop-counter shall not be modified within condition or expression.
  • MISRA C:2012, 14.2 - A for loop shall be well-formed
c:BackJumpWithGoto

Unconstrained use of goto can lead to programs that are extremely difficult to comprehend and analyse. For C++, it can also lead to the program exhibiting unspecified behavior.

However, in many cases a total ban on goto requires the introduction of flags to ensure correct control flow, and it is possible that these flags may themselves be less transparent than the goto they replace.

Therefore, the restricted use of goto is allowed where that use will not lead to semantics contrary to developer expectations. "Back" jumps are prohibited, since they can be used to create iterations without using the well-defined iteration statements supplied by the core language.

Noncompliant Code Example

int f() {
  int j = 0;
L1:
  ++j;
  if (10 == j) {
    goto L2;         // forward jump ignored
  }
  // ...
  goto L1;           // Noncompliant
L2:
  return ++j;
}

Compliant Solution

int f() {
  for (int j = 0; j < 11; j++) {
    // ...
  }
  return ++j;
}

See

  • MISRA C++:2008, 6-6-2 - The goto statement shall jump to a label declared later in the same function body
  • MISRA C:2012, 15.2 - The goto statement shall jump to a label declared later in the same function
c:IncAndDecMixedWithOtherOperators

The use of increment and decrement operators in method calls or in combination with other arithmetic operators is not recommended, because:

  • It can significantly impair the readability of the code.
  • It introduces additional side effects into a statement, with the potential for undefined behavior.
  • It is safer to use these operators in isolation from any other arithmetic operators.

Noncompliant Code Example

u8a = ++u8b + u8c--;
foo = bar++ / 4;

Compliant Solution

The following sequence is clearer and therefore safer:

++u8b;
u8a = u8b + u8c;
u8c--;
foo = bar / 4;
bar++;

See

  • MISRA C:2004, 12.1 - Limited dependence should be placed on the C operator precedence rules in expressions.
  • MISRA C:2004, 12.13 - The increment (++) and decrement (--) operators should not be mixed with other operators in an expression.
  • MISRA C++:2008, 5-2-10 - The increment (++) and decrement (--) operator should not be mixed with other operators in an expression.
  • MISRA C:2012, 12.1 - The precedence of operators within expressions should be made explicit
  • MISRA C:2012, 13.3 - A full expression containing an increment (++) or decrement (--) operator should have no other potential side effects other than that cause by the increment or decrement operator
  • CERT, EXP30-C. - Do not depend on the order of evaluation for side effects
  • CERT, EXP50-CPP. - Do not depend on the order of evaluation for side effects
  • CERT, EXP05-J. - Do not follow a write by a subsequent write or read of the same object within an expression
c:S897

If a type is declared but not used, then it is unclear to a reviewer if the type is redundant or it has been left unused by mistake.

Noncompliant Code Example

void unusedtype()
{
  typedef int local_Type; // Noncompliant, unused
}

See

  • MISRA C++:2008, 0-1-5 - A project shall not contain unused type declarations.
vbnet:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

Noncompliant Code Example

Dim username As String = "admin"
Dim password As String = "Password123"
Dim usernamePassword As String = "user=admin&password=Password123"
Dim usernamePassword2 As String = "user=admin&" & "password=" & password

Compliant Solution

Dim username As String = "admin"
Dim password As String = GetEncryptedPassword()
Dim usernamePassword As String = String.Format("user={0}&password={1}", GetEncryptedUsername(), GetEncryptedPassword())

See

vbnet:S112

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

Public Sub DoSomething(obj As Object)
  If obj Is Nothing Then
    ' Noncompliant
    Throw New NullReferenceException("obj")
  End If
  ' ...
End Sub

Compliant Solution

Public Sub DoSomething(obj As Object)
  If obj Is Nothing Then
    Throw New ArgumentNullException("obj")
  End If
  ' ...
End Sub

See

vbnet:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

Public Sub SetName(name As String)
  name = name
End Sub

Compliant Solution

Public Sub SetName(name As String)
  Me.name = name
End Sub

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
vbnet:S1659

Declaring multiple variable on one line is difficult to read.

Noncompliant Code Example

Module Module1
  Public Const AAA As Integer = 5, BBB = 42, CCC As String = "foo"  ' Noncompliant
End Module

Compliant Solution

Module Module1
  Public Const AAA As Integer = 5
  Public Const BBB = 42
  Public Const CCC as String = "foo"
End Module

See

  • CERT, DCL52-J. - Do not declare more than one variable per declaration
  • CERT, DCL04-C. - Do not declare more than one variable per declaration
vbnet:S1147

End statements exit the control flow of the program in an unstructured way. This statement stops code execution immediately without executing Dispose or Finalize methods, or executing Finally blocks. Therefore, it should be avoided.

Noncompliant Code Example

Module Module1
    Sub Print(ByVal str As String)
       Try
            ...
            End       ' Noncompliant
        Finally
            ' do something important here
            ...
        End Try
    End Sub
End Module
vbnet:S1301

switch statements are useful when there are many different cases depending on the value of the same expression.

For just one or two cases however, the code will be more readable with if statements.

Noncompliant Code Example

Select Case variable
    Case 0
        doSomething()
    Case Else
        doSomethingElse()
End Select

Compliant Solution

If variable = 0 Then
    doSomething()
Else
    doSomethingElse()
End If
vbnet:S1145

if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.

There are three possible causes for the presence of such code:

  • An if statement was changed during debugging and that debug code has been committed.
  • Some value was left unset.
  • Some logic is not doing what the programmer thought it did.

In any of these cases, unconditional if statements should be removed.

Noncompliant Code Example

    If True Then ' Noncompliant
      DoSomething()
    End If

    If False Then ' Noncompliant
      DoSomethingElse()
    End If

Compliant Solution

DoSomething();
' ...

See

vbnet:S2077

Formatting strings used as SQL queries is security-sensitive. It has led in the past to the following vulnerabilities:

SQL queries often need to use a hardcoded SQL string with a dynamic parameter coming from a user request. Formatting a string to add those parameters to the request is a bad practice as it can result in an SQL injection. The safe way to add parameters to a SQL query is to use SQL binding mechanisms.

This rule flags the execution of SQL queries which are built using formatting of strings, even if there is no injection. This rule does not detect SQL injections. The goal is to guide security code reviews and to prevent a common bad practice.

The following specific method signatures are tested:

  • System.Data.SqlClient.SqlCommand.SqlCommand(string, ...)
  • System.Data.SqlClient.SqlDataAdapter.SqlDataAdapter(string, ...)
  • System.Data.Odbc.OdbcCommand.OdbcCommand(string, ...)
  • System.Data.Odbc.OdbcDataAdapter.OdbcDataAdapter(string, ...)
  • System.Data.SqlServerCe.SqlCeCommand.SqlCeCommand(string, ...)
  • System.Data.SqlServerCe.SqlCeDataAdapter.SqlCeDataAdapter(string, ...)
  • System.Data.OracleClient.OracleCommand.OracleCommand(string, ...)
  • System.Data.OracleClient.OracleDataAdapter.OracleDataAdapter(string, ...)
  • Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecuteSqlCommand(...)
  • Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecuteSqlCommandAsync(...)
  • Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSql<TEntity>(System.Linq.IQueryable<TEntity>, System.FormattableString)
  • System.Data.SqlClient.SqlCommand.CommandText.set
  • System.Data.Odbc.OdbcCommand.CommandText.set
  • System.Data.SqlServerCe.SqlCeCommand.CommandText.set
  • System.Data.OracleClient.OracleCommand.CommandText.set

The following formatting methods will raise an issue:

  • String.Concat
  • String.Format

Ask Yourself Whether

  • the SQL query is built using string formatting technics, such as concatenating variables.
  • some of the values are coming from an untrusted source and are not sanitized.

You may be at risk if you answered yes to this question.

Recommended Secure Coding Practices

  • Avoid building queries manually using formatting technics. If you do it anyway, do not include user input in this building process.
  • Use parameterized queries, prepared statements, or stored procedures whenever possible.
  • You may also use ORM frameworks such as Hibernate which, if used correctly, reduce injection risks.
  • Avoid executing SQL queries containing unsafe input in stored procedures or functions.
  • Sanitize every unsafe input.

You can also reduce the impact of an attack by using a database account with low privileges.

Sensitive Code Example

Public Sub SqlCommands(ByVal connection As SqlConnection, ByVal query As String, ByVal param As String)
    Dim sensitiveQuery As String = String.Concat(query, param)
    command = New SqlCommand(sensitiveQuery) ' Questionable

    command.CommandText = sensitiveQuery ' Questionable

    Dim adapter As SqlDataAdapter
    adapter = New SqlDataAdapter(sensitiveQuery, connection) ' Questionable
End Sub

Public Sub Foo(ByVal context As DbContext, ByVal query As String, ByVal param As String)
    Dim sensitiveQuery As String = String.Concat(query, param)
    context.Database.ExecuteSqlCommand(sensitiveQuery) ' Questionable

    context.Query(Of User)().FromSql(sensitiveQuery) ' Questionable
End Sub

Exceptions

No issue will be raised in the following cases:

  • When the SQL query is a FormattableString provided directly to ExecuteSqlCommand, ExecuteSqlCommandAsync or FromSql. In this case the FormattableString is automatically converted to a parametrized query. This feature was added in Entity Framework Core 2.0. See Entity Framework's documentation for more information.
Public Sub Foo(ByVal context As DbContext, ByVal value As String)
    context.Database.ExecuteSqlCommand("SELECT * FROM mytable") ' No issue raised. The query is hard-coded. Thus no injection is possible.
    context.Database.ExecuteSqlCommand($"SELECT * FROM mytable WHERE mycol={value}") ' No issue raised. The FormattableString is transformed into a parametrized query.
End Sub

See

vbnet:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

vbnet:S3011

Changing or bypassing accessibility is security-sensitive. For example, it has led in the past to the following vulnerability:

private methods were made private for a reason, and the same is true of every other visibility level. Altering or bypassing the accessibility of classes, methods, or fields violates the encapsulation principle and could introduce security holes.

This rule raises an issue when reflection is used to change the visibility of a class, method or field, and when it is used to directly update a field value.

Ask Yourself Whether

  • there is a good reason to override the existing accessibility level of the method/field. This is very rarely the case. Accessing hidden fields and methods will make your code unstable as they are not part of the public API and may change in future versions.
  • this method is called by untrusted code. *
  • it is possible to modify or bypass the accessibility of sensitive methods or fields using this code. *

* You are at risk if you answered yes to those questions.

Recommended Secure Coding Practices

Don't change or bypass the accessibility of any method or field if possible.

If untrusted code can execute this method, make sure that it cannot decide which method or field's accessibility can be modified or bypassed.

Sensitive Code Example

Imports System.Reflection

Dim dynClass = Type.GetType("MyInternalClass")
' Sensitive. Using BindingFlags.NonPublic will return non-public members
Dim bindingAttr As BindingFlags = BindingFlags.NonPublic Or BindingFlags.Static
Dim dynMethod As MethodInfo = dynClass.GetMethod("mymethod", bindingAttr)
Dim result = dynMethod.Invoke(dynClass, Nothing)

See

vbnet:S1075

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.

See

vbnet:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

This rule ignores *, +, &, <<, and >>.

Noncompliant Code Example

If (a = a) Then
  doZ()
End If

If a = b OrElse a = b Then
  doW()
End If

Dim j = 5 / 5
j = 5 \ 5
j = 5 Mod 5
Dim k = 5 - 5

Dim i = 42
i /= i
i -= i

Exceptions

This rule ignores *, +, and =.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
vbnet:S2178

The use of non-short-circuit logic in a boolean context is likely a mistake - one that could cause serious program errors as conditions are evaluated under the wrong circumstances.

Noncompliant Code Example

If GetTrue() Or GetFalse() Then ' Noncompliant; both sides evaluated
End If

Compliant Solution

If GetTrue() OrElse GetFalse() Then ' true short-circuit logic
End If

See

  • CERT, EXP46-C. - Do not use a bitwise operator with a Boolean-like operand
vbnet:S5042

Expanding archive files is security-sensitive. For example, expanding archive files has led in the past to the following vulnerabilities:

Applications that expand archive files (zip, tar, jar, war, 7z, ...) should verify the path where the archive's files are expanded and not trust blindly the content of the archive. Archive's files should not be expanded outside of the root directory where the archive is supposed to be expanded. Also, applications should control the size of the expanded data to not be a victim of Zip Bomb attack. Failure to do so could allow an attacker to use a specially crafted archive that holds directory traversal paths (e.g. ../../attacker.sh) or the attacker could overload the file system, processors or memory of the operating system where the archive is expanded making the target OS completely unusable.

This rule raises an issue when code handle archives. The goal is to guide security code reviews.

Ask Yourself Whether

  • there is no validation of the name of the archive entry
  • there is no validation of the effective path where the archive entry is going to be expanded
  • there is no validation of the size of the expanded archive entry
  • there is no validation of the ratio between the compressed and uncompressed archive entry

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Validate the full path of the extracted file against the full path of the directory where files are expanded.

  • the canonical path of the expanded file must start with the canonical path of the directory where files are extracted.
  • the name of the archive entry must not contain "..", i.e. reference to a parent directory.

Stop extracting the archive if any of its entries has been tainted with a directory traversal path.

Define and control the ratio between compressed and uncompress bytes.

Define and control the maximum allowed expanded file size.

Count the number of file entries extracted from the archive and abort the extraction if their number is greater than a predefined threshold.

Sensitive Code Example

For Each entry As ZipArchiveEntry in archive.Entries
    ' entry.FullName could contain parent directory references ".." and the destinationPath variable could become outside of the desired path
    string destinationPath = Path.GetFullPath(Path.Combine(path, entry.FullName))
    entry.ExtractToFile(destinationPath) ' Sensitive, extracts the entry to a file

    Dim stream As Stream
    stream = entry.Open() ' Sensitive, the entry is about to be extracted
Next

See

vbnet:S1172

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

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

Noncompliant Code Example

Private Sub DoSomething(ByVal a As Integer, ByVal b as Integer) ' "b" is unused
    Compute(a)
End Sub

Private Function DoSomething2(ByVal a As Integer, ByVal b As Integer) As Integer ' "a" is unused
    Compute(b)
    Return b
End Function

Compliant Solution

Private Sub DoSomething(ByVal a As Integer)
    Compute(a)
End Sub

Private Function DoSomething2(ByVal b As Integer) As Integer
    Compute(b)
    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.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
vbnet:S1862

A chain of If/ElseIf statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to True.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

Noncompliant Code Example

If param = 1 Then
  OpenWindow()
ElseIf param = 2 Then
  CloseWindow()
ElseIf param = 1 Then ' Noncompliant
  MoveWindowToTheBackground()
End If

Compliant Solution

If param = 1 Then
  OpenWindow()
ElseIf param = 2 Then
  CloseWindow()
ElseIf param = 3 Then
  MoveWindowToTheBackground()
End If

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
vbnet:S1226

While it is technically correct to assign to parameters from within method bodies, doing so before the parameter value is read is likely a bug. Instead, initial values of parameters should be, if not treated as readonly then at least read before reassignment.

Noncompliant Code Example

Module Module1
    Sub Foo(ByVal a As Integer)
        a = 42                  ' Noncompliant
    End Sub
End Module

Compliant Solution

Module Module1
    Sub Foo(ByVal a As Integer)
        Dim tmp = a
        tmp = 42
    End Sub
End Module

Exceptions

ByRef parameters are ignored.

Module Module1
    Sub Foo(ByRef a As Integer)
        a = 42                  ' Ignored; it is a ByRef parameter
    End Sub
End Module
vbnet:S1313

Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:

Today's services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery and deployment:

  • The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
  • It forces the same address to be used in every environment (dev, sys, qa, prod).

Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service at this address or spoof the IP address. Such an attack is always possible, but in the case of a hardcoded IP address the fix will be much slower, which will increase an attack's impact.

Recommended Secure Coding Practices

  • make the IP address configurable.

Noncompliant Code Example

Dim ip = "192.168.12.42" ' Noncompliant
Dim address = IPAddress.Parse(ip)

Compliant Solution

Dim ip = ConfigurationManager.AppSettings("myapplication.ip") ' Compliant
Dim address = IPAddress.Parse(ip)

Exceptions

  • Although "::" is a valid IPv6 address, the rule doesn't report on it.
  • No issue is reported for 127.0.0.1 because loopback is not considered as sensitive

See

vbnet:S131

The requirement for a final Case Else clause is defensive programming.

This clause should either take appropriate action or contain a suitable comment as to why no action is taken.

Noncompliant Code Example

Select Case param ' Noncompliant - Case Else clause is missing
  Case 0
    DoSomething()
  Case 1
    DoSomethingElse()
End Select

Compliant Solution

Select Case param
  Case 0
    DoSomething()
  Case 1
    DoSomethingElse()
  Case Else ' Compliant
    DoSomethingElse()
End Select

See

vbnet:S4784

Using regular expressions is security-sensitive. It has led in the past to the following vulnerabilities:

Evaluating regular expressions against input strings is potentially an extremely CPU-intensive task. Specially crafted regular expressions such as (a+)+s will take several seconds to evaluate the input string aaaaaaaaaaaaaaaaaaaaaaaaaaaaabs. The problem is that with every additional a character added to the input, the time required to evaluate the regex doubles. However, the equivalent regular expression, a+s (without grouping) is efficiently evaluated in milliseconds and scales linearly with the input size.

Evaluating such regular expressions opens the door to Regular expression Denial of Service (ReDoS) attacks. In the context of a web application, attackers can force the web server to spend all of its resources evaluating regular expressions thereby making the service inaccessible to genuine users.

This rule flags any execution of a hardcoded regular expression which has at least 3 characters and at least two instances of any of the following characters: *+{.

Example: (a+)*

Ask Yourself Whether

  • the executed regular expression is sensitive and a user can provide a string which will be analyzed by this regular expression.
  • your regular expression engine performance decrease with specially crafted inputs and regular expressions.

You may be at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Check whether your regular expression engine (the algorithm executing your regular expression) has any known vulnerabilities. Search for vulnerability reports mentioning the one engine you're are using.

If the regular expression is vulnerable to ReDos attacks, mitigate the risk by using a "match timeout" to limit the time spent running the regular expression.

Remember also that a ReDos attack is possible if a user-provided regular expression is executed. This rule won't detect this kind of injection.

Sensitive Code Example

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Runtime.Serialization
Imports System.Text.RegularExpressions
Imports System.Web

Namespace N
    Public Class RegularExpression
        Private Sub Foo(ByVal pattern As String, ByVal options As RegexOptions, ByVal matchTimeout As TimeSpan,
                        ByVal input As String, ByVal replacement As String, ByVal evaluator As MatchEvaluator)
            ' All the following instantiations are Sensitive. Validate the regular expression and matched input.
            Dim r As Regex = New System.Text.RegularExpressions.Regex("(a+)+b")
            r = New System.Text.RegularExpressions.Regex("(a+)+b", options)
            r = New System.Text.RegularExpressions.Regex("(a+)+b", options, matchTimeout)

            ' All the following static methods are Sensitive.
            System.Text.RegularExpressions.Regex.IsMatch(input, "(a+)+b")
            System.Text.RegularExpressions.Regex.IsMatch(input, "(a+)+b", options)
            System.Text.RegularExpressions.Regex.IsMatch(input, "(a+)+b", options, matchTimeout)

            System.Text.RegularExpressions.Regex.Match(input, "(a+)+b")
            System.Text.RegularExpressions.Regex.Match(input, "(a+)+b", options)
            System.Text.RegularExpressions.Regex.Match(input, "(a+)+b", options, matchTimeout)

            System.Text.RegularExpressions.Regex.Matches(input, "(a+)+b")
            System.Text.RegularExpressions.Regex.Matches(input, "(a+)+b", options)
            System.Text.RegularExpressions.Regex.Matches(input, "(a+)+b", options, matchTimeout)

            System.Text.RegularExpressions.Regex.Replace(input, "(a+)+b", evaluator)
            System.Text.RegularExpressions.Regex.Replace(input, "(a+)+b", evaluator, options)
            System.Text.RegularExpressions.Regex.Replace(input, "(a+)+b", evaluator, options, matchTimeout)
            System.Text.RegularExpressions.Regex.Replace(input, "(a+)+b", replacement)
            System.Text.RegularExpressions.Regex.Replace(input, "(a+)+b", replacement, options)
            System.Text.RegularExpressions.Regex.Replace(input, "(a+)+b", replacement, options, matchTimeout)

            System.Text.RegularExpressions.Regex.Split(input, "(a+)+b")
            System.Text.RegularExpressions.Regex.Split(input, "(a+)+b", options)
            System.Text.RegularExpressions.Regex.Split(input, "(a+)+b", options, matchTimeout)
        End Sub
    End Class
End Namespace

Exceptions

Some corner-case regular expressions will not raise an issue even though they might be vulnerable. For example: (a|aa)+, (a|a?)+.

It is a good idea to test your regular expression if it has the same pattern on both side of a "|".

See

vbnet:S126

This rule applies whenever an If statement is followed by one or more ElseIf statements; the final ElseIf should be followed by an Else statement.

The requirement for a final Else statement is defensive programming.

The Else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final Case Else clause in a Select Case statement.

Noncompliant Code Example

If x = 0 Then
    DoSomething()
ElseIf x = 1 Then
    DoSomethingElse()
End If

Compliant Solution

If x = 0 Then
    DoSomething()
ElseIf x = 1 Then
    DoSomethingElse()
Else
    Throw New ArgumentException("...")
End If

Exceptions

None

See

vbnet:S1048

If Finalize or an override of Finalize throws an exception, and the runtime is not hosted by an application that overrides the default policy, the runtime terminates the process immediately without graceful cleanup (finally blocks and finalizers are not executed). This behavior ensures process integrity if the finalizer cannot free or destroy resources.

The rule reports on throw statements used in finalizers.

Noncompliant Code Example

Class MyClass
    Protected Overrides Sub Finalize()
        Throw New NotImplementedException() ' Noncompliant
    End Sub
End Class

Compliant Solution

Class MyClass
    Protected Overrides Sub Finalize()
        ' No throw
    End Sub
End Class
vbnet:S2255

Using cookies is security-sensitive. It has led in the past to the following vulnerabilities:

Attackers can use widely-available tools to read cookies, sensitive information written by the server will be exposed.

This rule flags code that writes cookies.

Ask Yourself Whether

  • sensitive information is stored inside the cookie.

You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

Cookies should only be used to manage the user session. The best practice is to keep all user-related information server-side and link them to the user session, never sending them to the client. In a very few corner cases, cookies can be used for non-sensitive information that need to live longer than the user session.

Do not try to encode sensitive information in a non human-readable format before writing them in a cookie. The encoding can be reverted and the original information will be exposed.

Using cookies only for session IDs doesn't make them secure. Follow OWASP best practices when you configure your cookies.

As a side note, every information read from a cookie should be Sanitized.

Sensitive Code Example

' === .NET Framework ===

Dim myCookie As HttpCookie = New HttpCookie("UserSettings")
myCookie("CreditCardNumber") = "1234 1234 1234 1234" ' Sensitive; sensitive data stored
myCookie.Values("password") = "5678" ' Sensitive
myCookie.Value = "mysecret" ' Sensitive
...
Response.Cookies.Add(myCookie)


' === .NET Core ===

Response.Headers.Add("Set-Cookie", ...) ' Sensitive
Response.Cookies.Append("mykey", "myValue") ' Sensitive

See

flex:S4524

switch can contain a default clause for various reasons: to handle unexpected values, to show that all the cases were properly considered.

For readability purpose, to help a developer to quickly find the default behavior of a switch statement, it is recommended to put the default clause at the end of the switch statement. This rule raises an issue if the default clause is not the first or the last one of the switch's cases.

Noncompliant Code Example

switch (param) {
  case 0:
    doSomething();
    break;
  default: // default clause should be the first or last one
    error();
    break;
  case 1:
    doSomethingElse();
    break;
}

Compliant Solution

switch (param) {
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
  default:
    error();
    break;
}

See

  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
flex:S1172

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

Noncompliant Code Example

function doSomething(a:int, b:int):void      // "b" is unused
{
  compute(a);
}

Compliant Solution

function doSomething(a:int):void
{
  compute(a);
}

Exceptions

The following cases are ignored

  • event handlers.
  • overriding methods.
  • all methods in classes implementing one or more interfaces.
  • methods which are empty or where the body consists of a single comment or a single throw statement (i.e. where the intention is apparently to simulate an abstract class).
override function doSomething(a:int):void {    // ignored
  compute(a);
}

...

class AbstractSomething {
  public function doSomething(a:int) {  // ignored
    throw new IllegalOperationError("doSomething() is abstract");
  }

...

interface I {
  function action(a:int, b:int);
}

class C extends I {
  function action(a:int, b:int) { // ignored
    return doSomethignWith(a);
  }
}

function clickHandler(event:MouseEvent):void { // ignored
   trace("click");
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
flex:S1301

switch statements are useful when there are many different cases depending on the value of the same expression.

For just one or two cases however, the code will be more readable with if statements.

Noncompliant Code Example

switch (variable) {
  case 0:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Compliant Solution

if (variable == 0) {
  doSomething();
} else {
  doSomethingElse();
}
flex:S1145

if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.

There are three possible causes for the presence of such code:

  • An if statement was changed during debugging and that debug code has been committed.
  • Some value was left unset.
  • Some logic is not doing what the programmer thought it did.

In any of these cases, unconditional if statements should be removed.

Noncompliant Code Example

if (true) {
  doSomething();
}
...
if (false) {
  doSomethingElse();
}

Compliant Solution

doSomething();
...

See

flex:S3923

Having all branches in a switch or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a switch/if chain at all.

Noncompliant Code Example

if (b == 0) {  // Noncompliant
  doOneMoreThing();
} else {
  doOneMoreThing();
}

int b = a > 12 ? 4 : 4;  // Noncompliant

switch (i) {  // Noncompliant
  case 1:
    doSomething();
    break;
  case 2:
    doSomething();
    break;
  case 3:
    doSomething();
    break;
  default:
    doSomething();
}

Exceptions

This rule does not apply to if chains without else-s, or to switch-es without default clauses.

if(b == 0) {    //no issue, this could have been done on purpose to make the code more readable
  doSomething();
} else if(b == 1) {
  doSomething();
}
flex:S1951

The trace() function outputs debug statements, which can be read by anyone with a debug version of the Flash player. Because sensitive information could easily be exposed in this manner, trace() should never appear in production code.

Noncompliant Code Example

    var val:Number = doCalculation();
    trace("Calculation result: " + val);  // Noncompliant

Compliant Solution

    var val:Number = doCalculation();

See

flex:S1871

Having two cases in a switch statement or two branches in an if chain 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 chain they should be combined, or for a switch, one should fall through to the other.

Noncompliant Code Example

switch (i) {
  case 1:
    doFirstThing();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  case 3:  // Noncompliant; duplicates case 1's implementation
    doFirstThing();
    doSomething();
    break;
  default:
    doTheRest();
}

if (a >= 0 && a < 10) {
  doFirstThing();
  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else if (a >= 20 && a < 50) {
  doFirstThing();
  doTheThing();  // Noncompliant; duplicates first condition
}
else {
  doTheRest();
}

Exceptions

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a switch statement that contain a single line of code with or without a following break.

if(a == 1) {
  doSomething();  //no issue, usually this is done on purpose to increase the readability
} else if (a == 2) {
  doSomethingElse();
} else {
  doSomething();
}

But this exception does not apply to if chains without else-s, or to switch-es without default clauses when all branches have the same single line of code. In case of if chains with else-s, or of switch-es with default clauses, rule S3923 raises a bug.

if(a == 1) {
  doSomething();  //Noncompliant, this might have been done on purpose but probably not
} else if (a == 2) {
  doSomething();
}
flex:FunctionSinglePointOfExit

This is required by IEC 61508, under good programming style.

Noncompliant Code Example

function func1() { // Noncompliant - there are two points of exit
  if (false) {
    return;
  }
}

function func2() { // Noncompliant - there are two points of exit
  if (a > 0) {
    return 0;
  }
  return -1;
}

Compliant Solution

function func1() {
  return;
}

function func2() {
}

function func3();
flex:SwitchWithoutDefault

The requirement for a final default clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken.

Noncompliant Code Example

switch (param) { // Noncompliant - default clause is missing
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
}

switch (param) {
  default: // Noncompliant - default clause should be the last one
    doSomething();
    break;
  case 0:
    doSomethingElse();
    break;
}

Compliant Solution

switch (param) {
  case 0:
    doSomethingElse();
    break;
  default:
    doSomethingElse();
    break;
}

See

flex:S1117

Overriding or shadowing a variable declared in an outer scope can strongly impact the readability, and therefore the maintainability, of a piece of code. Further, it could lead maintainers to introduce bugs because they think they're using one variable but are really using another.

Noncompliant Code Example

class Foo {
  public var myField:int;

  public function doSomething():String {
    var myField:int = 0;
    ...
  }
}

See

flex:S1116

Empty statements, i.e. ;, are usually introduced by mistake, for example because:

  • It was meant to be replaced by an actual statement, but this was forgotten.
  • There was a typo which lead the semicolon to be doubled, i.e. ;;.

Noncompliant Code Example

function doSomething():void {
  ;                                                       // Noncompliant - was used as a kind of TODO marker
}

function doSomethingElse():void {
  trace("Hello, world!");;                     // Noncompliant - double ;
  ...
  for (var i:int = 0; i < 3; trace(i), i++);       // Noncompliant - Rarely, they are used on purpose as the body of a loop. It is a bad practice to have side-effects outside of the loop body
  ...
}

Compliant Solution

function doSomething():void {}

function doSomethingElse():void {
  trace("Hello, world!");
  ...
  for (var i:int = 0; i < 3; i++){
    trace(i);
  }
  ...
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • CERT, MSC51-J. - Do not place a semicolon immediately following an if, for, or while condition
  • CERT, EXP15-C. - Do not place a semicolon on the same line as an if, for, or while statement
flex:S1314

Integer literals starting with a zero are octal rather than decimal values. While using octal values is fully supported, most developers do not have experience with them. They may not recognize octal values as such, mistaking them instead for decimal values.

Noncompliant Code Example

var myNumber:int = 010;  // Noncompliant. myNumber will hold 8, not 10 - was this really expected?

Compliant Solution

var myNumber:int = 8;

See

flex:CommentedCode

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

flex:NonEmptyCaseWithoutBreak

When the execution is not explicitly terminated at the end of a switch case, it continues to execute the statements of the following case. While this is sometimes intentional, it often is a mistake which leads to unexpected behavior.

Noncompliant Code Example

switch (myVariable) {
  case 1:
    foo();
    break;
  case 2:  // Both 'doSomething()' and 'doSomethingElse()' will be executed. Is it on purpose ?
    doSomething();
  default:
    doSomethingElse();
    break;
}

Compliant Solution

switch (myVariable) {
  case 1:
    foo();
    break;
  case 2:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Exceptions

This rule is relaxed in the following cases:

switch (myVariable) {
  case 0: // Empty case used to specify the same behavior for a group of cases.
  case 1:
    doSomething();
    break;
  case 2: // Use of return statement
    return;
  case 3: // Use of throw statement
    throw new IllegalStateException();
  case 4: // Use of continue statement
    continue;
  default: // For the last case, use of break statement is optional
    doSomethingElse();
}

See

  • MITRE, CWE-484 - Omitted Break Statement in Switch
  • CERT, MSC17-C. - Finish every set of statements associated with a case label with a break statement
  • CERT, MSC52-J. - Finish every set of statements associated with a case label with a break statement
flex:S127

A for loop stop condition should test the loop counter against an invariant value (i.e. one that is true at both the beginning and ending of every loop iteration). Ideally, this means that the stop condition is set to a local variable just before the loop begins.

Stop conditions that are not invariant are slightly less efficient, as well as being difficult to understand and maintain, and likely lead to the introduction of errors in the future.

This rule tracks three types of non-invariant stop conditions:

  • When the loop counters are updated in the body of the for loop
  • When the stop condition depend upon a method call
  • When the stop condition depends on an object property, since such properties could change during the execution of the loop.

Noncompliant Code Example

for (var i = 0; i < 10; i++) {
  ...
  i = i - 1; // Noncompliant
  ...
}

for (var i = 0; i < getMaximumNumber(); i++) {...}

Compliant Solution

int stopCondition = getMaximumNumber();
for (var i = 0; i < stopCondition; i++) {...}
flex:S1444

There is no good reason to declare a field "public" and "static" without also declaring it "const". Most of the time this is a kludge to share a state among several objects. But with this approach, any object can do whatever it wants with the shared state, such as setting it to null.

Noncompliant Code Example

public class Greeter {
  public static var foo:Foo = new Foo(...);
  ...
}

Compliant Solution

public class Greeter {
  public static const FOO:Foo = new Foo(...);
  ...
}

See

flex:S1442

Alert.show(...) can be useful for debugging during development, but in production mode this kind of pop-up could expose sensitive information to attackers, and should never be displayed.

Noncompliant Code Example

if(unexpectedCondition)
{
  Alert.show("Unexpected Condition");
}

See

cpp:S1016

Declaring overriding virtual functions with the override keyword (or virtual for code compliant with c++98, c++03 standards) removes the need to check the base class to determine whether a function is virtual. In addition, declaring a function as override ensures that the function really overrides a function defined in a base class, making the code more robust.

Noncompliant Code Example

class Base
{
  virtual void f();
};
class Derived : public Base
{
  void f(); // Noncompliant, implicitly declared "virtual"
};

Compliant Solution

For code compliant with c++98 or c++03 standards:

class Base
{
  virtual void f();
};
class Derived : public Base
{
  virtual void f(); // Compliant, explicitly declared "virtual"
};

For code compliant with at least c++11 standard:

class Base
{
  virtual void f();
};
class Derived : public Base
{
  void f() override; // Compliant
};

See

  • MISRA C++:2008, 10-3-2 - Each overriding virtual function shall be declared with the virtual keyword.

See also

cpp:S1013

If a base class is both virtual and non-virtual in a multiple inheritance hierarchy then there will be at least two copies of the base class sub-object in the derived object. This may not be consistent with developer expectations.

Noncompliant Code Example

class A {};
class B1: public virtual A {};
class B2: public virtual A {};
class B3: public A {};
class C: public B1, B2, B3 {}; // Noncompliant, A is both virtual (through B1 and B2) and non-virtual (through B3)

Compliant Solution

class A {};
class B1: public virtual A {};
class B2: public virtual A {};
class B3: public virtual A {};
class C: public B1, B2, B3 {}; // Compliant, A is always virtual

See

  • MISRA C++:2008, 10-1-3 - An accessible base class shall not be both virtual and non-virtual in the same hierarchy.
cpp:S2589

If a boolean expression doesn't change the evaluation of the condition, then it is entirely unnecessary, and can be removed. If it is gratuitous because it does not match the programmer's intent, then it's a bug and the expression should be fixed.

Noncompliant Code Example

a = true;
if (a) { // Noncompliant
  doSomething();
}

if (b && a) { // Noncompliant; "a" is always "true"
  doSomething();
}

if (c || !a) { // Noncompliant; "!a" is always "false"
  doSomething();
}

Compliant Solution

a = true;
if (foo(a)) {
  doSomething();
}

if (b) {
  doSomething();
}

if (c) {
  doSomething();
}

See

  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
  • MITRE, CWE-571 - Expression is Always True
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-489 - Leftover Debug Code
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
cpp:S990

<stdlib.h>'s abort, exit, getenv, and system have undefined, and implementation-defined behaviors, and should therefore be used.

Noncompliant Code Example

#include <stdlib.h>

void f( ) {
  exit(0); // Noncompliant
}

See

  • MISRA C:2004, 20.11 - The library functions abort, exit, getenv and system from library <stdlib.h> shall not be used.
  • MISRA C++:2008, 18-0-3 - The library functions abort, exit, getenv and system from library <cstdlib> shall not be used.
  • MISRA C:2012, 21.8 - The library functions abort, exit, getenv and system of <stdlib.h> shall not be used
  • CERT, ENV33-C. - Do not call system()
  • CERT, ERR50-CPP. - Do not abruptly terminate the program
cpp:S1011

The use of virtual base classes can introduce a number of undefined and potentially confusing behaviours. The use of virtual bases is not recommended.

Noncompliant Code Example

class B {};
class D: public virtual B {}; // Noncompliant, B is a virtual base

See

  • MISRA C++:2008, 10-1-1 - Classes should not be derived from virtual bases.
cpp:PPIncludeSignal

Signal handling contains implementation-defined and undefined behavior.

Noncompliant Code Example

#include <signal.h> /* Noncompliant */

See

  • MISRA C:2004, 20.8 - The signal handling facilities of <signal.h> shall not be used.
  • MISRA C:2012, 21.5 - The standard header file <signal.h> shall not be used
cpp:S871

C++ allows the traditional C-style casts [E.G. (int) f] and functional notation casts [E.G. int(f)], but adds its own forms:

  • static_cast<type>(expression)
  • const_cast<type>(expression)
  • dynamic_cast<type>(expression)
  • reinterpret_cast<type>(expression)

C-style casts and functional notation casts are largely functionally equivalent. However, when they do not invoke a converting constructor, C-style casts are capable of performing dangerous conversions between unrelated types and of changing a variable's const-ness. Attempt to do these things with an explicit C++-style cast, and the compiler will catch the error. Use a C-style or functional notation cast, and it cannot.

Additionally, C++-style casts are preferred because they are visually striking. The visual subtlety of a C-style or functional cast may mask that a cast has taken place, but a C++-style cast draws attention to itself, and makes the the programmer's intention explicit.

Noncompliant Code Example

#include <iostream>

class Base { };

class Derived: public Base
{
public:
  int a;
};

void DoSomethingElse(Derived *ptr)
{
  ptr->a = 42;
}

void DoSomething(const Base *ptr)
{
  Derived* derived = (Derived*)ptr; // Noncompliant; inadvertently removes constness
  DoSomethingElse(derived);
}

int main(int argc, char* argv[])
{
  Derived *ptr = new Derived();
  ptr->a = 1337;

  DoSomething(ptr);

  std::cout << ptr->a << std::endl; /* 1337 was expected, but 42 is printed */

  return 0;
}

Compliant Solution

/* ... */

void DoSomething(const Base *ptr)
{
  /* error: static_cast from type 'const Base*' to type 'Derived*' casts away qualifiers */
  Derived* derived = static_cast<Derived*>(ptr); // Compliant. Compile fails with above error
  DoSomethingElse(derived);
}

/* ... */

Exceptions

Void casts and explicit constructor calls are allowed.

See

  • MISRA C++:2008, 5-2-4 - C-style casts (other than void casts) and functional notation casts (other than explicit constructor calls) shall not be used.
cpp:S2583

Conditional expressions which are always true or false can lead to dead code. Such code is always buggy and should never be used in production.

Noncompliant Code Example

a = false;
if (a) { // Noncompliant
  doSomething(); // never executed
}

if (!a || b) { // Noncompliant; "!a" is always "true", "b" is never evaluated
  doSomething();
} else {
  doSomethingElse(); // never executed
}

Exceptions

This rule will not raise an issue when the condition is an integer constant or a const variable of integer type.

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

See

  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
cpp:S1017

A virtual function has an implementation that may be replaced in a child class. A pure virtual has no implementation, and must be implemented in child classes.

Hiding a base class implementation with a "pure implementation" (=0) is sure to confuse extenders, who may not be aware of the base class' implementation. Instead, they'll see there's no implementation in the class they're extending and assume that none exists. When that base class implementation contains crucial functionality such as freeing resources, this could cause future users of the class to introduce bugs.

This rule raises an issue if a pure virtual function overrides a virtual function that is not pure.

Noncompliant Code Example

struct A {
  virtual void func1();
  virtual void func2() = 0;
};

struct B : A {
  virtual void func1() = 0; // Noncompliant; override non-pure virtual
  virtual void func2() = 0; // Compliant; but useless
};

Compliant Solution

struct A {
  virtual void func1();
  virtual void func2() = 0;
};

struct B : A {
  virtual void func1(); // Compliant; non-pure virtual
};

See

  • MISRA C++:2008, 10-3-3 - A virtual function shall only be overridden by a pure virtual function if it is itself declared as pure virtual.
cpp:S982

setjmp.h functions allow the normal function mechanisms to be bypassed and should be used only with extreme caution, if at all.

Calling setjmp saves the program environment into the buffer passed into the call. Later calling longjmp returns execution to the point at which setjmp was called and restores the context that was saved into the buffer. But the values of non-volatile local variables after longjmp are indeterminate. Additionally invoking longjmp from a nested signal handler is undefined, as is longjmping back to a method that has already completed execution.

This rule flags all instances of setjmp, _setjmp, longjmp, _longjmp, sigsetjmp, siglongjmp and <setjmp.h>.

Noncompliant Code Example

#include <setjmp.h>  // Noncompliant

jmp_buf buf;

int main(int argc, char* argv[]) {
  int i = setjmp(buf);  // Noncompliant
  if (i == 0) { // value of i was assigned after env was saved & will be indeterminate after longjmp();
    // normal execution
  } else {
    // recover
  }
}

//...

void fun() {
  //...
  longjmp(buf, 1);  // Noncompliant
}

Compliant Solution

int main(int argc, char* argv[]) {
  // normal execution
}

//...

void fun() {
  //...
}

See

  • MISRA C:2004, 20.7 - The setjmp macro and the longjmp function shall not be used.
  • MISRA C++:2008, 17-0-5 - The setjmp macro and the longjmp function shall not be used.
  • MISRA C:2012, 21.4 - The standard header file <setjmp.h> shall not be used
  • CERT, MSC22-C. - Use the setjmp(), longjmp() facility securely
  • CERT, ERR52-CPP. - Do not use setjmp() or longjmp()
cpp:S864

The rules of operator precedence are complicated and can lead to errors. For this reason, parentheses should be used for clarification in complex statements. However, this does not mean that parentheses should be gratuitously added around every operation.

Parentheses are not needed:

  • with a unary operator, except when ! is used as left operand in comparison expressions
  • when all the operators in an expression are the same
  • when only a single operator is involved
  • around the right-hand side of an assignment operator unless the right-hand side itself contains an assignment

Parentheses are needed:

  • in the condition of a ternary operator if it uses operators
  • when overloaded shift operator << or >> is used in an expression with comparison operators

Noncompliant Code Example

x = a + b;
x = a * -1;
x = a + b + c;
x = f ( a + b, c );

x = a == b ? a : a - b; // Noncompliant
x = a + b - c + d; // Noncompliant
x = a * 3 + c + d; // Noncompliant

if (a = f(b,c) == true) { ... } // Noncompliant; == evaluated first
x - b ? a : c; // Noncompliant; "-" evaluated first
s << 5 == 1; // Noncompliant; "<<" evaluated first

Compliant Solution

x = a + b;
x = a * -1;
x = a + b + c;
x = f ( a + b, c );

x = ( a == b ) ? a : ( a - b );
x = ( a + b ) - ( c + d );
x = ( a * 3 ) + c + d;

if ( (a = f(b,c)) == true) { ... }
(x - b) ? a : c; // Compliant
(s << 5) == 1; // Compliant

See

  • MISRA C:2004, 12.1 - Limited dependence should be placed on C's operator precedence rules in expressions
  • MISRA C:2004, 12.2 - The value of an expression shall be the same under any order of evaluation that the standard permits.
  • MISRA C:2004, 12.5 - The operands of a logical && or || shall be primary-expressions.
  • MISRA C++:2008, 5-0-1 - The value of an expression shall be the same under any order of evaluation that the standard permits.
  • MISRA C++:2008, 5-0-2 - Limited dependence should be placed on C++ operator precedence rules in expressions
  • MISRA C++:2008, 5-2-1 - Each operand of a logical && or || shall be a postfix-expression.
  • MISRA C:2012, 12.1 - The precedence of operators within expressions should be made explicit
  • CERT, EXP00-C. - Use parentheses for precedence of operation
  • CERT, EXP53-J. - Use parentheses for precedence of operation
  • MITRE, CWE-783 - Operator Precedence Logic Error
cpp:S985

errno is a facility of C++ which should in theory be useful, but which in practice is poorly defined by ISO/IEC 14882:2003. A non-zero value may or may not indicate that a problem has occurred; therefore errno shall not be used.

Even for those functions for which the behaviour of errno is well defined, it is preferable to check the values of inputs before calling the function rather than relying on using errno to trap errors.

Noncompliant Code Example

#include <cstdlib>
#include <cerrno>

void f1 ( const char_t * str )
{
  errno = 0; // Noncompliant
  int32_t i = atoi ( str );
  if ( 0 != errno ) // Noncompliant
  {
    // handle error case???
  }
}

See

  • MISRA C:2004, 20.5 - The error indicator errno shall not be used.
  • MISRA C++:2008, 19-3-1 - The error indicator errno shall not be used.

See Also

  • ISO/IEC 14882:2003
cpp:S984

The use of dynamic memory can lead to out-of-storage run-time failures, which are undesirable.

The built-in new and delete operators, other than the placement versions, use dynamic heap memory. The functions calloc, malloc, realloc and free also use dynamic heap memory.

There is a range of unspecified, undefined and implementation-defined behaviour associated with dynamic memory allocation, as well as a number of other potential pitfalls. Dynamic heap memory allocation may lead to memory leaks, data inconsistency, memory exhaustion, non-deterministic behaviour, etc.

Note that some implementations may use dynamic heap memory allocation to implement other functions (for example, functions in the library cstring). If this is the case, then these functions shall also be avoided.

Noncompliant Code Example

int *b;
void initialize()
{
  b = (int *b) alloc ( 1024 * sizeof ( int ) ); // Noncompliant, could lead to an out-of-storage run-time failure.
  if( b == 0 )
  {
    // handle case when dynamic allocation failed.
  }
}

Compliant Solution

int b[1024]; // Compliant solution.

See

  • MISRA C:2004, 20.4 - Dynamic heap memory allocation shall not be used.
  • MISRA C++ 2008, 18-4-1 - Dynamic heap memory allocation shall not be used.
  • MISRA C:2012, 21.3 The memory allocation and deallocation functions of <stdlib.h> shall not be used
cpp:S986

offsetof can lead to undefined behavior when the argument types are incompatible or when bit fields are used. Therefore offsetof should be avoided.

Noncompliant Code Example

#include <stddef.h>

struct A
{
  int32_t i;
};

void f1 ( )
{
  offsetof ( A, i ); // Noncompliant
}

See

  • MISRA C:2004, 20.6 - The macro offsetof, in library <stddef.h>, shall not be used.
  • MISRA C++ 2008, 18-2-1 - The macro offsetof, in library <stddef.h>, shall not be used.
cpp:S989

<stdlib.h>'s atof, atoi, and atol functions, which convert strings to numbers, have undefined behavior when the strings cannot be converted, and should therefore be avoided.

Noncompliant Code Example

int converter (const char * numstr) {
  return atoi(numstr); // Noncompliant
}

Compliant Solution

int converter (const char * numstr) {
  return strtol(numstr, NULL, 10);
}

See

  • MISRA C:2004, 20.10 - The library functions atof, atoi and atol from library <stdlib.h> shall not be used.
  • MISRA C++:2008, 18-0-2 - The library functions atof, atoi and atol from library <cstdlib> shall not be used.
  • MISRA C:2012, 21.7 - The atof, atoi, atol and atoll functions of <stdlib.h> shall not be used
  • CERT, ERR34-C. - Detect errors when converting a string to a number
cpp:SingleGotoOrBreakPerIteration

Restricting the number of exits from a loop is done in the interests of good structured programming. One break or goto statement is acceptable in a loop since this allows, for example, for dual-outcome loops or optimal coding.

Noncompliant Code Example

With the default threshold of 1:

for (int i = 0; i < 10; i++) {
  if (...) {
    break;      //  Compliant
  }
  else if (...) {
    break;      //  Non-compliant - second jump from loop
  }
  else {
    ...
  }
}
while (...) {
  if (...) {
    break;      // Compliant
  }
  if (...) {
    break;      // Non-compliant - second jump from loop
  }
}

Compliant Solution

for (int i = 0; i < 10; i++) {
  if (...) {
    break;      //  Compliant
  }
}
while (...) {
  if (...) {
    break;    // Compliant
  }
}

See

  • MISRA C:2004, 14.6 - For any iteration statement there shall be at most one break statement used for loop termination.
  • MISRA C++:2008, 6-6-4 - For any iteration statement there shall be no more than one break or goto statement used for loop termination.
  • MISRA C:2012, 15.4 - There should be no more than one break or goto statement used to terminate any iteration statement
cpp:S867

The use of operands with types other than bool with these operators is unlikely to be meaningful (or intended). This rule allows the detection of such uses, which often occur because the logical operators (&&, || and !) can be easily confused with the bitwise operators (&, | and ~).

Noncompliant Code Example

if ( 1 && ( c < d ) ) // Noncompliant
if ( ( a < b ) && ( c + d ) ) // Noncompliant
if ( u8_a && ( c + d ) ) // Noncompliant
if ( !0 ) // Noncompliant, always true
if ( !ptr ) // Noncompliant
if ( ( a < b ) && ( c < d ) ) // Compliant
if ( !false ) // Compliant

Compliant Solution

if ( 1 != 0 && ( c < d ) ) // Compliant, but left operand is always true
if ( ( a < b ) && ( c + d ) != 0 ) // Compliant
if ( u8_a != 0 && ( c + d ) != 0) // Compliant
if ( 0 == 0 ) // Compliant, always true
if ( ptr != NULL ) // Compliant

See

  • MISRA C:2004, 12.6 - The operands of logical operators (&&, || and !) should be effectively Boolean. Expressions that are effectively Boolean should not be used as operands to operators other than (&&, || and !).
  • MISRA C++:2008, 5-3-1 - Each operand of the ! operator, the logical && or the logical || operators shall have type bool.
  • CERT, EXP54-J. - Understand the differences between bitwise and logical operators
cpp:S1144

private methods that are never executed are dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.

Noncompliant Code Example

static void unusedStaticFunction() { // Noncompliant
}

class Server {
public:
  void start() { // Compliant, the member function "start()" is public
    log("start");
  }
private:
  void clear() { // Noncompliant, the member function "clear()" is unused
  }
  void log(const char * msg) { // Compliant, the member function "log()" is used in "start() { ... }"
    printf(msg);
  }
};

See

* MISRA C++:2008, 0-1-10 - Every defined function shall be called at least once.

cpp:NarrowAndWideStringConcat

Concatenation of wide and narrow string literals leads to undefined behavior.

Noncompliant Code Example

wchar_t n_array[] = "Hello" L"World";     // Noncompliant
wchar_t w_array[] = L"Hello" "World";     // Noncompliant

Compliant Solution

char_t n_array[] = "Hello" "World";     // Compliant
wchar_t w_array[] = L"Hello" L"World";	// Compliant

See

  • MISRA C++:2008, 2-13-5 - Narrow and wide string literals shall not be concatenated.
  • CERT STR10-C. - Do not concatenate different type of string literals
cpp:S873

Enumerations have implementation-defined representation and so should not be used in arithmetic contexts.

Noncompliant Code Example

enum { COLOUR_0, COLOUR_1, COLOUR_2, COLOUR_COUNT } colour;
if ( COLOUR_0 == colour ) { ... }
if ( ( COLOUR_0 + COLOUR_1 ) == colour ) { ... } // Noncompliant, arithmetic used
if ( colour < COLOUR_COUNT ) { ... }

See

  • MISRA C++:2008, 4-5-2 - Expressions with type enum shall not be used as operands to builtin operators other than the subscript operator [ ], the assignment operator =, the equality operators == and !=, the unary & operator, and the relational operators <, <=, >, >=
cpp:S872

The use of bool operands with other operators is unlikely to be meaningful (or intended). Best case it will be confusing to maintainers, worst case it will not have the intended effect. Either way, it is highly recommended to stick to boolean operators when dealing with bool operands.

This rule allows the detection of such uses, which often occur because the logical operators (&&, || and !) can be easily confused with the bitwise operators (&, | and ~).

Noncompliant Code Example

bool b1 = true;
bool b2 = false;
int8_t s8a;
if ( b1 & b2 ) // Noncompliant
if ( ~b1 ) // Noncompliant
if ( b1 < b2 ) // Noncompliant
if ( b1 ^ b2 ) // Noncompliant

Compliant Solution

if ( b1 && b2 )
if ( !b1 )
if ( b1 == false )
if ( b1 == b2 )
if ( b1 != b2 )
s8a = b1 ? 3 : 7;

Exceptions

Operators |= and &= are ignored when used with bool operands. Operator ++ is also ignored with a bool operand because it is covered by rule S2668.

void test(bool b1, bool b2, int i1) {
  b1 |= b2; // ignored
  b1++; // ignored here, handled by S2668
  b1 &= b2; // ignored
  b1 &= i1; // Noncompliant; right operand is not a bool
}

See

  • MISRA C++:2008, 4-5-1 - Expressions with type bool shall not be used as operands to built-in operators other than the assignment operator =, the logical operators &&, ||, !, the equality operators == and !=, the unary & operator, and the conditional operator.
cpp:S874

Most bitwise operators (~, >>, >>=, &, &=, ^, ^=, |, and |=) have implementation-dependent results when performed on signed operands, and bitwise left shift (<< and <<=) has undefined behavior when performed on negative operands. Therefore bitwise operations should not be performed on signed operands.

Noncompliant Code Example

if ( ( uint16_a & int16_b ) == 0x1234U )
if ( ~int16_a == 0x1234U )

Compliant Solution

if ( ( uint16_a | uint16_b ) == 0x1234U )
if ( ~uint16_a == 0x1234U )

Exceptions

When used as bit flags, it is acceptable to use preprocessor macros as arguments to the & and | operators even if the value is not explicitly declared as unsigned.

fd = open(file_name, UO_WRONLY | UO_CREAT | UO_EXCL | UO_TRUNC, 0600);

If the right-side operand to a shift operator is known at compile time, it is acceptable for the value to be represented with a signed type provided it is positive.

#define SHIFT 24
foo = 15u >> SHIFT;

See

  • MISRA C:2004, 12.7 - Bitwise operators shall not be applied to operands whose underlying type is signed
  • MISRA C++:2008, 5-0-21 - Bitwise operators shall only be applied to operands of unsigned underlying type
  • MISRA C:2012, 10.1 - Operands shall not be of an inappropriate essential type
  • CERT, INT13-C. - Use bitwise operators only on unsigned operands
  • MITRE, CWE-682 - Incorrect Calculation
cpp:S876

Applying the unary minus operator to an unsigned variable or expression will always yield another unsigned expression. More plainly, in some cases the operation itself is meaningless, and in some other cases the result will be unexpected. In all cases it is bad practice. Therefore the unary minus operator should not be applied to unsigned variables or expressions.

Noncompliant Code Example

uint8_t a = -1U;
int32_t b = -a; // Noncompliant; b is assigned -255
uint32_t c = 1U;
int64_t d = -c; // Noncompliant; d is assigned MAX_UINT

Exceptions

This rule ignores -1U because it is commonly used as shorthand for MAX_UINT.

See

  • MISRA C:2004, 12.9 - The unary minus operator shall not be applied to an expression whose underlying type is unsigned.
  • MISRA C++:2008, 5-3-2 - The unary minus operator shall not be applied to an expression whose underlying type is unsigned.
  • MISRA C:2012, 10.1 - Operands shall not be of an inappropriate essential type
cpp:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

cpp:S878

The comma operator takes two expressions, executes them from left to right and returns the result of the second one. Use of this operator is generally detrimental to the readability and reliability of code, and the same effect can be achieved by other means.

Noncompliant Code Example

i = a += 2, a + b;  // What's the value of i ?

Compliant Solution

a +=  2;
i = a + b;

Exceptions

Use of comma operator is tolerated in initialization and increment expressions of for loops.

for(i = 0, j = 5; i < 6; i++, j++) { ... }

See

  • MISRA C:2004, 12.10 - The comma operator shall not be used.
  • MISRA C++:2008, 5-18-1 - The comma operator shall not be used.
  • MISRA C:2012, 12.3 - The comma operator should not be used
cpp:S2324

Flexible array members are most likely to be used in conjunction with dynamic memory allocation.

The presence of flexible array members modifies the behaviour of the sizeof operator in ways that might not be expected by a programmer. The assignment of a structure that contains a flexible array member to another structure of the same type may not behave in the expected manner as it copies only those elements up to but not including the start of the flexible array member.

Noncompliant Code Example

#include <stdlib.h>
struct s
{
  uint16_t len;
  uint32_t data[ ]; // Noncompliant - flexible array member
} str;

struct s *copy ( struct s *s1 )
{
  struct s *s2 = malloc ( sizeof ( struct s ) + ( s1->len * sizeof ( uint32_t ) ) );
  /* Omit malloc ( ) return check for brevity */
  *s2 = *s1; /* Only copies s1->len */
  return s2;
}

See

  • MISRA C:2012, 18.7 - Flexible array members shall not be declared.
cpp:S3656

If a class is just a data store without logic, it can safely contain only public member variables and no member functions. Otherwise, data members are tightly coupled to the class' logic, and encapsulation must be used. In this case, having only private member variables ensures that logic is defined only in the member functions of the class. Structuring it this way makes It easier to guarantee integrity and easier for maintainers to understand the code.

But when an object provides encapsulation by using protected member variables, data integrity logic can be spread through the class and all its derived class, becoming a source of complexity and that will be error prone for maintainers and extenders.

That's why protected member variables should be changed to private and manipulated exclusively through public or protected member functions of the base class.

This rule raises an issue when a class or struct contains protected member variables.

Noncompliant Code Example

class Stat {
public:
  long int getCount() {
    return count;
  }
protected:
  long int count = 0; // Noncompliant; expose a protected member variable.
                      // By just looking at "Stat" class, it's not possible to be sure that "count"
                      // is modified properly, we also need to check all derived classes
};

class EventStat : public Stat {
public:
  void onEvent() {
    if (count < LONG_MAX) {
      count++;
    }
  }
};

Compliant Solution

class Stat {
public:
  long int getCount() {
    return count;
  }
protected:
  void increment() { // Compliant; expose a protected member function
    if (count < LONG_MAX) {
      count++;
    }
  }
private:
  long int count = 0; // member variable is private
};

class EventStat : public Stat {
public:
  void onEvent() {
    increment();
  }
};

See

  • MISRA C++:2008, 11-0-1 - Member data in non-POD class types shall be private.
cpp:S2323

Line-splicing occurs when the \ character is immediately followed by a new-line character. If the source line containing a // comment ends with a '\', the next line becomes part of the comment. This may result in unintentional removal of code.

Noncompliant Code Example

void f ( void )
{
  int x = 0; // comment \
  if (x)
  {
    ++x; /* This is always executed */
  }
}

See

  • MISRA C:2012, 3.2 - Line-splicing shall not be used in // comments
cpp:S1117

Overriding or shadowing a variable declared in an outer scope can strongly impact the readability, and therefore the maintainability, of a piece of code. Further, it could lead maintainers to introduce bugs because they think they're using one variable but are really using another.

Noncompliant Code Example

class Foo
{
public:
  void doSomething();

private:
  int myField;
};

void Foo::doSomething()
{
    int myField = 0; // Noncompliant
    // ...
}
void f(int x, bool b) {
  int y = 4;
  if (b) {
    int x = 7; // Noncompliant
    int y = 9; // Noncompliant
    // ...
  }
}

Compliant Solution

class Foo
{
public:
  void doSomething();

private:
  int myField;
};

void Foo::doSomething()
{
    int myInternalField = 0; // Compliant
    // ...
}
void f(int x, bool b) {
  int y = 4;
  if (b) {
    int z = 7; // Better yet: Use meaningful names
    int w = 9;
    // ...
  }
}

Exceptions

It is common in a constructor to have constructor arguments shadowing the fields that they will initialize. This pattern avoids the need to select new names for the constructor arguments, and will not be reported by this rule:

class Point{
public:
  Point(int x, int y) : x(x), y(y) {} // Compliant by exception
private:
  int x;
  int y;
};

See

  • MISRA C:2004, 5.2 - Identifiers in an inner scope shall not use the same name as an identifier in an outer scope, and therefore hide that identifier
  • MISRA C++:2008, 2-10-2 - Identifiers declared in an inner scope shall not hide an identifier declared in an outer scope
  • MISRA C:2012, 5.3 - An identifier declared in an inner scope shall not hide an identifier declared in an outer scope
  • CERT, DCL01-C. - Do not reuse variable names in subscopes
  • CERT, DCL51-J. - Do not shadow or obscure identifiers in subscopes
cpp:S1116

Empty statements, i.e. ;, are usually introduced by mistake, for example because:

  • It was meant to be replaced by an actual statement, but this was forgotten.
  • There was a typo which lead the semicolon to be doubled, i.e. ;;.

Noncompliant Code Example

void doSomething() {
  ;                                                       // Noncompliant - was used as a kind of TODO marker
}

Compliant Solution

void doSomething() {
}

Exceptions

In the case of empty expanded macro and in the case of 2 consecutive semi-colons when one of the two is part of a macro-definition then the issue is not raised.

Example:

#define A(x) x;
#define LOG(x)

void fun() {
  A(5);
  LOG(X);
}

See

  • MISRA C:2004, 14.3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment provided that the first character following the null statement is a white-space character.
  • MISRA C++:2008, 6-2-3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment, provided that the first character following the null statement is a white-space character.
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • CERT, MSC51-J. - Do not place a semicolon immediately following an if, for, or while condition
  • CERT, EXP15-C. - Do not place a semicolon on the same line as an if, for, or while statement
cpp:S961

This is a constraint error, but preprocessors have been known to ignore this problem. Each argument in a function-like macro must consist of at least one preprocessing token otherwise the behaviour is undefined.

See

  • MISRA C:2004, 19.8 - A function-like macro shall not be invoked without all of its arguments.
  • MITRE, CWE-628 - Function Call with Incorrectly Specified Arguments
cpp:S969

The defined preprocessing directive is used in the context of #if and #elif expressions to see whether a given identifier has been defined as a macro. It returns a value of 0 (false) or 1 (true), and has two valid forms, defined IDENTIFIER and defined ( IDENTIFIER ). Since it is essentially a macro existence check, it cannot take expressions as arguments.

Note that since

#if defined AN_IDENTIFIER

is equivalent to

#ifdef AN_IDENTIFIER

defined is most useful when there are multiple arguments to check, E.G.

#if defined AAA || defined BBB

Noncompliant Code Example

#if defined ( X > Y ) // Noncompliant; expressions not allowed

Compliant Solution

#if defined X && defined Y && X > Y

See

  • MISRA C:2004, 19.14 - The defined preprocessor operator shall only be used in one of the two standard forms.
  • MISRA C++:2008, 16-1-1 - The defined preprocessor operator shall only be used in one of the two standard forms.
cpp:S960

It is tempting to treat function-like macros as functions, but the two things work differently. For instance, the use of functions offers parameter type-checking, while the use of macros does not. Additionally, with macros, there is the potential for a macro to be evaluated multiple times. In general, functions offer a safer, more robust mechanism than function-like macros, and that safety usually outweighs the speed advantages offered by macros. Therefore functions should be used instead when possible.

Noncompliant Code Example

#define CUBE (X) ((X) * (X) * (X)) // Noncompliant

void func(void) {
  int i = 2;
  int a = CUBE(++i); // Noncompliant. Expands to: int a = ((++i) * (++i) * (++i))
  // ...
}

Compliant Solution

inline int cube(int i) {
  return i * i * i;
}

void func(void) {
  int i = 2;
  int a = cube(++i); // yields 27
  // ...
}

See

  • MISRA C:2004, 19.7 - A function should be used in preference to a function-like macro.
  • MISRA C++:2008, 16-0-4 - Function-like macros shall not be defined.
  • MISRA C:2012, Dir. 4.9 - A function should be used in preference to a function-like macro where they are interchangeable
  • CERT, PRE00-C. - Prefer inline or static functions to function-like macros
cpp:S966

An attempt to use an undefined identifier may elicit a warning from the preprocessor. Or it may not; the preprocessor may simply assume that the undefined token has a value of 0.

Therefore macro identifiers should not be used in preprocessor directives until after they have been defined, and this limited usage should be enforced with the use of definition tests.

Noncompliant Code Example

#if x > 0  /* x assumed to be zero if not defined */
#include SOMETHING_IMPORTANT
#endif

#ifdef y  /* Okay; y is not evaluated */
#if y > 0 /* Okay; y must be defined to reach this point */
...
#endif
#endif

Compliant Solution

#define x 10
...
#if x > 0
#include SOMETHING_IMPORTANT
#endif

#if defined ( y ) && ( y > 0 )  /* more compact form, same result as before */
...
#endif

See

  • MISRA C:2004, 19.11 - All macro identifiers in preprocessor directives shall be defined before use, except in #ifdef and #ifndef preprocessor directives and the defined() operator.
  • MISRA C:2012, 20.9 - All identifiers used in the controlling expression of #if or #elif preprocessing directives shall be #define’d before evaluation
cpp:S967

Because the evaluation order of # and ## are not specified, the results of using them both in the same macro could be unpredictable. Therefore macros should contain at most once instance of either # or ##.

Noncompliant Code Example

#define PRINT_FIELD(field) printf (#field " = " ##field);

Compliant Solution

#define FIELD_VAL(field) ##field
#define PRINT_FIELD(field) printf(#field " = " FIELD_VAL(field))

See

  • MISRA C:2004, 19.12
  • MISRA C++ 2008, 16-3-1
  • Related: MISRA C:2012, 20.11
cpp:S2335

There is potential for confusion if an octal or hexadecimal escape sequence is immediately followed by other characters. Instead, such sequences shall be terminated by either:

  • The start of another escape sequence.
  • The end of the character constant or the end of a string literal.

Noncompliant Code Example

const char *s1 = "\x41g";  // Noncompliant
int c1 = '\141t'; // Noncompliant

Compliant Solution

const char *s2 = "\x41" "g"; // Compliant - terminated by end of literal
const char *s3 = "\x41\x67"; // Compliant - terminated by another escape
int c2 = '\141\t'; // Compliant - terminated by another escape

See

  • MISRA C:2012, 4.1 - Octal and hexadecimal escape sequences shall be terminated
cpp:S1003

A using directive makes names from another namespace available in the current scope. It should only be used when those names do not create an ambiguity with other names, otherwise, it is better to fully qualify the names you want to use.

When you write a header file, you don't know from which context it will be included. Therefore, if this header contains using directives, you cannot be sure that they will not create ambiguities in that context. Those ambiguities could lead to compilation failures or, worse, to a different function being selected by overload resolution depending on the order of inclusion of headers.

A using declaration behaves in the same way but only for one name. Because of their much narrower scope, this rule does not apply to using declarations.

Noncompliant Code Example

// f1.h
void foo ( char_t a );
namespace NS1
{
  void foo( int32_t a );
}

inline void bar ( )
{
  foo ( 0 );
}

// f2.h
namespace NS1
{
}
using namespace NS1; // Noncompliant

// f1.cc
#include "f1.h"
#include "f2.h"

int32_t m1 ( )
{
  bar ( ); // bar calls foo ( char_t );
}

// f2.cc
#include "f2.h"
#include "f1.h"
void m2 ( )
{
  bar ( ); // bar calls foo ( int32_t );
}

Exceptions

The issue only happens if the using directive is at global scope or at namespace scope. If is is inside a function body, it will cease to be in effect at the end of the current scope, and will not propagate to the users of the header file.

See

* MISRA C++:2008, 7-3-6 - using-directives and using-declarations (excluding class scope or function scope using-declarations) shall not be used in header files.

* C++ core guidelines SF.7 Don’t write using namespace at global scope in a header file

cpp:S1244

Floating point math is imprecise because of the challenges of storing such values in a binary representation. Even worse, floating point math is not associative; push a float or a double through a series of simple mathematical operations and the answer will be different based on the order of those operation because of the rounding that takes place at each step.

Even simple floating point assignments are not simple:

float f = 0.1; // 0.100000001490116119384765625
double d = 0.1; // 0.1000000000000000055511151231257827021181583404541015625

(Results will vary based on compiler and compiler settings.)

Therefore, the use of the equality (==) and inequality (!=) operators on float or double values is almost always an error.

The accepted solution is to use or write a float comparison library that takes floating-point granularity (FLT_EPSILON) and the magnitude of the numbers being compared into account.

This rule checks for the use of direct and indirect equality/inequailty tests on floats and doubles.

Noncompliant Code Example

float myNumber = 3.146;
if ( myNumber == 3.146 ) {  //Noncompliant. Because of floating point imprecision, this will be false
  // ...
}

if (myNumber <= 3.146 && mNumber >= 3.146) { // Noncompliant indirect equality test
  // ...
}

if (myNumber < 4 || myNumber > 4) { // Noncompliant indirect inequality test
  // ...
}

See

  • MISRA C:2004, 13.3 - Floating-point expressions shall not be tested for equality or inequality.
  • MISRA C++:2008, 6-2-2 - Floating-point expressions shall not be directly or indirectly tested for equality or inequality
cpp:S860

Converting an integer type to a pointer generally leads to unspecified behavior. There are several cases where it might be legitimate:

- Converting the integral literal 0 to the null pointer (but you should use nullptr instead, see S4962),

- Converting back to a pointer a pointer value that was converted to a large enough integer (see S1767),

- On embedded devices, device drivers... converting a hard-coded address to a pointer to read some specific memory (this often goes together with the use of volatile, since such memory values can change from the outside of the program).

Since even legitimate cases are corner cases that require to be reviewed carefully, this rule simply reports all places where an integer is cast into a pointer (except the literal 0).

Noncompliant Code Example

struct S {
  int i;
  int j;
};

void f(void* a);

void g(int i) {
  S* s1 = (S*)i; // Noncompliant
  f((void*)i); // Noncompliant
}

See

  • MISRA C++ 2008, 5-2-8 - An object with integer type or pointer to void type shall not be converted to an object with pointer type.
  • CERT, INT36-C. - Converting a pointer to integer or integer to pointer
cpp:S2216

The values that can be represented by a signed bit field with a length of one bit may not meet developer expectations. For example according to the C99 Standard, Section 6.2.6.2, a single-bit signed bit-field has a single (one) sign bit and no (zero) value bits.

This rule does not apply to unnamed bit fields, as their values cannot be accessed.

Noncompliant Code Example

signed int f:1;  // Noncompliant; there's only room here for the sign

Compliant Solution

unsigned int f:1;

or

signed int:1; // unnamed

or

signed int f:2;

See

  • MISRA C:2004, 6.5 - Bit fields of type signed int shall be at least 2 bits long
  • MISRA C:2012, 6.2 - Single-bit named bit fields shall not be of a signed type
  • MISRA C++:2008, 9-6-4 - Named bit-fields with signed integer type shall have a length of more than one bit
cpp:S3548

It is a best practice in the public part of a class body, to describe only information relevant for reusers of this class, without implementation details like inline specifier.

For inline member function defined outside of the class body, this rule verifies that inline is set on the definition and not on the declaration of the function.

Noncompliant Code Example

class Foo {
  public:
    inline void method();  // Noncompliant
    // ...
};
void Foo::method() {
  // ...
}

Compliant Solution

class Foo {
  public:
    void method();
    // ...
};
inline void Foo::method() {
  // ...
}

See

cpp:S1006

Overriding the default parameter value inherited from a parent class will lead to unexpected results when the child class is referenced from a pointer to the parent class.

Noncompliant Code Example

enum E_ShapeColor {E_RED, E_GREEN, E_BLUE};
class Shape
{
public:
  virtual void draw(E_ShapeColor color = E_RED) const = 0;
  ...
};
class Rectangle : public Shape
{
public:
  virtual void draw(E_ShapeColor color = E_BLUE) const; // Non-compliant
  ...
};

...

E_ShapeColor *shape = new Rectangle;
shape->draw;  // unexpectedly calls Rectangle::draw(RED)

Compliant Solution

enum E_ShapeColor {E_RED, E_GREEN, E_BLUE};
class Shape
{
public:
  virtual void draw(E_ShapeColor color = E_RED) const = 0;
  ...
};
class Rectangle : public Shape
{
public:
// draw() no longer overrides the default parameter. There is no need to re-declare it
  ...

See

  • MISRA C++ 2008, 8-3-1 - Parameters in a overriding virtual function shall either use the same default arguments as the function they override, or else shall not specify any default arguments.
cpp:InvalidEscapeSequence

The use of an undefined escape sequence leads to undefined behavior. The defined escape sequences (ISO/IEC 14882:2003 [1] §2.13.2) are: \n, \t, \v, \b, \r, \f, \a, \\, ?, \', \", \<Octal Number>, and \x<Hexadecimal Number>.

Noncompliant Code Example

const char_t a[ 2 ] = "\k";   // Noncompliant
const char_t b[ 2 ] = "\b";   // Compliant

See

  • MISRA C:2004, 4.1 - Only those escape sequences that are defined in ISO C standard shall be used.
  • MISRA C++:2008, 2-13-1 - Only those escape sequences that are defined in ISO/IEC 14882:2003 shall be used.
cpp:S859

Using const in your code improves reliability and maintenance. When passing a const value, developers assume that its value won't be changed. But using const_cast<>() to cast away a const qualifier, destroys developer assumptions and code reliability. It is a bad practice and reveals a flaw in the design. Furthermore, it may have an undefined behavior.

Noncompliant Code Example

User& func(const int& value, const User& user) {
  const_cast<int&>(value) = 2; // Noncompliant and undefined behavior
  return const_cast<User&>(user); // Noncompliant
}

Compliant Solution

User& func(int& value, User& user) {
  value = 2;
  return user;
}

See

  • MISRA C:2004, 11.5 - A cast shall not be performed that removes any const or volatile qualification from the type addressed by a pointer
  • MISRA C++:2008, 5-2-5 - A cast shall not remove any const or volatile qualification from the type of a pointer or reference
  • MISRA C:2012, 11.8 - A cast shall not remove any const or volatile qualification from the type pointed to by a pointer
  • CERT, EXP32-C. - Do not access a volatile object through a nonvolatile reference
  • CERT, EXP05-C. - Do not cast away a const qualification
  • CERT, EXP55-CPP. - Do not access a cv-qualified object through a cv-unqualified type
cpp:OctalConstantAndSequence

Integer literals starting with a zero are octal rather than decimal values. While using octal values is fully supported, most developers do not have experience with them. They may not recognize octal values as such, mistaking them instead for decimal values.

Noncompliant Code Example

int myNumber = 010;   // Noncompliant. myNumber will hold 8, not 10 - was this really expected?

Compliant Solution

int myNumber = 8;

See

  • MISRA C:2004, 7.1 - Octal constants (other than zero) and octal escape sequences shall not be used.
  • MISRA C++:2008, 2-13-2 - Octal constants (other than zero) and octal escape sequences (other than "\0") shall not be used
  • MISRA C:2012, 7.1 - Octal constants shall not be used
  • CERT, DCL18-C. - Do not begin integer constants with 0 when specifying a decimal value
  • CERT, DCL50-J. - Use visually distinct identifiers
cpp:PPIncludeCtime

Various aspects of ctime are implementation-defined or unspecified, such as the formats of times.

Noncompliant Code Example

#include <ctime>  /* Noncompliant */

void f()
{
  clock();
}

See

  • MISRA C++:2008, 18-0-4 - The time handling functions of library <ctime> shall not be used.
cpp:S854

The type of an integer is dependent on a complex combination of factors including:

  • The magnitude of the constant;
  • The implemented sizes of the integer types;
  • The presence of any suffixes;
  • The number base in which the value is expressed (i.e. decimal, octal or hexadecimal).

For example, the value 0x8000 is of type unsigned int in a 16-bit environment, but of type (signed) int in a 32-bit environment.

Note:

  • Any value with a "U" suffix is of unsigned type;
  • An unsuffixed decimal value less than 2^31 is of signed type.

But:

  • An unsuffixed hexadecimal value greater than or equal to 2^15 may be of signed or unsigned type;
  • For C90, an unsuffixed decimal value greater than or equal to 2^31 may be of signed or unsigned type.

In C++, if an overload set includes candidates for an unsigned int and an int, then the overload that would be matched by 0x8000 is therefore dependent on the implemented integer size. Adding a "U" suffix to the value specifies that it is unsigned.

See

  • MISRA C:2004, 10.6 - A "U" suffix shall be applied to all constants of unsigned type.
  • MISRA C++:2008, 2-13-3 - A "U" suffix shall be applied to all octal or hexadecimal integer literals of unsigned type.
  • MISRA C:2012, 7.2 - A "u" or "U" suffix shall be applied to all integer constants that are represented in an unsigned type.
cpp:S855

Conversion of a function pointer to a different type of pointer results in undefined behaviour. This means, for example, that a pointer to a function cannot be converted to a pointer to a different type of function.

Noncompliant Code Example

int f(int a)
{
  float (*p)(float) = (float (*)(float)) & f; // Noncompliant
}

See

  • MISRA C:2004, 11.1 - Conversions shall not be performed between a pointer to a function and any type other than an integral type.
  • MISRA C++:2008, 5-2-6 - A cast shall not convert a pointer to a function to any other pointer type, including a pointer to function type.
  • MISRA C:2012, 11.1 - Conversions shall not be performed between a pointer to a function and any other type
cpp:S977

Preprocessing directives (lines that start with #) can be used to conditionally include or exclude code from compilation. Malformed preprocessing directives could lead to the exclusion or inclusion of more code than was intended. Therefore all preprocessing directives should be syntactically meaningful.

Noncompliant Code Example

#define AAA 2
...
int foo(void)
{
  int x = 0;
  ...

#ifndef AAA
  x = 1;
#else1  /* Noncompliant */
  x = AAA;
#endif

  ...
  return x;
}

Compliant Solution

#define AAA 2
...
int foo(void)
{
  int x = 0;
  ...

#ifndef AAA
  x = 1;
#else
  x = AAA;
#endif

  ...
  return x;
}

See

  • MISRA C:2004, 19.16 - Preprocessing directives shall be syntactically meaningful even when excluded by preprocessor.
  • MISRA C++:2008, 16-0-8 - If the # token appears as the first token on a line, then it shall be immediately followed by a preprocessing token.
  • MISRA C:2012, 20.13 - A line whose first token is # shall be a valid preprocessing directive
cpp:S978

Defining or declaring identifiers with reserved names may lead to undefined behavior. Similarly, defining macros, variables or functions/methods with the same names as functions from the standard library is likely to lead to unexpected results.

Additionally, such identifiers have the potential to thoroughly confuse people who are unfamiliar with the code base, possibly leading them to introduce additional errors. Therefore reserved words and the names of standard library functions should not be used as identifiers.

This rule applies to:

  • defined
  • standard library function names
  • identifiers that begin with two underscores
  • identifiers that begin with an underscore, followed by an uppercase letter
  • identifiers in the global namespace that start with an underscore

Noncompliant Code Example

#ifndef _MY_FILE
#define _MY_FILE   // Noncompliant: starts with '_'

int free(void *pArg, int len) {  // Noncompliant: free is a standard function
  int __i; // Noncompliant: starts with "__"
  //...
}
#endif

Compliant Solution

#ifndef MY_FILE
#define MY_FILE

int clean(void *pArg, int len) {
  int i;
  //...
}
#endif

See

  • MISRA C:2004, 20.1 - Reserved identifiers, macros and functions in the standard library, shall not be defined redefined or undefined.
  • MISRA C++:2008, 17-0-1 - Reserved identifiers, macros and functions in the standard library shall not be defined, redefined, or undefined.
  • MISRA C:2012, 21.2 - A reserved identifier or macro name shall not be declared
  • CERT, DCL37-C. - Do not declare or define a reserved identifier
  • CERT, DCL51-CPP. - Do not declare or define a reserved identifier
cpp:S856

Casting an object pointer can very easily lead to undefined behavior. Only a few cases are supported, for instance casting an object pointer to a large enough integral type (and back again), casting an object pointer to a pointer to void (and back again)... Using a pointer cast to access an object as if it was of another type than its real type is not supported in general.

This rule detect casts between object pointers and incompatible types.

Noncompliant Code Example

struct S1 *p1;
struct S2;
void f ()
{
  (float) p1; // Noncompliant, conversion to floating point type
  (int *) p1; // Noncompliant
  float f;
  int *i = (int *)&f; // Noncompliant, undefined behavior even if sizeof(int) == sizeof(float)
  (int) p1; // Compliant, but might be undefined behavior if 'int' is not large enough to hold the value of p1.
  (void *) p1; // Compliant, conversion to 'void *'
  (struct S2 *)p1; // Noncompliant, conversion to another type.
}

Exceptions

In C, it is allowed to cast an object pointer to a character pointer to access the byte representation of the object. This rule ignores this case.

Anything can be safely cast to void (since nothing can be done with a result of this cast), and doing so is a common pattern to silence compiler warnings about unused variables. This rule ignores such casts.

void f(int *p) {
  (void)p;
}

See

  • MISRA C:2004, 11.2 - Conversions shall not be performed between a pointer to object and any type other than an integral type, another pointer to object type or a pointer to void.
  • MISRA C:2012, 11.3 - A cast shall not be performed between a pointer to object type and a pointer to a different object type.
cpp:GotoLabelInNestedBlock

Use of goto can lead to programs that are extremely difficult to comprehend and analyse, and possibly to unspecified behavior.

Unfortunately, removing goto from some code can lead to a rewritten version that is even more difficult to understand than the original. Therefore, limited use of goto is sometimes advised.

However, the use of goto to jump into or out of a sub-block of code, such as into the body of a for loop is never acceptable, because it is extremely difficult to understand and will likely yield results other than what is intended.

Noncompliant Code Example

void f1 (int a) {
  if (a <=0) {
    goto L2;  // Noncompliant; jumps into a different block
  }

  if (a == 0) {
  {
    goto L1; // Compliant
  }
  goto L2;  // Noncompliant; jumps into a block

L1:
  for (int i = 0; i < a; i++) {
  L2:
    //...  Should only have come here with a >=0. Loop is infinite if a < 0
  }
}

Compliant Solution

void f1 (int a) {
  if (a <=0) {
    // ...
  }

  if (a == 0) {
  {
    goto L1; // Compliant
  }

L1:
  for (int i = 0; i < a; i++) {
  L2:
    //...
  }
}

See

  • MISRA C++:2008, 6-6-1 - Any label referenced by a goto statement shall be declared in the same block, or in a block enclosing the goto statement
  • MISRA C:2012, 15.3 - Any label referenced by a goto statement shall be declared in the same block, or in a block enclosing the goto statement
cpp:S946

If the address of an automatic object is assigned to another automatic object of larger scope, or to a static object, or returned from a function then the object containing the address may exist beyond the time when the original object ceases to exist (and its address becomes invalid).

Noncompliant Code Example

int* f(void) {
  int local_auto;
  return &local_auto; // Noncompliant, returning address of an object allocated on the stack.
}

See

  • MISRA C:2004, 17.6
  • MISRA C++:2008, 7-5-2
  • MISRA C:2012, 18.6
  • CERT, DCL30-C. - Declare objects with appropriate storage durations
cpp:S1172

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

In case of Objective-C it is acceptable to have unused parameters if the method is supposed to be overridden.

Noncompliant Code Example

void doSomething(int a, int b) { // Noncompliant, "b" is unused
  compute(a);
}

Compliant Solution

void doSomething(int a) {
  compute(a);
}

See

  • MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions.
  • MISRA C:2012, 2.7 - There should be no unused parameters in functions
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
cpp:AssignmentInSubExpression

Assignments within sub-expressions are hard to spot and therefore make the code less readable. Ideally, sub-expressions should not have side-effects.

Noncompliant Code Example

if ((str = cont.substring(pos1, pos2)).isEmpty()) {  // Noncompliant
  //...

Compliant Solution

str = cont.substring(pos1, pos2);
if (str.isEmpty()) {
  //...

Exceptions

Assignments explicitly enclosed in parentheses are ignored.

while ((run = keepRunning())) {
  //...
}

See

  • MISRA C:2004, 13.1 - Assignment operators shall not be used in expressions that yield a Boolean value
  • MISRA C++:2008, 6-2-1 - Assignment operators shall not be used in sub-expressions
  • MISRA C:2012, 13.4 - The result of an assignment operator should not be used
  • MITRE, CWE-481 - Assigning instead of Comparing
  • CERT, EXP45-C. - Do not perform assignments in selection statements
  • CERT, EXP51-J. - Do not perform assignments in conditional expressions
cpp:S824

A function declared at block scope will refer to a member of the enclosing namespace, and so the declaration should be explicitly placed at the namespace level.

Additionally, where a declaration statement could either declare a function or an object, the compiler will choose to declare the function. To avoid potential developer confusion over the meaning of a declaration, functions should not be declared at block scope.

Noncompliant Code Example

class A {
};

void fun() {
  void nestedFun();  // Noncompliant; declares a function in block scope

  A a();      // Noncompliant; declares a function at block scope, not an object
}

See

  • MISRA C:2004, 8.6 - Functions shall be declared at file scope
  • MISRA C++:2008, 3-1-2 - Functions shall not be declared at block scope
cpp:S943

While they are extraordinarily useful, pointers are not the most intuitive concept in the world. Pointers to pointers are even harder to understand and use correctly. And with each additional level of indirection, pointer variables become more difficult to use correctly. Therefore pointer declarators should be limited to no more than two levels of nesting.

Noncompliant Code Example

typedef int * INTPTR;
struct s {
 int ** s1;
 int *** s2; // Noncompliant
};

struct s ** ps1;
struct s *** ps2; // Noncompliant

int ** ( *pfunc1)();
int ** ( **pfunc2)();
int ** (***pfunc3)(); // Noncompliant
int *** ( **pfunc4)(); // Noncompliant

void function( int ** par1,
               int *** par2, // Noncompliant
               INTPTR * par3,
               int * par4[],
               int ** par5[]) // Noncompliant
{
  int ** ptr1;
  int *** ptr2; // Noncompliant
  INTPTR * ptr3;
  int * ptr4[ 10 ];
  int ** ptr5[ 10 ]; //Noncompliant
}

Compliant Solution

typedef int * INTPTR;
struct s {
 int ** s1;
 int ** s2;
};

struct s ** ps1;
struct s ** ps2;

int ** (*pfunc1)();
int ** (**pfunc2)();
int ** (**pfunc3)();
int ** (**pfunc4)();

void function( int ** par1,
               int ** par2,
               INTPTR * par3,
               int * par4[],
               int * par5[])
{
  int ** ptr1;
  int ** ptr2;
  INTPTR * ptr3;
  int * ptr4[ 10 ];
  int * ptr5[ 10 ];
}

See

  • MISRA C:2004, 17.5 - The declaration of objects should contain no more than 2 levels of pointer indirection
  • MISRA C++:2008, 5-0-19 - The declaration of objects shall contain no more than two levels of pointer indirection
  • MISRA C:2012, 18.5 - Declarations should contain no more than two levels of pointer nesting
cpp:S5303

See

  • MISRA C++2008, 5-2-4
cpp:S5305

See

  • MISRA C++2008, 6-3-1 The statement forming the body of a switch, while, do … while or for statement shall be a compound statement.
cpp:S5306

See

  • MISRA C++2008, 6-4-1 An if ( condition ) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement.
cpp:S5302

See

  • MISRA C++ 2008, 5-2-2
cpp:S1065

If a label is declared but not used in the program, it can be considered as dead code and should therefore be removed.

This will improve maintainability as developers will not wonder what this label is used for.

Noncompliant Code Example

void fun() {
  label: doSomething();
}

Compliant Solution

void fun() {
  doSomething();
}

See

  • MISRA C:2012, 2.6 - A function should not contain unused label declarations
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
cpp:S5307

See

  • MISRA C++2008, 6-4-2
cpp:S5309

See

  • MISRA C 2004, 15.5 - Every switch statement shall have at least one case clause.
  • MISRA C++ 2008, 6-4-8 - Every switch statement shall have at least one case-clause.
cpp:LiteralSuffix

Using upper case literal suffixes removes the potential ambiguity between "1" (digit 1) and "l" (letter el) for declaring literals.

Noncompliant Code Example

const int        a = 0u;      // Noncompliant
const int        b = 0l;      // Noncompliant
const int        c = 0Ul;     // Noncompliant
const int        d = 0x12bu;  // Noncompliant
const float      m = 1.2f;    // Noncompliant
const float      n = 1.2l;    // Noncompliant

Compliant Solution

const int        a = 0U;
const int        b = 0L;
const int        c = 0UL;
const int        d = 0x12bU;
const float      m = 1.2F;
const float      n = 1.2L;

See

  • MISRA C++:2008, 2-13-4 - Literal suffixes shall be upper case
  • MISRA C:2012, 7.3 - The lowercase character "l" shall not be used in a literal suffix
  • CERT DCL16-C. - Use "L," not "l," to indicate a long value
  • CERT, DCL50-J. - Use visually distinct identifiers
cpp:S836

Variables should be initialized before their use to avoid unexpected behaviors due to garbage values.

Noncompliant Code Example

void function(int flag, int b) {
  int a;
  if (flag) {
    a = b;
  }
  return a; // Noncompliant - "a" has not been initialized in all paths
}

Compliant Solution

void function(int flag, int b) {
  int a = 0;
  if (flag) {
    a = b;
  }
  return a;
}

See

  • MITRE, CWE-457 - Use of Uninitialized Variable
  • MISRA C:2004, 9.1 - All automatic variables shall have been assigned a value before being used.
  • MISRA C++:2008, 8-5-1 - All variables shall have a defined value before they are used.
cpp:S831

See

  • MISRA C++ 2008, 3-3-1
cpp:S833

See

  • MISRA C++ 2008, 3-3-2
  • MISRA C 2004, 8.11
  • MISRA C 2012, 8.8
cpp:S835

ISO/IEC 14882:2003 [1] requires initializer lists for arrays, structures and union types to be enclosed in a single pair of braces (though the behaviour if this is not done is undefined). The rule given here goes further in requiring the use of additional braces to indicate nested structures.

This forces the developer to explicitly consider and demonstrate the order in which elements of complex data types are initialized (e.g. multi-dimensional arrays).

The zero initialization of arrays or structures shall only be applied at the top level.

The non-zero initialization of arrays or structures requires an explicit initializer for each element.

A similar principle applies to structures, and nested combinations of structures, arrays and other types.

Note also that all the elements of arrays or structures can be initialized (to zero or NULL) by giving an explicit initializer for the first element only. If this method of initialization is chosen then the first element should be initialized to zero (or NULL), and nested braces need not be used.

Noncompliant Code Example

int a1[3][2] = { 1, 2, 3, 4, 5, 6 }; // Noncompliant
int a2[5] = { 1, 2, 3 }; // Noncompliant, partial initialization
int a3[2][2] = { { }, { 1, 2 } }; // Noncompliant, zero initialization at sub-level

Compliant Solution

int a1[3][2] = { { 1, 2 }, { 3, 4 }, { 5, 6 } }; // Compliant
int a2[5] = { 1, 2, 3, 0, 0 }; // Compliant, Non-zero initialization
int a2[5] = { 0 }; // Compliant, zero initialization
int a3[2][2] = { }; // Compliant, zero initialization

See

  • MISRA C:2004, 9.2 - Braces shall be used to indicate and match the structure in the non-zero initialization of arrays and structures.
  • MISRA C++:2008, 8-5-2 - Braces shall be used to indicate and match the structure in the nonzero initialization of arrays and structures.
  • MISRA C:2012, 9.2 - The initializer of an aggregate or union shall be enclosed in braces.
cpp:S834

It is possible to declare an array without explicitly specifying its size, but using an explicit size declaration is clearer, and is therefore preferred.

Noncompliant Code Example

int arr1 [ ];  // Noncompliant; nothing specified
int arr2 [ ] = { [0] = 1, [12] = 36, [4] = 93 }; // Noncompliant; highest index determines size. May be difficult to spot
int pirate [ ] = { 2, 4, 8, 42, 501, 90210, 7, 1776 }; // Noncompliant; size is implicit, not explicit

Compliant Solution

int arr1 [10];
int arr2 [13] = { [0] = 1, [12] = 36, [4] = 93 };
int pirate [10] = { 2, 4, 8, 42, 501, 90210, 7, 1776 }; // Implicitly-assigned size was 8. Desired size was 10.

See

  • MISRA C:2004, 8.12 - When an array is declared with external linkage, its size shall be stated explicitly or defined implicitly by initialisation
  • MISRA C++:2008, 3-1-3 - When an array is declared, its size shall either be stated explicitly or defined implicitly by initialization
  • MISRA C:2012, 8.11 - When an array with external linkage is declared, its size should be explicitely specified
  • MISRA C:2012, 9.5 - Where designated initializers are used to initialize an array object the size of the array shall be specified explicitly
  • CERT, ARR02-C. - Explicitly specify array bounds, even if implicitly defined by an initializer
cpp:S1036

Having a switch and its cases wholly encompassed by a control structure such as a try, @try, catch, @catch, or a loop is perfectly acceptable. (try and catch are used hereafter to refer to both variants.) It is also acceptable to have a goto and its target label wholly encompassed in a control structure.

What is not acceptable is using a goto or case to suddenly jump into the body of a try, catch, Objective-C @finally, or loop structure. Tangling labels or switch blocks with other control structures results in code that is difficult, if not impossible to understand. More importantly, when it compiles (some of these constructs won't compile under ISO-conformant compilers), it can lead to unexpected results. Therefore this usage should be strictly avoided.

This C++ code sample, which is also applicable to Objective-C if try and catch are converted to @try and @catch, demonstrates jumping into a switch and into a try and catch :

Noncompliant Code Example

void f ( int32_t i )
{
  if ( 10 == i )
  {
    goto Label_10; // Noncompliant; goto transfers control into try block
  }

  if ( 11 == i )
  {
    goto Label_11; // Noncompliant; goto transfers control into catch block
  }

  switch ( i )
  {
    case 1:
      try
      {
        Label_10:
        case 2:  // Noncompliant; switch transfers control into try block
          // Action
          break;
      }
      catch ( ... )
      {
        Label_11:
        case 3: // Noncompliant; switch transfers control into catch block
          // Action
          break;
      }
      break;
    default:
    {
      // Default Action
      break;
    }
  }
}

Compliant Solution

void f ( int32_t i )
{
  switch ( i )
  {
    case 1:
    case 2:
      // Action
      break;
    case 3:
      // Action
      break;
    case 10:

    default:
    {
      // Default Action
      break;
    }
  }

  try
  {
    if ( 2 == i || 10 == i)
    {
      // Action
    }
  }
  catch ( ... )
  {
    if (3 == i || 11 == i)
    {
      // Action
    }
  }
}

See

  • MISRA C++:2008, 15-0-3 - Control shall not be transferred into a try or catch block using goto or switch statement
  • CERT, MSC20-C. - Do not use a switch statement to transfer control into a complex block
cpp:S1035

If an exception object of pointer type is thrown and that pointer refers to a dynamically created object, then it may be unclear which function is responsible for destroying it, and when. This ambiguity does not exist if the object is thrown by value and caught by reference.

Noncompliant Code Example

class E
{
  // Implementation
};

void fn ( int16_t i )
{
  static E e1;
  E * e2 = new E;
  if ( i > 10 )
  {
    throw ( &e1 ); // Non-compliant – pointer type thrown
  }
  else
  {
    throw ( e2 ); // Non-compliant – pointer type thrown
  }
}

Compliant Solution

class E
{
  // Implementation
};

void fn ( int16_t i )
{
  static E e;
  throw ( &e ); // Compliant – reference type thrown
}

See

  • MISRA C++ 2008, 15-0-2 - An exception object should not have pointer type.
cpp:S2486

When exceptions occur, it is usually a bad idea to simply ignore them. Instead, it is better to handle them properly, or at least to log them.

Noncompliant Code Example

void save() {
  try {
    saveDocument();
  } catch (const std::exception& ex) {
  }
}

Compliant Solution

void save() {
  try {
    saveDocument();
  } catch (const std::exception& ex) {
    log << "Exception while saving the document: " << ex.what();
  }
}

See

cpp:S3696

Just because you can stick your hand in a blender, that doesn't mean you should. Similarly, you can throw anything, but that doesn't mean you should throw something that's not derived at some level from std::exception.

If you can't find an existing exception type that suitably conveys what you need to convey, then you should extend std::exception to create one.

Specifically, part of the point of throwing exceptions is to communicate about the conditions of the error, but primitives have far less ability to communicate meaningfully than exceptions. And, the creation of some other object type could itself throw an exception, resulting in program termination.

Further, catching non-exception types is painful and fraught with the potential for (further) error.

Noncompliant Code Example

throw 42;                               // Noncompliant
throw "Invalid negative index.";        // Noncompliant
throw std::string("Permission denied"); // Noncompliant
throw nullptr;                          // Noncompliant

Compliant Solution

throw std::domain_error("User ID not found.");
throw std::out_of_range("Invalid negative index.");
throw std::system_error(EACCES, std::system_category());
throw std::invalid_argument("Unexpected null 'user_id' argument.");

See

  • MISRA C++:2008, 15-1-2 - NULL shall not be thrown explicitly.
cpp:S1032

Explicit specializations of function templates are not considered in overload resolution, only the main template. As a consequence, the function that will be selected might very well be different from what seems natural to the developer, leading to hard to understand bugs. Moreover, function templates don't allow partial specialization.

Instead of specializing a function template, you may choose to overload it with another template or non template function, since a more specialized overload will be preferred to a generic overload.

Noncompliant Code Example

template <typename T> void f ( T );
template <> void f<char*> ( char * ); // explicit specialization, noncompliant

Compliant Solution

template <typename T> void f ( T );
void f( char * ); // overload, compliant

Exceptions

This rule ignores cases where none of the main function template arguments depend on a template parameter: Even if the code could still be written without function template specialization (by deferring the real work to a class template, and offering specializations of this class template as customization point to the user), there is no risk of confusion for overload resolution in these cases.

// For real code, use std::numeric_limits instead...
template <class T> T max();
template <> float max<float>() { return FLT_MAX; }  // Ignored

template<class T>
bool isMax(T t){
    return t == max<T>();
}

See

cpp:DigraphUsage

The use of digraphs may not meet developer expectations.

The digraphs are:

  • <%
  • %>
  • <:
  • :>
  • %:
  • %:%:

Noncompliant Code Example

template <typename T>
class A
{
  public:
    template<int32_t i>
    void f2();
};

void f(A<int32_t> * a<:10:>)    /* Noncompliant - usage of '<:' instead of '[' and ':>' instead of ']' */
<%                              /* Noncompliant - usage of '<%' instead of '{' */
  a<:0:>->f2<20>();             /* Noncompliant - usage of '<:' and ':>' */
%>                              /* Noncompliant - usage of '%>' instead of '}' */

Compliant Solution

/* ... */

void f(A<int32_t> * a[10])      /* Compliant */
{                               /* Compliant */
  a[0]->f2<20>();               /* Compliant */
}                               /* Compliant */

See

  • MISRA C++:2008, 2-5-1 - Digraphs should not be used.
cpp:S925

Recursion is a powerful tool, but it can be tricky to get right. Getting it wrong can lead to stack overflow errors and cause system problems. Even when you do get it right, recursive code can be difficult to understand, perhaps leading to maintenance problems in the future. Therefore recursion should be avoided in general and used only with due deliberation and caution when it is strictly necessary.

This rule checks for direct recursion (when a function calls itself).

Noncompliant Code Example

int pow(int num, int exponent) {
  if (exponent > 1) {
    num = num * pow(num, exponent-1);  // Noncompliant; direct recursion
  }
  return num;
}

Compliant Solution

int pow(int num, int exponent) {
  int val = num;
  while (exponent > 0) {
    val *= num;
    --exponent;
  }
  return val;
}

See

  • MISRA C:2004, 16.2 - Functions shall not call themselves, either directly or indirectly.
  • MISRA C++:2008, 7-5-4 - Functions should not call themselves, either directly or indirectly.
  • MISRA C:2012, 17.2 - Functions shall not call themselves, either directly or indirectly
cpp:S926

Naming the parameters in a function prototype helps identify how they'll be used by the function, thereby acting as a thin layer of documentation for the function.

Noncompliant Code Example

void divide (int, int);

Compliant Solution

void divide (int numerator, int denominator);

See

  • MISRA C:2004, 16.3 - Identifiers shall be given for all of the parameters in a function prototype declaration
  • MISRA C:2012, 8.2 - Function types shall be in prototype form with named parameters
cpp:S920

When there is only a single condition to test, you have the option of using either a switch statement or an if-else if-else statement. For a larger set of potential values, a switch can be easier to read, but when the condition being tested is essentially boolean, then an if/else statement should be used instead.

Noncompliant Code Example

_Bool b = p > 0;
switch (b) { // Noncompliant
...
}
switch (x == 0) { // Noncompliant
...
}

Compliant Solution

_Bool b = p > 0;
if (b) {
...
} else {
...
}
if (x == 0) {
...
} else {
...
}

See

  • MISRA C:2004, 15.4 - A switch expression shall not represent a value that is effectively Boolean
  • MISRA C++ 2008, 6-4-7 - The condition of a switch statement shall not have bool type
  • MISRA C:2012, 16.7 - A switch-expression shall not have essentially Boolean type
cpp:FunctionEllipsis

Passing arguments via an ellipsis bypasses the type checking performed by the compiler. Additionally, passing an argument with non-POD class type leads to undefined behavior. Note that the rule specifies "defined" (and not "declared") so as to permit the use of existing library functions.

Noncompliant Code Example

void MyPrintf ( char_t * pFormat, ... )	// Noncompliant
{
  // ...
}

See

  • MISRA C:2004, 16.1 - Functions shall not be defined with a variable number of arguments.
  • MISRA C++:2008, 8-4-1 - Functions shall not be defined using the ellipsis notation.
  • CERT, DCL50-CPP. - Do not define a C-style variadic function
cpp:S802

Reusing a typedef name either as another typedef name or for any other purpose may lead to developer confusion.

The same typedef shall not be duplicated anywhere in the project, even if the declarations are identical.

Note that where the type definition is made in a header file, and that header file is included in multiple source files, this rule is not violated.

Noncompliant Code Example

{
  typedef unsigned char uint8_t;
}

{
  typedef unsigned char uint8_t; // Noncompliant, redefinition
}

{
  unsigned char uint8_t; // Noncompliant, reuse of uint8_t for another purpose
}

Compliant Solution

typedef unsigned char uint8_t;
{
}

{
}

{
  unsigned char myChar;
}

See

  • MISRA C:2004, 5.3 - A typedef name shall be a unique identifier.
  • MISRA C++:2008, 2-10-3 - A typedef name (including qualification, if any) shall be a unique identifier.
cpp:S1045

When testing to see if the type of an exception matches the type of a handler, a derived class exception will match with a handler for its base class. If the base class handler is found before the handler for the derived class, the base class handler will be used. The derived class handler is unreachable code and can never be executed.

Noncompliant Code Example

// classes used for exception handling
class B { };
class D: public B { };
// Using the classes from above ...
try
{
  // ...
}
catch ( B &b ) // Noncompliant – will catch derived classes as well
{
  // ...
}
catch ( D &d ) // Noncompliant – Derived class will be caught above
{
  // Any code here will be unreachable,
}

Compliant Solution

// Using the same classes from above ...
try
{
  // ...
}
catch ( D &d ) // Compliant – Derived class caught before base class
{
  // ...
}
catch ( B &b ) // Compliant – Base class caught after derived class
{
  // ...
}

See

  • MISRA C++:2008, 15-3-6
  • CERT, ERR54-CPP. - Catch handlers should order their parameter types from most derived to least derived
cpp:S1044

When exception classes are caught by value, rather than by reference, slicing occurs, yielding an instance of the exception's base class, rather than the potentially more specific exception class that was actually thrown. This means that only the base class' functions will be available; any additional data or functionality that is offered by the extended class will not be accessible. Therefore exception classes should always be caught by reference.

Noncompliant Code Example

try
{
  // ...
}
catch(ExceptionClass ex)
{
  //...
}

Compliant Solution

try
{
  // ...
}
catch(ExceptionClass &ex)
{
  //...
}

Exceptions

This rule doesn't raise an issue when no parameter name is provided for the exception.

try {
  // ...
} catch(ExceptionClass) {
  // ...
}

See

  • MISRA C++:2008, 15-3-5 - A class type exception shall always be caught by reference
  • CERT, ERR61-CPP. - Catch exceptions by lvalue reference
cpp:UnaryAndOverloaded

Taking the address of an object of incomplete type, where the complete type contains a user declared operator & leads to undefined behavior.

Noncompliant Code Example

// A.h
class A
{
public:
  A * operator & ( );      // Noncompliant
};

// f1.cc
class A;
void f ( A & a )
{
  &a;	// uses built-in operator &
}

// f2.cc
#include "A.h"
void f2 ( A & a )
{
  &a;	// use user-defined operator &
}

See

  • MISRA C++ 2008, 5-3-3 - The unary & operator shall not be overloaded.
cpp:S936

Using a "bald" function name is likely a bug. Rather than testing the return value of a function with a void parameter list, it implicitly retrieves the address of that function in memory. If that's truly what's intended, then it should be made explicit with the use of the & (address-of) operator. If it's not, then a parameter list (even an empty one) should be added after the function name.

Noncompliant Code Example

int func(void) {
  // ...
}

void f2(int a, int b) {
  // ...
  if (func) {  // Noncompliant - tests that the memory address of func() is non-null
    //...
  }
  // ...
}

Compliant Solution

void f2(int a, int b) {
  // ...
  if (func()) {  // tests that the return value of func() > 0
    //...
  }
  // ...
}

Exceptions

Callback functions are a common occurrence and are usually not passed with a preceding &. There is however little ambiguity so this rule ignores function identifiers when used as a parameter of a function call.

void foo() {
  // ...
}

registerEvent(AnEvent, foo);

See

  • MISRA C:2004, 16.9 - A function identifier shall only be used with either a preceding &, or with a parenthesized parameter list, which may be empty.
  • MISRA C++:2008, 8-4-4 - A function identifier shall only be used to call the function or it shall be preceded by &.
cpp:S814

The use of any type other than signed short, unsigned short, signed char, unsigned char, signed int, unsigned int or _Bool for a bit field is implementation-defined, and therefore not portable.

Noncompliant Code Example

int b:3; // Noncompliant - may have the range of values 0..7 or -4..3

Compliant Solution

unsigned int b:3;

See

  • MISRA C:2004, 6.4 - Bit fields shall only be defined to be of type unsigned int or signed int.
  • MISRA C++:2008, 9-6-2 - Bit-fields shall be either bool type or an explicitly unsigned or signed integral type.
  • MISRA C:2012, 6.1 - Bit-fields shall only be declared with an appropriate type
  • CERT, INT12-C. - Do not make assumptions about the type of a plain int bit-field when used in an expression
cpp:S935

Every call to a function with a non-void return type is expected to return some value. Including a return path in a non-void function that does not explicitly return a value results in undefined behavior.

Conversely, every call to a function with a void return type is expected to not return any value. Returning a value from a void function probably indicates a programming error.

Noncompliant Code Example

int my_func (int a)
{
  if (a > 100)
  {
    return; // Noncompliant
  }

  if (a > 80)
  {
    throw new Exception(); // Compliant
  }

  // Noncompliant
}

Compliant Solution

int my_func (int a)
{
  if (a > 100)
  {
    return 12;
  }

  if (a > 80)
  {
    throw new Exception();
  }

  return a;
}

See

  • MISRA C:2004, 16.8 - All exit paths from a function with non-void return type shall have an explicit return statement with an expression
  • MISRA C++:2008, 8-4-3 - All exit paths from a function with non-void return type shall have an explicit return statement with an expression
  • MISRA C:2012, 17.4 - All exit paths from a function with non-void return type shall have an explicit return statement with an expression
  • MITRE, CWE-394 - Unexpected Status Code or Return Value
  • CERT, MSC37-C. - Ensure that control never reaches the end of a non-void function
  • CERT, MSC52-CPP. - Value-returning functions must return a value from all exit paths
  • CERT, MSC53-CPP. - Do not return from a function declared [[noreturn]]
cpp:S811

See

  • MISRA C++ 2008, 5-0-13
cpp:S810

There are three distinct char types, (plain) char, signed char and unsigned char. signed char and unsigned char should only be used for numeric data, and plain char should only be used for character data. Since it is implementation-defined, the signedness of the plain char type should not be assumed.

Noncompliant Code Example

signed char a = 'a'; // Noncompliant, explicitly signed
unsigned char b = '\r'; // Noncompliant, explicitly unsigned
char c = 10; // Noncompliant

unsigned char d = c; // Noncompliant, d is explicitly signed while c is not
char e = a; // Noncompliant, a is explicitly signed while e is not

Compliant Solution

char a = 'a';
char b = '\r';
unsigned char c = 10;
signed char c = 10;

Exceptions

  • Since the integer value 0 is used as a sentinel for the end of a string, converting this value to char is ignored.

See

  • MISRA C:2004, 6.1 - The plain char type shall be used only for the storage and use of character values
  • MISRA C:2004, 6.2 - signed and unsigned char type shall be used only for the storage and use of number values
  • MISRA C++:2008, 5-0-11 - The plain char type shall only be used for the storage and use of character values
  • MISRA C++:2008, 5-0-12 - signed char and unsigned char type shall only be used for the storage and use of numeric values
  • CERT, INT07-C. - Use only explicitly signed or unsigned char type for numeric values
  • CERT, STR00-C. - Represent characters using an appropriate type
  • CERT, STR04-C. - Use plain char for characters in the basic character set
cpp:S812

See

  • MISRA C++ 2008, 5-0-14 - The first operand of a conditional-operator shall have type bool.
cpp:S813

The basic numeric types char, int, short, long, float, double, and long double should not be used. Instead, specific-length typedefs should be. This rule helps to clarify the size of the storage, but does not guarantee portability because of the asymmetric behavior of integral promotion.

Note that it is still important to understand the integer size of the implementation, and developers should be aware of the actual implementation of the typedefs under these definitions.

Noncompliant Code Example

int function(unsigned short a) // Noncompliant
{
  // ...
}

Compliant Solution

#include <stdint.h>
int32_t function(uint16_t a) // Compliant
{
  // ...
}

See

  • MISRA C:2004, 6.3 - typedefs that indicate size and signedness should be used in place of the basic types
  • MISRA C++:2008, 3-9-2 - typedefs that indicate size and signedness should be used in place of the basic numerical types

See Also

  • MISRA C++ 2008 Section 6.5.0 on integral promotion
cpp:IdentifierLongerThan31

In addition to being difficult to use, too-long variable names can limit code portability. The ISO standard requires that variable, type, function and label names be no more than 31 characters long.

Note that 31 characters is an upper bound, rather than a length recommendation. Shorter names are better, as long as they're still communicative.

Noncompliant Code Example

int this_is_a_very_long_identifier_that_definitely_should_be_renamed = 0;

Compliant Solution

int reasonable_identifier = 0;

See

  • MISRA C:2004, 5.1 - Identifiers (internal and external) shall not rely on the significance of more than 31 character.
  • CERT, DCL23-C. - Guarantee that mutually visible identifiers are unique
cpp:S905

Any statement (other than a null statement, which means a statement containing only a semicolon ;) which has no side effect and does not result in a change of control flow will normally indicate a programming error, and therefore should be refactored.

Noncompliant Code Example

int func(int a, int b) {
  int result = 0;
  a + b; // Noncompliant, no side effect.
  return result;
}

Compliant Solution

int func(int a, int b) {
  int result = a + b; // Compliant
  return result;
}

See

  • MITRE, CWE-482 - Comparing instead of Assigning
  • MISRA C:2004, 14.2 - All non-null statements shall either have at least one side-effect however executed, or cause control flow to change.
cpp:UnnamedNamespaceInHeader

An unnamed namespace will be unique within each translation unit. Any declarations appearing in an unnamed namespace in a header will refer to a different entity in each translation unit, which is probably not the expected behavior.

Noncompliant Code Example

// Header.hpp
namespace                  // Noncompliant
{
  extern int32_t x;
}
// File1.cpp
#include "Header.cpp"

namespace
{
  int32_t x;
}

void fn_a(void)
{
  x = 42;
}
// File2.cpp
#include "Header.cpp"

namespace
{
  int32_t x;  // this is a different x than in File1.cpp
}

void fn_b(void)
{
  fn_a();                  // Is expected to initialize "x" to 42
  if (x == 42)             // But does not, as there are 2 distinct "x" variables
  {
  }
}

See

  • MISRA C++:2008, 7-3-3 - There shall be no unnamed namespaces in header files.
  • CERT, DCL59-CPP. - Do not define an unnamed namespace in a header file
cpp:S1301

switch statements are useful when there are many different cases depending on the value of the same expression.

For just one or two cases however, the code will be more readable with if statements.

Moreover, if statements are obviously more suitable when the condition of the switch is boolean.

Noncompliant Code Example

switch (variable) {
  case 0:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Compliant Solution

if (variable == 0) {
  doSomething();
} else {
  doSomethingElse();
}

See

  • MISRA C:2012, 16.6 - Every switch statement shall have at least two switch-clauses
cpp:PPUndefUsage

#undef should not normally be needed. Its use can lead to confusion with respect to the existence or meaning of a macro when it is used in the code.

Noncompliant Code Example

#ifndef MY_HDR
#define MY_HDR
#endif
...
#undef MY_HDR    /* Noncompliant */

See

  • MISRA C:2004, 19.6 - #undef shall not be used.
  • MISRA C++:2008, 16-0-3 - #undef shall not be used.
  • MISRA C:2012, 20.5 - #undef should not be used
cpp:SwitchLabelPlacement

A switch-label can be placed anywhere within the statements that form the body of a switch statement, potentially leading to unstructured code. To prevent this from happening, the scope of a case-label or default-label shall be the statement forming the body of a switch statement. All case-clauses and the default-clause shall be at the same scope.

Noncompliant Code Example

switch (x) {
  case 1: // Compliant
    if (foo) {
      case 2: // Noncompliant
        break;
      default: // Noncompliant
        break;
    }
    break;
  default: // Compliant
    break;
}

See

  • MISRA C 2004, 15.1 - A switch label shall only be used when the most closely-enclosing compound statement is the body of a switch statement.
  • MISRA C++ 2008, 6-4-4 - A switch-label shall only be used when the most closely-enclosing compound statement is the body of a switch statement.
  • MISRA C 2012, 16.2 - A switch label shall only be used when the most closely-enclsoing compound statement is the body of a switch statement
cpp:EnumPartialInitialization

If an enumerator list is given with no explicit initialization of members, then C/C++ allocates a sequence of integers starting at zero for the first element and increasing by one for each subsequent element.

An explicit initialization of the first element, as permitted by this rule, forces the allocation of integers to start at the given value. When adopting this approach it is essential to ensure that the initialization value used is small enough that no subsequent value in the list will exceed the int storage used by enumeration constants.

Explicit initialization of all items in the list, which is also permissible, prevents the mixing of automatic and manual allocation, which is error prone.

However, it is then the responsibility of the developer to ensure that all values are in the required range, and that values are not unintentionally duplicated.

Noncompliant Code Example

enum color { red = 3, blue, green, yellow = 5 }; // Noncompliant; both green and yellow = 5

Compliant Solution

enum color { red = 3, blue = 4, green = 5, yellow = 5 }; // Compliant

See

  • MISRA C:2004, 9.3 - In an enumerator list, the "=" construct shall not be used to explicitly initialize members other than the first, unless all items are explicitly initialized.
  • MISRA C++:2008, 8-5-3 - In an enumerator list, the = construct shall not be used to explicitly initialize members other than the first, unless all items are explicitly initialized.
cpp:SingleDeclarationPerStatement

Where multiple declarators appear in the same declaration the type of an identifier may not meet developer expectations.

Noncompliant Code Example

int i1; int j1; // Compliant, but not preferred
int i2, *j2; // Noncompliant
int *i3,
&j3 = i2; // Noncompliant

Compliant Solution

int i1;
int j1;
int i2;
int *j2;
int *i3;
int &j3 = i2;

See

  • MISRA C++:2008, 8-0-1 - An init-declarator-list or a member-declarator-list shall consist of a single init-declarator or member-declarator respectively
  • CERT, DCL52-J. - Do not declare more than one variable per declaration
  • CERT, DCL04-C. - Do not declare more than one variable per declaration
cpp:S1763

Jump statements (return, break, continue, goto) and throw expressions move control flow out of the current code block. So any unlabelled statements that come after a jump are dead code.

Noncompliant Code Example

int fun(int a) {
  int i = 10;
  return i + a;       // Noncompliant
  i++;             // dead code
}

Compliant Solution

int fun(int a) {
  int i = 10;
  return i + a;
}

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code
  • MISRA C++:2008, 0-1-9 - There shall be no dead code
  • MISRA C:2012, 2.1 - A project shall not contain unreachable code
  • MISRA C:2012, 2.2 - There shall be no dead code
  • MITRE, CWE-561 - Dead Code
  • CERT, MSC56-J. - Detect and remove superfluous code and values
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
cpp:PPStringifyAndPastingUsage

The evaluation order of both the # and ## preprocessor operators is unspecified. Compilers have been known to implement these operators inconsistently, therefore, to avoid these problems, do not use them.

Noncompliant Code Example

#define A(Y)   #Y    /* Noncompliant */
#define A(X,Y) X##Y  /* Noncompliant */

See

  • MISRA C:2004, 19.13 - The # and ## preprocessor operators should not be used.
  • MISRA C++:2008, 16-3-2 - The # and ## operators should not be used.
  • MISRA C:2012, 20.10 - The # and ## preprocessor operators should not be used
cpp:S1761

The standard, predefined macros, such as __FILE__ and __LINE__, are primarily intended for use by the implementation, and changing them could result in undefined behavior.

This rule checks that the following predefined macros are not defined, undefined, or redefined: assert, errno, __FILE__, __LINE__, __TIME__, __DATE__, __TIMESTAMP__, __COUNTER__, __INCLUDE_LEVEL__, __BASE_FILE__, and _Pragma.

Noncompliant Code Example

#undef __LINE__

See

  • MISRA C:2004, 20.1 - Reserved identifiers, macros and functions in the standard library shall not be defined, redefined, or undefined
  • MISRA C++:2008, 17-0-1 - Reserved identifiers, macros and functions in the standard library shall not be defined, redefined, or undefined
  • MISRA C:2012, 21.1 - #define and #undef shall not be used on a reserved identifier or reserved macro name
cpp:S3949

Numbers are infinite, but the types that hold them are not. Each numeric type has hard upper and lower bounds. Try to calculate or assign numbers beyond those bounds, and the result will be surprising:

- For unsigned types, it will be a value that has silently wrapped around from the expected positive value to another one, following the rules of modular arithmetic (if the maximum unsigned char is 255, adding 10 to an unsigned char equals to 250 will yield the value 4)

- For signed type, this is undefined behavior.

Noncompliant Code Example

void test(char c) {
  switch (c) {
    case 2000: // Noncompliant
      // ...
      break;
  }

  int a = 4608 * 1024 * 1024; // Noncompliant
}
cpp:S1767

The size of integer required to hold a memory address is implementation-dependent. Therefore, casting a pointer (i.e. a memory address) to any integral data type may result in data loss because the integral type is too small to hold the full address value.

When treating a memory address as integer type is absolutely required, you should be sure to use a large enough type to hold all the data.

Noncompliant Code Example

int *p;
int addr = ( int ) &p;

See

  • MISRA C:2004, 11.3 - A cast should not be performed between a pointer type and an integral type.
  • MISRA C++:2008, 5-2-9 - A cast should not convert a pointer type to an integral type.
  • MISRA C:2012, 11.4 - A conversion should not be performed between a pointer to object and an integer type
  • CERT, INT36-C. - Converting a pointer to integer or integer to pointer
cpp:S1219

Even if it is legal, mixing case and non-case labels in the body of a switch statement is very confusing and can even be the result of a typing error.

Noncompliant Code Example

Case 1, the code is syntactically correct but the behavior is not the expected one

switch (day) {
  case MONDAY:
  case TUESDAY:
  WEDNESDAY:   // instead of "case WEDNESDAY"
    doSomething();
    break;
  ...
}

Case 2, the code is correct and behaves as expected but is hardly readable

switch (day) {
  case MONDAY:
    break;
  case TUESDAY:
    foo:for(int i = 0 ; i < X ; i++) {
         /* ... */
        break foo;  // this break statement doesn't relate to the nesting case TUESDAY
         /* ... */
    }
    break;
    /* ... */
}

Compliant Solution

Case 1

switch (day) {
  case MONDAY:
  case TUESDAY:
  case WEDNESDAY:
    doSomething();
    break;
  ...
}

Case 2

switch (day) {
  case MONDAY:
    break;
  case TUESDAY:
    compute(args); // put the content of the labelled "for" statement in a dedicated method
    break;

    /* ... */
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
cpp:C99CommentUsage

This excludes the use of // C99 style comments and C++ style comments, since these are not permitted in C90. Many compilers support the // style of comments as an extension to C90. The use of // in preprocessor directives (e.g. #define) can vary. Also the mixing of /* ... */ and // is not consistent. This is more than a style issue, since different (pre C99) compilers may behave differently.

Noncompliant Code Example

int main(int argc, char* argv[])
{
  // Do nothing - Noncompliant
  return 0;
}

Compliant Solution

int main(int argc, char* argv[])
{
  /* Do nothing - Compliant */
  return 0;
}

See

  • MISRA C:2004, 2.2 - Source code shall only use /* ... */ style comments.
cpp:S1103

Defining a nested single-line comment within a multi-line comment invites errors. It may lead a developer to wrongly think that the lines located after the single-line comment are not part of the comment.

If a comment starting sequence, /* or //, occurs within a /* comment, is it quite likely to be caused by a missing */ comment ending sequence.

If a comment starting sequence occurs within a // comment, it is probably because a region of code has been commented-out using //.

Noncompliant Code Example

/* some comment, end comment marker accidentally omitted
// Make sure this function is called in a thread safe context
Perform_Critical_Safety_Function(X);
...
/* this comment is non-compliant */

Exceptions

The sequence // is permitted within a // comment.

See

  • CERT, MSC04-C. - Use comments consistently and in a readable fashion
  • MISRA C:2004, 2.3 - The character sequence /* shall not be used within a comment.
  • MISRA C++:2008, 2-7-1 - The character sequence /* shall not be used within a C-style comment.
  • MISRA C:2012, 3.1 - The character sequences /* and // shall not be used within a comment
cpp:Union

The use of unions to access an object in different ways may result in the data being misinterpreted. Therefore, this rule prohibits the use of unions for any purpose.

Noncompliant Code Example

union U1 { // Noncompliant
    float j;
    int i;
};

See

  • MISRA C:2004, 18.4 - Unions shall not be used.
  • MISRA C++:2008, 9-5-1 - Unions shall not be used.
  • MISRA C:2012, 19.2 - The union keyword should not be used
cpp:GlobalNamespaceMembers

Declaring names in appropriate namespaces reduces the number of names found during lookup, helping ensure that the names found meet developer exceptions.

This rule has been tuned to raise an issue when a name part of the global namespace has for sure an external linkage and so exists beyond a particular translation unit. In other words, an issue is raised when a name that is part of the global namespace is for sure accessible through the whole program.

Noncompliant Code Example

int      a;         // Noncompliant
int      b = 1;     // Noncompliant
MyStruct c;         // Noncompliant
MyStruct d = {1,2}; // Noncompliant

extern int      a = 1;        // Noncompliant
extern MyStruct b = {1,2};    // Noncompliant and not excluded as the structure is initialized

extern const int      a = 1;     // Noncompliant
extern const MyStruct b = {1,2}; // Noncompliant and not excluded as the structure is initialized

void            m1() { } // Noncompliant
extern void     m2() { } // Noncompliant

class A { // Noncompliant
};

Compliant Solution

namespace MY_API { // Compliant
  int  a;
  int  b = 1;
  extern const int c = 3;
  void m1() {
  }

  class A {
  };
}

namespace {        // Compliant
  int  b = 1;
  void m2() {
  }
}

int32_t main() {   // Compliant

}

static int            a;         // Compliant
static MyStruct       b;         // Compliant
static int            c = 1;     // Compliant
static MyStruct       d = {1,2}; // Compliant
static const int      e = 1;     // Compliant
static const MyStruct f = {1,2}; // Compliant

static void                       m1();        // Compliant
static void                       m2()     { } // Compliant
template <typename T> static void m3(T& a) { } // Compliant

const int      a = 1;     // Compliant
const MyStruct b = {1,2}; // Compliant

extern "C" int       a = 1;   // Compliant
extern "C" const int b = 1;   // Compliant
extern "C" void      m1() { } // Compliant

typedef int      a; // Compliant
typedef MyStruct b; // Compliant

bool operator==(const X::Y& p1, const X::Y& p2) { return p1.x == p2.x; }                   // Compliant
void *operator new(size_t bytes, const X::Y& context) { return X::malloc(bytes,context); } // Compliant
void operator delete(void* ptr,  const X::Y& context) { X::free(bytes,context); }          // Compliant

See

  • MISRA C++:2008, 7-3-1 - The global namespace shall only contain main, namespace declarations and extern "C" declarations.
cpp:ContinueUsage

continue is an unstructured control flow statement. It makes code less testable, less readable and less maintainable. Structured control flow statements such as if should be used instead.

Noncompliant Code Example

int i;
for (i = 0; i < 10; i++) {
  if (i == 5) {
    continue;  /* Noncompliant */
  }
  printf("i = %d\n", i);
}

Compliant Solution

int i;
for (i = 0; i < 10; i++) {
  if (i != 5) {
    printf("i = %d\n", i);
  }
}

See

  • MISRA C:2004, 14.5 - The continue statement shall not be used.
cpp:ElseIfWithoutElse

This rule applies whenever an if statement is followed by one or more else if statements; the final else if should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch statement.

Noncompliant Code Example

if (x == 0) {
  doSomething();
} else if (x == 1) {
  doSomethingElse();
}

Compliant Solution

if (x == 0) {
  doSomething();
} else if (x == 1) {
  doSomethingElse();
} else {
  error();
}

Exceptions

When all branches of an if-else if end with return, break or throw, the code that comes after the if implicitly behaves as if it was in an else clause. This rule will therefore ignore that case.

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
cpp:TrigraphUsage

Trigraphs are denoted by a sequence of 2 question marks followed by a specified third character (e.g. ??- represents a '~' (tilde) character and ??) represents a ']'). They can cause accidental confusion with other uses of two question marks.

Noncompliant Code Example

static const char str[] = "(Date should be in the form ??-??-??)"; // Noncompliant. Evaluates to "(Date should be in the form ~~]"

Compliant Solution

static const char str[] = "(Date should be in the form ?" "?-?" "?-?" ?)";  // adjacent string literals concatenated at compile time
static const char str2[] = "(Date should be in the form ?-?-?)"; // problem avoided by eliminating 2nd '?' in each sequence
static const char str3[] = "(Date should be in the form ? ?-? ?-? ?)"; // problem avoided by spacing '?'s out

See

  • MISRA C:2004, 4.2 - Trigraphs shall not be used
  • MISRA C++:2008, 2-3-1 - Trigraphs shall not be used
  • MISRA C:2012, 4.2 - Trigraphs shall not be used
  • CERT, PRE07-C. - Avoid using repeated question marks
cpp:GotoUsage

goto is an unstructured control flow statement. It makes code less readable and maintainable. Structured control flow statements such as if, for, while, continue or break should be used instead.

Noncompliant Code Example

int i = 0;
loop:
  printf("i = %d\n", i);
  i++;
  if (i < 10){
    goto loop; // Noncompliant
  }

Compliant Solution

for (int i = 0; i < 10; i++) {
  printf("i = %d\n", i);
}

See

  • MISRA C:2004, 14.4 - The goto statement shall not be used.
  • MISRA C:2012, 15.1 - The goto statement should not be used
cpp:S5298

See

  • MISRA C++ 2008, 3-1-3
cpp:S5180

Taking the address of a library function is not something robust: The library might make changes to a function that are compatible with a normal use of a function, but not with taking its address (for instance, adding a parameter with a default value, or adding an overload to an overload set). More specifically, the standard library has stated that there would be no barrier against such changes, and that for stability users should not take the address of standard library functions.

Noncompliant Code Example

int main() {
  std::unique_ptr<FILE, int(*)(FILE*)> fp(
    fopen("test.txt", "r"),
    fclose); // Non compliant, address of fclose is implicitly taken
  // Work with fp
}

Compliant Solution

int main() {
  std::unique_ptr<FILE, int(*)(FILE*)> fp(
    fopen("test.txt", "r"),
    [](FILE*file){return fclose(file);});
  // Work with fp
}

See

  • https://wg21.link/P0921 - Document of the C++ standardization committee about change management in the standard library.
cpp:LogicalExpressionOperands

The effect of this rule is to require that operands are appropriately parenthesized. Parentheses are important in this situation both for readability of code and for ensuring that the behavior is as the developer intended.

Where an expression consists of either a sequence of only logical && or a sequence of logical ||, extra parentheses are not required.

Noncompliant Code Example

if (x == 0 && ishigh);                   // Noncompliant
if (x || y || z);
if (x || y && z);                        // Noncompliant
if (x && !y);                            // Noncompliant
if (is_odd(y) && x);
if ((x > c1) && (y > c2) && (z > c3));
if ((x > c1) && (y > c2) || (z > c3));   // Noncompliant

Compliant Solution

if ((x == 0) && ishigh);
if (x || y || z);
if (x || (y && z));
if (x && (!y));
if (is_odd(y) && x);
if ((x > c1) && (y > c2) && (z > c3));
if ((x > c1) && ((y > c2) || (z > c3)));

See

  • MISRA C:2004, 12.5 - The operands of a logical && or || shall be primary-expressions.
  • MISRA C++:2008, 5-2-1 - Each operand of a logical && or || shall be a postfix-expression.
cpp:GlobalMainFunction

A global function named main is the entry point to the program, and is the only identifier which must be in the global namespace. The use of main for other functions may not meet developer expectations.

Noncompliant Code Example

int main() {       // Compliant
}

namespace {
  int main() {     // Noncompliant
  }
}
namespace NS {
  int main() {     // Noncompliant
  }
}

See

  • MISRA C++:2008, 7-3-2 - The identifier main shall not be used for a function other than global function main.
cpp:PPIncludeCstdio

This includes file and I/O functions fgetpos, fopen, ftell, gets, perror, remove, rename, etc.

Streams and file I/O have a large number of unspecified, undefined and implementation-defined behaviors associated with them.

Noncompliant Code Example

#include <cstdio>  /* Noncompliant */

void fn()
{
  char_t array[10];
  gets(array);           /* Can lead to buffer over-run */
}

See

  • MISRA C++:2008, 27-0-1 - The stream input/output library <cstdio> shall not be used.
cpp:EmptyThrowOutsideHandler

An empty throw re-throws the temporary object that represents an exception. Its use is intended to enable the handling of an exception to be split across two or more handlers.

However, syntactically, there is nothing to prevent throw; being used outside a catch handler, where there is no exception object to re-throw. This may lead to implementation-defined program termination.

Noncompliant Code Example

void f1(void)
{
  throw;   // Noncompliant - will call std::terminate()
}

void g1(void)
{
  try
  {
    f1();
    throw; // Noncompliant
  }
  catch (...)
  {
    // ...
  }
}

Compliant Solution

void f1(void)
{
  try
  {
    throw(42);
  }
  catch (int32_t i) // int will be handled first here
  {
    if (i > 0)
    {
      throw;        // and then re-thrown - Compliant
    }
  }
}

void g1(void)
{
  try
  {
    f1();
  }
  catch (int32_t i)
  {
    // Handle re-throw from f1()
    // after f1's handler has done what it needs
  }
}

See

  • MISRA C++:2008, 15-1-3 - An empty throw (throw;) shall only be used in the compound-statement of a catch handler.
cpp:PPDefineOrUndefFromBlock

While it is legal to place #define and #undef directives anywhere in a source file, placing them outside of the global namespace is misleading since their scope is not actually restricted. This may be inconsistent with developer expectations.

Noncompliant Code Example

namespace NS
{
  #ifndef MY_HDR
  #define MY_HDR    /* Noncompliant */
  #undef FOO        /* Noncompliant */
  #endif
}

Compliant Solution

#ifndef MY_HDR
#define MY_HDR
#undef FOO
#endif

See

  • MISRA C:2004, 19.5 - Macros shall not be #define'd or #undef'd within a block.
  • MISRA C++:2008, 16-0-2 - Macros shall only be #define'd or #undef'd in the global namespace.
cpp:CommentedCode

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
cpp:PPIncludeTime

Includes time, strftime. This library is associated with clock times. Various aspects are implementation dependent or unspecified, such as the formats of times. If any of the facilities of time.h are used, then the exact implementation for the compiler being used must be determined, and a deviation raised.

Noncompliant Code Example

#include <time.h>  /* Noncompliant */

See

  • MISRA C:2004, 20.12 - The time handling functions of library <time.h> shall not be used.
  • MISRA C:2012, 21.10 - The Standard Library time and date functions shall not be used
cpp:S1709

If you invoked a method with arguments of the wrong type, you would typically expect an error at compile time (if not in the IDE). However, when the expected parameter is a class with a single-argument constructor, the compiler will implicitly pass the method argument to that constructor to implicitly create an object of the correct type for the method invocation. Alternately, if the wrong type has a conversion operator to the correct type, the operator will be called to create an object of the needed type.

But just because you can do something, that doesn't mean you should, and using implicit conversions makes the execution flow difficult to understand. Readers may not notice that a conversion occurs, and if they do notice, it will raise a lot of questions: Is the source type able to convert to the destination type? Is the destination type able to construct an instance from the source? Is it both? And if so, which method is called by the compiler?

Moreover, implicit promotions can lead to unexpected behavior, so they should be prevented by using the explicit keyword on single-argument constructors and (C++11) conversion operators. Doing so will prevent the compiler from performing implicit conversions.

Noncompliant Code Example

struct Bar {
};

struct Foo {
  Foo(Bar& bar); // Noncompliant; allow implicit conversion from 'Bar' to 'Foo'
};

struct Baz {
  operator Foo(); // Noncompliant; allow implicit conversion from 'Baz' to 'Foo'
};

void func(const Foo& b); // this function needs a 'Foo' not a 'Bar' nor a 'Baz'

int test(Bar& bar, Baz& baz) {
  func(bar); // implicit conversion using Foo::Foo(Bar& bar)
  func(baz); // implicit conversion using Baz::operator Foo()
  func(baz);
}

Compliant Solution

struct Bar {
};

struct Foo {
  explicit Foo(Bar& bar); // Compliant, using "explicit" keyword
};

struct Baz {
  Foo asFoo();             // Compliant, explicit function
  explicit operator Foo(); // Compliant, using C++11 "explicit" keyword for conversion function
};

void func(const Foo& b); // this function needs a 'Foo' not a 'Bar' nor a 'Baz'

int test(Bar& bar, Baz& baz) {
  func(Foo(bar));              // explicit conversion using Foo::Foo(Bar& bar)
  func(baz.asFoo());           // explicit conversion using Baz::asFoo()
  func(static_cast<Foo>(baz)); // explicit conversion using Baz::operator Foo()
}

See

  • MISRA C++:2008, 12-1-3 - All constructors that are callable with a single argument of fundamental type shall be declared explicit.
cpp:S127

A for loop stop condition should test the loop counter against an invariant value (i.e. one that is true at both the beginning and ending of every loop iteration). Ideally, this means that the stop condition is set to a local variable just before the loop begins.

Stop conditions that are not invariant are slightly less efficient, as well as being difficult to understand and maintain, and likely lead to the introduction of errors in the future.

This rule tracks three types of non-invariant stop conditions:

  • When the loop counters are updated in the body of the for loop
  • When the stop condition depend upon a method call
  • When the stop condition depends on an object property, since such properties could change during the execution of the loop.

Noncompliant Code Example

for (int i = 0; i < 10; i++) {
  ...
  i = i - 1; // Noncompliant
  ...
}
for (int i = 0; i < getMaximumNumber(); i++) {
}

Compliant Solution

for (int i = 0; i < 10; i++) {
  ...
}
int stopCondition = getMaximumNumber();
for (int i = 0; i < stopCondition; i++) {
}

See

  • MISRA C:2004, 13.6 - Numeric variables being used within a for loop for iteration counting shall not be modified in the body of the loop.
  • MISRA C++:2008, 6-5-3 - The loop-counter shall not be modified within condition or statement.
cpp:UsingDirective

Using-directives add additional scopes to the set of scopes searched during name lookup. All identifiers in these scopes become visible, increasing the possibility that the identifier found by the compiler does not meet developer expectations. Using-declarations or fully-qualified names restricts the set of names considered to only the name explicitly specified, and so these are safer options.

Noncompliant Code Example

namespace NS1 {
  int i1;
  int j1;
}

using namespace NS1; // Noncompliant

namespace NS2 {
  int i2;
  int j2;
}

using NS2::j2; // Compliant

See

  • MISRA C++:2008, 7-3-4 - using-directives shall not be used.
cpp:EllipsisHandlerNotLast

The catch-all handler should come last in a chain of catch or @catch statements because it catches everything, and any more-specific catch/@catch that comes after it will never be used, even when the relevant condition occurs.

This C++ code sample also applies to Objective-C.

Noncompliant Code Example

void f1()
{
  try
  {
    // ...
  }
  catch (...)
  {
    // Handle all exception types
  }
  catch (int32_t i)  // Noncompliant - handler will never be called
  {
  }
}

Compliant Solution

void f1()
{
  try
  {
    // ...
  }
  catch (int32_t i)  // Compliant - int handler
  {
    // Handle int exceptions
  }
  catch (...)        // Compliant - catch-all handler
  {
    // Handle all other exception types
  }
}

See

  • MISRA C++:2008, 15-3-7 - Where multiple handlers are provided in a single try-catch statement or function-try-block, any ellipsis (catch-all) handler shall occur last.
cpp:PPIncludeCHeader

The use of C headers and therefore C functions in a C++ program, is sometimes necessary, but should be avoided in favor of C++ headers and functions.

Noncompliant Code Example

#include <string.h>

Compliant Solution

#include <cstring>
#include <string>

See

  • MISRA C++:2008, 18-0-1 - The C library shall not be used.
cpp:CommaAndOrOverloaded

Overloaded versions of the comma and logical conjunction operators have the semantics of function calls whose sequence point and ordering semantics are different from those of the built- in versions. It may not be clear at the point of use that these operators are overloaded, and so developers may be unaware which semantics apply.

Noncompliant Code Example

#include "util.h"
class A
{
public:
  UtilType getValue ( );
  UtilType setValue ( UtilType const & );
};
void f1 ( A & a1, A & a2 )
{
  a1.getValue ( ) && a2.setValue ( 0 );	// Short circuiting may occur
}
bool operator && ( UtilType const &,
             UtilType const & );                       // Noncompliant
void f2 ( A & a1, A & a2 )
{
a1.getValue ( ) && a2.setValue ( 0 );     // Both operands evaluated if type returned has overloaded operator&&
}

See

  • MISRA C++ 2008, 5-2-11 - The comma operator, && operator and the || operator shall not be overloaded.
cpp:S121

While not technically incorrect, the omission of curly braces can be misleading, and may lead to the introduction of errors during maintenance.

Noncompliant Code Example

if (condition)  // Noncompliant
  executeSomething();

Compliant Solution

if (condition) {
  executeSomething();
}

See

  • MISRA C:2004, 14.8 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C:2004, 14.9 - An if (expression) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C++:2008, 6-3-1 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C++:2008, 6-4-1 - An if (condition) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C:2012, 15.6 - The body of an iteration-statement or a selection-statement shall be a compound-statement
  • CERT, EXP19-C. - Use braces for the body of an if, for, or while statement
  • CERT, EXP52-J. - Use braces for the body of an if, for, or while statement
cpp:SideEffectInRightHandSideOfLogical

There are some situations in C++ where certain parts of expressions may not be evaluated. If these sub-expressions contain side effects then those side effects may or may not occur, depending on the values of other sub expressions. The operators which can lead to this problem are && and ||, where the evaluation of the right-hand operand is conditional on the value of the left-hand operand. The conditional evaluation of the right-hand operand of one of the logical operators can easily cause problems if the developer relies on a side effect occurring.

Operations that cause side effects are:

  • accessing a volatile object
  • modifying an object
  • modifying a file
  • calling a function that performs any operations that cause changes in the state of the execution environment of the calling function.

This rule raises an issue when there is assignment or the use of the increment/decrement operators in right-hand operands.

Noncompliant Code Example

if ( ishigh && ( x == i++ ) ) // Noncompliant
...
if ( ishigh && ( x ==  getX() ) ) // Only acceptable if getX() is known to have no side effects

The operations that cause side effects are accessing a volatile object, modifying an object, modifying a file, or calling a function

that does any of those operations, which cause changes in the state of the execution environment of the calling function.

For the time being, this rule only check that there is no assignment or no use of increment/decrement operators made in right hand operands.

See

  • MISRA C:2004, 12.4 - The right-hand operand of a logical && or || operator shall not contain side effects.
  • MISRA C++:2008, 5-14-1 - The right hand operand of a logical && or || operator shall not contain side effects.
  • MISRA C:2012, 13.5 - The right hand operand of a logical && or || operator shall not contain persistent side effects
  • CERT, EXP02-C. - Be aware of the short-circuit behavior of the logical AND and OR operators
cpp:S2193

When using a floating-point for loop counter, an accumulation of rounding errors may result in a mismatch between the expected and actual number of iterations.

Even if floating-point loop counters appears to behave correctly on one implementation, it may give a different number of iterations on another implementation.

Noncompliant Code Example

for (float counter = 0.0f; counter < 1.0f; counter += 0.001f) {
  ...
}

Compliant Solution

for (int counter = 0; counter < 1000; ++counter) {
  ...
}

See

  • MISRA C:2004, 13.4 - The controlling expression of a for statement shall not contain any objects of floating type.
  • MISRA C++:2008, 6-5-1 - A for loop shall contain a single loop-counter which shall not have floating type.
  • MISRA C:2012, 14.1 - A loop counter shall not have essentially floating type.
  • CERT, NUM09-J. - Do not use floating-point variables as loop counters
  • CERT, FLP30-C. - Do not use floating-point variables as loop counters
cpp:ExceptionInDestructor

When an exception is thrown, the call stack is unwound up to the point where the exception is to be handled. The destructors for all automatic objects declared between the point where the exception is thrown and where it is to be handled will be invoked. If one of these destructors exits with an exception, then the program will terminate in an implementation-defined manner, potentially yielding unexpected results.

Note that it is acceptable for a destructor to throw an exception that is handled within the destructor, for example within a try-catch block.

Noncompliant Code Example

class C1 {
  public: ~C1() {
    throw(42);   // Noncompliant - destructor exits with an exception
  }
};

void foo() {
  C1 c; // program terminates when c is destroyed
  throw(10);
}

Compliant Solution

class C1 {
  public: ~C1() {
    try {
      throw(42);   // Compliant - exception will not leave destructor
    } catch (int i) {  // int handler
      // Handle int exception throw by destructor
    }
  }
};

void foo() {
  C1 c;
  throw(10);
}

See

  • MISRA C++:2008, 15-5-1 - A class destructor shall not exit with an exception.
cpp:S5319

See

  • MISRA C++ 2008, 8-4-2: The identifiers used for the parameters in a re-declaration or override of a function shall be identical to those in the declaration.
cpp:S5318

See

  • MISRA C++2008, 7-3-6
cpp:PPIncludeStdio

This includes file and I/O functions fgetpos, fopen, ftell, gets, perror, remove, rename and ungetc.

Streams and file I/O have a large number of unspecified, undefined and implementation-defined behaviors associated with them. It is assumed within MISRA C that they will not normally be needed in production code in embedded systems.

If any of the features of stdio.h need to be used in production code, then the issues associated with the features need to be understood.

Noncompliant Code Example

#include <stdio.h> /* Noncompliant */

See

  • MISRA C:2004, 20.9 - The input/output library <stdio.h> shall not be used in production code.
  • MISRA C++:2008, 27-0-1 - The stream input/output library <cstdio> shall not be used.
  • MISRA C:2012, 21.6 - The Standard Library input/output functions shall not be used
cpp:S1081

When using legacy C functions, it's up to the developer to make sure the size of the buffer to be written to is large enough to avoid buffer overflows. Buffer overflows can cause the program to crash at a minimum. At worst, a carefully crafted overflow can cause malicious code to be executed.

This rule reports use of the following insecure functions: strcpy(), strcat(), sprintf(), gets() and getpw().

In such cases, it's better to use an alternate, secure function which allows you to define the maximum number of characters to be written to the buffer:

  • strlcpy (BSD library) or strncpy
  • strlcat (BSD library) or strncat
  • snprintf
  • fgets
  • getpwuid

(Be aware that strncpy and strncat don't guarantee the string will be null-terminated.)

Noncompliant Code Example

sprintf(str, "%s", message);   // Noncompliant
strcpy(str, message); // Noncompliant

Compliant Solution

snprintf(str, sizeof(str), "%s", message);
strlcpy(str, message, sizeof(str));

strncpy(str, message, sizeof(str) -1); // Leave room for null
str[sizeof(str) - 1] = '\0'; // Make sure the string is null-terminated

See

cpp:S784

Ensuring that assembly language code is encapsulated and isolated aids portability. Where assembly language instructions are needed, they shall be encapsulated and isolated in either assembler functions or C++ functions.

Noncompliant Code Example

void fn ( void )
{
  DoSomething ( );
  asm ( "NOP" ); // Noncompliant, asm mixed with C/C++ statements
  DoSomething ( );
}

Compliant Solution

void Delay ( void )
{
  asm ( "NOP" ); // Compliant, asm not mixed with C/C++ statements
}

void fn ( void )
{
  DoSomething ( );
  Delay ( ); // Compliant, Assembler is encapsulated
  DoSomething ( );
}

See

  • MISRA C 2004, 2.1 - Assembly language shall be encapsulated and isolated.
  • MISRA C++ 2008, 7-4-3 - Assembly language shall be encapsulated and isolated.
cpp:S793

The #pragma directive is implementation-defined, hence it is important both to demonstrate that all uses are correct, and to minimize, localize and encapsulate any use of pragmas within dedicated functions whenever possible.

The meaning of each pragma shall be documented.

There shall be sufficient supporting description to demonstrate that the behavior of the pragma and its implications for the application, have been fully understood.

This rule flags all instances of #pragma directives, and leaves it to the user to determine whether they have been properly documented.

See

  • MISRA C:2004, 3.4 - All uses of the #pragma directive shall be documented and explained
  • MISRA C++:2008, 16-6-1 - All uses of the #pragma directive shall be documented
  • CERT, MSC00-C - Compile cleanly at high warning levels
cpp:S5028

A macro is a textual replacement, which means that it's not respecting the type system, it's not respecting scoping rules... There is no reason not to use a constant instead.

Most of the time, a macro can be replaced by a constexpr declaration (a constant that is guaranteed to be computed during compilation). If your compiler is too old to properly handle constexpr, you may use const instead.

If you have a series of related integer macros, you might also consider replacing them by an enum.

Noncompliant Code Example

#define MAX_MEMORY 640 // Noncompliant

#define LEFT   0 // Noncompliant
#define RIGHT  1 // Noncompliant
#define JUMP   2 // Noncompliant
#define SHOOT  3 // Noncompliant

Compliant Solution

constexpr size_t MAX_MEMORY = 640;
enum class Actions {Left, Right, Jump, Shoot};

See

cpp:S5266

In programming languages keywords have a special meaning and are reserved to the language. It is hence a bad idea to define macros with keywords as macro identifier as it can easily lead to undefined behavior:

  • The same object might be defined differently in different places, which violates the One Definition Rule
  • If you include any header from the standard library, it is undefined behavior to define such macros

Additionally, it is very awkward for anyone reading the code to have a keyword that means something different.

Noncompliant Code Example

#define int some_other_type // Noncompliant
#include <stdlib.h>;

See

* MISRA C:2012, 20.4 - A macro shall not be defined with the same name as a keyword

cpp:PPBadIncludeForm

These are the only forms for the #include directive permitted by the standard. The behavior is undefined when other forms are used.

Noncompliant Code Example

#include filename.h        // Noncompliant

Compliant Solution

#include "filename.h"        // Compliant
#include <filename.h>

#define HEADER "filename.h"
#include HEADER

See

  • MISRA C:2004, 19.3 - The #include directive shall be followed by either a <filename> or "filename" sequence.
  • MISRA C++:2008, 16-2-6 - The #include directive shall be followed by either a <filename> or "filename" sequence.
  • MISRA C:2012, 20.3 - The #include directive shall be followed by either a <filename> or "filename" sequence
cpp:PPIncludeNonStandardCharacters

If the ', \, " or /* characters are used between < and > delimiters or the ', \ or /* characters are used between the " delimiters in a header name preprocessing token, then the behavior is undefined.

Noncompliant Code Example

#include <"foo">     // Noncompliant
#include "dir\foo.h" // Noncompliant

See

  • MISRA C:2004, 19.2 - Non-standard characters should not occur in header file names in #include directives.
  • MISRA C++:2008, 16-2-4 - The ', ", /* or // characters shall not occur in a header file name.
  • MISRA C++:2008, 16-2-5 - The \ character should not occur in a header file name.
  • MISRA C:2012, 20.2 - The ', " or \ characters and the /* or // character sequences shall not occur in a header file name
cpp:FunctionSinglePointOfExit

This is required by IEC 61508, under good programming style.

Noncompliant Code Example

int function1()
{
  return 3;
}

void function2()
{
  function1();
}

int function3(char* ptr) /* Noncompliant; two explicit returns */
{
  if (ptr == NULL) return -1;

  return 7;
}

void function4(char *ptr) /* Noncompliant; two returns, one explicit and one implicit */
{
  if (1) return;

  printf("hello world!\n");
}

See

  • MISRA C:2004, 14.7 - A function shall have a single point of exit at the end of the function.
  • MISRA C++:2008, 6-6-5 - A function shall have a single point of exit at the end of the function
  • MISRA C:2012, 15.5 - A function should have a single point of exit at the end
cpp:SwitchWithoutDefault

The requirement for a final default clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken. When the switch covers all current values of an enum - and especially when it doesn't - a default case should still be used because there is no guarantee that the enum won't be extended.

Noncompliant Code Example

switch (param) { // Noncompliant - default clause is missing
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
}

Compliant Solution

switch (param) {
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
  default:
    doDefault();
    break;
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
  • MITRE, CWE-478 - Missing Default Case in Switch Statement
  • CERT, MSC01-C. - Strive for logical completeness

See also

cpp:PPIncludeNotAtTop

To aid code readability, all the #include directives in a particular code file should be grouped together near the top of the file. The only items which may precede an #include in a file are other preprocessor directives or comments.

Noncompliant Code Example

#include <h1.h> /* Compliant */
int32_t i;
#include <f2.h> /* Noncompliant */

Compliant Solution

#include <h1.h>
#include <f2.h>

int32_t i;

See

  • MISRA C:2004, 19.1 - #include statements in a file should only be preceded by other preprocessor directives or comments.
  • MISRA C++:2008, 16-0-1 - #include directives in a file shall only be preceded by other preprocessor directives or comments.
  • MISRA C:2012, 20.1 - #include directives should only be preceded by preprocessor directives or comments
cpp:NonEmptyCaseWithoutBreak

When the execution is not explicitly terminated at the end of a switch case, it continues to execute the statements of the following case. While this is sometimes intentional, it often is a mistake which leads to unexpected behavior.

Noncompliant Code Example

switch (myVariable) {
  case 1:
    foo();
    break;
  case 2:  // Both 'doSomething()' and 'doSomethingElse()' will be executed. Is it on purpose ?
    doSomething();
  default:
    doSomethingElse();
    break;
}

Compliant Solution

switch (myVariable) {
  case 1:
    foo();
    break;
  case 2:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Exceptions

This rule is relaxed in the following cases:

switch (myVariable) {
  case 0:                                // Empty case used to specify the same behavior for a group of cases.
  case 1:
    doSomething();
    break;
  case 2:                                // Use of return statement
    return;
  case 3:                                // Use of throw statement
    throw 1;
  case 4:                                // Use of continue statement
    continue;
  default:                               // For the last case, use of break statement is optional
    doSomethingElse();
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.2 - An unconditional break statement shall terminate every non-empty switch clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-5 - An unconditional throw or break statement shall terminate every non-empty switch-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.3 - An unconditional break statement shall terminate every switch-clause
  • MITRE, CWE-484 - Omitted Break Statement in Switch
  • CERT, MSC17-C. - Finish every set of statements associated with a case label with a break statement
  • CERT, MSC52-J. - Finish every set of statements associated with a case label with a break statement
cpp:S886

The for statement provides a general-purpose looping facility. Using a restricted form of loop makes code easier to review and to analyse.

The three clauses of a for statement are the:

  • First clause which should
    • be empty, or
    • assign a value to the loop counter, or
    • define and initialize the loop counter (C99).
  • Second clause which should
    • be an expression that has no persistent side effects, and
    • not use objects that are modified in the for loop body.
  • Third clause which should
    • be an expression whose only persistent side effect is to modify the value of the loop counter, and
    • not use objects that are modified in the for loop body.

Noncompliant Code Example

for( int i = 0 ; i++ < 10 ; i += 1 ) { // Noncompliant, loop counter is updated in the condition
}

for( int i = 0 ; ; ) { // Noncompliant, initialized variable i is not used in the condition
}

for( int i = 0 , j = 0 ; i < 10 ; i += j) { // Noncompliant, j is modified in the body
  j = i + 1;
}

See

  • MISRA C:2004, 13.5 - The three expressions of a for statement shall be concerned only with loop control.
  • MISRA C++:2008, 6-5-5 - A loop-control-variable other than the loop-counter shall not be modified within condition or expression.
  • MISRA C:2012, 14.2 - A for loop shall be well-formed
cpp:BackJumpWithGoto

Unconstrained use of goto can lead to programs that are extremely difficult to comprehend and analyse. For C++, it can also lead to the program exhibiting unspecified behavior.

However, in many cases a total ban on goto requires the introduction of flags to ensure correct control flow, and it is possible that these flags may themselves be less transparent than the goto they replace.

Therefore, the restricted use of goto is allowed where that use will not lead to semantics contrary to developer expectations. "Back" jumps are prohibited, since they can be used to create iterations without using the well-defined iteration statements supplied by the core language.

Noncompliant Code Example

int f() {
  int j = 0;
L1:
  ++j;
  if (10 == j) {
    goto L2;         // forward jump ignored
  }
  // ...
  goto L1;           // Noncompliant
L2:
  return ++j;
}

Compliant Solution

int f() {
  for (int j = 0; j < 11; j++) {
    // ...
  }
  return ++j;
}

See

  • MISRA C++:2008, 6-6-2 - The goto statement shall jump to a label declared later in the same function body
  • MISRA C:2012, 15.2 - The goto statement shall jump to a label declared later in the same function
cpp:IncAndDecMixedWithOtherOperators

The use of increment and decrement operators in method calls or in combination with other arithmetic operators is not recommended, because:

  • It can significantly impair the readability of the code.
  • It introduces additional side effects into a statement, with the potential for undefined behavior.
  • It is safer to use these operators in isolation from any other arithmetic operators.

Noncompliant Code Example

u8a = ++u8b + u8c--;
foo = bar++ / 4;

Compliant Solution

The following sequence is clearer and therefore safer:

++u8b;
u8a = u8b + u8c;
u8c--;
foo = bar / 4;
bar++;

See

  • MISRA C:2004, 12.1 - Limited dependence should be placed on the C operator precedence rules in expressions.
  • MISRA C:2004, 12.13 - The increment (++) and decrement (--) operators should not be mixed with other operators in an expression.
  • MISRA C++:2008, 5-2-10 - The increment (++) and decrement (--) operator should not be mixed with other operators in an expression.
  • MISRA C:2012, 12.1 - The precedence of operators within expressions should be made explicit
  • MISRA C:2012, 13.3 - A full expression containing an increment (++) or decrement (--) operator should have no other potential side effects other than that cause by the increment or decrement operator
  • CERT, EXP30-C. - Do not depend on the order of evaluation for side effects
  • CERT, EXP50-CPP. - Do not depend on the order of evaluation for side effects
  • CERT, EXP05-J. - Do not follow a write by a subsequent write or read of the same object within an expression
cpp:S5008

void* is a pointer to memory of unknown type, and therefore works outside of the safety net provided by the type system. While it can be useful in a function body to interface with external code, there is no good reason to step out of the robust C++ type system when defining a function, either for the function parameters, or for the function return type.

If you want to work with raw memory buffer, use unsigned char * (or byte * if your compiler supports it).

If you want to work with different types of data, define a function template and use typed pointers, instead of void *.

If you want to provide to users of an API an opaque type, declare a type and don't provide its definition (like with FILE*).

Noncompliant Code Example

void saveBuffer(void *buffer, size_t size); // Noncompliant
void duplicate(void* destination, size_t count, void *source, size_t size); // Noncompliant

Compliant Solution

void saveBuffer(unsigned char *buffer, size_t size);
template<class T>
void duplicate(T* destination, size_t count, T *source);
cpp:S897

If a type is declared but not used, then it is unclear to a reviewer if the type is redundant or it has been left unused by mistake.

Noncompliant Code Example

void unusedtype()
{
  typedef int local_Type; // Noncompliant, unused
}

See

  • MISRA C++:2008, 0-1-5 - A project shall not contain unused type declarations.
csharpsquid:S2225

Calling ToString() on an object should always return a string. Returning null instead contravenes the method's implicit contract.

Noncompliant Code Example

public override string ToString ()
{
  if (this.collection.Count == 0)
  {
    return null; // Noncompliant
  }
  else
  {
    // ...
  }
}

Compliant Solution

public override string ToString ()
{
  if (this.collection.Count == 0)
  {
    return string.Empty;
  }
  else
  {
    // ...
  }
}

See

csharpsquid:S2589

If a boolean expression doesn't change the evaluation of the condition, then it is entirely unnecessary, and can be removed. If it is gratuitous because it does not match the programmer's intent, then it's a bug and the expression should be fixed.

Noncompliant Code Example

a = true;
if (a) // Noncompliant
{
  DoSomething();
}

if (b && a) // Noncompliant; "a" is always "true"
{
  DoSomething();
}

if (c || !a) // Noncompliant; "!a" is always "false"
{
  DoSomething();
}

Compliant Solution

a = true;
if (Foo(a))
{
  DoSomething();
}

if (b)
{
  DoSomething();
}

if (c)
{
  DoSomething();
}

See

  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
  • MITRE, CWE-571 - Expression is Always True
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-489 - Leftover Debug Code
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
csharpsquid:S2583

Conditional expressions which are always true or false can lead to dead code. Such code is always buggy and should never be used in production.

Noncompliant Code Example

a = false;
if (a) // Noncompliant
{
  DoSomething(); // never executed
}

if (!a || b) // Noncompliant; "!a" is always "true", "b" is never evaluated
{
  DoSomething();
}
else
{
  DoSomethingElse(); // never executed
}

Exceptions

This rule will not raise an issue in either of these cases:

  • When the condition is a single const bool
const bool debug = false;
//...
if (debug)
{
  // Print something
}
  • When the condition is the literal true or false.

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

See

csharpsquid:S2228

Debug statements are always useful during development. But include them in production code - particularly in code that runs client-side - and you run the risk of inadvertently exposing sensitive information.

Noncompliant Code Example

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

Exceptions

The following are ignored by this rule:

  • Console Applications
  • Calls in methods decorated with [Conditional ("DEBUG")]
  • Calls included in DEBUG preprocessor branches (#if DEBUG)

See

csharpsquid:S1147

Calling Environment.Exit(exitCode) or Application.Exit() terminates the process and returns an exit code to the operating system..

Each of these methods should be used with extreme care, and only when the intent is to stop the whole application.

Noncompliant Code Example

Environment.Exit(0);
Application.Exit();

Exceptions

These methods are ignored inside Main.

csharpsquid:S1145

if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.

There are three possible causes for the presence of such code:

  • An if statement was changed during debugging and that debug code has been committed.
  • Some value was left unset.
  • Some logic is not doing what the programmer thought it did.

In any of these cases, unconditional if statements should be removed.

Noncompliant Code Example

if (true)
{
  DoSomething();
}
...
if (false)
{
  DoSomethingElse();
}

Compliant Solution

DoSomething();
...

See

Deprecated

This rule is deprecated; use S2583 instead.

csharpsquid:S1144

private or internal types or private members that are never executed or referenced are dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.

Noncompliant Code Example

public class Foo
{
    private void UnusedPrivateMethod() {...} // Noncompliant

    private class UnusedClass {...} // Noncompliant
}

Compliant Solution

public class Foo
{
    public Foo()
    {
        UsedPrivateMethod();
    }

    private void UsedPrivateMethod()
    {
        var c = new UsedClass();
    }

    private class UsedClass {...}
}

Exceptions

This rule doesn't raise issues on:

  • Empty constructors
  • Attributed members
  • Main method
  • Methods with event handler signature void Foo(object, EventArgs) that are declared in partial class
  • Empty serialization constructor on type with System.SerializableAttribute attribute.
  • Internals in assemblies that have a System.Runtime.CompilerServices.InternalsVisibleToAttribute attribute.
csharpsquid:S1944

Inappropriate casts are issues that will lead to unexpected behavior or runtime errors, such as InvalidCastExceptions. The compiler will catch bad casts from one class to another, but not bad casts to interfaces. Nor will it catch nullable values that are known to be null but that are cast to their underlying value types anyway.

It is much better to use the as operator because it will return null instead of throwing an exception.

Noncompliant Code Example

public interface IMyInterface
{ /* ... */ }

public class Implementer : IMyInterface
{ /* ... */ }

public class MyClass
{ /* ... */ }

public static class Program
{
  public static void Main()
  {
    var myclass = new MyClass();
    var x = (IMyInterface) myclass; // Noncompliant, InvalidCastException is being thrown
    var b = myclass is IMyInterface; // Noncompliant, always false

    int? i = null;
    var ii = (int)i; // Noncompliant, InvalidOperationException is being thrown
  }
}

Compliant Solution

public interface IMyInterface
{ /* ... */ }

public class Implementer : IMyInterface
{ /* ... */ }

public class MyClass
{ /* ... */ }

public static class Program
{
  public static void Main()
  {
    var myclass = new MyClass();
    var x = myclass as IMyInterface; // Compliant, but will always be null
    var b = false;

    int? i = null;
    if (i.HasValue)
    {
      var ii = (int)i;
    }
  }
}

Exceptions

No issue is reported if the interface has no implementing class in the assembly.

See

csharpsquid:S881

The use of increment and decrement operators in method calls or in combination with other arithmetic operators is not recommended, because:

  • It can significantly impair the readability of the code.
  • It introduces additional side effects into a statement, with the potential for undefined behavior.
  • It is safer to use these operators in isolation from any other arithmetic operators.

Noncompliant Code Example

u8a = ++u8b + u8c--;
foo = bar++ / 4;

Compliant Solution

The following sequence is clearer and therefore safer:

++u8b;
u8a = u8b + u8c;
u8c--;
foo = bar / 4;
bar++;

See

  • CERT, EXP30-C. - Do not depend on the order of evaluation for side effects
  • CERT, EXP50-CPP. - Do not depend on the order of evaluation for side effects
  • CERT, EXP05-J. - Do not follow a write by a subsequent write or read of the same object within an expression
csharpsquid:S3776

Cognitive 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.

See

csharpsquid:S3897

The IEquatable<T> interface has only one method in it: Equals(<T>). If you've already written Equals(T), there's no reason not to explicitly implement IEquatable<T>. Doing so expands the utility of your class by allowing it to be used where an IEquatable is called for.

Note**: Classes that implement IEquatable<T> should also be sealed.

Noncompliant Code Example

class MyClass  // Noncompliant
{
  public bool Equals(MyClass other)
  {
    //...
  }
}

Compliant Solution

sealed class MyClass : IEquatable<MyClass>
{
  public override bool Equals(object other)
  {
    return Equals(other as MyClass);
  }

  public bool Equals(MyClass other)
  {
    //...
  }
}
csharpsquid:S2688

NaN is not equal to anything, even itself. Testing for equality or inequality against NaN will yield predictable results, but probably not the ones you want.

Instead, the best way to see whether a variable is equal to NaN is to use Number.isNaN(), since ES2015, or (perhaps counter-intuitively) to compare it to itself. Since NaN !== NaN, when a !== a, you know it must equal NaN.

Noncompliant Code Example

var a = double.NaN;

if (a == double.NaN) // Noncompliant; always false
{
  Console.WriteLine("a is not a number");  // this is dead code
}
if (a != double.NaN)  // Noncompliant; always true
{
  Console.WriteLine("a is not NaN"); // this statement is not necessarily true
}

Compliant Solution

if (double.IsNaN(a))
{
  console.log("a is not a number");
}

See

csharpsquid:S2201

When the call to a function doesn't have any side effects, what is the point of making the call if the results are ignored? In such case, either the function call is useless and should be dropped or the source code doesn't behave as expected.

This rule raises an issue when the results of the following methods are ignored:

  • LINQ method,
  • [Pure] method,
  • any method on string, int, ..., System.Collections.Immutable.ImmutableArray<T>, ImmutableHashSet<T>, ...

Note: although string.Intern has a side effect, ignoring its return value is still suspicious as it is the only reference ensured to point to the intern pool.

Noncompliant Code Example

coll.Where(i => i > 5).Select(i => i*i); // Noncompliant
"this string".Equals("other string"); // Noncompliant

Compliant Solution

var res = coll.Where(i => i > 5).Select(i => i*i);
var isEqual = "this string".Equals("other string");

Exceptions

This rule doesn't report issues on method calls with out or ref arguments.

See

csharpsquid:S2681

Curly braces can be omitted from a one-line block, such as with an if statement or for loop, but doing so can be misleading and induce bugs.

This rule raises an issue when the whitespacing of the lines after a one line block indicates an intent to include those lines in the block, but the omission of curly braces means the lines will be unconditionally executed once.

Noncompliant Code Example

if (condition)
  FirstActionInBlock();
  SecondAction();  // Noncompliant; executed unconditionally
ThirdAction();

if(condition) FirstActionInBlock(); SecondAction();  // Noncompliant; secondAction executed unconditionally

if(condition) FirstActionInBlock();  // Noncompliant
  SecondAction();  // Executed unconditionally

string str = null;
for (int i = 0; i < array.Length; i++)
  str = array[i];
  DoTheThing(str);  // Noncompliant; executed only on last array element

Compliant Solution

if (condition)
{
  FirstActionInBlock();
  SecondAction();
}
ThirdAction();

string str = null;
for (int i = 0; i < array.Length; i++)
{
  str = array[i];
  DoTheThing(str);
}

See

csharpsquid:S1117

Overriding or shadowing a variable declared in an outer scope can strongly impact the readability, and therefore the maintainability, of a piece of code. Further, it could lead maintainers to introduce bugs because they think they're using one variable but are really using another.

Noncompliant Code Example

class Foo
{
  public int myField;

  public void DoSomething()
  {
    int myField = 0;  // Noncompliant
    ...
  }
}

See

csharpsquid:S2326

Type parameters that aren't used are dead code, which can only distract and possibly confuse developers during maintenance. Therefore, unused type parameters should be removed.

Noncompliant Code Example

public class MoreMath<T>   // Noncompliant; <T> is ignored
{
  public int Add<T>(int a, int b) // Noncompliant; <T> is ignored
  {
    return a + b;
  }
}

Compliant Solution

public class MoreMath
{
  public int Add (int a, int b)
  {
    return a + b;
  }
}
csharpsquid:S1116

Empty statements, i.e. ;, are usually introduced by mistake, for example because:

  • It was meant to be replaced by an actual statement, but this was forgotten.
  • There was a typo which lead the semicolon to be doubled, i.e. ;;.

Noncompliant Code Example

void DoSomething()
{
    ; // Noncompliant - was used as a kind of TODO marker
}

void DoSomethingElse()
{
    Console.WriteLine("Hello, world!");;  // Noncompliant - double ;
    // ...
    // Rarely, they are used on purpose as the body of a loop. It is a bad practice to
    // have side-effects outside of the loop:
    for (int i = 0; i < 3; Console.WriteLine(i), i++); // Noncompliant
    // ...
}

Compliant Solution

void DoSomething()
{
}

void DoSomethingElse()
{
    Console.WriteLine("Hello, world!");
    // ...
    for (int i = 0; i < 3; i++)
    {
        Console.WriteLine(i);
     }
    // ...
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • CERT, MSC51-J. - Do not place a semicolon immediately following an if, for, or while condition
  • CERT, EXP15-C. - Do not place a semicolon on the same line as an if, for, or while statement
csharpsquid:S1244

Floating point math is imprecise because of the challenges of storing such values in a binary representation. Even worse, floating point math is not associative; push a float or a double through a series of simple mathematical operations and the answer will be different based on the order of those operation because of the rounding that takes place at each step.

Even simple floating point assignments are not simple:

float f = 0.100000001f; // 0.1
double d = 0.10000000000000001; // 0.1

(Results will vary based on compiler and compiler settings)

Therefore, the use of the equality (==) and inequality (!=) operators on float or double values is almost always an error.

This rule checks for the use of direct and indirect equality/inequality tests on floats and doubles.

Noncompliant Code Example

float myNumber = 3.146f;
if ( myNumber == 3.146f ) //Noncompliant. Because of floating point imprecision, this will be false
{
  // ...
}

if (myNumber <= 3.146f && mNumber >= 3.146f) // Noncompliant indirect equality test
{
  // ...
}

if (myNumber < 4 || myNumber > 4) // Noncompliant indirect inequality test
{
  // ...
}
csharpsquid:S1121

Assignments within sub-expressions are hard to spot and therefore make the code less readable. Ideally, sub-expressions should not have side-effects.

Noncompliant Code Example

if (string.IsNullOrEmpty(result = str.Substring(index, length))) // Noncompliant
{
  //...
}

Compliant Solution

var result = str.Substring(index, length);
if (string.IsNullOrEmpty(result))
{
  //...
}

Exceptions

Assignments inside lambda and delegate expressions are allowed.

Furthermore, the following patterns are also accepted:

var a = b = c = 10;
while ((val = GetNewValue()) > 0)
{
...
}
private MyClass instance;
public MyClass Instance
{
  get
  {
    return instance ?? (instance = new MyClass());
  }
}

See

csharpsquid:S2219

To check the type of an object there are several options:

  • expr is SomeType or expr.GetType() == typeof(SomeType) if the type is known at compile time,
  • typeInstance.IsInstanceOfType(expr) if the type is calculated during runtime.

If runtime calculated Types need to be compared:

  • typeInstance1.IsAssignableFrom(typeInstance2).

Depending on whether the type is returned by a GetType() or typeof() call, the IsAssignableFrom() and IsInstanceOfType() might be simplified. Similarly, if the type is sealed, the type comparison with == can be converted to an is call. Simplifying the calls also make null checking unnecessary because both is and IsInstanceOfType performs it already.

Finally, utilizing the most concise language constructs for type checking makes the code more readable, so

  • expr as T != null checks should be simplified to expr is T, and
  • expr is T should be converted to expr != null, when expr is of type T.

Noncompliant Code Example

class Fruit { }
sealed class Apple : Fruit { }

class Program
{
  static void Main()
  {
    var apple = new Apple();
    var b = apple != null && apple.GetType() == typeof (Apple); // Noncompliant
    b = typeof(Apple).IsInstanceOfType(apple); // Noncompliant
    if (apple != null)
    {
      b = typeof(Apple).IsAssignableFrom(apple.GetType()); // Noncompliant
    }
    var appleType = typeof (Apple);
    if (apple != null)
    {
      b = appleType.IsAssignableFrom(apple.GetType()); // Noncompliant
    }

    Fruit f = apple;
    if (f as Apple != null) // Noncompliant
    {
    }
    if (apple is Apple) // Noncompliant
    {
    }
  }
}

Compliant Solution

class Fruit { }
sealed class Apple : Fruit { }

class Program
{
  static void Main()
  {
    var apple = new Apple();
    var b = apple is Apple;
    b = apple is Apple;
    b = apple is Apple;
    var appleType = typeof(Apple);
    b = appleType.IsInstanceOfType(apple);

    Fruit f = apple;
    if (f is Apple)
    {
    }
    if (apple != null)
    {
    }
  }
}

Exceptions

Calling GetType on an object of Nullable<T> type returns the underlying generic type parameter T, thus a comparison with typeof(Nullable<T>) can't be simplified to use the is operator, which doesn't make difference between T and T?.

int? i = 42;
bool condition = i.GetType() == typeof(int?); // false;
condition = i is int?; // true

No issue is reported on the following expressions:

  • expr is T when either operand of the is operator is a value type. In that case CS0183 or CS0184 reports
  • expr is object, as this is a common and efficient pattern to do null checks
csharpsquid:S1006

Default arguments are determined by the static type of the object. If a default argument is different for a parameter in an overriding method, the value used in the call will be different when calls are made via the base or derived object, which may be contrary to developer expectations.

Default parameter values are useless in explicit interface implementations, because the static type of the object will always be the implemented interface. Thus, specifying default values is useless and confusing.

Noncompliant Code Example

public class Base
{
  public virtual void Write(int i = 42)
  {
    Console.WriteLine(i);
  }
}

public class Derived : Base
{
  public override void Write(int i = 5) // Noncompliant
  {
    Console.WriteLine(i);
  }
}

public class Program
{
  public static void Main()
  {
    var derived = new Derived();
    derived.Write(); // writes 5
    Print(derived);  // writes 42; was that expected?
  }
  private void Print(Base item)
  {
    item.Write();
  }
}

Compliant Solution

public class Base
{
  public virtual void Write(int i = 42)
  {
    Console.WriteLine(i);
  }
}

public class Derived : Base
{
  public override void Write(int i = 42)
  {
    Console.WriteLine(i);
  }
}

public class Program
{
  public static void Main()
  {
    var derived = new Derived();
    derived.Write(); // writes 42
    Print(derived);  // writes 42
  }
  private void Print(Base item)
  {
    item.Write();
  }
}

See

  • MISRA C++ 2008, 8-3-1 - Parameters in a overriding virtual function shall either use the same default arguments as the function they override, or else shall not specify any default arguments.
csharpsquid:S5042

Expanding archive files is security-sensitive. For example, expanding archive files has led in the past to the following vulnerabilities:

Applications that expand archive files (zip, tar, jar, war, 7z, ...) should verify the path where the archive's files are expanded and not trust blindly the content of the archive. Archive's files should not be expanded outside of the root directory where the archive is supposed to be expanded. Also, applications should control the size of the expanded data to not be a victim of Zip Bomb attack. Failure to do so could allow an attacker to use a specially crafted archive that holds directory traversal paths (e.g. ../../attacker.sh) or the attacker could overload the file system, processors or memory of the operating system where the archive is expanded making the target OS completely unusable.

This rule raises an issue when code handle archives. The goal is to guide security code reviews.

Ask Yourself Whether

  • there is no validation of the name of the archive entry
  • there is no validation of the effective path where the archive entry is going to be expanded
  • there is no validation of the size of the expanded archive entry
  • there is no validation of the ratio between the compressed and uncompressed archive entry

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Validate the full path of the extracted file against the full path of the directory where files are expanded.

  • the canonical path of the expanded file must start with the canonical path of the directory where files are extracted.
  • the name of the archive entry must not contain "..", i.e. reference to a parent directory.

Stop extracting the archive if any of its entries has been tainted with a directory traversal path.

Define and control the ratio between compressed and uncompress bytes.

Define and control the maximum allowed expanded file size.

Count the number of file entries extracted from the archive and abort the extraction if their number is greater than a predefined threshold.

Sensitive Code Example

foreach (ZipArchiveEntry entry in archive.Entries)
{
    //  entry.FullName could contain parent directory references ".." and the destinationPath variable could become outside of the desired path
    string destinationPath = Path.GetFullPath(Path.Combine(path, entry.FullName));

    entry.ExtractToFile(destinationPath); // Sensitive, extracts the entry in a file

    Stream stream;
    stream = entry.Open(); // Sensitive, the entry is about to be extracted
}

See

csharpsquid:S2386

public static mutable fields of classes which are accessed directly should be protected to the degree possible. This can be done by reducing the accessibility of the field or by changing the return type to an immutable type.

This rule raises issues for public static fields with a type inheriting/implementing System.Array or System.Collections.Generic.ICollection<T>.

Noncompliant Code Example

public class A
{
  public static string[] strings1 = {"first","second"};  // Noncompliant
  public static List<String> strings3 = new List<String>();  // Noncompliant
  // ...
}

Compliant Solution

public class A
{
  protected static string[] strings1 = {"first","second"};
  protected static List<String> strings3 = new List<String>();
  // ...
}

Exceptions

No issue is reported:

  • If the type of the field inherits/implements one (at least) of the following types:
    • System.Collections.ObjectModel.ReadOnlyCollection<T>
    • System.Collections.ObjectModel.ReadOnlyDictionary<TKey, TValue>
    • System.Collections.Immutable.IImmutableArray<T>
    • System.Collections.Immutable.IImmutableDictionary<TKey, TValue>
    • System.Collections.Immutable.IImmutableList<T>
    • System.Collections.Immutable.IImmutableSet<T>
    • System.Collections.Immutable.IImmutableStack<T>
    • System.Collections.Immutable.IImmutableQueue<T>
  • If the field is readonly and is initialized inline with an immutable type (i.e. inherits/implements one of the types in the previous list) or null.

See

csharpsquid:S4564

ASP.Net has a feature to validate HTTP requests to prevent potentially dangerous content to perform a cross-site scripting (XSS) attack. There is no reason to disable this mechanism even if other checks to prevent XXS attacks are in place.

This rule raises an issue if a method with parameters is marked with System.Web.Mvc.HttpPostAttribute and not System.Web.Mvc.ValidateInputAttribute(true).

Noncompliant Code Example

public class FooBarController : Controller
{
    [HttpPost] // Noncompliant
    [ValidateInput(false)]
    public ActionResult Purchase(string input)
    {
        return Foo(input);
    }

    [HttpPost] // Noncompliant
    public ActionResult PurchaseSomethingElse(string input)
    {
        return Foo(input);
    }
}

Compliant Solution

public class FooBarController : Controller
{
    [HttpPost]
    [ValidateInput(true)] // Compliant
    public ActionResult Purchase(string input)
    {
        return Foo(input);
    }
}

Exceptions

Parameterless methods marked with System.Web.Mvc.HttpPostAttribute will not trigger this issue.

See

csharpsquid:S1854

A dead store happens when a local variable is assigned a value that is not read by any subsequent instruction. Calculating or retrieving a value only to then overwrite it or throw it away, could indicate a serious error in the code. Even if it's not an error, it is at best a waste of resources. Therefore all calculated values should be used.

Noncompliant Code Example

i = a + b; // Noncompliant; calculation result not used before value is overwritten
i = compute();

Compliant Solution

i = a + b;
i += compute();

Exceptions

No issue is reported when

  • the analyzed method body contains try blocks,
  • a lambda expression captures the local variables, or
  • the variable is unused (case covered by Rule S1481)
  • initializations to -1, 0, 1, null, true, false, "" and string.Empty.

See

csharpsquid:S1172

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

This rule raises an issue when a private method of a class/struct takes a parameter without using it.

Noncompliant Code Example

private void DoSomething(int a, int b) // "b" is unused
{
    Compute(a);
}

private void DoSomething2(int a) // value of "a" is unused
{
    a = 10;
    Compute(a);
}

Compliant Solution

private void DoSomething(int a)
{
    Compute(a);
}

private void DoSomething2()
{
    var a = 10;
    Compute(a);
}

Exceptions

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

  • The this parameter of extension methods.
  • Methods decorated with attributes.
  • Empty methods.
  • Methods which only throw NotImplementedException.
  • Main methods.
  • virtual, override methods.
  • interface implementations.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
csharpsquid:S1862

A chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

Noncompliant Code Example

if (param == 1)
{
  OpenWindow();
}
else if (param == 2)
{
  CloseWindow();
}
else if (param == 1) // Noncompliant
{
  MoveWindowToTheBackground();
}

Compliant Solution

if (param == 1)
{
  OpenWindow();
}
else if (param == 2)
{
  CloseWindow();
}
else if (param == 3)
{
  MoveWindowToTheBackground();
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
csharpsquid:S2278

According to the US National Institute of Standards and Technology (NIST), the Data Encryption Standard (DES) is no longer considered secure:

Adopted in 1977 for federal agencies to use in protecting sensitive, unclassified information, the DES is being withdrawn because it no longer provides the security that is needed to protect federal government information.

Federal agencies are encouraged to use the Advanced Encryption Standard, a faster and stronger algorithm approved as FIPS 197 in 2001.

For similar reasons, RC2 should also be avoided.

Noncompliant Code Example

using (var tripleDES = new TripleDESCryptoServiceProvider()) //Noncompliant
{
  //...
}

Compliant Solution

using (var aes = new AesCryptoServiceProvider())
{
  //...
}

See

csharpsquid:S4211

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

using System;
using System.Security;

namespace MyLibrary
{

    [SecurityCritical]
    public class Foo
    {
        [SecuritySafeCritical] // Noncompliant
        public void Bar()
        {
        }
    }
}

Compliant Solution

using System;
using System.Security;

namespace MyLibrary
{

    [SecurityCritical]
    public class Foo
    {
        public void Bar()
        {
        }
    }
}

See

csharpsquid:S3366

In single-threaded environments, the use of this in constructors is normal, and expected. But in multi-threaded environments, it could expose partially-constructed objects to other threads, and should be used with caution.

The classic example is a class with a static list of its instances. If the constructor stores this in the list, another thread could access the object before it's fully-formed. Even when the storage of this is the last instruction in the constructor, there's still a danger if the class is not final. In that case, the initialization of subclasses won't be complete before this is exposed.

This rule raises an issue when this is assigned to any globally-visible object in a constructor, and when it is passed to the method of another object in a constructor

Noncompliant Code Example

public class Monument
{
  public static readonly List<Monument> ALL_MONUMENTS = new List<Monument>();
  // ...

  public Monument(string location, ...)
  {
    ALL_MONUMENTS.Add(this);  // Noncompliant; passed to a method of another object

    this.location = location;
    // ...
  }
}

Exceptions

This rule ignores instances of assigning this directly to a static field of the same class because that case is covered by S3010.

See

  • CERT, TSM01-J. - Do not let the this reference escape during object construction
  • CERT, TSM03-J. - Do not publish partially initialized objects
csharpsquid:S2275

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);
s = string.Format("{{0}", arg0);
s = string.Format("{0}}", arg0);
s = string.Format("{-1}", arg0);
s = string.Format("{0} {1}", arg0);

Compliant Solution

s = string.Format("{0}", 42); // Compliant
s = string.Format("{0,10}", 42); // Compliant
s = string.Format("{0,-10}", 42); // Compliant
s = string.Format("{0:0000}", 42); // Compliant
s = string.Format("{2}-{0}-{1}", 1, 2, 3); // Compliant
s = string.Format("no format"); // Compliant

Exceptions

  • No issue is raised if the format string is not a const.
var pattern = "{0} {1} {2}";
var res = string.Format(pattern, 1, 2); // Compliant, not const string are not recognized
  • No issue is raised if the argument is not an inline creation array.
var array = new int[] {};
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.

See

csharpsquid:S4212

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 to do this.

This rule raises an issue when a type implements the System.Runtime.Serialization.ISerializable interface, is not a delegate or interface, is declared in an assembly that allows partially trusted callers and has a constructor that takes a System.Runtime.Serialization.SerializationInfo object and a System.Runtime.Serialization.StreamingContext object which is not secured by a security check, but one or more of the regular constructors in the type is secured.

Noncompliant Code Example

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security;
using System.Security.Permissions;

[assembly: AllowPartiallyTrustedCallersAttribute()]
namespace MyLibrary
{
    [Serializable]
    public class Foo : ISerializable
    {
        private int n;

        [FileIOPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
        public Foo()
        {
           n = -1;
        }

        protected Foo(SerializationInfo info, StreamingContext context) // Noncompliant
        {
           n = (int)info.GetValue("n", typeof(int));
        }

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
           info.AddValue("n", n);
        }
    }
}

Compliant Solution

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security;
using System.Security.Permissions;

[assembly: AllowPartiallyTrustedCallersAttribute()]
namespace MyLibrary
{
    [Serializable]
    public class Foo : ISerializable
    {
        private int n;

        [FileIOPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
        public Foo()
        {
           n = -1;
        }

        [FileIOPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
        protected Foo(SerializationInfo info, StreamingContext context)
        {
           n = (int)info.GetValue("n", typeof(int));
        }

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
           info.AddValue("n", n);
        }
    }
}

See

csharpsquid:S3457

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";

Exceptions

  • No issue is raised if the format string is not a const.
var pattern = "{0} {1} {2}";
var res = string.Format(pattern, 1, 2); // Compliant, not const string are not recognized
  • No issue is raised if the argument is not an inline creation array.
var array = new int[] {};
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.

See

csharpsquid:S2245

Using pseudorandom number generators (PRNGs) is security-sensitive. For example, it has led in the past to the following vulnerabilities:

* CVE-2013-6386

* CVE-2006-3419

* CVE-2008-4102

When software generates predictable values in a context requiring unpredictability, it may be possible for an attacker to guess the next value that will be generated, and use this guess to impersonate another user or access sensitive information.

As the System.Random class relies on a pseudorandom number generator, it should not be used for security-critical applications or for protecting sensitive data. In such context, the System.Cryptography.RandomNumberGenerator class which relies on a cryptographically strong random number generator (RNG) should be used in place.

Ask Yourself Whether

  • the code using the generated value requires it to be unpredictable. It is the case for all encryption mechanisms or when a secret value, such as a password, is hashed.
  • the function you use generates a value which can be predicted (pseudo-random).
  • the generated value is used multiple times.
  • an attacker can access the generated value.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

  • Only use random number generators which are recommended by OWASP or any other trusted organization.
  • Use the generated random values only once.
  • You should not expose the generated random value. If you have to store it, make sure that the database or file is secure.

Sensitive Code Example

var random = new Random(); // Sensitive use of Random
byte[] data = new byte[16];
random.NextBytes(data);
return BitConverter.ToString(data); // Check if this value is used for hashing or encryption

Compliant Solution

using System.Security.Cryptography;
...
var randomGenerator = RandomNumberGenerator.Create(); // Compliant for security-sensitive use cases
byte[] data = new byte[16];
randomGenerator.GetBytes(data);
return BitConverter.ToString(data);

See

csharpsquid:S131

The requirement for a final default clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken. Even when the switch covers all current values of an enum, a default case should still be used because there is no guarantee that the enum won't be extended.

Noncompliant Code Example

int foo = 42;
switch (foo) // Noncompliant
{
  case 0:
    Console.WriteLine("foo = 0");
    break;
  case 42:
    Console.WriteLine("foo = 42");
    break;
}

Compliant Solution

int foo = 42;
switch (foo) // Compliant
{
  case 0:
    Console.WriteLine("foo = 0");
    break;
  case 42:
    Console.WriteLine("foo = 42");
    break;
  default:
    throw new InvalidOperationException("Unexpected value foo = " + foo);
}

See

csharpsquid:S2486

When exceptions occur, it is usually a bad idea to simply ignore them. Instead, it is better to handle them properly, or at least to log them.

This rule only reports on empty catch clauses that catch generic Exceptions.

Noncompliant Code Example

string text = "";
try
{
    text = File.ReadAllText(fileName);
}
catch (Exception exc) // Noncompliant
{
}

Compliant Solution

string text = "";
try
{
    text = File.ReadAllText(fileName);
}
catch (Exception exc)
{
    logger.Log(exc);
}

Exceptions

When a block contains a comment, it is not considered to be empty.

See

csharpsquid:S4784

Using regular expressions is security-sensitive. It has led in the past to the following vulnerabilities:

Evaluating regular expressions against input strings is potentially an extremely CPU-intensive task. Specially crafted regular expressions such as (a+)+s will take several seconds to evaluate the input string aaaaaaaaaaaaaaaaaaaaaaaaaaaaabs. The problem is that with every additional a character added to the input, the time required to evaluate the regex doubles. However, the equivalent regular expression, a+s (without grouping) is efficiently evaluated in milliseconds and scales linearly with the input size.

Evaluating such regular expressions opens the door to Regular expression Denial of Service (ReDoS) attacks. In the context of a web application, attackers can force the web server to spend all of its resources evaluating regular expressions thereby making the service inaccessible to genuine users.

This rule flags any execution of a hardcoded regular expression which has at least 3 characters and at least two instances of any of the following characters: *+{.

Example: (a+)*

Ask Yourself Whether

  • the executed regular expression is sensitive and a user can provide a string which will be analyzed by this regular expression.
  • your regular expression engine performance decrease with specially crafted inputs and regular expressions.

You may be at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Check whether your regular expression engine (the algorithm executing your regular expression) has any known vulnerabilities. Search for vulnerability reports mentioning the one engine you're are using.

If the regular expression is vulnerable to ReDos attacks, mitigate the risk by using a "match timeout" to limit the time spent running the regular expression.

Remember also that a ReDos attack is possible if a user-provided regular expression is executed. This rule won't detect this kind of injection.

Sensitive Code Example

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using System.Web;

namespace N
{
    public class RegularExpression
    {
        void Foo(RegexOptions options, TimeSpan matchTimeout, string input,
                 string replacement, MatchEvaluator evaluator)
        {
            // All the following instantiations are Sensitive.
            new System.Text.RegularExpressions.Regex("(a+)+");
            new System.Text.RegularExpressions.Regex("(a+)+", options);
            new System.Text.RegularExpressions.Regex("(a+)+", options, matchTimeout);

            // All the following static methods are Sensitive.
            System.Text.RegularExpressions.Regex.IsMatch(input, "(a+)+");
            System.Text.RegularExpressions.Regex.IsMatch(input, "(a+)+", options);
            System.Text.RegularExpressions.Regex.IsMatch(input, "(a+)+", options, matchTimeout);

            System.Text.RegularExpressions.Regex.Match(input, "(a+)+");
            System.Text.RegularExpressions.Regex.Match(input, "(a+)+", options);
            System.Text.RegularExpressions.Regex.Match(input, "(a+)+", options, matchTimeout);

            System.Text.RegularExpressions.Regex.Matches(input, "(a+)+");
            System.Text.RegularExpressions.Regex.Matches(input, "(a+)+", options);
            System.Text.RegularExpressions.Regex.Matches(input, "(a+)+", options, matchTimeout);

            System.Text.RegularExpressions.Regex.Replace(input, "(a+)+", evaluator);
            System.Text.RegularExpressions.Regex.Replace(input, "(a+)+", evaluator, options);
            System.Text.RegularExpressions.Regex.Replace(input, "(a+)+", evaluator, options, matchTimeout);
            System.Text.RegularExpressions.Regex.Replace(input, "(a+)+", replacement);
            System.Text.RegularExpressions.Regex.Replace(input, "(a+)+", replacement, options);
            System.Text.RegularExpressions.Regex.Replace(input, "(a+)+", replacement, options, matchTimeout);

            System.Text.RegularExpressions.Regex.Split(input, "(a+)+");
            System.Text.RegularExpressions.Regex.Split(input, "(a+)+", options);
            System.Text.RegularExpressions.Regex.Split(input, "(a+)+", options, matchTimeout);
        }
    }
}

Exceptions

Some corner-case regular expressions will not raise an issue even though they might be vulnerable. For example: (a|aa)+, (a|a?)+.

It is a good idea to test your regular expression if it has the same pattern on both side of a "|".

See

csharpsquid:S3218

It's possible to name the members of an inner class the same as the static members of its enclosing class - possible, but a bad idea. That's because maintainers may be confused about which members are being used where. Instead the inner class' members should be renamed and all the references updated.

Noncompliant Code Example

class Outer
{
  public static int A;

  public class Inner
  {
    public int A; //Noncompliant
    public int MyProp
    {
      get { return A; }  // Returns inner A. Was that intended?
    }
  }
}

After a rename

class Outer
{
  public static int A;

  public class Inner
  {
    public int B;
    public int MyProp
    {
      get { return A; }  // Still compiles and runs but functionality has changed
    }
  }
}

Compliant Solution

class Outer
{
  public static int A;

  public class Inner
  {
    public int InnerA;
    public int MyProp
    {
      get { return InnerA; }
    }
  }
}

See

csharpsquid:S927

The name of a parameter in an externally visible method override does not match the name of the parameter in the base declaration of the method, or the name of the parameter in the interface declaration of the method or the name of any other partial definition.

Noncompliant Code Example

partial class Point
{
  partial void MoveVertically(int z);
}

partial class Point
{
  int x = 0;
  int y = 0;
  int z = 0;

  partial void MoveVertically(int y)  // Noncompliant
  {
    this.y = y;
  }
}

interface IFoo
{
  void Bar(int i);
}

class Foo : IFoo
{
  void Bar(int z) // Noncompliant, parameter name should be i
  {
  }
}

Compliant Solution

partial class Point
{
  partial void MoveVertically(int z);
}

partial class Point
{
  int x = 0;
  int y = 0;
  int z = 0;

  partial void MoveVertically(int z)
  {
    this.z = z;
  }
}

interface IFoo
{
  void Bar(int i);
}

class Foo : IFoo
{
  void Bar(int i)
  {
  }
}

See

  • CERT, DCL40-C. - Do not create incompatible declarations of the same function or object
csharpsquid:S126

This rule applies whenever an if statement is followed by one or more else if statements; the final else if should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch statement.

Noncompliant Code Example

if (x == 0)
{
    DoSomething();
}
else if (x == 1)
{
    DoSomethingElse();
}

Compliant Solution

if (x == 0)
{
    DoSomething();
}
else if (x == 1)
{
    DoSomethingElse();
}
else
{
    throw new InvalidOperationException();
}

Exceptions

None

See

csharpsquid:S127

A for loop stop condition should test the loop counter against an invariant value (i.e. one that is true at both the beginning and ending of every loop iteration). Ideally, this means that the stop condition is set to a local variable just before the loop begins.

Stop conditions that are not invariant are slightly less efficient, as well as being difficult to understand and maintain, and likely lead to the introduction of errors in the future.

This rule tracks three types of non-invariant stop conditions:

  • When the loop counters are updated in the body of the for loop
  • When the stop condition depend upon a method call
  • When the stop condition depends on an object property, since such properties could change during the execution of the loop.

Noncompliant Code Example

class Foo
{
    static void Main()
    {
        for (int i = 1; i <= 5; i++)
        {
            Console.WriteLine(i);
            if (condition)
            {
               i = 20;
           }
        }
    }
}

Compliant Solution

class Foo
{
    static void Main()
    {
        for (int i = 1; i <= 5; i++)
        {
            Console.WriteLine(i);
        }
    }
}
csharpsquid:S1048

If Finalize or an override of Finalize throws an exception, and the runtime is not hosted by an application that overrides the default policy, the runtime terminates the process immediately without graceful cleanup (finally blocks and finalizers are not executed). This behavior ensures process integrity if the finalizer cannot free or destroy resources.

The rule reports on throw statements used in finalizers.

Noncompliant Code Example

class MyClass
{
    ~MyClass()
    {
        throw new NotImplementedException(); // Noncompliant
    }
}

Compliant Solution

class MyClass
{
    ~MyClass()
    {
        // no throw
    }
}
csharpsquid:S2259

A reference to null should never be dereferenced/accessed. Doing so will cause a NullReferenceException to be thrown. At best, such an exception will cause abrupt program termination. At worst, it could expose debugging information that would be useful to an attacker, or it could allow an attacker to bypass security measures.

Noncompliant Code Example

object o = null;
if (condition)
{
  M1(o.ToString()); // Noncompliant, always null
}
else
{
  o = new object();
}
M2(o.ToString());

Exceptions

Calls to extension methods are not reported because they can still operate on null values.

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;

public sealed class ValidatedNotNullAttribute : Attribute { }

public static class Guard
{
    public static void NotNull<T>([ValidatedNotNull] this T value, string name) where T : class
    {
        if (value == null)
            throw new ArgumentNullException(name);
    }
}

public static class Utils
{
    public static string ToUpper(string value)
    {
        Guard.NotNull(value, nameof(value));
        if (value == null)
        {
            return value.ToString(); // Compliant, this code is not reachable
        }
        return value.ToUpper();
    }
}

See

csharpsquid:S1168

Returning null instead of an actual array or collection forces callers of the method to explicitly test for nullity, making them more complex and less readable.

Moreover, in many cases, null is used as a synonym for empty.

Noncompliant Code Example

public Result[] GetResults()
{
    return null; // Noncompliant
}

public IEnumerable<Result> GetResults()
{
    return null; // Noncompliant
}

public IEnumerable<Result> GetResults() => null; // Noncompliant

public IEnumerable<Result> Results
{
    get
    {
        return null; // Noncompliant
    }
}

public IEnumerable<Result> Results => null; // Noncompliant

Compliant Solution

public Result[] GetResults()
{
    return new Result[0];
}

public IEnumerable<Result> GetResults()
{
    return Enumerable.Empty<Result>();
}

public IEnumerable<Result> GetResults() => Enumerable.Empty<Result>();

public IEnumerable<Result> Results
{
    get
    {
        return Enumerable.Empty<Result>();
    }
}

public IEnumerable<Result> Results => Enumerable.Empty<Result>();

Exceptions

Although string is a collection, the rule won't report on it.

See

  • CERT, MSC19-C. - For functions that return an array, prefer returning an empty array over a null value
  • CERT, MET55-J. - Return an empty array or collection instead of a null value for methods that return an array or collection
csharpsquid:S3346

An assertion is a piece of code that's used during development when the compilation debug mode is activated. It allows a program to check itself as it runs. When an assertion is true, that means everything is operating as expected.

In non-debug mode, all Debug.Assert are automatically left out. So, by contract, the boolean expressions that are evaluated by those assertions must absolutely not contain any side effects. Otherwise, when leaving the Debug mode, the functional behavior of the application is not the same anymore.

The rule will raise if the method name starts with any of the following remove, delete, add, pop, update, retain, insert, push, append, clear, dequeue, enqueue, dispose, put, or set, although SetEquals will be ignored.

Noncompliant Code Example

Debug.Assert(list.Remove("dog"));

Compliant Solution

bool result = list.Remove("dog");
Debug.Assert(result);

See

  • CERT, EXP06-J. - Expressions used in assertions must not produce side effects
csharpsquid:S2255

Using cookies is security-sensitive. It has led in the past to the following vulnerabilities:

Attackers can use widely-available tools to read cookies, sensitive information written by the server will be exposed.

This rule flags code that writes cookies.

Ask Yourself Whether

  • sensitive information is stored inside the cookie.

You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

Cookies should only be used to manage the user session. The best practice is to keep all user-related information server-side and link them to the user session, never sending them to the client. In a very few corner cases, cookies can be used for non-sensitive information that need to live longer than the user session.

Do not try to encode sensitive information in a non human-readable format before writing them in a cookie. The encoding can be reverted and the original information will be exposed.

Using cookies only for session IDs doesn't make them secure. Follow OWASP best practices when you configure your cookies.

As a side note, every information read from a cookie should be Sanitized.

Sensitive Code Example

// === .Net Framework ===

HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie["CreditCardNumber"] = "1234 1234 1234 1234"; // Sensitive; sensitive data stored
myCookie.Values["password"] = "5678"; // Sensitive
myCookie.Value = "mysecret"; // Sensitive
...
Response.Cookies.Add(myCookie);


// === .Net Core ===

Response.Headers.Add("Set-Cookie", ...); // Sensitive
Response.Cookies.Append("mykey", "myValue"); // Sensitive

See

csharpsquid:S4433

An un-authenticated LDAP connection can lead to transactions without access control. Authentication, and with it, access control, are the last line of defense against LDAP injections and should not be disabled.

This rule raises an issue when an LDAP connection is created with AuthenticationTypes.Anonymous or AuthenticationTypes.None.

Noncompliant Code Example

DirectoryEntry myDirectoryEntry = new DirectoryEntry(adPath);
myDirectoryEntry.AuthenticationType = AuthenticationTypes.None; // Noncompliant

DirectoryEntry myDirectoryEntry = new DirectoryEntry(adPath, "u", "p", AuthenticationTypes.None); // Noncompliant

Compliant Solution

DirectoryEntry myDirectoryEntry = new DirectoryEntry(myADSPath); // Compliant; default DirectoryEntry.AuthenticationType property value is "Secure" since .NET Framework 2.0

DirectoryEntry myDirectoryEntry = new DirectoryEntry(myADSPath, "u", "p", AuthenticationTypes.Secure);

See

csharpsquid:S1163

Throwing an exception from within a finally block will mask any exception which was previously thrown in the try or catch block, and the masked's exception message and stack trace will be lost.

Noncompliant Code Example

try
{
  /* some work which end up throwing an exception */
  throw new ArgumentException();
}
finally
{
  /* clean up */
  throw new InvalidOperationException();       // Noncompliant; will mask the ArgumentException
}

Compliant Solution

try
{
  /* some work which end up throwing an exception */
  throw new ArgumentException();
}
finally
{
  /* clean up */                       // Compliant
}

See

  • CERT, ERR05-J. - Do not let checked exceptions escape from a finally block
csharpsquid:S4432

Encryption algorithms can be used with various modes. Some combinations are not secured:

  • Electronic Codebook (ECB) mode: Under a given key, any given plaintext block always gets encrypted to the same ciphertext block. Thus, it does not hide data patterns well. In some senses, it doesn't provide serious message confidentiality, and it is not recommended for use in cryptographic protocols at all.
  • Cipher Block Chaining (CBC) with PKCS#5 padding (or PKCS#7) is susceptible to padding oracle attacks. CBC + PKCS#7 can be used if combined with an authenticity check (HMAC-SHA256 for example) on the cipher text.

In both cases, Galois/Counter Mode (GCM) with no padding should be preferred. As the .NET framework doesn't provide this natively, the use of a certified third party lib is recommended.

This rule raises an issue when any of the following CipherMode is detected: ECB, CBC, OFB, CFB, CTS.

Noncompliant Code Example

AesManaged aes = new AesManaged
{
  KeySize = 128,
  BlockSize = 128,
  Mode = CipherMode.OFB, // Noncompliant
  Padding = PaddingMode.PKCS7
};

See

csharpsquid:S818

Using upper case literal suffixes removes the potential ambiguity between "1" (digit 1) and "l" (letter el) for declaring literals.

Noncompliant Code Example

const long b = 0l;      // Noncompliant

Compliant Solution

const long b = 0L;

See

csharpsquid:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

Noncompliant Code Example

string username = "admin";
string password = "Password123"; // Noncompliant
string usernamePassword  = "user=admin&password=Password123"; // Noncompliant
string usernamePassword2 = "user=admin&" + "password=" + password; // Noncompliant

Compliant Solution

string username = "admin";
string password = GetEncryptedPassword();
string usernamePassword = string.Format("user={0}&password={1}", GetEncryptedUsername(), GetEncryptedPassword());

See

csharpsquid:S112

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

public void DoSomething(object obj)
{
  if (obj == null)
  {
    throw new NullReferenceException("obj");  // Noncompliant
  }
  // ...
}

Compliant Solution

public void DoSomething(object obj)
{
  if (obj == null)
  {
    throw new ArgumentNullException("obj");
  }
  // ...
}

See

csharpsquid:S1659

Declaring multiple variable on one line is difficult to read.

Noncompliant Code Example

class MyClass
{
  private int a, b; // Noncompliant

  public void Method()
  {
    int c, d; // Noncompliant
  }
}

Compliant Solution

class MyClass
{
  private int a;
  private int b;

  public void Method()
  {
    int c;
    int d;
  }
}

See

  • CERT, DCL52-J. - Do not declare more than one variable per declaration
  • CERT, DCL04-C. - Do not declare more than one variable per declaration
csharpsquid:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

public void SetName(string name)
{
  name = name;
}

Compliant Solution

public void SetName(string name)
{
  this.name = name;
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
csharpsquid:S907

goto is an unstructured control flow statement. It makes code less readable and maintainable. Structured control flow statements such as if, for, while, continue or break should be used instead.

csharpsquid:S2184

When division is performed on ints, the result will always be an int. You can assign that result to a double, float or decimal with automatic type conversion, but having started as an int, the result will likely not be what you expect. If the result of int division is assigned to a floating-point variable, precision will have been lost before the assignment. Instead, at least one operand should be cast or promoted to the final type before the operation takes place.

Noncompliant Code Example

static void Main()
{
  decimal dec = 3/2; // Noncompliant
  Method(3/2); // Noncompliant
}

static void Method(float f) { }

Compliant Solution

static void Main()
{
  decimal dec = (decimal)3/2;
  Method(3.0F/2);
}

static void Method(float f) { }

See

  • MITRE, CWE-190 - Integer Overflow or Wraparound
  • CERT, NUM50-J. - Convert integers to floating point for floating-point operations
  • CERT, INT18-C. - Evaluate integer expressions in a larger size before comparing or assigning to that size
  • SANS Top 25 - Risky Resource Management
csharpsquid:S106

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

  • The user must be able to easily retrieve the logs
  • The format of all logged message must be uniform to allow the user to easily read the log
  • Logged data must actually be recorded
  • Sensitive data must only be logged securely

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
    // ...
}

Exceptions

The following are ignored by this rule:

  • Console Applications
  • Calls in methods decorated with [Conditional ("DEBUG")]
  • Calls included in DEBUG preprocessor branches (#if DEBUG)

See

csharpsquid:S1301

switch statements are useful when there are many different cases depending on the value of the same expression.

For just one or two cases however, the code will be more readable with if statements.

Noncompliant Code Example

switch (variable)
{
  case 0:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Compliant Solution

if (variable == 0)
{
  doSomething();
}
else
{
  doSomethingElse();
}
csharpsquid:S121

While not technically incorrect, the omission of curly braces can be misleading, and may lead to the introduction of errors during maintenance.

Noncompliant Code Example

// the two statements seems to be attached to the if statement, but that is only true for the first one:
if (condition)
  ExecuteSomething();
  CheckSomething();

Compliant Solution

if (condition)
{
  ExecuteSomething();
  CheckSomething();
}

See

  • CERT, EXP19-C. - Use braces for the body of an if, for, or while statement
  • CERT, EXP52-J. - Use braces for the body of an if, for, or while statement
csharpsquid:S2197

When the modulus of a negative number is calculated, the result will either be negative or zero. Thus, comparing the modulus of a variable for equality with a positive number (or a negative one) could result in unexpected results.

Noncompliant Code Example

public bool IsOdd(int x)
{
  return x % 2 == 1;  // Noncompliant; if x is an odd negative, x % 2 == -1
}

Compliant Solution

public bool IsOdd(int x)
{
  return x %2 != 0;
}

or

public bool IsOdd(uint x)
{
  return x %2 == 1;
}

See

  • CERT, NUM51-J. - Do not assume that the remainder operator always returns a nonnegative result for integral operands
  • CERT, INT10-C - Do not assume a positive remainder when using the % operator
csharpsquid:S2077

Formatting strings used as SQL queries is security-sensitive. It has led in the past to the following vulnerabilities:

SQL queries often need to use a hardcoded SQL string with a dynamic parameter coming from a user request. Formatting a string to add those parameters to the request is a bad practice as it can result in an SQL injection. The safe way to add parameters to a SQL query is to use SQL binding mechanisms.

This rule flags the execution of SQL queries which are built using formatting of strings, even if there is no injection. This rule does not detect SQL injections. The goal is to guide security code reviews and to prevent a common bad practice.

The following specific method signatures are tested:

  • System.Data.SqlClient.SqlCommand.SqlCommand(string, ...)
  • System.Data.SqlClient.SqlDataAdapter.SqlDataAdapter(string, ...)
  • System.Data.Odbc.OdbcCommand.OdbcCommand(string, ...)
  • System.Data.Odbc.OdbcDataAdapter.OdbcDataAdapter(string, ...)
  • System.Data.SqlServerCe.SqlCeCommand.SqlCeCommand(string, ...)
  • System.Data.SqlServerCe.SqlCeDataAdapter.SqlCeDataAdapter(string, ...)
  • System.Data.OracleClient.OracleCommand.OracleCommand(string, ...)
  • System.Data.OracleClient.OracleDataAdapter.OracleDataAdapter(string, ...)
  • Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecuteSqlCommand(...)
  • Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecuteSqlCommandAsync(...)
  • Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSql<TEntity>(System.Linq.IQueryable<TEntity>, System.FormattableString)
  • System.Data.SqlClient.SqlCommand.CommandText.set
  • System.Data.Odbc.OdbcCommand.CommandText.set
  • System.Data.SqlServerCe.SqlCeCommand.CommandText.set
  • System.Data.OracleClient.OracleCommand.CommandText.set

The following formatting methods will raise an issue:

  • String.Concat
  • String.Format
  • FormattableString, with some exceptions (see the Exceptions section)

Ask Yourself Whether

  • the SQL query is built using string formatting technics, such as concatenating variables.
  • some of the values are coming from an untrusted source and are not sanitized.

You may be at risk if you answered yes to this question.

Recommended Secure Coding Practices

  • Avoid building queries manually using formatting technics. If you do it anyway, do not include user input in this building process.
  • Use parameterized queries, prepared statements, or stored procedures whenever possible.
  • You may also use ORM frameworks such as Hibernate which, if used correctly, reduce injection risks.
  • Avoid executing SQL queries containing unsafe input in stored procedures or functions.
  • Sanitize every unsafe input.

You can also reduce the impact of an attack by using a database account with low privileges.

Sensitive Code Example

public void Foo(DbContext context, string query, string param)
{
    string sensitiveQuery = string.Concat(query, param);
    context.Database.ExecuteSqlCommand(sensitiveQuery); // Sensitive
    context.Query<User>().FromSql(sensitiveQuery); // Sensitive

    context.Database.ExecuteSqlCommand($"SELECT * FROM mytable WHERE mycol={value}", param); // Sensitive, the FormattableString is evaluated and converted to RawSqlString
    string query = $"SELECT * FROM mytable WHERE mycol={param}";
    context.Database.ExecuteSqlCommand(query); // Sensitive, the FormattableString has already been evaluated, it won't be converted to a parametrized query.
}

public void Bar(SqlConnection connection, string param)
{
    SqlCommand command;
    string sensitiveQuery = string.Format("INSERT INTO Users (name) VALUES (\"{0}\")", param);
    command = new SqlCommand(sensitiveQuery); // Sensitive

    command.CommandText = sensitiveQuery; // Sensitive

    SqlDataAdapter adapter;
    adapter = new SqlDataAdapter(sensitiveQuery, connection); // Sensitive
}

Exceptions

No issue will be raised in the following cases:

  • When the SQL query is a FormattableString provided directly to ExecuteSqlCommand, ExecuteSqlCommandAsync or FromSql. In this case the FormattableString is automatically converted to a parametrized query. This feature was added in Entity Framework Core 2.0. See Entity Framework's documentation for more information.
public void Foo(DbContext context, string value)
{
    context.Database.ExecuteSqlCommand("SELECT * FROM mytable"); // No issue raised. The query is hard-coded. Thus no injection is possible.

    context.Database.ExecuteSqlCommand($"SELECT * FROM mytable WHERE mycol={value}"); // No issue raised. The FormattableString is transformed into a parametrized query.
}

See

csharpsquid:S3011

Changing or bypassing accessibility is security-sensitive. For example, it has led in the past to the following vulnerability:

private methods were made private for a reason, and the same is true of every other visibility level. Altering or bypassing the accessibility of classes, methods, or fields violates the encapsulation principle and could introduce security holes.

This rule raises an issue when reflection is used to change the visibility of a class, method or field, and when it is used to directly update a field value.

Ask Yourself Whether

  • there is a good reason to override the existing accessibility level of the method/field. This is very rarely the case. Accessing hidden fields and methods will make your code unstable as they are not part of the public API and may change in future versions.
  • this method is called by untrusted code. *
  • it is possible to modify or bypass the accessibility of sensitive methods or fields using this code. *

* You are at risk if you answered yes to those questions.

Recommended Secure Coding Practices

Don't change or bypass the accessibility of any method or field if possible.

If untrusted code can execute this method, make sure that it cannot decide which method or field's accessibility can be modified or bypassed.

Sensitive Code Example

using System.Reflection;

Type dynClass = Type.GetType("MyInternalClass");
// Sensitive. Using BindingFlags.NonPublic will return non-public members
BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Static;
MethodInfo dynMethod = dynClass.GetMethod("mymethod", bindingAttr);
object result = dynMethod.Invoke(dynClass, null);

See

csharpsquid:S1075

Hardcoding 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 hardcoded. 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 hardcoded.

This rule raises an issue when URI's or path delimiters are hardcoded.

Exceptions

This rule does not raise an issue when an ASP.NET virtual path is passed as an argument to one of the following:

  • methods: System.Web.HttpServerUtilityBase.MapPath(), System.Web.HttpRequestBase.MapPath(), System.Web.HttpResponseBase.ApplyAppPathModifier(), System.Web.Mvc.UrlHelper.Content()
  • all methods of: System.Web.VirtualPathUtility
  • constructors of: Microsoft.AspNetCore.Mvc.VirtualFileResult, Microsoft.AspNetCore.Routing.VirtualPathData

See

csharpsquid:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Noncompliant Code Example

if ( a == a ) // always true
{
  doZ();
}
if ( a != a ) // always false
{
  doY();
}
if ( a == b && a == b ) // if the first one is true, the second one is too
{
  doX();
}
if ( a == b || a == b ) // if the first one is true, the second one is too
{
  doW();
}

int j = 5 / 5; //always 1
int k = 5 - 5; // always 0

c.Equals(c);    //always true
Object.Equals(c, c); //always true

Exceptions

This rule ignores *, +, =, <<, and >>.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
csharpsquid:S2178

The use of non-short-circuit logic in a boolean context is likely a mistake - one that could cause serious program errors as conditions are evaluated under the wrong circumstances.

Noncompliant Code Example

if (GetTrue() | GetFalse()) // Noncompliant; both sides evaluated
{
}

Compliant Solution

if (GetTrue() || GetFalse()) // true short-circuit logic
{
}

See

  • CERT, EXP46-C. - Do not use a bitwise operator with a Boolean-like operand
csharpsquid:S1698

Using the equality == and inequality != operators to compare two objects generally works. The operators can be overloaded, and therefore the comparison can resolve to the appropriate method. However, when the operators are used on interface instances, then == resolves to reference equality, which may result in unexpected behavior if implementing classes override Equals. Similarly, when a class overrides Equals, but instances are compared with non-overloaded ==, there is a high chance that value comparison was meant instead of the reference one.

Noncompliant Code Example

public interface IMyInterface
{
}

public class MyClass : IMyInterface
{
    public override bool Equals(object obj)
    {
        //...
    }
}

public class Program
{
    public static void Method(IMyInterface instance1, IMyInterface instance2)
    {
        if (instance1 == instance2) // Noncompliant, will do reference equality check, but was that intended? MyClass overrides Equals.
        {
            Console.WriteLine("Equal");
        }
    }
}

Compliant Solution

public interface IMyInterface
{
}

public class MyClass : IMyInterface
{
    public override bool Equals(object obj)
    {
        //...
    }
}

public class Program
{
    public static void Method(IMyInterface instance1, IMyInterface instance2)
    {
        if (object.Equals(instance1, instance2)) // object.Equals checks for null and then calls the instance based Equals, so MyClass.Equals
        {
            Console.WriteLine("Equal");
        }
    }
}

Exceptions

The rule does not report on comparisons of System.Type instances and on comparisons inside Equals overrides.

It also does not raise an issue when one of the operands is null nor when one of the operand is cast to object (because in this case we want to ensure reference equality even if some == overload is present).

See

  • MITRE, CWE-595 - Comparison of Object References Instead of Object Contents
  • MITRE, CWE-597 - Use of Wrong Operator in String Comparison
  • CERT, EXP03-J. - Do not use the equality operators when comparing values of boxed primitives
  • CERT, EXP50-J. - Do not confuse abstract object equality with reference equality
csharpsquid:S1696

NullReferenceException should be avoided, not caught. Any situation in which NullReferenceException is explicitly caught can easily be converted to a null test, and any behavior being carried out in the catch block can easily be moved to the "is null" branch of the conditional.

Noncompliant Code Example

public int GetLengthPlusTwo(string str)
{
    int length = 2;
    try
    {
       length += str.Length;
    }
    catch (NullReferenceException e)
    {
        log.info("argument was null");
    }
    return length;
}

Compliant Solution

public int GetLengthPlusTwo(string str)
{
    int length = 2;

    if (str != null)
    {
        length += str.Length;
    }
    else
    {
        log.info("argument was null");
    }
    return length;
}

See

  • MITRE, CWE-395 - Use of NullPointerException Catch to Detect NULL Pointer Dereference
  • CERT, ERR08-J. - Do not catch NullPointerException or any of its ancestors
csharpsquid:S3871

The point of having custom exception types is to convey more information than is available in standard types. But custom exception types must be public for that to work.

If a method throws a non-public exception, the best you can do on the caller's side is to catch the closest public base of the class. That is, you lose all that custom information you created the exception type to pass.

Noncompliant Code Example

internal class MyException : Exception   // Noncompliant
{
  // ...
}

Compliant Solution

public class MyException : Exception
{
  // ...
}

Exceptions

This rule ignores Exception types that are not derived directly from System.Exception, System.SystemException, or System.ApplicationException.

See

csharpsquid:S1699

Calling an overridable method from a constructor could result in failures or strange behaviors when instantiating a subclass which overrides the method.

For example:

  • The subclass class constructor starts by calling the parent class constructor.
  • The parent class constructor calls the method, which has been overridden in the child class.
  • If the behavior of the child class method depends on fields that are initialized in the child class constructor, unexpected behavior (like a NullReferenceException) can result, because the fields aren't initialized yet.

Noncompliant Code Example

public class Parent
{
  public Parent()
  {
    DoSomething();  // Noncompliant
  }

  public virtual void DoSomething() // can be overridden
  {
    ...
  }
}

public class Child : Parent
{
  private string foo;

  public Child(string foo) // leads to call DoSomething() in Parent constructor which triggers a NullReferenceException as foo has not yet been initialized
  {
    this.foo = foo;
  }

  public override void DoSomething()
  {
    Console.WriteLine(this.foo.Length);
  }
}

See

  • CERT, MET05-J. - Ensure that constructors do not call overridable methods
  • CERT, OOP50-CPP. - Do not invoke virtual functions from constructors or destructors
csharpsquid:S4040

Certain characters, once normalized to lowercase, cannot make a round trip. That is, they can not be converted from one locale to another and then accurately restored to their original characters.

It is therefore strongly recommended to normalize characters and strings to uppercase instead.

Noncompliant Code Example

Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");
var areStringEqual = "INTEGER".ToLower() == "integer"; // Noncompliant, the result is false as the ToLower will resolve to "ınteger"
var areCharEqual = char.ToLower('I') == 'i'; // Noncompliant, the result is false as the ToLower will resolve to "ı"

var incorrectRoundtrip = "İ".ToLowerInvariant().ToUpper() == "I".ToLowerInvariant().ToUpper(); // Noncompliant, because of the lower we lose the information about the correct uppercase character

Compliant Solution

Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR");
var areStringEqual = "ınteger".ToUpperInvariant() == "ıNTEGER";
var areCharEqual = char.ToUpperInvariant('ı') == 'ı';
var correctRoundtrip = "İ".ToUpperInvariant().ToLower() != "I".ToUpperInvariant().ToLower();

See

csharpsquid:S2674

You cannot assume that any given stream reading call will fill the byte[] passed in to the method with the number of bytes requested. Instead, you must check the value returned by the read method to see how many bytes were read. Fail to do so, and you introduce a bug that is both harmful and difficult to reproduce.

This rule raises an issue when a Stream.Read or a Stream.ReadAsync method is called, but the return value is not checked.

Noncompliant Code Example

public void DoSomething(string fileName)
{
  using (var stream = File.Open(fileName, FileMode.Open))
  {
    var result = new byte[stream.Length];
    stream.Read(result, 0, (int)stream.Length); // Noncompliant
    // ... do something with result
  }
}

Compliant Solution

public void DoSomething(string fileName)
{
  using (var stream = File.Open(fileName, FileMode.Open))
  {
    var buffer = new byte[1024];
    using (var ms = new MemoryStream())
    {
        int read;
        while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, read);
        }
        // ... do something with ms
    }
  }
}

See

  • CERT, FIO10-J. - Ensure the array is filled when using read() to fill an array
csharpsquid:S3884

CoSetProxyBlanket and CoInitializeSecurity both work to set the permissions context in which the process invoked immediately after is executed. Calling them from within that process is useless because it's too late at that point; the permissions context has already been set.

Specifically, these methods are meant to be called from non-managed code such as a C++ wrapper that then invokes the managed, i.e. C# or VB.NET, code.

Noncompliant Code Example

[DllImport("ole32.dll")]
static extern int CoSetProxyBlanket([MarshalAs(UnmanagedType.IUnknown)]object pProxy, uint dwAuthnSvc, uint dwAuthzSvc,
	[MarshalAs(UnmanagedType.LPWStr)] string pServerPrincName, uint dwAuthnLevel, uint dwImpLevel, IntPtr pAuthInfo,
	uint dwCapabilities);

public enum RpcAuthnLevel
{
	Default = 0,
	None = 1,
	Connect = 2,
	Call = 3,
	Pkt = 4,
	PktIntegrity = 5,
	PktPrivacy = 6
}

public enum RpcImpLevel
{
	Default = 0,
	Anonymous = 1,
	Identify = 2,
	Impersonate = 3,
	Delegate = 4
}

public enum EoAuthnCap
{
	None = 0x00,
	MutualAuth = 0x01,
	StaticCloaking = 0x20,
	DynamicCloaking = 0x40,
	AnyAuthority = 0x80,
	MakeFullSIC = 0x100,
	Default = 0x800,
	SecureRefs = 0x02,
	AccessControl = 0x04,
	AppID = 0x08,
	Dynamic = 0x10,
	RequireFullSIC = 0x200,
	AutoImpersonate = 0x400,
	NoCustomMarshal = 0x2000,
	DisableAAA = 0x1000
}

[DllImport("ole32.dll")]
public static extern int CoInitializeSecurity(IntPtr pVoid, int cAuthSvc, IntPtr asAuthSvc, IntPtr pReserved1,
	RpcAuthnLevel level, RpcImpLevel impers, IntPtr pAuthList, EoAuthnCap dwCapabilities, IntPtr pReserved3);

static void Main(string[] args)
{
	var hres1 = CoSetProxyBlanket(null, 0, 0, null, 0, 0, IntPtr.Zero, 0); // Noncompliant

	var hres2 = CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero, IntPtr.Zero, RpcAuthnLevel.None,
		RpcImpLevel.Impersonate, IntPtr.Zero, EoAuthnCap.None, IntPtr.Zero); // Noncompliant
}

See

csharpsquid:S1226

While it is technically correct to assign to parameters from within method bodies, doing so before the parameter value is read is likely a bug. Instead, initial values of parameters, caught exceptions, and foreach parameters should be, if not treated as final, then at least read before reassignment.

Noncompliant Code Example

public void DoTheThing(string str, int i, List<string> strings)
{
  str = i.ToString(i);  // Noncompliant

  foreach (var s in strings)
  {
    s = "hello world";  // Noncompliant
  }
}
csharpsquid:S1313

Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:

Today's services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery and deployment:

  • The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
  • It forces the same address to be used in every environment (dev, sys, qa, prod).

Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service at this address or spoof the IP address. Such an attack is always possible, but in the case of a hardcoded IP address the fix will be much slower, which will increase an attack's impact.

Recommended Secure Coding Practices

  • make the IP address configurable.

Noncompliant Code Example

var ip = "192.168.12.42";
var address = IPAddress.Parse(ip);

Compliant Solution

var ip = ConfigurationManager.AppSettings["myapplication.ip"];
var address = IPAddress.Parse(ip);

Exceptions

  • Although "::" is a valid IPv6 address, the rule doesn't report on it.
  • No issue is reported for 127.0.0.1 because loopback is not considered as sensitive

See

csharpsquid:S1449

string.ToLower(), ToUpper, IndexOf, LastIndexOf, and Compare are all culture-dependent, as are some (floating point number and DateTime-related) calls to ToString. Fortunately, all have variants which accept an argument specifying the culture or formatter to use. Leave that argument off and the call will use the system default culture, possibly creating problems with international characters.

string.CompareTo() is also culture specific, but has no overload that takes a culture information, so instead it's better to use CompareOrdinal, or Compare with culture.

Calls without a culture may work fine in the system's "home" environment, but break in ways that are extremely difficult to diagnose for customers who use different encodings. Such bugs can be nearly, if not completely, impossible to reproduce when it's time to fix them.

Noncompliant Code Example

var lowered = someString.ToLower(); //Noncompliant

Compliant Solution

var lowered = someString.ToLower(CultureInfo.InvariantCulture);

or

var lowered = someString.ToLowerInvariant();

See

  • CERT, STR02-J. - Specify an appropriate locale when comparing locale-dependent data
csharpsquid:S1206

There is a contract between Equals(object) and GetHashCode(): If two objects are equal according to the Equals(object) method, then calling GetHashCode() on each of them must yield the same result. If this is not the case, many collections won't handle class instances correctly.

In order to comply with the contract, Equals(object) and GetHashCode() should be either both inherited, or both overridden.

Noncompliant Code Example

class MyClass {    // Noncompliant - should also override "hashCode()"

  @Override
  public boolean equals(Object obj) {
    /* ... */
  }

}

Compliant Solution

class MyClass {    // Compliant

  @Override
  public boolean equals(Object obj) {
    /* ... */
  }

  @Override
  public int hashCode() {
    /* ... */
  }

}

See

  • MITRE, CWE-581 - Object Model Violation: Just One of Equals and Hashcode Defined
  • CERT, MET09-J. - Classes that define an equals() method must also define a hashCode() method
csharpsquid:S2092

The "secure" attribute prevents cookies from being sent over plaintext connections such as HTTP, where they would be easily eavesdropped upon. Instead, cookies with the secure attribute are only sent over encrypted HTTPS connections.

Recommended Secure Coding Practices

  • set the field Secure to true on the HttpCookie object

Noncompliant Code Example

HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie.Secure = false; // Noncompliant; explicitly set to false
...
Response.Cookies.Add(myCookie);
HttpCookie myCookie = new HttpCookie("UserSettings"); // Noncompliant; the default value of 'Secure' is used (=false)
...
Response.Cookies.Add(myCookie);

Compliant Solution

HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie.Secure = true; // Compliant
...
Response.Cookies.Add(myCookie);

See

css:S1116

Extra semicolons are usually introduced by mistake, for example because:

  • It was meant to be replaced by one more property declaration, but this was forgotten.
  • There was a typo which lead the semicolon to be doubled, i.e. ;;.

See

  • MISRA C:2004, 14.3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment provided that the first character following the null statement is a white-space character.
  • MISRA C++:2008, 6-2-3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment, provided that the first character following the null statement is a white-space character.
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • CERT, MSC51-J. - Do not place a semicolon immediately following an if, for, or while condition
  • CERT, EXP15-C. - Do not place a semicolon on the same line as an if, for, or while statement
squid:S3032

Using the standard getClassLoader() may not return the right class loader in a JEE context. Instead, go through the currentThread.

Noncompliant Code Example

ClassLoader cl = this.getClass().getClassLoader();  // Noncompliant

Compliant Solution

ClassLoader cl = Thread.currentThread().getContextClassLoader();
squid:S3864

According to its JavaDocs, java.util.Stream.peek() ā€œexists mainly to support debuggingā€ purposes. Although this does not mean that using it for other purposes is discouraged, relying on peek() without careful consideration can lead to error-prone code such as:

  • If the stream pipeline does not include a terminal operation, no elements will be consumed and the peek() action will not be invoked at all.
  • As long as a stream implementation can reach the final step, it can freely optimize processing by only producing some elements or even none at all (e.g. relying on other collection methods for counting elements). Accordingly, the peek() action will be invoked for fewer elements or not at all.

This rule raises an issue for each use of peek() to be sure that it is challenged and validated by the team to be meant for production debugging/logging purposes.

Noncompliant Code Example

Stream.of("one", "two", "three", "four")
         .filter(e -> e.length() > 3)
         .peek(e -> System.out.println("Filtered value: " + e)); // Noncompliant

See

csharpsquid:S4049

Properties are accessed like fields which makes them easier to use.

This rule raises an issue when the name of a public or protected method starts with Get, takes no parameter, and returns a value that is not an array.

Noncompliant Code Example

using System;

namespace MyLibrary
{
    public class Foo
    {
        private string name;

        public string GetName()  // Noncompliant
        {
            return name;
        }
    }
}

Compliant Solution

using System;

namespace MyLibrary
{
    public class Foo
    {
        private string name;

        public string Name
        {
            get
            {
                return name;
            }
        }
    }
}

Exceptions

The rule doesn't raise an issue when the method:

  • Is a constructor
  • Is an override
  • Is an interface implementation
  • Is async
  • Returns Task, Task<T>
  • Is named GetEnumerator, GetAwaiter
csharpsquid:S2360

The overloading mechanism should be used in place of optional parameters for several reasons:

  • Optional parameter values are baked into the method call site code, thus, if a default value has been changed, all referencing assemblies need to be rebuilt, otherwise the original values will be used.
  • The Common Language Specification (CLS) allows compilers to ignore default parameter values, and thus require the caller to explicitly specify the values. For example, if you want to consume a method with default argument from another .NET compatible language (for instance C++/CLI), you will have to provide all arguments. When using method overloads, you could achieve similar behavior as default arguments.
  • Optional parameters prevent muddying the definition of the function contract. Here is a simple example: if there are two optional parameters, when one is defined, is the second one still optional or mandatory?

Noncompliant Code Example

void Notify(string company, string office = "QJZ") // Noncompliant
{
}

Compliant Solution

void Notify(string company)
{
  Notify(company, "QJZ");
}
void Notify(string company, string office)
{
}

Exceptions

The rule ignores non externally visible methods.

squid:S4925

In the past, it was required to load a JDBC driver before creating a java.sql.Connection. Nowadays, when using JDBC 4.0 drivers, this is no longer required and Class.forName() can be safely removed because JDBC 4.0 (JDK 6) drivers available in the classpath are automatically loaded.

This rule raises an issue when Class.forName() is used with one of the following values:

  • com.mysql.jdbc.Driver
  • oracle.jdbc.driver.OracleDriver
  • com.ibm.db2.jdbc.app.DB2Driver
  • com.ibm.db2.jdbc.net.DB2Driver
  • com.sybase.jdbc.SybDriver
  • com.sybase.jdbc2.jdbc.SybDriver
  • com.teradata.jdbc.TeraDriver
  • com.microsoft.sqlserver.jdbc.SQLServerDriver
  • org.postgresql.Driver
  • sun.jdbc.odbc.JdbcOdbcDriver
  • org.hsqldb.jdbc.JDBCDriver
  • org.h2.Driver
  • org.firebirdsql.jdbc.FBDriver
  • net.sourceforge.jtds.jdbc.Driver

Noncompliant Code Example

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Demo {
  private static final String DRIVER_CLASS_NAME = "org.postgresql.Driver";
  private final Connection connection;

  public Demo(String serverURI) throws SQLException, ClassNotFoundException {
    Class.forName(DRIVER_CLASS_NAME); // Noncompliant; no longer required to load the JDBC Driver using Class.forName()
    connection = DriverManager.getConnection(serverURI);
  }
}

Compliant Solution

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Demo {
    private final Connection connection;

    public Demo(String serverURI) throws SQLException {
        connection = DriverManager.getConnection(serverURI);
    }
}
python:S4721

OS commands are security-sensitive. For example, their use has led in the past to the following vulnerabilities:

Applications that execute operating system commands or execute commands that interact with the underlying system should neutralize any externally-provided input used to construct those commands. Failure to do so could allow an attacker to execute unexpected or dangerous commands, potentially leading to loss of confidentiality, integrity or availability.

This rule flags code that specifies the name of the command to run. The goal is to guide security code reviews.

Ask Yourself Whether

  • the executed command is constructed by input that is externally-influenced, for example, user input (attacker). (*)
  • the command execution is not restricted to the right users. (*)
  • the application can be redesigned to not rely on external input to execute the command.

(*) You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Restrict the control given to the user over the executed command:

  • make the executed command part of a whitelist and reject all commands not part of this list.
  • sanitize the user input.

Restrict which users can have access to the command:

  • use a firewall to protect the process running the code, and to protect the network from the command.
  • authenticate the user and allow only some users to run the command.

Reduce the damage the command can do:

  • execute the code in a sandbox environment that enforces strict boundaries between the operating system and the process. For example: a "jail".
  • refuse to run the command if the process has too many privileges. For example: forbid running the code as "root".

Sensitive Code Example

Python 3

import subprocess
import os

params = ["ls", "-l"]

subprocess.run(params)  # Sensitive
subprocess.Popen(params)  # Sensitive

# Older API

subprocess.call(params)  # Sensitive
subprocess.check_call(params)  # Sensitive
subprocess.check_output(params)  # Sensitive

cmd = "ls -l"
os.system(cmd)  # Sensitive

mode = os.P_WAIT
file = "ls"
path = "/bin/ls"
env = os.environ
os.spawnl(mode, path, *params)  # Sensitive
os.spawnle(mode, path, *params, env)  # Sensitive
os.spawnlp(mode, file, *params)  # Sensitive
os.spawnlpe(mode, file, *params, env)  # Sensitive
os.spawnv(mode, path, params)  # Sensitive
os.spawnve(mode, path, params, env)  # Sensitive
os.spawnvp(mode, file, params)  # Sensitive
os.spawnvpe(mode, file, params, env)  # Sensitive

mode = 'r'
(child_stdout) = os.popen(cmd, mode, 1)  # Sensitive
# print(child_stdout.read())

(_, output) = subprocess.getstatusoutput(cmd)  # Sensitive

out = subprocess.getoutput(cmd)  # Sensitive

os.startfile(path)  # Sensitive

os.execl(path, *params)  # Sensitive
os.execle(path, *params, env)  # Sensitive
os.execlp(file, *params)  # Sensitive
os.execlpe(file, *params, env)  # Sensitive
os.execv(path, params)  # Sensitive
os.execve(path, params, env)  # Sensitive
os.execvp(file, params)  # Sensitive
os.execvpe(file, params, env)  # Sensitive

Python 2

import os
import popen2

cmd = "ls -l"
mode = "r"
(_, child_stdout) = os.popen2(cmd, mode)  # Sensitive
(_, child_stdout, _) = os.popen3(cmd, mode)  # Sensitive
(_, child_stdout) = os.popen4(cmd, mode)  # Sensitive

(child_stdout, _) = popen2.popen2(cmd)  # Sensitive
(child_stdout, _, _) = popen2.popen3(cmd)  # Sensitive
(child_stdout, _) = popen2.popen4(cmd)  # Sensitive

See

python:BackticksUsage

Backticks are a deprecated alias for repr(). Don't use them any more, the syntax was removed in Python 3.0.

Noncompliant Code Example

return `num`  # Noncompliant

Compliant Solution

return repr(num)
python:S2077

Formatting strings used as SQL queries is security-sensitive. It has led in the past to the following vulnerabilities:

SQL queries often need to use a hardcoded SQL string with a dynamic parameter coming from a user request. Formatting a string to add those parameters to the request is a bad practice as it can result in an SQL injection. The safe way to add parameters to a SQL query is to use SQL binding mechanisms.

Note that this rule does not detect SQL injections.

This rule flags the execution of formatted SQL via Django APIs. The goal is to guide security code reviews and to prevent a common bad practice.

A string is considered formatted if it uses one of the following operations:

  • str.format(...)
  • str % str
  • str + str
  • f"SELECT * FROM mytable WHERE name = '{value}'"
  • F"SELECT * FROM mytable WHERE name = '{value}'"

Ask Yourself Whether

  • the SQL query is built using string formatting technics, such as concatenating variables.
  • some of the values are coming from an untrusted source and are not sanitized.

You may be at risk if you answered yes to this question.

Recommended Secure Coding Practices

You can also reduce the impact of an attack by using a database account with low privileges.

Sensitive Code Example

from django.db import models
from django.db import connection
from django.db import connections
from django.db.models.expressions import RawSQL

value = input()


class MyUser(models.Model):
    name = models.CharField(max_length=200)


def query_my_user(request, params, value):
    MyUser.objects.raw(request + value)  # Sensitive

    # Parametrized queries
    MyUser.objects.raw(request + value, params)  # Sensitive.

    with connection.cursor() as cursor:
        cursor.execute(request + value)  # Sensitive

    with connections['my_db'].cursor() as cursor:
        cursor.execute(request + value)  # Sensitive

    # https://docs.djangoproject.com/en/2.1/ref/models/expressions/#raw-sql-expressions

    RawSQL("select col from %s where mycol = %s and othercol = " + value, ("test",))  # Sensitive

    # https://docs.djangoproject.com/en/2.1/ref/models/querysets/#extra

    MyUser.objects.extra(
        select={
            'mycol':  "select col from sometable here mycol = %s and othercol = " + value}, # Sensitive
...     select_params=(someparam,),
        },
    )

Exceptions

The current implementation does not follow variables. It will only detect SQL queries which are formatted directly in the function call.

See

python:ExecStatementUsage

Use of the exec statement could be dangerous, and should be avoided. Moreover, the exec statement was removed in Python 3.0. Instead, the built-in exec() function can be used.

Noncompliant Code Example

exec 'print 1' # Noncompliant

Compliant Solution

exec('print 1')
python:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

python:S1313

Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:

Today's services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery and deployment:

  • The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
  • It forces the same address to be used in every environment (dev, sys, qa, prod).

Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service at this address or spoof the IP address. Such an attack is always possible, but in the case of a hardcoded IP address the fix will be much slower, which will increase an attack's impact.

Recommended Secure Coding Practices

  • make the IP address configurable.

Noncompliant Code Example

ip = '192.168.12.42'
sock = socket.socket()
sock.bind((ip, 9090))

Compliant Solution

ip = config.get(section, ipAddress)
sock = socket.socket()
sock.bind((ip, 9090))

Exceptions

No issue is reported for the following cases because they are not considered sensitive:

  • Loopback addresses 127.0.0.0/8 in CIDR notation (from 127.0.0.0 to 127.255.255.255)
  • Broadcast address 255.255.255.255
  • Non routable address 0.0.0.0
  • Strings of the form 2.5.<number>.<number> as they often match Object Identifiers (OID).

See

python:S1871

Having two 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 they should be combined.

Noncompliant Code Example

if 0 <= a < 10:
    do_first()
    do_second()
elif 10 <= a < 20:
    do_the_other_thing()
elif 20 <= a < 50:
    do_first()         # Noncompliant; duplicates first condition
    do_second()

Exceptions

Blocks in an if chain that contain a single line of code are ignored.

if 0 <= a < 10:
    do_first()
elif 10 <= a < 20:
    do_the_other_thing()
elif 20 <= a < 50:
    do_first()         # no issue, usually this is done on purpose to increase the readability

But this exception does not apply to if chains without else-s when all branches have the same single line of code. In case of if chains with else-s rule S3923 raises a bug.

if 0 <= a < 10:
    do_first()
elif 20 <= a < 50:
    do_first()         # Noncompliant, this might have been done on purpose but probably not
python:S4784

Using regular expressions is security-sensitive. It has led in the past to the following vulnerabilities:

Evaluating regular expressions against input strings is potentially an extremely CPU-intensive task. Specially crafted regular expressions such as (a+)+s will take several seconds to evaluate the input string aaaaaaaaaaaaaaaaaaaaaaaaaaaaabs. The problem is that with every additional a character added to the input, the time required to evaluate the regex doubles. However, the equivalent regular expression, a+s (without grouping) is efficiently evaluated in milliseconds and scales linearly with the input size.

Evaluating such regular expressions opens the door to Regular expression Denial of Service (ReDoS) attacks. In the context of a web application, attackers can force the web server to spend all of its resources evaluating regular expressions thereby making the service inaccessible to genuine users.

This rule flags any execution of a hardcoded regular expression which has at least 3 characters and at least two instances of any of the following characters: *+{.

Example: (a+)*

Ask Yourself Whether

  • the executed regular expression is sensitive and a user can provide a string which will be analyzed by this regular expression.
  • your regular expression engine performance decrease with specially crafted inputs and regular expressions.

You may be at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Check whether your regular expression engine (the algorithm executing your regular expression) has any known vulnerabilities. Search for vulnerability reports mentioning the one engine you're are using.

Use if possible a library which is not vulnerable to Redos Attacks such as Google Re2.

Remember also that a ReDos attack is possible if a user-provided regular expression is executed. This rule won't detect this kind of injection.

Sensitive Code Example

Django

from django.core.validators import RegexValidator
from django.urls import re_path

RegexValidator('(a*)*b')  # Sensitive

def define_http_endpoint(view):
    re_path(r'^(a*)*b/$', view)  # Sensitive

re module

import re
from re import compile, match, search, fullmatch, split, findall, finditer, sub, subn


input = 'input string'
replacement = 'replacement'

re.compile('(a*)*b')  # Sensitive
re.match('(a*)*b', input)  # Sensitive
re.search('(a*)*b', input)  # Sensitive
re.fullmatch('(a*)*b', input)  # Sensitive
re.split('(a*)*b', input)  # Sensitive
re.findall('(a*)*b', input)  # Sensitive
re.finditer('(a*)*b',input)  # Sensitive
re.sub('(a*)*b', replacement, input)  # Sensitive
re.subn('(a*)*b', replacement, input)  # Sensitive

regex module

import regex
from regex import compile, match, search, fullmatch, split, findall, finditer, sub, subn, subf, subfn, splititer

input = 'input string'
replacement = 'replacement'

regex.subf('(a*)*b', replacement, input)  # Sensitive
regex.subfn('(a*)*b', replacement, input)  # Sensitive
regex.splititer('(a*)*b', input)  # Sensitive

regex.compile('(a*)*b')  # Sensitive
regex.match('(a*)*b', input)  # Sensitive
regex.search('(a*)*b', input)  # Sensitive
regex.fullmatch('(a*)*b', input)  # Sensitive
regex.split('(a*)*b', input)  # Sensitive
regex.findall('(a*)*b', input)  # Sensitive
regex.finditer('(a*)*b',input)  # Sensitive
regex.sub('(a*)*b', replacement, input)  # Sensitive
regex.subn('(a*)*b', replacement, input)  # Sensitive

Exceptions

Some corner-case regular expressions will not raise an issue even though they might be vulnerable. For example: (a|aa)+, (a|a?)+.

It is a good idea to test your regular expression if it has the same pattern on both side of a "|".

See

python:S4828

Signalling processes is security-sensitive. It has led in the past to the following vulnerabilities:

* CVE-2009-0390

* CVE-2002-0839

* CVE-2008-1671

Sending signals without checking properly which process will receive it can cause a denial of service.

Ask Yourself Whether

* the PID of the process to which the signal will be sent is coming from an untrusted source. It could for example come from a world-writable file.

* users who are asking for the signal to be sent might not have the permission to send those signals.

You are at risk if you answered yes to any of these questions.

Recommended Secure Coding Practices

* If the signal is sent because of a user's request. Check that the user is allowed to send this signal. You can for example forbid it if the user doesn't own the process.

* Secure the source from which the process PID is read.

* Run the process sending the signals with minimal permissions.

Sensitive Code Example

import os

def send_signal(pid, sig, pgid):
    os.kill(pid, sig)  # Sensitive
    os.killpg(pgid, sig)  # Sensitive

See

* MITRE, CWE-283 - Unverified Ownership

python:S4823

Using command line arguments is security-sensitive. It has led in the past to the following vulnerabilities:

Command line arguments can be dangerous just like any other user input. They should never be used without being first validated and sanitized.

Remember also that any user can retrieve the list of processes running on a system, which makes the arguments provided to them visible. Thus passing sensitive information via command line arguments should be considered as insecure.

This rule raises an issue on every reference to sys.argv, call to optparse.OptionParser() or a call to argparse.ArgumentParser(). The goal is to guide security code reviews.

Ask Yourself Whether

  • any of the command line arguments are used without being sanitized first.
  • your application accepts sensitive information via command line arguments.

If you answered yes to any of these questions you are at risk.

Recommended Secure Coding Practices

Sanitize all command line arguments before using them.

Any user or application can list running processes and see the command line arguments they were started with. There are safer ways of providing sensitive information to an application than exposing them in the command line. It is common to write them on the process' standard input, or give the path to a file containing the information.

See

python:S4829

Reading Standard Input is security-sensitive. It has led in the past to the following vulnerabilities:

It is common for attackers to craft inputs enabling them to exploit software vulnerabilities. Thus any data read from the standard input (stdin) can be dangerous and should be validated.

This rule flags code that reads from the standard input.

Ask Yourself Whether

  • data read from the standard input is not sanitized before being used.

You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

Sanitize all data read from the standard input before using it.

Sensitive Code Example

Python 2 and Python 3

import sys
from sys import stdin, __stdin__

# Any reference to sys.stdin or sys.__stdin__ without a method call is Sensitive
sys.stdin  # Sensitive

for line in sys.stdin:  # Sensitive
    print(line)

it = iter(sys.stdin)  # Sensitive
line = next(it)

# Calling the following methods on stdin or __stdin__ is sensitive
sys.stdin.read()  # Sensitive
sys.stdin.readline()  # Sensitive
sys.stdin.readlines()  # Sensitive

# Calling other methods on stdin or __stdin__ does not require a review, thus it is not Sensitive
sys.stdin.seekable()  # Ok
# ...

Python 2 only

raw_input('What is your password?')  # Sensitive

Python 3 only

input('What is your password?')  # Sensitive

Function fileinput.input and class fileinput.FileInput read the standard input when the list of files is empty.

for line in fileinput.input():  # Sensitive
    print(line)

for line in fileinput.FileInput():  # Sensitive
    print(line)

for line in fileinput.input(['setup.py']):  # Ok
    print(line)

for line in fileinput.FileInput(['setup.py']):  # Ok
    print(line)

See:

python:S4507

Delivering code in production with debug features activated is security-sensitive. It has led in the past to the following vulnerabilities:

An application's debug features enable developers to find bugs more easily. It often gives access to detailed information on both the system running the application and users. Sometime it even enables the execution of custom commands. Thus deploying on production servers an application which has debug features activated is extremely dangerous.

Ask Yourself Whether

  • the code or configuration enabling the application debug features is deployed on production servers.
  • the application runs by default with debug features activated.

You are at risk if you answered yes to any of these questions.

Recommended Secure Coding Practices

The application should run by default in the most secure mode, i.e. as on production servers. This is to prevent any mistake. Enabling debug features should be explicitly asked via a command line argument, an environment variable or a configuration file.

Check that every debug feature is controlled by only very few configuration variables: logging, exception/error handling, access control, etc... It is otherwise very easy to forget one of them.

Do not enable debug features on production servers.

Sensitive Code Example

Django

from django.conf import settings

settings.configure(DEBUG=True)  # Sensitive when set to True
settings.configure(DEBUG_PROPAGATE_EXCEPTIONS=True)  # Sensitive when set to True

def custom_config(config):
    settings.configure(default_settings=config, DEBUG=True)  # Sensitive

Django's "global_settings.py" configuration file

# NOTE: The following code raises issues only if the file is named "global_settings.py". This is the default
# name of Django configuration file

DEBUG = True  # Sensitive
DEBUG_PROPAGATE_EXCEPTIONS = True  # Sensitive

See

python:S125

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
python:S1763

Jump statements (return, break, continue, and raise) move control flow out of the current code block. So any statements that come after a jump are dead code.

Noncompliant Code Example

def fun(a):
  i = 10
  return i + a       # Noncompliant
  i += 1             # this is never executed

Compliant Solution

def fun(a):
  i = 10
  return i + a

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code
  • MISRA C++:2008, 0-1-9 - There shall be no dead code
  • MISRA C:2012, 2.1 - A project shall not contain unreachable code
  • MISRA C:2012, 2.2 - There shall be no dead code
  • MITRE, CWE-561 - Dead Code
  • CERT, MSC56-J. - Detect and remove superfluous code and values
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
python:S1523

Executing code dynamically is security-sensitive. It has led in the past to the following vulnerabilities:

Some APIs enable the execution of dynamic code by providing it as strings at runtime. These APIs might be useful in some very specific meta-programming use-cases. However most of the time their use is frowned upon as they also increase the risk of Injected Code. Such attacks can either run on the server or in the client (exemple: XSS attack) and have a huge impact on an application's security.

This rule marks for review each occurrence of such dynamic code execution. This rule does not detect code injections. It only highlights the use of APIs which should be used sparingly and very carefully. The goal is to guide security code reviews.

Ask Yourself Whether

  • the executed code may come from an untrusted source and hasn't been sanitized.
  • you really need to run code dynamically.

You are at risk if you answered yes to the first question. You are increasing the security risks for no reason if you answered yes to the second question.

Recommended Secure Coding Practices

Regarding the execution of unknown code, the best solution is to not run code provided by an untrusted source. If you really need to do it, run the code in a sandboxed environment. Use jails, firewalls and whatever means your operating system and programming language provide (example: Security Managers in java, iframes and same-origin policy for javascript in a web browser).

Do not try to create a blacklist of dangerous code. It is impossible to cover all attacks that way.

Avoid using dynamic code APIs whenever possible. Hard-coded code is always safer.

Sensitive Code Example

import os

value = input()
command = 'os.system("%s")' % value

def evaluate(command, file, mode):
    eval(command)  # Sensitive.

eval(command)  # Sensitive. Dynamic code

def execute(code, file, mode):
    exec(code)  # Sensitive.
    exec(compile(code, file, mode))  # Sensitive.

exec(command)  # Sensitive.

See

python:S4790

Hashing data is security-sensitive. It has led in the past to the following vulnerabilities:

Cryptographic hash functions are used to uniquely identify information without storing their original form. When not done properly, an attacker can steal the original information by guessing it (ex: with a rainbow table), or replace the original data with another one having the same hash.

This rule flags code that initiates hashing.

Ask Yourself Whether

  • the hashed value is used in a security context.
  • the hashing algorithm you are using is known to have vulnerabilities.
  • salts are not automatically generated and applied by the hashing function.
  • any generated salts are cryptographically weak or not credential-specific.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

  • for security related purposes, use only hashing algorithms which are currently known to be strong. Avoid using algorithms like MD5 and SHA1 completely in security contexts.
  • do not define your own hashing- or salt algorithms as they will most probably have flaws.
  • do not use algorithms that compute too quickly, like SHA256, as it must remain beyond modern hardware capabilities to perform brute force and dictionary based attacks.
  • use a hashing algorithm that generate its own salts as part of the hashing. If you generate your own salts, make sure that a cryptographically strong salt algorithm is used, that generated salts are credential-specific, and finally, that the salt is applied correctly before the hashing.
  • save both the salt and the hashed value in the relevant database record; during future validation operations, the salt and hash can then be retrieved from the database. The hash is recalculated with the stored salt and the value being validated, and the result compared to the stored hash.
  • the strength of hashing algorithms often decreases over time as hardware capabilities increase. Check regularly that the algorithms you are using are still considered secure. If needed, rehash your data using a stronger algorithm.

Sensitive Code Example

hashlib module

import hashlib

def hash_data(algorithm):
    hashlib.new(algorithm)  # Sensitive

    hashlib.blake2b  # Sensitive
    hashlib.blake2s  # Sensitive
    hashlib.md5  # Sensitive
    hashlib.pbkdf2_hmac # Sensitive
    hashlib.sha1  # Sensitive
    hashlib.sha224  # Sensitive
    hashlib.sha256  # Sensitive
    hashlib.sha384  # Sensitive
    hashlib.sha3_224  # Sensitive
    hashlib.sha3_256  # Sensitive
    hashlib.sha3_384  # Sensitive
    hashlib.sha3_512  # Sensitive
    hashlib.sha512  # Sensitive
    hashlib.shake_128  # Sensitive
    hashlib.shake_256  # Sensitive
    hashlib.scrypt  # Sensitive

cryptography library

from cryptography.hazmat.primitives import hashes


def my_hash(algorithm):
    hashes.Hash(algorithm)  # Sensitive

Django

from django.contrib.auth.hashers import PBKDF2PasswordHasher, PBKDF2SHA1PasswordHasher, Argon2PasswordHasher, \
    BCryptSHA256PasswordHasher, BasePasswordHasher, BCryptPasswordHasher, SHA1PasswordHasher, MD5PasswordHasher, \
    UnsaltedSHA1PasswordHasher, UnsaltedMD5PasswordHasher, CryptPasswordHasher

from django.contrib.auth.hashers import make_password

# Changing default hashers

from django.conf import settings

def update_settings(value):
    settings.PASSWORD_HASHERS = value  # Sensitive, and also a bad practice


# Creating custom Hasher

class MyBasePasswordHasher(BasePasswordHasher):  # Sensitive
    pass

class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher):  # Sensitive
    pass

class MyPBKDF2SHA1PasswordHasher(PBKDF2SHA1PasswordHasher):  # Sensitive
    pass

class MyArgon2PasswordHasher(Argon2PasswordHasher):  # Sensitive
    pass

class MyBCryptSHA256PasswordHasher(BCryptSHA256PasswordHasher):  # Sensitive
    pass

class MyBCryptPasswordHasher(BCryptPasswordHasher):  # Sensitive
    pass

class MySHA1PasswordHasher(SHA1PasswordHasher):  # Sensitive
    pass

class MyMD5PasswordHasher(MD5PasswordHasher):  # Sensitive
    pass

class MyUnsaltedSHA1PasswordHasher(UnsaltedSHA1PasswordHasher):  # Sensitive
    pass

class MyUnsaltedMD5PasswordHasher(UnsaltedMD5PasswordHasher):  # Sensitive
    pass

class MyCryptPasswordHasher(CryptPasswordHasher):  # Sensitive
    pass


# Calling make_password with a specific hasher name or salt should be reviewed
def my_make_password(password, salt, hasher):
    make_password(password, salt=salt)  # Sensitive
    make_password(password, hasher=hasher)  # Sensitive
    make_password(password, salt=salt, hasher=hasher)  # Sensitive

    # No issue is raised when only the password is provided, then only the configuration should be reviewed
    make_password(password)  # OK

Django's "global_settings.py" configuration file

# NOTE: The following code raises issues only if the file is named "global_settings.py". This is the default
# name of Django configuration file

PASSWORD_HASHERS=[]  # Sensitive

Werkzeug

from werkzeug.security import generate_password_hash

def hash_password(password):
    generate_password_hash(password)  # Sensitive

passlib module

import passlib.hash

passlib.hash.apr_md5_crypt  # Sensitive
passlib.hash.argon2  # Sensitive
passlib.hash.atlassian_pbkdf2_sha1  # Sensitive
passlib.hash.bcrypt  # Sensitive
passlib.hash.bcrypt_sha256  # Sensitive
passlib.hash.bigcrypt  # Sensitive
passlib.hash.bsd_nthash  # Sensitive
passlib.hash.bsdi_crypt  # Sensitive
passlib.hash.cisco_asa  # Sensitive
passlib.hash.cisco_pix  # Sensitive
passlib.hash.cisco_type7  # Sensitive
passlib.hash.crypt16  # Sensitive
passlib.hash.cta_pbkdf2_sha1  # Sensitive
passlib.hash.des_crypt  # Sensitive
passlib.hash.django_argon2  # Sensitive
passlib.hash.django_bcrypt  # Sensitive
passlib.hash.django_bcrypt_sha256  # Sensitive
passlib.hash.django_des_crypt  # Sensitive
passlib.hash.django_disabled  # Sensitive
passlib.hash.django_pbkdf2_sha1  # Sensitive
passlib.hash.django_pbkdf2_sha256  # Sensitive
passlib.hash.django_salted_md5  # Sensitive
passlib.hash.django_salted_sha1  # Sensitive
passlib.hash.dlitz_pbkdf2_sha1  # Sensitive
passlib.hash.fshp  # Sensitive
passlib.hash.grub_pbkdf2_sha512  # Sensitive
passlib.hash.hex_md4  # Sensitive
passlib.hash.hex_md5  # Sensitive
passlib.hash.hex_sha1  # Sensitive
passlib.hash.hex_sha256  # Sensitive
passlib.hash.hex_sha512  # Sensitive
passlib.hash.htdigest  # Sensitive
passlib.hash.ldap_bcrypt  # Sensitive
passlib.hash.ldap_bsdi_crypt  # Sensitive
passlib.hash.ldap_des_crypt  # Sensitive
passlib.hash.ldap_hex_md5  # Sensitive
passlib.hash.ldap_hex_sha1  # Sensitive
passlib.hash.ldap_md5  # Sensitive
passlib.hash.ldap_md5_crypt  # Sensitive
passlib.hash.ldap_pbkdf2_sha1  # Sensitive
passlib.hash.ldap_pbkdf2_sha256  # Sensitive
passlib.hash.ldap_pbkdf2_sha512  # Sensitive
passlib.hash.ldap_plaintext  # Sensitive
passlib.hash.ldap_salted_md5  # Sensitive
passlib.hash.ldap_salted_sha1  # Sensitive
passlib.hash.ldap_sha1  # Sensitive
passlib.hash.ldap_sha1_crypt  # Sensitive
passlib.hash.ldap_sha256_crypt  # Sensitive
passlib.hash.ldap_sha512_crypt  # Sensitive
passlib.hash.lmhash  # Sensitive
passlib.hash.md5_crypt  # Sensitive
passlib.hash.msdcc  # Sensitive
passlib.hash.msdcc2  # Sensitive
passlib.hash.mssql2000  # Sensitive
passlib.hash.mssql2005  # Sensitive
passlib.hash.mysql323  # Sensitive
passlib.hash.mysql41  # Sensitive
passlib.hash.nthash  # Sensitive
passlib.hash.oracle10  # Sensitive
passlib.hash.oracle11  # Sensitive
passlib.hash.pbkdf2_sha1  # Sensitive
passlib.hash.pbkdf2_sha256  # Sensitive
passlib.hash.pbkdf2_sha512  # Sensitive
passlib.hash.phpass  # Sensitive
passlib.hash.plaintext  # Sensitive
passlib.hash.postgres_md5  # Sensitive
passlib.hash.roundup_plaintext  # Sensitive
passlib.hash.scram  # Sensitive
passlib.hash.scrypt  # Sensitive
passlib.hash.sha1_crypt  # Sensitive
passlib.hash.sha256_crypt  # Sensitive
passlib.hash.sha512_crypt  # Sensitive
passlib.hash.sun_md5_crypt  # Sensitive
passlib.hash.unix_disabled  # Sensitive
passlib.hash.unix_fallback  # Sensitive

pynacl library

import nacl.pwhash
from nacl.pwhash.argon2i import str as argon2i_str, kdf as argon2i_kdf
from nacl.pwhash.argon2id import str as argon2id_str, kdf as argon2id_kdf
from nacl.pwhash.scrypt import str as scrypt_str, kdf as scrypt_kdf

from nacl.hash import blake2b, sha256, sha512

blake2b  # Sensitive
sha256  # Sensitive
sha512  # Sensitive

nacl.pwhash.str  # Sensitive
nacl.pwhash.scryptsalsa208sha256_str  # Sensitive
nacl.pwhash.kdf_scryptsalsa208sha256  # Sensitive
nacl.pwhash.argon2id.str  # Sensitive
nacl.pwhash.argon2i.str  # Sensitive
nacl.pwhash.scrypt.str  # Sensitive
nacl.pwhash.argon2id.kdf  # Sensitive
nacl.pwhash.argon2i.kdf  # Sensitive
nacl.pwhash.scrypt.kdf  # Sensitive

argon2i_str  # Sensitive
argon2id_str  # Sensitive
scrypt_str  # Sensitive
argon2i_kdf  # Sensitive
argon2id_kdf  # Sensitive
scrypt_kdf  # Sensitive

See

javascript:S2589

If a boolean expression doesn't change the evaluation of the condition, then it is entirely unnecessary, and can be removed. If it is gratuitous because it does not match the programmer's intent, then it's a bug and the expression should be fixed.

Noncompliant Code Example

a = true;
if (a) { // Noncompliant
  doSomething();
}

if (b && a) { // Noncompliant; "a" is always "true"
  doSomething();
}

if (c || !a) { // Noncompliant; "!a" is always "false"
  doSomething();
}

Compliant Solution

a = true;
if (foo(a)) {
  doSomething();
}

if (b) {
  doSomething();
}

if (c) {
  doSomething();
}

See

  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
  • MITRE, CWE-571 - Expression is Always True
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-489 - Leftover Debug Code
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
javascript:S2583

Conditional expressions which are always true or false can lead to dead code. Such code is always buggy and should never be used in production.

Noncompliant Code Example

a = false;
if (a) { // Noncompliant
  doSomething(); // never executed
}

if (!a || b) { // Noncompliant; "!a" is always "true", "b" is never evaluated
  doSomething();
} else {
  doSomethingElse(); // never executed
}

See

  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
javascript:S1145

if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.

There are three possible causes for the presence of such code:

  • An if statement was changed during debugging and that debug code has been committed.
  • Some value was left unset.
  • Some logic is not doing what the programmer thought it did.

In any of these cases, unconditional if statements should be removed.

Noncompliant Code Example

if (true) {  // Noncompliant
  doSomething();
}
...
if (false) {  // Noncompliant
  doSomethingElse();
}

if (!options || options === true) { doThirdThing(); }  // Noncompliant; always true

Compliant Solution

doSomething();

doThirdThing();

See

  • MITRE, CWE-489 - Leftover Debug Code
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant

Deprecated

This rule is deprecated; use S2583 instead.

javascript:S881

The use of increment and decrement operators in method calls or in combination with other arithmetic operators is not recommended, because:

  • It can significantly impair the readability of the code.
  • It introduces additional side effects into a statement, with the potential for undefined behavior.
  • It is safer to use these operators in isolation from any other arithmetic operators.

Noncompliant Code Example

u8a = ++u8b + u8c--;
foo = bar++ / 4;

Compliant Solution

The following sequence is clearer and therefore safer:

++u8b;
u8a = u8b + u8c;
u8c--;
foo = bar / 4;
bar++;

See

  • MISRA C:2004, 12.1 - Limited dependence should be placed on the C operator precedence rules in expressions.
  • MISRA C:2004, 12.13 - The increment (++) and decrement (--) operators should not be mixed with other operators in an expression.
  • MISRA C++:2008, 5-2-10 - The increment (++) and decrement (--) operator should not be mixed with other operators in an expression.
  • MISRA C:2012, 12.1 - The precedence of operators within expressions should be made explicit
  • MISRA C:2012, 13.3 - A full expression containing an increment (++) or decrement (--) operator should have no other potential side effects other than that cause by the increment or decrement operator
  • CERT, EXP30-C. - Do not depend on the order of evaluation for side effects
  • CERT, EXP50-CPP. - Do not depend on the order of evaluation for side effects
  • CERT, EXP05-J. - Do not follow a write by a subsequent write or read of the same object within an expression
javascript:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

javascript:S878

The comma operator takes two expressions, executes them from left to right and returns the result of the second one. Use of this operator is generally detrimental to the readability and reliability of code, and the same effect can be achieved by other means.

Noncompliant Code Example

i = a += 2, a + b;  // What's the value of i ?

Compliant Solution

a +=  2;
i = a + b;

Exceptions

Use of comma operator is tolerated in initialization and increment expressions of for loops.

for(i = 0, j = 5; i < 6; i++, j++) { ... }

See

  • MISRA C:2004, 12.10 - The comma operator shall not be used.
  • MISRA C++:2008, 5-18-1 - The comma operator shall not be used.
  • MISRA C:2012, 12.3 - The comma operator should not be used
javascript:S2201

When the call to a function doesn't have any side effects, what is the point of making the call if the results are ignored? In such case, either the function call is useless and should be dropped or the source code doesn't behave as expected.

To prevent generating any false-positives, this rule triggers an issues only on a predefined list of known objects & functions.

Noncompliant Code Example

'hello'.lastIndexOf('e'); // Noncompliant

Compliant Solution

let char = 'hello'.lastIndexOf('e');

See

javascript:S2681

Curly braces can be omitted from a one-line block, such as with an if statement or for loop, but doing so can be misleading and induce bugs.

This rule raises an issue when the whitespacing of the lines after a one line block indicates an intent to include those lines in the block, but the omission of curly braces means the lines will be unconditionally executed once.

Noncompliant Code Example

if (condition)
  firstActionInBlock();
  secondAction();  // Noncompliant; executed unconditionally
thirdAction();

if (condition) firstActionInBlock(); secondAction();  // Noncompliant; secondAction executed unconditionally

if (condition) firstActionInBlock();  // Noncompliant
  secondAction();  // Executed unconditionally

if (condition); secondAction();  // Noncompliant; secondAction executed unconditionally

String str = null;
for (int i = 0; i < array.length; i++)
  str = array[i];
  doTheThing(str);  // Noncompliant; executed only on last array element

Compliant Solution

if (condition) {
  firstActionInBlock();
  secondAction();
}
thirdAction();

String str = null;
for (int i = 0; i < array.length; i++) {
  str = array[i];
  doTheThing(str);
}

See

javascript:S1117

Overriding or shadowing a variable declared in an outer scope can strongly impact the readability, and therefore the maintainability, of a piece of code. Further, it could lead maintainers to introduce bugs because they think they're using one variable but are really using another.

See

javascript:S1116

Extra semicolons (;) are usually introduced by mistake, for example because:

  • It was meant to be replaced by an actual statement, but this was forgotten.
  • There was a typo which lead the semicolon to be doubled, i.e. ;;.
  • There was a misunderstanding about where semicolons are required or useful.

Noncompliant Code Example

var x = 1;; // Noncompliant

function foo() {
};  // Noncompliant

Compliant Solution

var x = 1;

function foo() {
}

See

  • MISRA C:2004, 14.3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment provided that the first character following the null statement is a white-space character.
  • MISRA C++:2008, 6-2-3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment, provided that the first character following the null statement is a white-space character.
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • CERT, MSC51-J. - Do not place a semicolon immediately following an if, for, or while condition
  • CERT, EXP15-C. - Do not place a semicolon on the same line as an if, for, or while statement
javascript:AssignmentWithinCondition

Assignments within sub-expressions are hard to spot and therefore make the code less readable. Ideally, sub-expressions should not have side-effects.

Noncompliant Code Example

if ((str = cont.substring(pos1, pos2)) != '') {  // Noncompliant
  //...
}

Compliant Solution

str = cont.substring(pos1, pos2);
if (str != '') {
  //...
}

Exceptions

Assignments in while statement conditions, and assignments enclosed in relational expressions are allowed.

while ((line = nextLine()) != null) {...}  // Compliant

while (line = nextLine()) {...}  // Compliant

if (line = nextLine()) {...}  // Noncompliant

See

  • MISRA C:2004, 13.1 - Assignment operators shall not be used in expressions that yield a Boolean value
  • MISRA C++:2008, 6-2-1 - Assignment operators shall not be used in sub-expressions
  • MISRA C:2012, 13.4 - The result of an assignment operator should not be used
  • MITRE, CWE-481 - Assigning instead of Comparing
  • CERT, EXP45-C. - Do not perform assignments in selection statements
  • CERT, EXP51-J. - Do not perform assignments in conditional expressions
javascript:S2692

Most checks against an indexOf call against a string or array compare it with -1 because 0 is a valid index. Any checks which look for values >0 ignore the first element, which is likely a bug. If you're merely checking the presence of the string, consider using includes instead. Before using includes method make sure that your browser version is supporting it.

Noncompliant Code Example

var color = "blue";
var name = "ishmael";
var number = 123;

var arr = [color, name];

if (arr.indexOf("blue") > 0) { // Noncompliant
  // ...
}
if (name.indexOf("ish") > 0) { // Noncompliant
  // ...
}

Compliant Solution

var color = "blue";
var name = "ishmael";
var number = 123;

var arr = [color, name];

if (arr.indexOf("blue") >= 0) {
  // ...
}
if (name.includes("ish")) {
  // ...
}

See

javascript:DebuggerStatement

The debugger statement can be placed anywhere in procedures to suspend execution. Using the debugger statement is similar to setting a breakpoint in the code. By definition such statement must absolutely be removed from the source code to prevent any unexpected behavior or added vulnerability to attacks in production.

Noncompliant Code Example

for (i = 1; i<5; i++) {
  // Print i to the Output window.
  Debug.write("loop index is " + i);
  // Wait for user to resume.
  debugger;
}

Compliant Solution

for (i = 1; i<5; i++) {
  // Print i to the Output window.
  Debug.write("loop index is " + i);
}

See

javascript:OctalNumber

Integer literals starting with a zero are octal rather than decimal values. While using octal values is fully supported, most developers do not have experience with them. They may not recognize octal values as such, mistaking them instead for decimal values.

Noncompliant Code Example

var myNumber = 010;   // Noncompliant. myNumber will hold 8, not 10 - was this really expected?

Compliant Solution

var myNumber = 8;

See

  • MISRA C:2004, 7.1 - Octal constants (other than zero) and octal escape sequences shall not be used.
  • MISRA C++:2008, 2-13-2 - Octal constants (other than zero) and octal escape sequences (other than "\0") shall not be used
  • MISRA C:2012, 7.1 - Octal constants shall not be used
  • CERT, DCL18-C. - Do not begin integer constants with 0 when specifying a decimal value
  • CERT, DCL50-J. - Use visually distinct identifiers
javascript:S2819

HTML5 adds the ability to send messages to documents served from other domains. According to the specification:

Authors should not use the wildcard keyword ( *) in the targetOrigin argument in messages that contain any confidential information, as otherwise there is no way to guarantee that the message is only delivered to the recipient to which it was intended.

To mitigate the risk of sending sensitive information to a document served from a hostile or unknown domain, this rule raises an issue each time Window.postMessage is used.

Noncompliant Code Example

var myWindow = document.getElementById('myIFrame').contentWindow;
myWindow.postMessage(message, "*"); // Noncompliant; how do you know what you loaded in 'myIFrame' is still there?

See

javascript:S3923

Having all branches in a switch or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a switch/if chain at all.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

if (b == 0) {  // Noncompliant
  doOneMoreThing();
}
else {
  doOneMoreThing();
}

let a = (b == 0) ? getValue() : getValue();   // Noncompliant

switch (i) {  // Noncompliant
  case 1:
    doSomething();
    break;
  case 2:
    doSomething();
    break;
  case 3:
    doSomething();
    break;
  default:
    doSomething();
}

Exceptions

This rule does not apply to if chains without else-s, or to switch-es without default clauses.

if(b == 0) {    //no issue, this could have been done on purpose to make the code more readable
  doSomething();
} else if(b == 1) {
  doSomething();
}
javascript:S2245

Using pseudorandom number generators (PRNGs) is security-sensitive. For example, it has led in the past to the following vulnerabilities:

When software generates predictable values in a context requiring unpredictability, it may be possible for an attacker to guess the next value that will be generated, and use this guess to impersonate another user or access sensitive information.

As the Math.random() function relies on a weak pseudorandom number generator, this function should not be used for security-critical applications or for protecting sensitive data. In such context, a cryptographically strong pseudorandom number generator (CSPRNG) should be used instead.

Ask Yourself Whether

  • the code using the generated value requires it to be unpredictable. It is the case for all encryption mechanisms or when a secret value, such as a password, is hashed.
  • the function you use generates a value which can be predicted (pseudo-random).
  • the generated value is used multiple times.
  • an attacker can access the generated value.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

  • Use a cryptographically strong pseudorandom number generator (CSPRNG) like crypto.getRandomValues().
  • Use the generated random values only once.
  • You should not expose the generated random value. If you have to store it, make sure that the database or file is secure.

Questionable Code Example

const val = Math.random(); // Questionable
// Check if val is used in a security context.

Compliant Solution

// === Client side ===
const crypto = window.crypto || window.msCrypto;
var array = new Uint32Array(1);
crypto.getRandomValues(array); // Compliant for security-sensitive use cases

// === Server side ===
const crypto = require('crypto');
const buf = crypto.randomBytes(1); // Compliant for security-sensitive use cases

See

javascript:S4787

Encrypting data is security-sensitive. It has led in the past to the following vulnerabilities:

Proper encryption requires both the encryption algorithm and the key to be strong. Obviously the private key needs to remain secret and be renewed regularly. However these are not the only means to defeat or weaken an encryption.

This rule flags function calls that initiate encryption/decryption. The goal is to guide security code reviews.

Ask Yourself Whether

  • the private key might not be random, strong enough or the same key is reused for a long long time.
  • the private key might be compromised. It can happen when it is stored in an unsafe place or when it was transferred in an unsafe manner.
  • the key exchange is made without properly authenticating the receiver.
  • the encryption algorithm is not strong enough for the level of protection required. Note that encryption algorithms strength decreases as time passes.
  • the chosen encryption library is deemed unsafe.
  • a nonce is used, and the same value is reused multiple times, or the nonce is not random.
  • the RSA algorithm is used, and it does not incorporate an Optimal Asymmetric Encryption Padding (OAEP), which might weaken the encryption.
  • the CBC (Cypher Block Chaining) algorithm is used for encryption, and it's IV (Initialization Vector) is not generated using a secure random algorithm, or it is reused.
  • the Advanced Encryption Standard (AES) encryption algorithm is used with an unsecure mode. See the recommended practices for more information.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

  • Generate encryption keys using secure random algorithms.
  • When generating cryptographic keys (or key pairs), it is important to use a key length that provides enough entropy against brute-force attacks. For the Blowfish algorithm the key should be at least 128 bits long, while for the RSA algorithm it should be at least 2048 bits long.
  • Regenerate the keys regularly.
  • Always store the keys in a safe location and transfer them only over safe channels.
  • If there is an exchange of cryptographic keys, check first the identity of the receiver.
  • Only use strong encryption algorithms. Check regularly that the algorithm is still deemed secure. It is also imperative that they are implemented correctly. Use only encryption libraries which are deemed secure. Do not define your own encryption algorithms as they will most probably have flaws.
  • When a nonce is used, generate it randomly every time.
  • When using the RSA algorithm, incorporate an Optimal Asymmetric Encryption Padding (OAEP).
  • When CBC is used for encryption, the IV must be random and unpredictable. Otherwise it exposes the encrypted value to crypto-analysis attacks like "Chosen-Plaintext Attacks". Thus a secure random algorithm should be used. An IV value should be associated to one and only one encryption cycle, because the IV's purpose is to ensure that the same plaintext encrypted twice will yield two different ciphertexts.
  • The Advanced Encryption Standard (AES) encryption algorithm can be used with various modes. Galois/Counter Mode (GCM) with no padding should be preferred to the following combinations which are not secured:
    • Electronic Codebook (ECB) mode: Under a given key, any given plaintext block always gets encrypted to the same ciphertext block. Thus, it does not hide data patterns well. In some senses, it doesn't provide serious message confidentiality, and it is not recommended for use in cryptographic protocols at all.
    • Cipher Block Chaining (CBC) with PKCS#5 padding (or PKCS#7) is susceptible to padding oracle attacks.

Questionable Code Example

// === Client side ===
crypto.subtle.encrypt(algo, key, plainData); // Questionable
crypto.subtle.decrypt(algo, key, encData); // Questionable
// === Server side ===
const crypto = require("crypto");
const cipher = crypto.createCipher(algo, key); // Questionable
const cipheriv = crypto.createCipheriv(algo, key, iv); // Questionable
const decipher = crypto.createDecipher(algo, key); // Questionable
const decipheriv = crypto.createDecipheriv(algo, key, iv); // Questionable
const pubEnc = crypto.publicEncrypt(key, buf); // Questionable
const privDec = crypto.privateDecrypt({ key: key, passphrase: secret }, pubEnc); // Questionable
const privEnc = crypto.privateEncrypt({ key: key, passphrase: secret }, buf); // Questionable
const pubDec = crypto.publicDecrypt(key, privEnc); // Questionable

See

javascript:S4784

Using regular expressions is security-sensitive. It has led in the past to the following vulnerabilities:

Evaluating regular expressions against input strings is potentially an extremely CPU-intensive task. Specially crafted regular expressions such as (a+)+s will take several seconds to evaluate the input string aaaaaaaaaaaaaaaaaaaaaaaaaaaaabs. The problem is that with every additional a character added to the input, the time required to evaluate the regex doubles. However, the equivalent regular expression, a+s (without grouping) is efficiently evaluated in milliseconds and scales linearly with the input size.

Evaluating such regular expressions opens the door to Regular expression Denial of Service (ReDoS) attacks. In the context of a web application, attackers can force the web server to spend all of its resources evaluating regular expressions thereby making the service inaccessible to genuine users.

This rule flags any execution of a hardcoded regular expression which has at least 3 characters and at least two instances of any of the following characters: *+{.

Example: (a+)*

Ask Yourself Whether

  • the executed regular expression is sensitive and a user can provide a string which will be analyzed by this regular expression.
  • your regular expression engine performance decrease with specially crafted inputs and regular expressions.

You may be at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Check whether your regular expression engine (the algorithm executing your regular expression) has any known vulnerabilities. Search for vulnerability reports mentioning the one engine you're are using.

Use if possible a library which is not vulnerable to Redos Attacks such as Google Re2.

Remember also that a ReDos attack is possible if a user-provided regular expression is executed. This rule won't detect this kind of injection.

Sensitive Code Example

const regex = /(a+)+b/; // Sensitive
const regex2 = new RegExp("(a+)+b"); // Sensitive

str.search("(a+)+b"); // Sensitive
str.match("(a+)+b"); // Sensitive
str.split("(a+)+b"); // Sensitive

Note: String.matchAll does not raise any issue as it is not supported by NodeJS.

See

javascript:CommentedCode

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
javascript:UnreachableCode

Jump statements (return, break and continue) and throw expressions move control flow out of the current code block. So any statements that come after a jump are dead code.

Noncompliant Code Example

function fun(a) {
  var i = 10;
  return i + a;
  i++;             // Noncompliant; this is never executed
}

Compliant Solution

function fun(int a) {
  var i = 10;
  return i + a;
}

Exceptions

This rule ignores unreachable break statements in switch clauses.

switch (x) {
  case 42:
     return 43;
     break;   // Compliant
  default:
    doSomething();
}

Hoisted variables declarations without initialization are always considered reachable.

function bar() {
  return x = function() {
    x.foo = 42;
  }
  var x;
}

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code
  • MISRA C++:2008, 0-1-9 - There shall be no dead code
  • MISRA C:2012, 2.1 - A project shall not contain unreachable code
  • MISRA C:2012, 2.2 - There shall be no dead code
  • MITRE, CWE-561 - Dead Code
  • CERT, MSC56-J. - Detect and remove superfluous code and values
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
javascript:S2255

Using cookies is security-sensitive. It has led in the past to the following vulnerabilities:

Attackers can use widely-available tools to read cookies, sensitive information written by the server will be exposed.

This rule flags code that writes cookies.

Ask Yourself Whether

  • sensitive information is stored inside the cookie.

You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

Cookies should only be used to manage the user session. The best practice is to keep all user-related information server-side and link them to the user session, never sending them to the client. In a very few corner cases, cookies can be used for non-sensitive information that need to live longer than the user session.

Do not try to encode sensitive information in a non human-readable format before writing them in a cookie. The encoding can be reverted and the original information will be exposed.

Using cookies only for session IDs doesn't make them secure. Follow OWASP best practices when you configure your cookies.

As a side note, every information read from a cookie should be Sanitized.

Sensitive Code Example

// === Built-in NodeJS modules ===
const http = require('http');
const https = require('https');

http.createServer(function(req, res) {
  res.setHeader('Set-Cookie', ['type=ninja', 'lang=js']); // Questionable
});
https.createServer(function(req, res) {
  res.setHeader('Set-Cookie', ['type=ninja', 'lang=js']); // Questionable
});
// === ExpressJS ===
const express = require('express');
const app = express();
app.use(function(req, res, next) {
  res.cookie('name', 'John'); // Questionable
});
// === In browser ===
// Set cookie
document.cookie = "name=John"; // Questionable

See

javascript:S2817

The Web SQL Database standard never saw the light of day. It was first formulated, then deprecated by the W3C and was only implemented in some browsers. (It is not supported in Firefox or IE.)

Further, the use of a Web SQL Database poses security concerns, since you only need its name to access such a database.

Noncompliant Code Example

var db = window.openDatabase("myDb", "1.0", "Personal secrets stored here", 2*1024*1024);  // Noncompliant

See

javascript:S4790

Hashing data is security-sensitive. It has led in the past to the following vulnerabilities:

Cryptographic hash functions are used to uniquely identify information without storing their original form. When not done properly, an attacker can steal the original information by guessing it (ex: with a rainbow table), or replace the original data with another one having the same hash.

This rule flags code that initiates hashing.

Ask Yourself Whether

  • the hashed value is used in a security context.
  • the hashing algorithm you are using is known to have vulnerabilities.
  • salts are not automatically generated and applied by the hashing function.
  • any generated salts are cryptographically weak or not credential-specific.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

  • for security related purposes, use only hashing algorithms which are currently known to be strong. Avoid using algorithms like MD5 and SHA1 completely in security contexts.
  • do not define your own hashing- or salt algorithms as they will most probably have flaws.
  • do not use algorithms that compute too quickly, like SHA256, as it must remain beyond modern hardware capabilities to perform brute force and dictionary based attacks.
  • use a hashing algorithm that generate its own salts as part of the hashing. If you generate your own salts, make sure that a cryptographically strong salt algorithm is used, that generated salts are credential-specific, and finally, that the salt is applied correctly before the hashing.
  • save both the salt and the hashed value in the relevant database record; during future validation operations, the salt and hash can then be retrieved from the database. The hash is recalculated with the stored salt and the value being validated, and the result compared to the stored hash.
  • the strength of hashing algorithms often decreases over time as hardware capabilities increase. Check regularly that the algorithms you are using are still considered secure. If needed, rehash your data using a stronger algorithm.

Questionable Code Example

// === Server side ===
const crypto = require("crypto");

const hash = crypto.createHash('sha1'); // Questionable regardless of algorithm used

crypto.scrypt(secret, salt, keylen, (err, derivedKey) => {}); // Questionable
const derivedKey = crypto.scryptSync(secret, salt, keylen); // Questionable
// === Client side ===
crypto.subtle.digest("SHA-256", buffer) // Questionable regardless of algorithm used
  .then(function (hash) {});

See

javascript:S930

You can easily call a JavaScript function with more arguments than the function needs, but the extra arguments will be just ignored by function execution.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

function say(a, b) {
  print(a + " " + b);
}

say("hello", "world", "!"); // Noncompliant; last argument is not used

Exceptions

No issue is reported when arguments is used in the body of the function being called.

function doSomething(a, b) {
  compute(arguments);
}

doSomething(1, 2, 3) // Compliant

See

  • MISRA C:2004, 16.6 - The number of arguments passed to a function shall match the number of parameters.
  • MITRE, CWE-628 - Function Call with Incorrectly Specified Arguments
  • CERT, DCL07-C. - Include the appropriate type information in function declarators
  • CERT, EXP37-C. - Call functions with the correct number and type of arguments
javascript:S905

Any statement (other than a null statement, which means a statement containing only a semicolon ;) which has no side effect and does not result in a change of control flow will normally indicate a programming error, and therefore should be refactored.

Noncompliant Code Example

a == 1; // Noncompliant; was assignment intended?
var msg = "Hello, "
  "World!"; // Noncompliant; have we forgotten '+' operator on previous line?

See

  • MITRE, CWE-482 - Comparing instead of Assigning
  • MISRA C:2004, 14.2 - All non-null statements shall either have at least one side-effect however executed, or cause control flow to change.
javascript:S3271

Session storage and local storage are HTML 5 features which allow developers to easily store megabytes of data client-side, as opposed to the 4Kb cookies can accommodate. While useful to speed applications up on the client side, it can be dangerous to store sensitive information this way because the data is not encrypted by default and any script on the page may access it.

This rule raises an issue when the localStorage and sessionStorage API's are used.

Noncompliant Code Example

localStorage.setItem("login", login); // Noncompliant
sessionStorage.setItem("sessionId", sessionId); // Noncompliant

See

javascript:S106

Debug statements are always useful during development. But include them in production code - particularly in code that runs client-side - and you run the risk of inadvertently exposing sensitive information, slowing down the browser, or even erroring-out the site for some users.

Noncompliant Code Example

console.log(password_entered); // Noncompliant

See

javascript:S1301

switch statements are useful when there are many different cases depending on the value of the same expression.

For just one or two cases however, the code will be more readable with if statements.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

switch (variable) {
  case 0:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Compliant Solution

if (variable == 0) {
  doSomething();
} else {
  doSomethingElse();
}

See

  • MISRA C:2012, 16.6 - Every switch statement shall have at least two switch-clauses
javascript:S2077

Formatting strings used as SQL queries is security-sensitive. It has led in the past to the following vulnerabilities:

* CVE-2018-9019

* CVE-2018-7318

* CVE-2017-5611

SQL queries often need to use a hardcoded SQL string with a dynamic parameter coming from a user request. Formatting a string to add those parameters to the request is a bad practice as it can result in an SQL injection. The safe way to add parameters to a SQL query is to use SQL binding mechanisms.

This rule flags the execution of SQL queries which are built using formatting of strings, even if there is no injection. This rule does not detect SQL injections. The goal is to guide security code reviews and to prevent a common bad practice.

This rule raises an issue when any of the following NodeJS APIs are used:

  • mysql.query()
  • mysql2.query()
  • pg.query()
  • sequelize.query()

The following formatting methods will raise an issue:

  • "string" + "string" concatenation
  • `string ${var}` templates
  • string.concat()
  • string.replace()

Ask Yourself Whether

  • the SQL query is built using string formatting technics, such as concatenating variables.
  • some of the values are coming from an untrusted source and are not sanitized.

You may be at risk if you answered yes to this question.

Recommended Secure Coding Practices

  • Avoid building queries manually using formatting technics. If you do it anyway, do not include user input in this building process.
  • Use parameterized queries, prepared statements, or stored procedures whenever possible.
  • You may also use ORM frameworks such as Hibernate which, if used correctly, reduce injection risks.
  • Avoid executing SQL queries containing unsafe input in stored procedures or functions.
  • Sanitize every unsafe input.

You can also reduce the impact of an attack by using a database account with low privileges.

Sensitive Code Example

// === MySQL ===
const mysql = require('mysql');
const mycon = mysql.createConnection({ host: host, user: user, password: pass, database: db });
mycon.connect(function(err) {
  mycon.query('SELECT * FROM users WHERE id = ' + userinput, (err, res) => {}); // Sensitive
});

// === PostgreSQL ===
const pg = require('pg');
const pgcon = new pg.Client({ host: host, user: user, password: pass, database: db });
pgcon.connect();
pgcon.query('SELECT * FROM users WHERE id = ' + userinput, (err, res) => {}); // Sensitive

Compliant Solution

// === MySQL ===
const mysql = require('mysql');
const mycon = mysql.createConnection({ host: host, user: user, password: pass, database: db });
mycon.connect(function(err) {
  mycon.query('SELECT name FROM users WHERE id = ?', [userinput], (err, res) => {});
});

// === PostgreSQL ===
const pg = require('pg');
const pgcon = new pg.Client({ host: host, user: user, password: pass, database: db });
pgcon.connect();
pgcon.query('SELECT name FROM users WHERE id = $1', [userinput], (err, res) => {});

Exceptions

This rule's current implementation does not follow variables. It will only detect SQL queries which are formatted directly in the function call.

const sql = 'SELECT * FROM users WHERE id = ' + userinput;
mycon.query(sql, (err, res) => {}); // Sensitive but no issue is raised.

See

javascript:S4817

Executing XPATH expressions is security-sensitive. It has led in the past to the following vulnerabilities:

User provided data such as URL parameters should always be considered as untrusted and tainted. Constructing XPath expressions directly from tainted data enables attackers to inject specially crafted values that changes the initial meaning of the expression itself. Successful XPath injections attacks can read sensitive information from the XML document.

Ask Yourself Whether

  • the XPATH expression might contain some unsafe input coming from a user.

You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

Sanitize any user input before using it in an XPATH expression.

Questionable Code Example

// === Server side ===

var xpath = require('xpath');
var xmldom = require('xmldom');

var doc = new xmldom.DOMParser().parseFromString(xml);
var nodes = xpath.select(userinput, doc); // Questionable
var node = xpath.select1(userinput, doc); // Questionable
// === Client side ===

// Chrome, Firefox, Edge, Opera, and Safari use the evaluate() method to select nodes:
var nodes = document.evaluate(userinput, xmlDoc, null, XPathResult.ANY_TYPE, null); // Questionable

// Internet Explorer uses its own methods to select nodes:
var nodes = xmlDoc.selectNodes(userinput); // Questionable
var node = xmlDoc.SelectSingleNode(userinput); // Questionable

See

javascript:S4818

Using sockets is security-sensitive. It has led in the past to the following vulnerabilities:

Sockets are vulnerable in multiple ways:

  • They enable a software to interact with the outside world. As this world is full of attackers it is necessary to check that they cannot receive sensitive information or inject dangerous input.
  • The number of sockets is limited and can be exhausted. Which makes the application unresponsive to users who need additional sockets.

This rules flags code that creates sockets. It matches only the direct use of sockets, not use through frameworks or high-level APIs such as the use of http connections.

Ask Yourself Whether

  • sockets are created without any limit every time a user performs an action.
  • input received from sockets is used without being sanitized.
  • sensitive data is sent via sockets without being encrypted.

You are at risk if you answered yes to any of these questions.

Recommended Secure Coding Practices

  • In many cases there is no need to open a socket yourself. Use instead libraries and existing protocols.
  • Encrypt all data sent if it is sensitive. Usually it is better to encrypt it even if the data is not sensitive as it might change later.
  • Sanitize any input read from the socket.
  • Limit the number of sockets a given user can create. Close the sockets as soon as possible.

Questionable Code Example

const net = require('net');

var socket = new net.Socket(); // Questionable
socket.connect(80, 'google.com');

// net.createConnection creates a new net.Socket, initiates connection with socket.connect(), then returns the net.Socket that starts the connection
net.createConnection({ port: port }, () => {}); // Questionable

// net.connect is an alias to net.createConnection
net.connect({ port: port }, () => {}); // Questionable

See

javascript:S1871

Having two cases in a switch statement or two branches in an if chain 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 chain they should be combined, or for a switch, one should fall through to the other.

Noncompliant Code Example

switch (i) {
  case 1:
    doFirstThing();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  case 3:  // Noncompliant; duplicates case 1's implementation
    doFirstThing();
    doSomething();
    break;
  default:
    doTheRest();
}

if (a >= 0 && a < 10) {
  doFirstThing();
  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else if (a >= 20 && a < 50) {
  doFirstThing();
  doTheThing();  // Noncompliant; duplicates first condition
}
else {
  doTheRest();
}

Compliant Solution

switch (i) {
  case 1:
  case 3:
    doFirstThing();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  default:
    doTheRest();
}

if ((a >= 0 && a < 10) || (a >= 20 && a < 50)) {
  doFirstThing();
  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else {
  doTheRest();
}

or

switch (i) {
  case 1:
    doFirstThing();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  case 3:
    doFirstThing();
    doThirdThing();
    break;
  default:
    doTheRest();
}

if (a >= 0 && a < 10) {
  doFirstThing();
  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else if (a >= 20 && a < 50) {
  doFirstThing();
  doTheThirdThing();
}
else {
  doTheRest();
}

Exceptions

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a switch statement that contain a single line of code with or without a following break.

  if(a == 1) {
  doSomething();  //no issue, usually this is done on purpose to increase the readability
} else if (a == 2) {
  doSomethingElse();
} else {
  doSomething();
}

But this exception does not apply to if chains without else-s, or to switch-es without default clauses when all branches have the same single line of code. In case of if chains with else-s, or of switch-es with default clauses, rule S3923 raises a bug.

  if(a == 1) {
  doSomething();  //Noncompliant, this might have been done on purpose but probably not
} else if (a == 2) {
  doSomething();
}
javascript:S2611

Including content in your site from an untrusted source can expose your users to attackers and even compromise your own site. For that reason, this rule raises an issue for each non-relative URL.

Noncompliant Code Example

function include(url) {
  var s = document.createElement("script");
  s.setAttribute("type", "text/javascript");
  s.setAttribute("src", url);
  document.body.appendChild(s);
}
include("http://hackers.com/steal.js")  // Noncompliant

See

javascript:Eval

Executing code dynamically is security-sensitive. It has led in the past to the following vulnerabilities:

Some APIs enable the execution of dynamic code by providing it as strings at runtime. These APIs might be useful in some very specific meta-programming use-cases. However most of the time their use is frowned upon as they also increase the risk of Injected Code. Such attacks can either run on the server or in the client (exemple: XSS attack) and have a huge impact on an application's security.

This rule raises issues on calls to eval and Function constructor. This rule does not detect code injections. It only highlights the use of APIs which should be used sparingly and very carefully. The goal is to guide security code reviews.

Ask Yourself Whether

  • the executed code may come from an untrusted source and hasn't been sanitized.
  • you really need to run code dynamically.

You are at risk if you answered yes to the first question. You are increasing the security risks for no reason if you answered yes to the second question.

Recommended Secure Coding Practices

Regarding the execution of unknown code, the best solution is to not run code provided by an untrusted source. If you really need to do it, run the code in a sandboxed environment. Use jails, firewalls and whatever means your operating system and programming language provide (example: Security Managers in java, iframes and same-origin policy for javascript in a web browser).

Do not try to create a blacklist of dangerous code. It is impossible to cover all attacks that way.

Avoid using dynamic code APIs whenever possible. Hard-coded code is always safer.

Noncompliant Code Example

let value = eval('obj.' + propName); // Questionable
let func = Function('obj' + propName); // Questionable

Exceptions

This rule will not raise an issue when the argument of the eval or Function is a literal string as it is reasonably safe.

See

javascript:UnusedFunctionArgument

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

Noncompliant Code Example

function doSomething(a, b) { // "a" is unused
  return compute(b);
}

Compliant Solution

function doSomething(b) {
  return compute(b);
}

Exceptions

When writing function callbacks, some arguments might be required as part of the function signature, but not actually needed by the callback code. For instance, JQuery has the 'each' helper to iterate over arrays or objects, but using the counter 'i' should remain optional:

$(["first", "last"]).each(function (i, value) {
  computeSomethingWithValue(value);
});

So only unused arguments listed at the end of the argument list will be flagged with issues because they could be omitted from the function signature. Unused arguments which are followed by an argument that is used will be ignored.

Examples :

var myFirsCallBackFunction = function (p1, p2, p3, p4) {  // p2 is ignored, but p4 is reported
                                              return p1 + p3; }

var mySecondCallBackFunction = function (p1, p2, p3, p4) {  // p1, p2 and p3 are ignored
                                              return p4; }

var myThirdCallBackFunction = function (p1, p2, p3, p4) {  // p1 is ignored but p3 and p4 are reported
                                              return p2; }

Further, when arguments is used in the function body, no parameter is reported as unused.

function doSomething(a, b, c) {
  compute(arguments);
}

See

  • MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions.
  • MISRA C:2012, 2.7 - There should be no unused parameters in functions
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
javascript:S4721

OS commands are security-sensitive. For example, their use has led in the past to the following vulnerabilities:

Applications that execute operating system commands or execute commands that interact with the underlying system should neutralize any externally-provided input used to construct those commands. Failure to do so could allow an attacker to execute unexpected or dangerous commands, potentially leading to loss of confidentiality, integrity or availability.

This rule flags code that specifies the name of the command to run. The goal is to guide security code reviews.

Ask Yourself Whether

  • the executed command is constructed by input that is externally-influenced, for example, user input (attacker). (*)
  • the command execution is not restricted to the right users. (*)
  • the application can be redesigned to not rely on external input to execute the command.

(*) You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Restrict the control given to the user over the executed command:

  • make the executed command part of a whitelist and reject all commands not part of this list.
  • sanitize the user input.

Restrict which users can have access to the command:

  • use a firewall to protect the process running the code, and to protect the network from the command.
  • authenticate the user and allow only some users to run the command.

Reduce the damage the command can do:

  • execute the code in a sandbox environment that enforces strict boundaries between the operating system and the process. For example: a "jail".
  • refuse to run the command if the process has too many privileges. For example: forbid running the code as "root".

Questionable Code Example

const cp = require('child_process');

// The following method calls are questionable. Validate the parameter string.
cp.exec(str);
cp.execSync(str);

// The following method calls are questionable if the shell parameter is set to true.
cp.spawn(str, { shell: true });
cp.spawnSync(str, { shell: true });
cp.execFile(str, { shell: true });
cp.execFileSync(str, { shell: true });

Exceptions

No issue will be raised if the string being passed is fully hard-coded.

See

javascript:S1219

Even if it is legal, mixing case and non-case labels in the body of a switch statement is very confusing and can even be the result of a typing error.

Noncompliant Code Example

Case 1, the code is syntactically correct but the behavior is not the expected one

switch (day) {
  case MONDAY:
  case TUESDAY:
  WEDNESDAY:   // instead of "case WEDNESDAY"
    doSomething();
    break;
  ...
}

Case 2, the code is correct and behaves as expected but is hardly readable

switch (day) {
  case MONDAY:
    break;
  case TUESDAY:
    foo:for(i = 0 ; i < X ; i++) {
         /* ... */
        break foo;  // this break statement doesn't relate to the nesting case TUESDAY
         /* ... */
    }
    break;
    /* ... */
}

Compliant Solution

Case 1

switch (day) {
  case MONDAY:
  case TUESDAY:
  case WEDNESDAY:
    doSomething();
    break;
  ...
}

Case 2

switch (day) {
  case MONDAY:
    break;
  case TUESDAY:
    compute(args); // put the content of the labelled "for" statement in a dedicated method
    break;

    /* ... */
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
javascript:CurlyBraces

While not technically incorrect, the omission of curly braces can be misleading, and may lead to the introduction of errors during maintenance.

Noncompliant Code Example

if (condition)  // Noncompliant
  executeSomething();

Compliant Solution

if (condition) {
  executeSomething();
}

See

  • MISRA C:2004, 14.8 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C:2004, 14.9 - An if (expression) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C++:2008, 6-3-1 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C++:2008, 6-4-1 - An if (condition) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C:2012, 15.6 - The body of an iteration-statement or a selection-statement shall be a compound-statement
  • CERT, EXP19-C. - Use braces for the body of an if, for, or while statement
  • CERT, EXP52-J. - Use braces for the body of an if, for, or while statement
javascript:ContinueStatement

continue is an unstructured control flow statement. It makes code less testable, less readable and less maintainable. Structured control flow statements such as if should be used instead.

Noncompliant Code Example

  for (i = 0; i < 10; i++) {
    if (i == 5) {
      continue;  /* Noncompliant */
    }
    alert("i = " + i);
  }

Compliant Solution

  for (i = 0; i < 10; i++) {
    if (i != 5) {  /* Compliant */
      alert("i = " + i);
    }
  }

See

  • MISRA C:2004, 14.5 - The continue statement shall not be used.
javascript:S1226

While it is technically correct to assign to parameters from within function bodies, it reduces code readability because developers won't be able to tell whether the original parameter or some temporary variable is being accessed without going through the whole function. Moreover, some developers might also expect assignments of function parameters to be visible to callers, which is not the case, and this lack of visibility could confuse them. Instead, all parameters, caught exceptions, and foreach parameters should be treated as constants.

Noncompliant Code Example

function MyClass(name, strings) {
  name = foo;                    // Noncompliant

  for (var str of strings) {
    str = "";  // Noncompliant
  }
}

See

  • MISRA C:2012, 17.8 - A function parameter should not be modified
javascript:SwitchWithoutDefault

The requirement for a final default clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken.

Noncompliant Code Example

switch (param) {  //missing default clause
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
}

switch (param) {
  default: // default clause should be the last one
    error();
    break;
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
}

Compliant Solution

switch (param) {
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
  default:
    error();
    break;
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
  • MITRE, CWE-478 - Missing Default Case in Switch Statement
  • CERT, MSC01-C. - Strive for logical completeness
javascript:S4823

Using command line arguments is security-sensitive. It has led in the past to the following vulnerabilities:

Command line arguments can be dangerous just like any other user input. They should never be used without being first validated and sanitized.

Remember also that any user can retrieve the list of processes running on a system, which makes the arguments provided to them visible. Thus passing sensitive information via command line arguments should be considered as insecure.

This rule raises an issue when on every program entry points (main methods) when command line arguments are used. The goal is to guide security code reviews.

Ask Yourself Whether

  • any of the command line arguments are used without being sanitized first.
  • your application accepts sensitive information via command line arguments.

If you answered yes to any of these questions you are at risk.

Recommended Secure Coding Practices

Sanitize all command line arguments before using them.

Any user or application can list running processes and see the command line arguments they were started with. There are safer ways of providing sensitive information to an application than exposing them in the command line. It is common to write them on the process' standard input, or give the path to a file containing the information.

Questionable Code Example

// The process object is a global that provides information about, and control over, the current Node.js process
var param = process.argv[2]; // Questionable: check how the argument is used
console.log('Param: ' + param);

See

javascript:ElseIfWithoutElse

This rule applies whenever an if statement is followed by one or more else if statements; the final else if should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch statement.

Noncompliant Code Example

if (x == 0) {
  doSomething();
} else if (x == 1) {
  doSomethingElse();
}

Compliant Solution

if (x == 0) {
  doSomething();
} else if (x == 1) {
  doSomethingElse();
} else {
  throw "Unexpected value for x";
}

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
javascript:NonEmptyCaseWithoutBreak

When the execution is not explicitly terminated at the end of a switch case, it continues to execute the statements of the following case. While this is sometimes intentional, it often is a mistake which leads to unexpected behavior.

Noncompliant Code Example

switch (myVariable) {
  case 1:
    foo();
    break;
  case 2:  // Both 'doSomething()' and 'doSomethingElse()' will be executed. Is it on purpose ?
    doSomething();
  default:
    doSomethingElse();
    break;
}

Compliant Solution

switch (myVariable) {
  case 1:
    foo();
    break;
  case 2:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Exceptions

This rule is relaxed in the following cases:

switch (myVariable) {
  case 0:                                // Empty case used to specify the same behavior for a group of cases.
  case 1:
    doSomething();
    break;
  case 2:                                // Use of return statement
    return;
  case 3:                               // Ends with comment when fall-through is intentional
    console.log("this case falls through")
    // fall through
  case 4:                                // Use of throw statement
    throw new IllegalStateException();
  case 5:                                // Use of continue statement
    continue;
  default:                               // For the last case, use of break statement is optional
    doSomethingElse();
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.2 - An unconditional break statement shall terminate every non-empty switch clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-5 - An unconditional throw or break statement shall terminate every non-empty switch-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.3 - An unconditional break statement shall terminate every switch-clause
  • MITRE, CWE-484 - Omitted Break Statement in Switch
  • CERT, MSC17-C. - Finish every set of statements associated with a case label with a break statement
  • CERT, MSC52-J. - Finish every set of statements associated with a case label with a break statement
javascript:S888

Testing for loop termination using an equality operator (== and !=) is dangerous, because it could set up an infinite loop. Using a broader relational operator instead casts a wider net, and makes it harder (but not impossible) to accidentally write an infinite loop.

Noncompliant Code Example

for (var i = 1; i != 10; i += 2)  // Noncompliant. Infinite; i goes from 9 straight to 11.
{
  //...
}

Compliant Solution

for (var i = 1; i <= 10; i += 2)  // Compliant
{
  //...
}

Exceptions

Equality operators are ignored if the loop counter is not modified within the body of the loop and either:

  • starts below the ending value and is incremented by 1 on each iteration.
  • starts above the ending value and is decremented by 1 on each iteration.

Equality operators are also ignored when the test is against null.

for (var i = 0; arr[i] != null; i++) {
  // ...
}

for (var i = 0; (item = arr[i]) != null; i++) {
  // ...
}

See

  • MISRA C++:2008, 6-5-2
  • MITRE, CWE-835 - Loop with Unreachable Exit Condition ('Infinite Loop')
  • CERT, MSC21-C. - Use robust loop termination conditions
javascript:S1442

alert(...) as well as confirm(...) and prompt(...) can be useful for debugging during development, but in production mode this kind of pop-up could expose sensitive information to attackers, and should never be displayed.

Noncompliant Code Example

if(unexpectedCondition) {
  alert("Unexpected Condition");
}

See

javascript:S5122

Enabling Cross-Origin Resource Sharing (CORS) is security-sensitive. For example, it has led in the past to the following vulnerabilities:

Applications that enable CORS will effectively relax the same-origin policy in browsers, which is in place to prevent AJAX requests to hosts other than the one showing in the browser address bar. Being too permissive, CORS can potentially allow an attacker to gain access to sensitive information.

This rule flags code that enables CORS or specifies any HTTP response headers associated with CORS. The goal is to guide security code reviews.

Ask Yourself Whether

  • Any URLs responding with Access-Control-Allow-Origin: * include sensitive content.
  • Any domains specified in Access-Control-Allow-Origin headers are checked against a whitelist.

Recommended Secure Coding Practices

  • The Access-Control-Allow-Origin header should be set only on specific URLs that require access from other domains. Don't enable the header on the entire domain.
  • Don't rely on the Origin header blindly without validation as it could be spoofed by an attacker. Use a whitelist to check that the Origin domain (including protocol) is allowed before returning it back in the Access-Control-Allow-Origin header.
  • Use Access-Control-Allow-Origin: * only if your application absolutely requires it, for example in the case of an open/public API. For such endpoints, make sure that there is no sensitive content or information included in the response.

Questionable Code Example

// === NodeJS built-in modules ===
const http = require('http');
const srv = http.createServer((req, res) => {
  res.writeHead(200, { 'Access-Control-Allow-Origin': '*' }); // Questionable
  res.end('ok');
});
srv.listen(3000);
// === ExpressJS ===
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors()); // Questionable
app.get('/product/:id', cors(), function (req, res, next) {}); // Questionable
app.listen(3000);

See

kotlin:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

abap:S4721

OS commands are security-sensitive. For example, their use has led in the past to the following vulnerabilities:

Applications that execute operating system commands or execute commands that interact with the underlying system should neutralize any externally-provided input used to construct those commands. Failure to do so could allow an attacker to execute unexpected or dangerous commands, potentially leading to loss of confidentiality, integrity or availability.

This rule flags code that specifies the name of the command to run. The goal is to guide security code reviews.

Ask Yourself Whether

  • the executed command is constructed by input that is externally-influenced, for example, user input (attacker). (*)
  • the command execution is not restricted to the right users. (*)
  • the application can be redesigned to not rely on external input to execute the command.

(*) You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Restrict the control given to the user over the executed command:

  • make the executed command part of a whitelist and reject all commands not part of this list.
  • sanitize the user input.

Restrict which users can have access to the command:

  • use a firewall to protect the process running the code, and to protect the network from the command.
  • authenticate the user and allow only some users to run the command.

Reduce the damage the command can do:

  • execute the code in a sandbox environment that enforces strict boundaries between the operating system and the process. For example: a "jail".
  • refuse to run the command if the process has too many privileges. For example: forbid running the code as "root".

Noncompliant Code Example

CALL 'SYSTEM' ID 'COMMAND' FIELD usr_input ID 'TAB' FIELD TAB1.  " Noncompliant

See

abap:S4524

CASE can contain a WHEN OTHERS clause for various reasons: to handle unexpected values, to show that all the cases were properly considered.

For readability purpose, to help a developer to quickly find the default behavior of a CASE statement, it is recommended to put the WHEN OTHERS clause at the end of the CASE statement. This rule raises an issue if the WHEN OTHERS clause is not the last one of the CASE's cases.

Noncompliant Code Example

CASE SY-INDEX.
  WHEN OTHERS.   // Noncompliant; WHEN OTHERS should be last statement
    WRITE 'Unexpected result'
  WHEN ONE.
    WRITE  'One'.
  WHEN 2.
    WRITE   'Two'.
ENDCASE.

Compliant Solution

CASE SY-INDEX.
  WHEN ONE.
    WRITE  'One'.
  WHEN 2.
    WRITE   'Two'.
  WHEN OTHERS. // Compliant
    WRITE 'Unexpected result'
ENDCASE.


See

  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
abap:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

Noncompliant Code Example

DATA: password(10) VALUE 'secret123',
           pwd(10) VALUE 'secret123'.

See

abap:S1493

There are two main reasons to ban dynamic clauses in SELECT statements.

The first relates to maintainability. One of the nice features of ABAP Design Time is the connection to the data dictionary; you get syntax errors if you try to address table fields that are not present anymore or that have typos. With dynamic SQL, the ability to statically check the code for this type of error is lost.

The other more critical reason relates to security. By definition, dynamic clauses make an application susceptible to SQL injection attacks.

Noncompliant Code Example

SELECT (select_clause)
 FROM (from_clause) CLIENT SPECIFIED INTO <fs>
 WHERE (where_clause)
 GROUP BY (groupby_clause) HAVING (having_clause)
 ORDER BY (orderby_clause).

See

abap:S108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

IF A = 0. " Noncompliant
ELSEIF A > 1. " Noncompliant
ELSE. " Noncompliant
ENDIF.

Exceptions

When a block contains a comment, this block is not considered to be empty.

abap:S1301

CASE statements are useful when there are many different cases depending on the value of the same expression.

For just one or two cases however, the code will be more readable with IF statements.

Noncompliant Code Example

CASE SY-INDEX.
  WHEN ONE.
    WRITE  'One'.
  WHEN 2.
    WRITE  'Two'.
ENDCASE.

Compliant Solution

CASE SY-INDEX.
  WHEN ONE.
    WRITE  'One'.
  WHEN 2.
    WRITE  'Two'.
  WHEN OTHERS.
    WRITE 'Unexpected result'
ENDCASE.

See

  • MISRA C:2012, 16.6 - Every switch statement shall have at least two switch-clauses
abap:S1313

Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:

Today's services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery and deployment:

  • The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
  • It forces the same address to be used in every environment (dev, sys, qa, prod).

Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service at this address or spoof the IP address. Such an attack is always possible, but in the case of a hardcoded IP address the fix will be much slower, which will increase an attack's impact.

Recommended Secure Coding Practices

  • make the IP address configurable.

Noncompliant Code Example

DATA: ip TYPE string VALUE '192.168.12.42'.

Exceptions

No issue is reported for the following cases because they are not considered sensitive:

  • Loopback addresses 127.0.0.0/8 in CIDR notation (from 127.0.0.0 to 127.255.255.255)
  • Broadcast address 255.255.255.255
  • Non routable address 0.0.0.0
  • Strings of the form 2.5.<number>.<number> as they often match Object Identifiers (OID).

See

abap:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

abap:S5117

Every AUTHORITY-CHECK statement sets the fields SY-SUBRC (also accessible as SYST-SUBRC) to the authorization check result. Thus SY-SUBRC value should be checked just after every AUTHORITY-CHECK statement.

Noncompliant Code Example

AUTHORITY-CHECK OBJECT 'S_MYOBJ' "Noncompliant
    ID 'ID1' FIELD myvalue.

Compliant Solution

AUTHORITY-CHECK OBJECT 'S_MYOBJ'  "Compliant
    ID 'ID1' FIELD myvalue.

  IF sy-subrc <> 0.
    MESSAGE 'NOT AUTHORIZED' TYPE 'E'.
  ENDIF.

Exceptions

No issue will be raised in the following cases:

  • One or more WRITE operation are performed between the AUTHORITY-CHECK statement and SY-SUBRC check. An exception will be however raised if the WRITE operation is a WRITE ... TO statement, as this will set again SY-SUBRC.
  • SY-SUBRC's value is assigned to a variable. We then assume that it will be checked later.
AUTHORITY-CHECK OBJECT 'S_MYOBJ'  "Compliant
    ID 'ID1' FIELD myvalue.
WRITE 'Test' " WRITE is accepted before checking SY-SUBRC
IF SY-SUBRC <> 0.
    EXIT.
ENDIF.

AUTHORITY-CHECK OBJECT 'S_MYOBJ'  "Compliant
    ID 'ID1' FIELD myvalue.
Tmp = SY-SUBRC " Assigning SY-SUBRC value to a variable. We assume that it will be checked later.
IF Tmp <> 0.
    EXIT.
ENDIF.
abap:S1511

The system field SY-SUBRC must be tested immediately after any statement setting this variable. Reading this variable informs on previous operation success or errors. Such errors should be handled properly so that the program continues in a consistent state.

This rule raises an issue when the field SY-SUBRC is not checked just after performing one of the following operations:

* Calling a function which can throw exceptions.

* Calling one of the file access operation OPEN DATASET, READ DATASET or DELETE DATASET.

SY-SUBRC check must be done either with the CASE, IF or CHECK statement.

Noncompliant Code Example

In the following case nothing happens if the exceptions NOT_FOUND or OTHERS are raised:

CALL FUNCTION 'STRING_SPLIT'
  EXPORTING
    DELIMITER = ':'
    STRING = FELD
  IMPORTING
    HEAD =   HEAD
    TAIL = TAIL
  EXCEPTIONS
    NOT_FOUND = 1
    OTHERS = 2.

Compliant Solution

CALL FUNCTION 'STRING_SPLIT'
  EXPORTING
    DELIMITER = ':'
    STRING = FELD
  IMPORTING
    HEAD =   HEAD
    TAIL = TAIL
  EXCEPTIONS
    NOT_FOUND = 1
    OTHERS = 2.
CASE SY-SUBRC.
  WHEN 1. ...
  WHEN 2. ...
  WHEN OTHER.
ENDCASE.

Exceptions

No issue will be raised in the following cases:

* One or more WRITE operation are performed between the statement setting SY-SUBRC and its check. An exception will be however raised if the WRITE operation is a WRITE ... TO, as this will set SY-SUBRC too.

* SY-SUBRC's value is assigned to a variable. We then assume that it will be checked later.

OPEN DATASET my_dataset FOR INPUT IN TEXT MODE ENCODING DEFAULT. " Compliant
WRITE 'Test'. " WRITE is accepted before checking SY-SUBRC
IF SY-SUBRC <> 0.
    EXIT.
ENDIF.

OPEN DATASET my_dataset FOR INPUT IN TEXT MODE ENCODING DEFAULT. " Compliant
Tmp = SY-SUBRC. " Assigning SY-SUBRC value to a variable. We assume that it will be checked later.
IF Tmp <> 0.
    EXIT.
ENDIF.
abap:S5118

The READ TABLE ... WITH KEY ... statement performs a linear search of STANDARD tables, which is very inefficient in most cases.

This rule raises an issue when a READ TABLE ... WITH KEY ... statement does not finish with BINARY SEARCH. No issue will be raised for HASHED and SORTED tables.

Noncompliant Code Example

TYPES BEGIN OF t_mytable,
    myfield TYPE i
END OF t_mytable.

DATA myworkarea TYPE t_mytable.

DATA mytable TYPE STANDARD TABLE OF t_mytable.

SORT mytable BY myfield.

READ TABLE mytable
    WITH KEY myfield = 42
    INTO myworkarea. " Noncompliant

Compliant Solution

TYPES BEGIN OF t_mytable,
    myfield TYPE i
END OF t_mytable.

DATA myworkarea TYPE t_mytable.

DATA mytable TYPE STANDARD TABLE OF t_mytable.

SORT mytable BY myfield.

READ TABLE mytable
    WITH KEY myfield = 42
    INTO myworkarea
    BINARY SEARCH. " Compliant

DATA my_hashed_table TYPE HASHED TABLE OF t_mytable
    WITH UNIQUE KEY myfield.

DATA my_sorted_table TYPE SORTED TABLE OF t_mytable
    WITH UNIQUE KEY myfield.

READ TABLE my_hashed_table
    WITH KEY myfield = 42
    INTO myworkarea. " Compliant

READ TABLE my_sorted_table
    WITH KEY myfield = 42
    INTO myworkarea. " Compliant
abap:S131

The requirement for an OTHERS clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken.

Noncompliant Code Example

CASE SY-INDEX.   // Noncompliant; missing WHEN OTHERS clause
  WHEN ONE.
    WRITE  'One'.
  WHEN 2.
    WRITE   'Two'.
ENDCASE.

Compliant Solution

CASE SY-INDEX.
  WHEN ONE.
    WRITE  'One'.
  WHEN 2.
    WRITE   'Two'.
  WHEN OTHERS. // Compliant
    WRITE 'Unexpected result'
ENDCASE.

CASE SY-INDEX.
  WHEN OTHERS.   // Compliant
    WRITE 'Unexpected result'
  WHEN ONE.
    WRITE  'One'.
  WHEN 2.
    WRITE   'Two'.
ENDCASE.

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
  • MITRE, CWE-478 - Missing Default Case in Switch Statement
  • CERT, MSC01-C. - Strive for logical completeness
abap:S5115

Checking logged users' permissions by comparing their name to a hardcoded string can create security vulnerabilities. It prevents system administrators from changing users' permissions when needed (example: when their account has been compromised). Thus system fields SY-UNAME and SYST-UNAME should not be compared to hardcoded strings. Use instead AUTHORITY-CHECK to check users' permissions.

This rule raises an issue when either of the system fields SY-UNAME or SYST-UNAME are compared to a hardcoded value in a CASE statement or using one of the following operators: =, EQ, <>, NE.

Noncompliant Code Example

IF SY-UNAME = 'ALICE'. " Noncompliant
ENDIF.

CASE SY-UNAME.
WHEN 'A'. " Noncompliant
ENDCASE.

Compliant Solution

AUTHORITY-CHECK OBJECT 'S_CARRID'
  ID 'CARRID' FIELD mycarrid.
IF sy-subrc <> 0.
  MESSAGE 'Not authorized' TYPE 'E'.
ENDIF.
abap:S1238

Passing parameters by reference instead of by value avoids the overhead of making a copy. Passing arguments via copy should only be done when it is technically mandated, as it is for example with RFC function modules.

Noncompliant Code Example

PERFORM subr USING a1 a2 a3 a4 a5.

Compliant Solution

PERFORM subr CHANGING a1 a2 a3 a4 a5.
abap:S125

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
abap:S126

This rule applies whenever an IF statement is followed by one or

more ELSEIF statements; the final ELSEIF should be followed by an ELSE statement.

The requirement for a final ELSE statement is defensive programming.

The ELSE statement should either take appropriate action or contain

a suitable comment as to why no action is taken. This is consistent with the

requirement to have a final OTHERS clause in a CASE

statement.

Noncompliant Code Example

IF RESULT > 0.
  PERFORM do_something.
ELSEIF RESULT = 0.
  PERFORM do_something_else.
ENDIF.

Compliant Solution

IF RESULT > 0.
  PERFORM do_something.
ELSEIF RESULT = 0.
  PERFORM do_something_else.
ELSE.
  PERFORM error.
ENDIF.

Exceptions

When all branches of an if-else if end with return, break or throw, the code that comes after the if implicitly behaves as if it was in an else clause. This rule will therefore ignore that case.

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
abap:S1486

A BREAK-POINT statement is used when debugging an application with help of the ABAP Debugger. But such debugging statements could make an application vulnerable to attackers, and should not be left in the source code.

Noncompliant Code Example

IF wv_parallel EQ 'X'.
  BREAK-POINT.
  WAIT UNTIL g_nb_return EQ wv_nb_call.
ENDIF.

Compliant Solution

IF wv_parallel EQ 'X'.
  WAIT UNTIL g_nb_return EQ wv_nb_call.
ENDIF.

See

abap:S2809

Using "CALL TRANSACTION" statements without an authority check is security sensitive. Its access should be restricted to specific users.

This rule raises when a CALL TRANSACTION has no explicit authorization check, i.e. when:

* the CALL TRANSACTION statement is not followed by WITH AUTHORITY-CHECK.

* the CALL TRANSACTION statement is not following an AUTHORITY-CHECK statement.

  • the CALL TRANSACTION statement is not following a call to the AUTHORITY_CHECK_TCODE function.

Ask Yourself Whether

* the CALL TRANSACTION statement is restricted to the right users.

You are at risk if you answered no to this question.

Recommended Secure Coding Practices

Check current user's authorization before every CALL TRANSACTION statement. Since ABAP 7.4 this should be done by appending WITH AUTHORITY-CHECK to CALL TRANSACTION statements. In earlier versions the AUTHORITY-CHECK statement or a call to the AUTHORITY_CHECK_TCODE function can be used.

Note that since ABAP 7.4 any CALL TRANSACTION statement not followed by WITH AUTHORITY-CHECK or WITHOUT AUTHORITY-CHECK is obsolete.

Sensitive Code Example

CALL TRANSACTION 'MY_DIALOG'.  " Sensitive as there is no apparent authorization check. It is also obsolete since ABAP 7.4.

Compliant Solution

AUTHORITY-CHECK OBJECT 'S_DIAGID'
                  ID 'ACTVT' FIELD '03'.
IF sy-subrc <> 0.
  " show an error message...
ENDIF.

CALL TRANSACTION 'MY_DIALOG'. " Ok but obsolete since ABAP 7.4.

or

CALL FUNCTION 'AUTHORITY_CHECK_TCODE'
  exporting
    tcode  = up_fdta
  exceptions
    ok     = 0
    others = 4.
CALL TRANSACTION up_fdta USING up_bdc mode 'E'. " Ok but obsolete since ABAP 7.4.

or

CALL TRANSACTION 'MY_DIALOG' WITH AUTHORITY-CHECK. " Recommended way since ABAP 7.4.

Exceptions

No issue will be raised when CALL TRANSACTION is followed by WITHOUT AUTHORITY-CHECK as it explicitly says that the TRANSACTION does not require an authorization check.

See

* OWASP Top 10 2017 Category A2 - Broken Authentication

* MITRE, CWE-285 - Improper Authorization

* MITRE, CWE-862 - Missing Authorization

* SANS Top 25 - Porous Defenses

abap:S4790

Hashing data is security-sensitive. It has led in the past to the following vulnerabilities:

Cryptographic hash functions are used to uniquely identify information without storing their original form. When not done properly, an attacker can steal the original information by guessing it (ex: with a rainbow table), or replace the original data with another one having the same hash.

This rule raises an issue when MD5_CALCULATE_HASH_FOR_RAW or MD5_CALCULATE_HASH_FOR_CHAR functions are used.

Ask Yourself Whether

  • the hashed value is used in a security context.
  • the hashing algorithm you are using is known to have vulnerabilities.
  • salts are not automatically generated and applied by the hashing function.
  • any generated salts are cryptographically weak or not credential-specific.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

  • for security related purposes, use only hashing algorithms which are currently known to be strong. Avoid using algorithms like MD5 and SHA1 completely in security contexts.
  • do not define your own hashing- or salt algorithms as they will most probably have flaws.
  • do not use algorithms that compute too quickly, like SHA256, as it must remain beyond modern hardware capabilities to perform brute force and dictionary based attacks.
  • use a hashing algorithm that generate its own salts as part of the hashing. If you generate your own salts, make sure that a cryptographically strong salt algorithm is used, that generated salts are credential-specific, and finally, that the salt is applied correctly before the hashing.
  • save both the salt and the hashed value in the relevant database record; during future validation operations, the salt and hash can then be retrieved from the database. The hash is recalculated with the stored salt and the value being validated, and the result compared to the stored hash.
  • the strength of hashing algorithms often decreases over time as hardware capabilities increase. Check regularly that the algorithms you are using are still considered secure. If needed, rehash your data using a stronger algorithm.

See

squid:S2225

Calling toString() or clone() on an object should always return a string or an object. Returning null instead contravenes the method's implicit contract.

Noncompliant Code Example

public String toString () {
  if (this.collection.isEmpty()) {
    return null; // Noncompliant
  } else {
    // ...

Compliant Solution

public String toString () {
  if (this.collection.isEmpty()) {
    return "";
  } else {
    // ...

See

squid:S2589

If a boolean expression doesn't change the evaluation of the condition, then it is entirely unnecessary, and can be removed. If it is gratuitous because it does not match the programmer's intent, then it's a bug and the expression should be fixed.

Noncompliant Code Example

a = true;
if (a) { // Noncompliant
  doSomething();
}

if (b && a) { // Noncompliant; "a" is always "true"
  doSomething();
}

if (c || !a) { // Noncompliant; "!a" is always "false"
  doSomething();
}

Compliant Solution

a = true;
if (foo(a)) {
  doSomething();
}

if (b) {
  doSomething();
}

if (c) {
  doSomething();
}

See

  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
  • MITRE, CWE-571 - Expression is Always True
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-489 - Leftover Debug Code
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
squid:S3436

According to the documentation,

A program may produce unpredictable results if it attempts to distinguish two references to equal values of a value-based class, whether directly via reference equality or indirectly via an appeal to synchronization...

This is because value-based classes are intended to be wrappers for value types, which will be primitive-like collections of data (similar to structs in other languages) that will come in future versions of Java.

Instances of a value-based class ...

  • do not have accessible constructors, but are instead instantiated through factory methods which make no committment as to the identity of returned instances;

Which means that you can't be sure you're the only one trying to lock on any given instance of a value-based class, opening your code up to contention and deadlock issues.

Under Java 8 breaking this rule may not actually break your code, but there are no guarantees of the behavior beyond that.

This rule raises an issue when a known value-based class is used for synchronization. That includes all the classes in the java.time package except Clock; the date classes for alternate calendars, HijrahDate, JapaneseDate, MinguoDate, ThaiBuddhistDate; and the optional classes: Optional, OptionalDouble, OptionalLong, OptionalInt.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 8.

Noncompliant Code Example

Optional<Foo> fOpt = doSomething();
synchronized (fOpt) {  // Noncompliant
  // ...
}

See

squid:S4524

switch can contain a default clause for various reasons: to handle unexpected values, to show that all the cases were properly considered.

For readability purpose, to help a developer to quickly find the default behavior of a switch statement, it is recommended to put the default clause at the end of the switch statement. This rule raises an issue if the default clause is not the last one of the switch's cases.

Noncompliant Code Example

switch (param) {
  case 0:
    doSomething();
    break;
  default: // default clause should be the last one
    error();
    break;
  case 1:
    doSomethingElse();
    break;
}

Compliant Solution

switch (param) {
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
  default:
    error();
    break;
}

See

  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
squid:S2583

Conditional expressions which are always true or false can lead to dead code. Such code is always buggy and should never be used in production.

Noncompliant Code Example

a = false;
if (a) { // Noncompliant
  doSomething(); // never executed
}

if (!a || b) { // Noncompliant; "!a" is always "true", "b" is never evaluated
  doSomething();
} else {
  doSomethingElse(); // never executed
}

Exceptions

This rule will not raise an issue in either of these cases:

  • When the condition is a single final boolean
final boolean debug = false;
//...
if (debug) {
  // Print something
}
  • When the condition is literally true or false.
if (true) {
  // do something
}

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

See

  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
squid:S3439

DefaultMessageListenerContainer is implemented as a JMS poller. While the Spring container is shutting itself down, as each in-progress JMS Consumer.receive() call completes, any non-null return value will be a JMS message that the DMLC will discard due to the shutdown in progress. That will result in the received message never being processed.

To prevent message loss during restart operations, set acceptMessagesWhileStopping to true so that such messages will be processed before shut down.

Noncompliant Code Example

<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">  <!-- Noncompliant -->
   <property name="connectionFactory" ref="connFactory" />
   <property name="destination" ref="dest" />
   <property name="messageListener" ref="serviceAdapter" />
   <property name="autoStartup" value="true" />
   <property name="concurrentConsumers" value="10" />
   <property name="maxConcurrentConsumers" value="10" />
   <property name="clientId" value="myClientID" />
</bean>

Compliant Solution

<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
   <property name="connectionFactory" ref="connFactory" />
   <property name="destination" ref="dest" />
   <property name="messageListener" ref="serviceAdapter" />
   <property name="autoStartup" value="true" />
   <property name="concurrentConsumers" value="10" />
   <property name="maxConcurrentConsumers" value="10" />
   <property name="clientId" value="myClientID" />
   <property name="acceptMessagesWhileStopping" value="true" />
</bean>
squid:S3437

According to the documentation,

A program may produce unpredictable results if it attempts to distinguish two references to equal values of a value-based class, whether directly via reference equality or indirectly via an appeal to synchronization, identity hashing, serialization...

For example (credit to Brian Goetz), imagine Foo is a value-based class:

Foo[] arr = new Foo[2];
arr[0] = new Foo(0);
arr[1] = new Foo(0);

Serialization promises that on deserialization of arr, elements 0 and 1 will not be aliased. Similarly, in:

Foo[] arr = new Foo[2];
arr[0] = new Foo(0);
arr[1] = arr[0];

Serialization promises that on deserialization of arr, elements 0 and 1 will be aliased.

While these promises are coincidentally fulfilled in current implementations of Java, that is not guaranteed in the future, particularly when true value types are introduced in the language.

This rule raises an issue when a Serializable class defines a non-transient, non-static field field whose type is a known serializable value-based class. Known serializable value-based classes are: all the classes in the java.time package except Clock; the date classes for alternate calendars: HijrahDate, JapaneseDate, MinguoDate, ThaiBuddhistDate.

Noncompliant Code Example

class MyClass implements Serializable {
  private HijrahDate date;  // Noncompliant; mark this transient
  // ...
}

Compliant Solution

class MyClass implements Serializable {
  private transient HijrahDate date;
  // ...
}

See

squid:S864

The rules of operator precedence are complicated and can lead to errors. For this reason, parentheses should be used for clarification in complex statements. However, this does not mean that parentheses should be gratuitously added around every operation.

This rule raises issues when && and || are used in combination, when assignment and equality or relational operators are used in together in a condition, and for other operator combinations according to the following table:

+, -, *, /, % <<, >>, >>> & ^ |
+, -, *, /, % x x x x
<<, >>, >>> x x x x
& x x x x
^ x x x x
| x x x x

Noncompliant Code Example

x = a + b - c;
x = a + 1 << b;  // Noncompliant

if ( a > b || c < d || a == d) {...}
if ( a > b && c < d || a == b) {...}  // Noncompliant
if (a = f(b,c) == 1) { ... } // Noncompliant; == evaluated first

Compliant Solution

x = a + b - c;
x = (a + 1) << b;

if ( a > b || c < d || a == d) {...}
if ( (a > b && c < d) || a == b) {...}
if ( (a = f(b,c)) == 1) { ... }

See

  • MISRA C:2004, 12.1 - Limited dependence should be placed on C's operator precedence rules in expressions
  • MISRA C:2004, 12.2 - The value of an expression shall be the same under any order of evaluation that the standard permits.
  • MISRA C:2004, 12.5 - The operands of a logical && or || shall be primary-expressions.
  • MISRA C++:2008, 5-0-1 - The value of an expression shall be the same under any order of evaluation that the standard permits.
  • MISRA C++:2008, 5-0-2 - Limited dependence should be placed on C++ operator precedence rules in expressions
  • MISRA C++:2008, 5-2-1 - Each operand of a logical && or || shall be a postfix-expression.
  • MISRA C:2012, 12.1 - The precedence of operators within expressions should be made explicit
  • CERT, EXP00-C. - Use parentheses for precedence of operation
  • CERT, EXP53-J. - Use parentheses for precedence of operation
  • MITRE, CWE-783 - Operator Precedence Logic Error
squid:S2115

Failure to password-protect a database is so careless or naive as to be almost negligent. Databases should always be password protected, but the use of a database connection with an empty password is a clear indication of a database that is not protected.

This rule flags database connections with empty passwords.

Noncompliant Code Example

Connection conn = DriverManager.getConnection("jdbc:derby:memory:myDB;create=true", "AppLogin", "");
Connection conn2 = DriverManager.getConnection("jdbc:derby:memory:myDB;create=true?user=user&password=");

Compliant Solution

DriverManager.getConnection("jdbc:derby:memory:myDB;create=true?user=user&password=password");

DriverManager.getConnection("jdbc:mysql://address=(host=myhost1)(port=1111)(key1=value1)(user=sandy)(password=secret),address=(host=myhost2)(port=2222)(key2=value2)(user=sandy)(password=secret)/db");

DriverManager.getConnection("jdbc:mysql://sandy:secret@[myhost1:1111,myhost2:2222]/db");

String url = "jdbc:postgresql://localhost/test";
Properties props = new Properties();
props.setProperty("user", "fred");
props.setProperty("password", "secret");
DriverManager.getConnection(url, props);

See

squid:S1148

Throwable.printStackTrace(...) prints a Throwable and its stack trace to some stream. By default that stream System.Err, which could inadvertently expose sensitive information.

Loggers should be used instead to print Throwables, as they have many advantages:

  • Users are able to easily retrieve the logs.
  • The format of log messages is uniform and allow users to browse the logs easily.

This rule raises an issue when printStackTrace is used without arguments, i.e. when the stack trace is printed to the default stream.

Noncompliant Code Example

try {
  /* ... */
} catch(Exception e) {
  e.printStackTrace();        // Noncompliant
}

Compliant Solution

try {
  /* ... */
} catch(Exception e) {
  LOGGER.log("context", e);
}

See

squid:S1145

if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.

There are three possible causes for the presence of such code:

  • An if statement was changed during debugging and that debug code has been committed.
  • Some value was left unset.
  • Some logic is not doing what the programmer thought it did.

In any of these cases, unconditional if statements should be removed.

Noncompliant Code Example

if (true) {
  doSomething();
}
...
if (false) {
  doSomethingElse();
}

if (2 < 3 ) { ... }  // Noncompliant; always false

int i = 0;
int j = 0;
// ...
j = foo();

if (j > 0 && i > 0) { ... }  // Noncompliant; always false - i never set after initialization

boolean b = true;
//...
if (b || !b) { ... }  // Noncompliant

Compliant Solution

doSomething();
...

See

  • MITRE, CWE-489 - Leftover Debug Code
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant

Deprecated

This rule is deprecated; use S2583 instead.

squid:S4530

Using Struts 1 ActionForm is security-sensitive. For example, their use has led in the past to the following vulnerability:

All classes extending org.apache.struts.action.Action are potentially remotely reachable. The ActionForm object provided as a parameter of the execute method is automatically instantiated and populated with the HTTP parameters. One should review the use of these parameters to be sure they are used safely.

This rule is there to allow a security auditor to quickly find some potential hotspots to review.

Ask Yourself Whether

  • some parameters of the ActionForm might not have been validated properly.
  • dangerous parameter names are accepted. Example: accept a "class" parameter and use the form to populate JavaBean properties (see the CVE-2014-0114 above).
  • there are unused fields which are not empty or undefined.

You are at risk if you answered to any of these questions.

Recommended Secure Coding Practices

All ActionForm's properties should be validated, including their size. Whenever possible, filter the parameters with a whitelist of valid values. Otherwise, escape any sensitive character and constrain the values as much as possible.

Allow only non security-sensitive property names. All the ActionForm's property names should be whitelisted.

Unused fields should be constrained so that they are either empty or undefined.

Noncompliant Code Example

// Struts 1.1+
public final class CashTransferAction extends Action {

  public String fromAccount = "";
  public String toAccount = "";

  public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse res) throws Exception {
    // usage of the "form" object to call some services doing JDBC actions
    [...]
    return mapping.findForward(resultat);
  }
}

See

squid:S4531

Using setters in Struts 2 ActionSupport is security-sensitive. For example, their use has led in the past to the following vulnerabilities:

All classes extending com.opensymphony.xwork2.ActionSupport are potentially remotely reachable. An action class extending ActionSupport will receive all HTTP parameters sent and these parameters will be automatically mapped to the setters of the Struts 2 action class. One should review the use of the fields set by the setters, to be sure they are used safely. By default, they should be considered as untrusted inputs.

This rule is there to allow a security auditor to quickly find some potential hotspots to review.

Ask Yourself Whether

  • the setter is needed. There is no need for it if the attribute's goal is not to map queries' parameter.
  • the value provided to the setter is properly sanitized before being used or stored. (*)

(*) You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

As said in Strut's documentation: "Do not define setters when not needed"

Sanitize the user input. This can be for example done by implementing the validate() method of com.opensymphony.xwork2.ActionSupport.

Noncompliant Code Example

public class AccountBalanceAction extends ActionSupport {
  private static final long serialVersionUID = 1L;
  private Integer accountId;

  // this setter might be called with user input
  public void setAccountId(Integer accountId) {
    this.accountId = accountId;
  }

  @Override
  public String execute() throws Exception {
    // call a service to get the account's details and its balance
    [...]
    return SUCCESS;
  }
}

See

squid:S881

The use of increment and decrement operators in method calls or in combination with other arithmetic operators is not recommended, because:

  • It can significantly impair the readability of the code.
  • It introduces additional side effects into a statement, with the potential for undefined behavior.
  • It is safer to use these operators in isolation from any other arithmetic operators.

Noncompliant Code Example

u8a = ++u8b + u8c--;
foo = bar++ / 4;

Compliant Solution

The following sequence is clearer and therefore safer:

++u8b;
u8a = u8b + u8c;
u8c--;
foo = bar / 4;
bar++;

See

  • MISRA C:2004, 12.1 - Limited dependence should be placed on the C operator precedence rules in expressions.
  • MISRA C:2004, 12.13 - The increment (++) and decrement (--) operators should not be mixed with other operators in an expression.
  • MISRA C++:2008, 5-2-10 - The increment (++) and decrement (--) operator should not be mixed with other operators in an expression.
  • MISRA C:2012, 12.1 - The precedence of operators within expressions should be made explicit
  • MISRA C:2012, 13.3 - A full expression containing an increment (++) or decrement (--) operator should have no other potential side effects other than that cause by the increment or decrement operator
  • CERT, EXP30-C. - Do not depend on the order of evaluation for side effects
  • CERT, EXP50-CPP. - Do not depend on the order of evaluation for side effects
  • CERT, EXP05-J. - Do not follow a write by a subsequent write or read of the same object within an expression
squid:S3329

In encryption, when Cipher Block Chaining (CBC) is used, the Initialization Vector (IV) must be random and unpredictable. Otherwise, the encrypted value is vulnerable to crypto-analysis attacks such as the "Chosen-Plaintext Attack".

An IV value should be associated to one, and only one encryption cycle, because the IV's purpose is to ensure that the same plaintext encrypted twice will yield two different ciphertexts.

To that end, IV's should be:

  • random
  • unpredictable
  • publishable (IVs are frequently published)
  • authenticated, along with the ciphertext, with a Message Authentication Code (MAC)

This rule raises an issue when the IV is:

  • hard-coded
  • created using java.util.Random rather than java.security.SecureRandom.

Noncompliant Code Example

public class MyCbcClass {

  public String applyCBC(String strKey, String plainText) {
    byte[] bytesIV = "7cVgr5cbdCZVw5WY".getBytes("UTF-8");

    /* KEY + IV setting */
    IvParameterSpec iv = new IvParameterSpec(bytesIV);
    SecretKeySpec skeySpec = new SecretKeySpec(strKey.getBytes("UTF-8"), "AES");

    /* Ciphering */
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);  // Noncompliant because IV hard coded and cannot vary with each ciphering round
    byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
    return DatatypeConverter.printBase64Binary(bytesIV) // IV is typically published
            + ";" + DatatypeConverter.printBase64Binary(encryptedBytes);
  }
}

Compliant Solution

public class MyCbcClass {

  SecureRandom random = new SecureRandom();

  public String applyCBC(String strKey, String plainText) {
    byte[] bytesIV = new byte[16];
    random.nextBytes(bytesIV);

    /* KEY + IV setting */
    IvParameterSpec iv = new IvParameterSpec(bytesIV);
    SecretKeySpec skeySpec = new SecretKeySpec(strKey.getBytes("UTF-8"), "AES");

    /* Ciphering */
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
    byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
    return DatatypeConverter.printBase64Binary(bytesIV)
            + ";" + DatatypeConverter.printBase64Binary(encryptedBytes);
  }
}

See

  • MITRE, CWE-330 - Use of Insufficiently Random Values
  • OWASP Top 10 2017 Category A6 - Security Misconfiguration
  • Derived from FindSecBugs rule STATIC_IV
squid:S2119

Creating a new Random object each time a random value is needed is inefficient and may produce numbers which are not random depending on the JDK. For better efficiency and randomness, create a single Random, then store, and reuse it.

The Random() constructor tries to set the seed with a distinct value every time. However there is no guarantee that the seed will be random or even uniformly distributed. Some JDK will use the current time as seed, which makes the generated numbers not random at all.

This rule finds cases where a new Random is created each time a method is invoked and assigned to a local random variable.

Noncompliant Code Example

public void doSomethingCommon() {
  Random rand = new Random();  // Noncompliant; new instance created with each invocation
  int rValue = rand.nextInt();
  //...

Compliant Solution

private Random rand = SecureRandom.getInstanceStrong();  // SecureRandom is preferred to Random

public void doSomethingCommon() {
  int rValue = this.rand.nextInt();
  //...

Exceptions

A class which uses a Random in its constructor or in a static main function and nowhere else will be ignored by this rule.

See

squid:S3655

Optional value can hold either a value or not. The value held in the Optional can be accessed using the get() method, but it will throw a

NoSuchElementException if there is no value present. To avoid the exception, calling the isPresent() or ! isEmpty() method should always be done before any call to get().

Alternatively, note that other methods such as orElse(...), orElseGet(...) or orElseThrow(...) can be used to specify what to do with an empty Optional.

Noncompliant Code Example

Optional<String> value = this.getOptionalValue();

// ...

String stringValue = value.get(); // Noncompliant

Compliant Solution

Optional<String> value = this.getOptionalValue();

// ...

if (value.isPresent()) {
  String stringValue = value.get();
}

or

Optional<String> value = this.getOptionalValue();

// ...

String stringValue = value.orElse("default");

See

squid:S3776

Cognitive 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.

See

squid:S2201

When the call to a function doesn't have any side effects, what is the point of making the call if the results are ignored? In such case, either the function call is useless and should be dropped or the source code doesn't behave as expected.

To prevent generating any false-positives, this rule triggers an issue only on the following predefined list of immutable classes in the Java API :

  • java.lang.String
  • java.lang.Boolean
  • java.lang.Integer
  • java.lang.Double
  • java.lang.Float
  • java.lang.Byte
  • java.lang.Character
  • java.lang.Short
  • java.lang.StackTraceElement
  • java.time.DayOfWeek
  • java.time.Duration
  • java.time.Instant
  • java.time.LocalDate
  • java.time.LocalDateTime
  • java.time.LocalTime
  • java.time.Month
  • java.time.MonthDay
  • java.time.OffsetDateTime
  • java.time.OffsetTime
  • java.time.Period
  • java.time.Year
  • java.time.YearMonth
  • java.time.ZonedDateTime
  • java.math.BigInteger
  • java.math.BigDecimal
  • java.util.Optional

Noncompliant Code Example

public void handle(String command){
  command.toLowerCase(); // Noncompliant; result of method thrown away
  ...
}

Compliant Solution

public void handle(String command){
  String formattedCommand = command.toLowerCase();
  ...
}

Exceptions

This rule will not raise an issue when both these conditions are met:

  • The method call is in a try block with an associated catch clause.
  • The method name starts with "parse", "format", "decode" or "valueOf" or the method is String.getBytes(Charset).
private boolean textIsInteger(String textToCheck) {

    try {
        Integer.parseInt(textToCheck, 10); // OK
        return true;
    } catch (NumberFormatException ignored) {
        return false;
    }
}

See

squid:S4502

Spring Security is coming out of the box with a protection against CSRF attacks. With 4.0, this protection is even enabled by default. Spring's recommendation is to "use CSRF protection for any request that could be processed by a browser by normal users". So there is no reason to disable it for standard web applications.

Recommended Secure Coding Practices

  • activate Spring Security's CSRF protection.

Noncompliant Code Example

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
	  http.csrf().disable(); // Noncompliant
	}
}

See

squid:S4508

Deserializing objects is security-sensitive. For example, it has led in the past to the following vulnerabilities:

Object deserialization from an untrusted source can lead to unexpected code execution. ObjectInputStream doesn't provide a way to apply rules on its InputStream argument. Knowing that all serializable classes in the scope of the classloader will be deserialized, there is a possibility that malicious code could be executed during the deserialization phase even if, in the end, a ClassCastException will be raised.

Deserialization takes a stream of bits and turns it into an object. If the stream contains the type of object you expect, all is well. But if you're deserializing untrusted input, and an attacker has inserted some other type of object, you're in trouble. Why? There are a few different attack scenarios, but one widely-documented one goes like this: Deserialization first instantiates an Object, then uses the readObject method to populate it. If the attacker has overridden readObject then he is entirely in control of what code executes during that process. It is only after readObject has completed that your newly-minted Object can be cast to the type you expected. A ClassCastException or ClassNotFoundException will be thrown, but at that point it's too late.

Ask Yourself Whether

  • an attacker could have tampered with the source provided to the deserialization function.
  • you are using an unsafe deserialization function. See the Recommended Secure Coding Practices for examples of safe libraries.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

To prevent insecure deserialization, you should either use look-ahead deserialization (pre-Java 9) or a filter to make sure you're dealing with the correct type of object before you act on it.

Several third-party libraries offer look-ahead deserialization, including:

  • ikkisoft's SerialKiller
  • Apache Commons Class IO's ValidatingObjectInputStream
  • contrast-rO0's SafeObjectInputStream

Note that it is possible to set a deserialization filter at the level of the JVM, but relying on that requires that your environment be configured perfectly. Every time. Additionally, such a filter may have unwanted impacts on other applications in the environment. On the other hand, setting a filter as close as possible to the deserialization that uses it allows you to specify a very narrow, focused filter.

You should also limit access to the serialized source. For example:

  • if it is a file, restrict the access to it.
  • if it comes from the network, restrict who has access to the process, such as with a Firewall or by authenticating the sender first.

See

squid:S4507

Delivering code in production with debug features activated is security-sensitive. It has led in the past to the following vulnerabilities:

An application's debug features enable developers to find bugs more easily. It often gives access to detailed information on both the system running the application and users. Sometime it even enables the execution of custom commands. Thus deploying on production servers an application which has debug features activated is extremely dangerous.

Ask Yourself Whether

  • the code or configuration enabling the application debug features is deployed on production servers.
  • the application runs by default with debug features activated.

You are at risk if you answered yes to any of these questions.

Recommended Secure Coding Practices

The application should run by default in the most secure mode, i.e. as on production servers. This is to prevent any mistake. Enabling debug features should be explicitly asked via a command line argument, an environment variable or a configuration file.

Check that every debug feature is controlled by only very few configuration variables: logging, exception/error handling, access control, etc... It is otherwise very easy to forget one of them.

Do not enable debug features on production servers.

Noncompliant Code Example

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity(debug = true) // Noncompliant
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  // ...
}

Compliant Solution

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity(debug = false) // Compliant
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  // ...
}

See

squid:S3416

It is convention to name each class's logger for the class itself. Doing so allows you to set up clear, communicative logger configuration. Naming loggers by some other convention confuses configuration, and using the same class name for multiple class loggers prevents the granular configuration of each class' logger. Some libraries, such as SLF4J warn about this, but not all do.

This rule raises an issue when a logger is not named for its enclosing class.

Noncompliant Code Example

public class MyClass {
  private final static Logger LOG = LoggerFactory.getLogger(WrongClass.class);  // Noncompliant; multiple classes using same logger
}

Compliant Solution

public class MyClass {
  private final static Logger LOG = LoggerFactory.getLogger(MyClass.class);
}
squid:S4512

Setting JavaBean properties is security sensitive. Doing it with untrusted values has led in the past to the following vulnerability:

JavaBeans can have their properties or nested properties set by population functions. An attacker can leverage this feature to push into the JavaBean malicious data that can compromise the software integrity. A typical attack will try to manipulate the ClassLoader and finally execute malicious code.

This rule raises an issue when:

  • BeanUtils.populate(...) or BeanUtilsBean.populate(...) from Apache Commons BeanUtils are called
  • BeanUtils.setProperty(...) or BeanUtilsBean.setProperty(...) from Apache Commons BeanUtils are called
  • org.springframework.beans.BeanWrapper.setPropertyValue(...) or org.springframework.beans.BeanWrapper.setPropertyValues(...) from Spring is called

Ask Yourself Whether

  • the new property values might have been tampered with or provided by an untrusted source.
  • sensitive properties can be modified, for example: class.classLoader

You are at risk if you answered yes to any of these question.

Recommended Secure Coding Practices

Sanitize all values used as JavaBean properties.

Don't set any sensitive properties. Keep full control over which properties are set. If the property names are provided by an unstrusted source, filter them with a whitelist.

Noncompliant Code Example

Company bean = new Company();
HashMap map = new HashMap();
Enumeration names = request.getParameterNames();
while (names.hasMoreElements()) {
    String name = (String) names.nextElement();
    map.put(name, request.getParameterValues(name));
}
BeanUtils.populate(bean, map); // Noncompliant; "map" is populated with data coming from user input, here "request.getParameterNames()"

See

squid:S1244

Floating point math is imprecise because of the challenges of storing such values in a binary representation. Even worse, floating point math is not associative; push a float or a double through a series of simple mathematical operations and the answer will be different based on the order of those operation because of the rounding that takes place at each step.

Even simple floating point assignments are not simple:

float f = 0.1; // 0.100000001490116119384765625
double d = 0.1; // 0.1000000000000000055511151231257827021181583404541015625

(Results will vary based on compiler and compiler settings);

Therefore, the use of the equality (==) and inequality (!=) operators on float or double values is almost always an error. Instead the best course is to avoid floating point comparisons altogether. When that is not possible, you should consider using one of Java's float-handling Numbers such as BigDecimal which can properly handle floating point comparisons. A third option is to look not for equality but for whether the value is close enough. I.e. compare the absolute value of the difference between the stored value and the expected value against a margin of acceptable error. Note that this does not cover all cases (NaN and Infinity for instance).

This rule checks for the use of direct and indirect equality/inequailty tests on floats and doubles.

Noncompliant Code Example

float myNumber = 3.146;
if ( myNumber == 3.146f ) { //Noncompliant. Because of floating point imprecision, this will be false
  // ...
}
if ( myNumber != 3.146f ) { //Noncompliant. Because of floating point imprecision, this will be true
  // ...
}

if (myNumber < 4 || myNumber > 4) { // Noncompliant; indirect inequality test
  // ...
}

float zeroFloat = 0.0f;
if (zeroFloat == 0) {  // Noncompliant. Computations may end up with a value close but not equal to zero.
}

Exceptions

Since NaN is not equal to itself, the specific case of testing a floating point value against itself is a valid test for NaN and is therefore ignored. Though using Double.isNaN method should be preferred instead, as intent is more explicit.

float f;
double d;
if(f != f) { // Compliant; test for NaN value
  System.out.println("f is NaN");
} else if (f != d) { // Noncompliant
  // ...
}

See

  • MISRA C:2004, 13.3 - Floating-point expressions shall not be tested for equality or inequality.
  • MISRA C++:2008, 6-2-2 - Floating-point expressions shall not be directly or indirectly tested for equality or inequality
squid:S4510

Deserialization from an untrusted source using the XMLDecoder library can lead to unexpected code execution. For example, it has led in the past to the following vulnerability:

XMLDecoder supports arbitrary method invocation. This capability is intended to call setter methods only but nothing prevents the execution of any other method.

This rule raises an issue when XMLDecoder is instantiated. The call to "readObject" is also highlighted to show where the malicious code can be executed.

Ask Yourself Whether

  • the XML input can come from an untrusted source and be tainted by a hacker. (*)
  • you require the advanced functionalities provided by the XMLDecoder class. If you simply need to deserialize XML you can use a more secure deserialization function.

(*) You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

If you only need a simple deserialization, use instead one of the deserialization libraries recommended by OWASP.

If you really need to use XMLDecoder, make sure that the serialized data cannot be tampered with.

Sensitive Code Example

public void decode(InputStream in) {
  XMLDecoder d = new XMLDecoder(in); // Sensitive
  Object result = d.readObject();
  [...]
  d.close();
}

See

squid:S4684

On one side, Spring MVC automatically bind request parameters to beans declared as arguments of methods annotated with @RequestMapping. Because of this automatic binding feature, it's possible to feed some unexpected fields on the arguments of the @RequestMapping annotated methods.

On the other end, persistent objects (@Entity or @Document) are linked to the underlying database and updated automatically by a persistence framework, such as Hibernate, JPA or Spring Data MongoDB.

These two facts combined together can lead to malicious attack: if a persistent object is used as an argument of a method annotated with @RequestMapping, it's possible from a specially crafted user input, to change the content of unexpected fields into the database.

For this reason, using @Entity or @Document objects as arguments of methods annotated with @RequestMapping should be avoided.

In addition to @RequestMapping, this rule also considers the annotations introduced in Spring Framework 4.3: @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping.

Noncompliant Code Example

import javax.persistence.Entity;

@Entity
public class Wish {
  Long productId;
  Long quantity;
  Client client;
}

@Entity
public class Client {
  String clientId;
  String name;
  String password;
}

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class WishListController {

  @PostMapping(path = "/saveForLater")
  public String saveForLater(Wish wish) {
    session.save(wish);
  }

  @RequestMapping(path = "/saveForLater", method = RequestMethod.POST)
  public String saveForLater(Wish wish) {
    session.save(wish);
  }
}

Compliant Solution

public class WishDTO {
  Long productId;
  Long quantity;
  Long clientId;
}

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class PurchaseOrderController {

  @PostMapping(path = "/saveForLater")
  public String saveForLater(WishDTO wish) {
    Wish persistentWish = new Wish();
    // do the mapping between "wish" and "persistentWish"
    [...]
    session.save(persistentWish);
  }

  @RequestMapping(path = "/saveForLater", method = RequestMethod.POST)
  public String saveForLater(WishDTO wish) {
    Wish persistentWish = new Wish();
    // do the mapping between "wish" and "persistentWish"
    [...]
    session.save(persistentWish);
  }
}

See

squid:S3355

Every filter defined in web.xml file should be used in a <filter-mapping> element. Otherwise such filters are not invoked.

Noncompliant Code Example

  <filter>
     <filter-name>DefinedNotUsed</filter-name>
     <filter-class>com.myco.servlet.ValidationFilter</filter-class>
  </filter>

Compliant Solution

  <filter>
     <filter-name>ValidationFilter</filter-name>
     <filter-class>com.myco.servlet.ValidationFilter</filter-class>
  </filter>

  <filter-mapping>
     <filter-name>ValidationFilter</filter-name>
     <url-pattern>/*</url-pattern>
  </filter-mapping>

See

squid:S1172

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

Noncompliant Code Example

void doSomething(int a, int b) {     // "b" is unused
  compute(a);
}

Compliant Solution

void doSomething(int a) {
  compute(a);
}

Exceptions

The rule will not raise issues for unused parameters:

  • that are annotated with @javax.enterprise.event.Observes
  • in overrides and implementation methods
  • in interface default methods
  • in non-private methods that only throw or that have empty bodies
  • in annotated methods, unless the annotation is @SuppressWarning("unchecked") or @SuppressWarning("rawtypes"), in which case the annotation will be ignored
  • in overridable methods (non-final, or not member of a final class, non-static, non-private), if the parameter is documented with a proper javadoc.
@Override
void doSomething(int a, int b) {     // no issue reported on b
  compute(a);
}

public void foo(String s) {
  // designed to be extended but noop in standard case
}

protected void bar(String s) {
  //open-closed principle
}

public void qix(String s) {
  throw new UnsupportedOperationException("This method should be implemented in subclasses");
}

/**
 * @param s This string may be use for further computation in overriding classes
 */
protected void foobar(int a, String s) { // no issue, method is overridable and unused parameter has proper javadoc
  compute(a);
}

See

  • MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions.
  • MISRA C:2012, 2.7 - There should be no unused parameters in functions
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
squid:S5304

Using environment variables is security-sensitive. For example, their use has led in the past to the following vulnerabilities:

Environment variables are sensitive to injection attacks, just like any other input.

Note also that environment variables can be exposed in multiple ways, storing sensitive information in them should be done carefully:

  • on Unix systems environment variables of one process can be read by another process running with the same UID.
  • environment variables might be forwarded to child processes.
  • application running in debug mode often exposes their environment variable.

This rule raises an issue when environment variables are read.

Ask Yourself Whether

  • Environment variables are used without being sanitized.
  • You store sensitive information in environment variables and other processes might be able to access them.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Sanitize every environment variable before using its value.

If you store sensitive information in an environment variable, make sure that no other process can access them, i.e. the process runs with a separate user account and child processes don't have access to their parent's environment.

Don't run your application in debug mode if it has access to sensitive information, including environment variables.

Sensitive Code Example

public class Main {
    public static void main (String[] args) {
        System.getenv();  // Sensitive
        System.getenv("myvar");  // Sensitive

        ProcessBuilder processBuilder = new ProcessBuilder();
        Map<String, String> environment = processBuilder.environment();  // Sensitive
        environment.put("VAR", "value");

        Runtime.getRuntime().exec("ping", new String[]{"env=val"});   // Sensitive
    }
}

See

  • MITRE, CWE-526 - Information Exposure Through Environmental Variables
  • MITRE, CWE-74 - Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection')
squid:S2278

According to the US National Institute of Standards and Technology (NIST), the Data Encryption Standard (DES) is no longer considered secure:

Adopted in 1977 for federal agencies to use in protecting sensitive, unclassified information, the DES is being withdrawn because it no longer provides the security that is needed to protect federal government information.

Federal agencies are encouraged to use the Advanced Encryption Standard, a faster and stronger algorithm approved as FIPS 197 in 2001.

For similar reasons, RC2 should also be avoided.

Noncompliant Code Example

Cipher c = Cipher.getInstance("DESede/ECB/PKCS5Padding");

Compliant Solution

Cipher c = Cipher.getInstance("AES/GCM/NoPadding");

See

squid:S5300

Sending emails is security-sensitive. For example, it has led in the past to the following vulnerabilities:

Emails can create multiple vulnerabilities:

Information exposure

Emails often contain sensitive information which might be exposed to an attacker.

Injecting dangerous content

Emails can contain html and javascript code, thus they can be used for XSS attacks.

Email Header Injection

This is one of the most common attacks.

Email fields such as subject, to, cc, bcc, from are set in Email "headers". Those headers are separated by CR ("carriage return" often represented as \r) or LF ("line feed" often represented as \n) characters.

If an unsanitized input is provided to a header field, it becomes vulnerable to Email Header Injection attacks. An attacker can then add fields in the header or even modify the message.

For example, providing the following value to the From field

me@example.com\nCc:injectedrecipient@otherexample.com\nBcc:yetanother@myexample.com,andagain@thisisdangerous.net

would result in injecting two additional fields (CC and BCC):

FROM: me@example.com
CC: injectedrecipient@otherexample.com
BCC: yetanother@myexample.com,andagain@thisisdangerous.net

This rule raises an issue when an API sending emails is called.

Ask Yourself Whether

  • Email headers are provided by users and are not sanitized.
  • Email content contains data provided by users and it is not sanitized.
  • The email is not sent using a strong protocol.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

  • Use an email library which sanitizes headers.
  • Sanitize every piece of data sent via emails, especially when the mime type is html.
  • Use a strong protocol to send your emails, i.e. secure versions of SSL or TLS.

Sensitive Code Example

import javax.mail.*;
import javax.mail.internet.MimeMessage;

public class Main {
    public static void sendEmail (Session session, String subject) throws MessagingException{
        Message message = new MimeMessage(session);  // Sensitive

        // For example the setSubject method is vulnerable to Header injection before
        // version 1.5.6 of javamail
        message.setSubject(subject);
        // ...
    }
}

See

squid:S2277

Without OAEP in RSA encryption, it takes less work for an attacker to decrypt the data or infer patterns from the ciphertext. This rule logs an issue as soon as a literal value starts with RSA/NONE.

Noncompliant Code Example

Cipher rsa = javax.crypto.Cipher.getInstance("RSA/NONE/NoPadding");

Compliant Solution

Cipher rsa = javax.crypto.Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");

See

squid:S1065

If a label is declared but not used in the program, it can be considered as dead code and should therefore be removed.

This will improve maintainability as developers will not wonder what this label is used for.

Noncompliant Code Example

void foo() {
  outer: //label is not used.
  for(int i = 0; i<10; i++) {
    break;
  }
}

Compliant Solution

void foo() {
  for(int i = 0; i<10; i++) {
    break;
  }
}

See

  • MISRA C:2012, 2.6 - A function should not contain unused label declarations
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
squid:S2390

When a parent class references a member of a subclass during its own initialization, the results might not be what you expect because the child class might not have been initialized yet. This could create what is known as an "initialisation cycle", or even a deadlock in some extreme cases.

To make things worse, these issues are very hard to diagnose so it is highly recommended you avoid creating this kind of dependencies.

Noncompliant Code Example

class Parent {
  static int field1 = Child.method(); // Noncompliant
  static int field2 = 42;

  public static void main(String[] args) {
    System.out.println(Parent.field1); // will display "0" instead of "42"
  }
}

class Child extends Parent {
  static int method() {
    return Parent.field2;
  }
}

See

squid:S4424

Empty implementations of the X509TrustManager interface are often created to allow connection to a host that is not signed by a root certificate authority. Such an implementation will accept any certificate, which leaves the application vulnerable to Man-in-the-middle attacks. The correct solution is to provide an appropriate trust store.

This rule raises an issue when an implementation of X509TrustManager never throws exception.

Noncompliant Code Example

class TrustAllManager implements X509TrustManager {

    @Override
    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {  // Noncompliant, nothing means trust any client
    }

    @Override
    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { // Noncompliant, this method never throws exception, it means trust any client
        LOG.log(Level.SEVERE, ERROR_MESSAGE);
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}

See

squid:S4787

Encrypting data is security-sensitive. It has led in the past to the following vulnerabilities:

Proper encryption requires both the encryption algorithm and the key to be strong. Obviously the private key needs to remain secret and be renewed regularly. However these are not the only means to defeat or weaken an encryption.

This rule flags function calls that initiate encryption/decryption. The goal is to guide security code reviews.

Ask Yourself Whether

  • the private key might not be random, strong enough or the same key is reused for a long long time.
  • the private key might be compromised. It can happen when it is stored in an unsafe place or when it was transferred in an unsafe manner.
  • the key exchange is made without properly authenticating the receiver.
  • the encryption algorithm is not strong enough for the level of protection required. Note that encryption algorithms strength decreases as time passes.
  • the chosen encryption library is deemed unsafe.
  • a nonce is used, and the same value is reused multiple times, or the nonce is not random.
  • the RSA algorithm is used, and it does not incorporate an Optimal Asymmetric Encryption Padding (OAEP), which might weaken the encryption.
  • the CBC (Cypher Block Chaining) algorithm is used for encryption, and it's IV (Initialization Vector) is not generated using a secure random algorithm, or it is reused.
  • the Advanced Encryption Standard (AES) encryption algorithm is used with an unsecure mode. See the recommended practices for more information.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

  • Generate encryption keys using secure random algorithms.
  • When generating cryptographic keys (or key pairs), it is important to use a key length that provides enough entropy against brute-force attacks. For the Blowfish algorithm the key should be at least 128 bits long, while for the RSA algorithm it should be at least 2048 bits long.
  • Regenerate the keys regularly.
  • Always store the keys in a safe location and transfer them only over safe channels.
  • If there is an exchange of cryptographic keys, check first the identity of the receiver.
  • Only use strong encryption algorithms. Check regularly that the algorithm is still deemed secure. It is also imperative that they are implemented correctly. Use only encryption libraries which are deemed secure. Do not define your own encryption algorithms as they will most probably have flaws.
  • When a nonce is used, generate it randomly every time.
  • When using the RSA algorithm, incorporate an Optimal Asymmetric Encryption Padding (OAEP).
  • When CBC is used for encryption, the IV must be random and unpredictable. Otherwise it exposes the encrypted value to crypto-analysis attacks like "Chosen-Plaintext Attacks". Thus a secure random algorithm should be used. An IV value should be associated to one and only one encryption cycle, because the IV's purpose is to ensure that the same plaintext encrypted twice will yield two different ciphertexts.
  • The Advanced Encryption Standard (AES) encryption algorithm can be used with various modes. Galois/Counter Mode (GCM) with no padding should be preferred to the following combinations which are not secured:
    • Electronic Codebook (ECB) mode: Under a given key, any given plaintext block always gets encrypted to the same ciphertext block. Thus, it does not hide data patterns well. In some senses, it doesn't provide serious message confidentiality, and it is not recommended for use in cryptographic protocols at all.
    • Cipher Block Chaining (CBC) with PKCS#5 padding (or PKCS#7) is susceptible to padding oracle attacks.

Sensitive Code Example

// === javax.crypto ===
import javax.crypto.Cipher;
Cipher c = Cipher.getInstance(...);  // Questionable

// === apache.commons.crypto ===
import java.util.Properties;
import org.apache.commons.crypto.utils.Utils;
import org.apache.commons.crypto.cipher.CryptoCipherFactory;
import org.apache.commons.crypto.cipher.CryptoCipherFactory.CipherProvider;

Properties properties = new Properties();
properties.setProperty(CryptoCipherFactory.CLASSES_KEY, CipherProvider.OPENSSL.getClassName());
final String transform = "AES/CBC/PKCS5Padding";
Utils.getCipherInstance(transform, properties);  // Questionable

See

squid:S4544

Using unsafe Jackson deserialization configuration is security-sensitive. It has led in the past to the following vulnerabilities:

When Jackson is configured to allow Polymorphic Type Handling (aka PTH), formerly known as Polymorphic Deserialization, "deserialization gadgets" may allow an attacker to perform remote code execution.

This rule raises an issue when:

  • enableDefaultTyping() is called on an instance of com.fasterxml.jackson.databind.ObjectMapper or org.codehaus.jackson.map.ObjectMapper.
  • or when the annotation @JsonTypeInfo is set at class or field levels and configured with use = JsonTypeInfo.Id.CLASS) or use = Id.MINIMAL_CLASS.

Ask Yourself Whether

  • You configured the Jackson deserializer as mentioned above.
  • The serialized data might come from an untrusted source.

You may be at risk if you answered yes to these questions.

Recommended Secure Coding Practices

  • Use the latest patch versions of jackson-databind blocking the already discovered "deserialization gadgets".
  • Avoid using the default typing configuration: ObjectMapper.enableDefaultTyping().
  • If possible, use @JsonTypeInfo(use = Id.NAME) instead of @JsonTypeInfo(use = Id.CLASS) or @JsonTypeInfo(use = Id. MINIMAL_CLASS) and so rely on @JsonTypeName and @JsonSubTypes.

Sensitive Code Example

ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(); // Sensitive
@JsonTypeInfo(use = Id.CLASS) // Sensitive
abstract class PhoneNumber {
}

See

squid:S4423

javax.net.ssl.SSLContext.getInstance returns a SSLContext object that implements the specified secure socket protocol. However, not all protocols are created equal and some legacy ones like "SSL", have been proven to be insecure.

This rule raises an issue when an SSLContext is created with an insecure protocol (ie: a protocol different from "TLS", "DTLS", "TLSv1.2", "DTLSv1.2", "TLSv1.3", "DTLSv1.3").

The recommended value is "TLS" or "DTLS" as it will always use the latest version of the protocol. However an issue will be raised if the bytecode was compiled with JDK7 or an even older version of JDK because they are not alias for TLSv1.2 and DTLSv1.2 but for weaker protocols.

Note that calling SSLContext.getInstance(...) with "TLSv1.2" or "DTLSv1.2" doesn't prevent protocol version negotiation. For example, if a client connects with "TLSv1.1" and the server used SSLContext.getInstance("TLSv1.2"), the connection will use "TLSv1.1". It is possible to enable only specific protocol versions by calling setEnabledProtocols on SSLSocket, SSLServerSocket or SSLEngine. However this should be rarely needed as clients usually ask for the most secure protocol supported.

Noncompliant Code Example

context = SSLContext.getInstance("SSL"); // Noncompliant

Compliant Solution

context = SSLContext.getInstance("TLSv1.2");

See

squid:S4426

When generating cryptographic keys (or key pairs), it is important to use a key length that provides enough entropy against brute-force attacks. For the Blowfish algorithm the key should be at least 128 bits long, while for the RSA algorithm it should be at least 2048 bits long.

This rule raises an issue when a Blowfish key generator or RSA key-pair generator is initialized with too small a length parameter.

Noncompliant Code Example

KeyGenerator keyGen = KeyGenerator.getInstance("Blowfish");
keyGen.init(64); // Noncompliant

KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(512); // Noncompliant

Compliant Solution

KeyGenerator keyGen = KeyGenerator.getInstance("Blowfish");
keyGen.init(128);

KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048);

See

squid:S2245

Using pseudorandom number generators (PRNGs) is security-sensitive. For example, it has led in the past to the following vulnerabilities:

When software generates predictable values in a context requiring unpredictability, it may be possible for an attacker to guess the next value that will be generated, and use this guess to impersonate another user or access sensitive information.

As the java.util.Random class relies on a pseudorandom number generator, this class and relating java.lang.Math.random() method should not be used for security-critical applications or for protecting sensitive data. In such context, the java.security.SecureRandom class which relies on a cryptographically strong random number generator (RNG) should be used in place.

Ask Yourself Whether

  • the code using the generated value requires it to be unpredictable. It is the case for all encryption mechanisms or when a secret value, such as a password, is hashed.
  • the function you use generates a value which can be predicted (pseudo-random).
  • the generated value is used multiple times.
  • an attacker can access the generated value.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

  • Use a cryptographically strong random number generator (RNG) like "java.security.SecureRandom" in place of this PRNG.
  • Use the generated random values only once.
  • You should not expose the generated random value. If you have to store it, make sure that the database or file is secure.

Sensitive Code Example

Random random = new Random(); // Questionable use of Random
byte bytes[] = new byte[20];
random.nextBytes(bytes); // Check if bytes is used for hashing, encryption, etc...

Compliant Solution

SecureRandom random = new SecureRandom(); // Compliant for security-sensitive use cases
byte bytes[] = new byte[20];
random.nextBytes(bytes);

See

squid:S3330

The HttpOnly cookie attribute tells the browser to prevent client-side scripts from reading cookies with the attribute, and its use can go a long way to defending against Cross-Site Scripting (XSS) attacks. Thus, as a precaution, the attribute should be set by default on all cookies set server-side, such as session id cookies.

When implementing Cross Site Request Forgery (XSRF) protection, a JavaScript-readable session cookie, generally named XSRF-TOKEN, should be created on the first HTTP GET request. For such a cookie, the HttpOnly attribute should be set to "false".

Setting the attribute can be done either programmatically, or globally via configuration files.

Noncompliant Code Example

Cookie cookie = new Cookie("myCookieName", value); // Noncompliant; by default cookie.isHttpOnly() is returning false

Compliant Solution

Cookie cookie = new Cookie("myCookieName", value);
cookie.setHttpOnly(true); // Compliant

See

squid:S4784

Using regular expressions is security-sensitive. It has led in the past to the following vulnerabilities:

Evaluating regular expressions against input strings is potentially an extremely CPU-intensive task. Specially crafted regular expressions such as (a+)+s will take several seconds to evaluate the input string aaaaaaaaaaaaaaaaaaaaaaaaaaaaabs. The problem is that with every additional a character added to the input, the time required to evaluate the regex doubles. However, the equivalent regular expression, a+s (without grouping) is efficiently evaluated in milliseconds and scales linearly with the input size.

Evaluating such regular expressions opens the door to Regular expression Denial of Service (ReDoS) attacks. In the context of a web application, attackers can force the web server to spend all of its resources evaluating regular expressions thereby making the service inaccessible to genuine users.

This rule flags any execution of a hardcoded regular expression which has at least 3 characters and at least two instances of any of the following characters: *+{.

Example: (a+)*

Ask Yourself Whether

  • the executed regular expression is sensitive and a user can provide a string which will be analyzed by this regular expression.
  • your regular expression engine performance decrease with specially crafted inputs and regular expressions.

You may be at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Check whether your regular expression engine (the algorithm executing your regular expression) has any known vulnerabilities. Search for vulnerability reports mentioning the one engine you're are using.

Use if possible a library which is not vulnerable to Redos Attacks such as Google Re2.

Remember also that a ReDos attack is possible if a user-provided regular expression is executed. This rule won't detect this kind of injection.

Sensitive Code Example

import java.util.regex.Pattern;

class BasePattern {
  String regex = "(a+)+b"; // a regular expression
  String input; // a user input

  void foo(CharSequence htmlString) {
    input.matches(regex);  // Sensitive
    Pattern.compile(regex);  // Sensitive
    Pattern.compile(regex, Pattern.CASE_INSENSITIVE);  // Sensitive

    String replacement = "test";
    input.replaceAll(regex, replacement);  // Sensitive
    input.replaceFirst(regex, replacement);  // Sensitive

    if (!Pattern.matches(".*<script>(a+)+b", htmlString)) { // Sensitive
    }
  }
}

This also applies for bean validation, where regexp can be specified:

import java.io.Serializable;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Email;
import org.hibernate.validator.constraints.URL;

class BeansRegex implements Serializable {
  @Pattern(regexp=".+@(a+)+b")  // Sensitive
  private String email;

  @Email(regexp=".+@(a+)+b")  // Sensitive
  private String email2;

  @URL(regexp="(a+)+b.com") // Sensitive
  private String url;
  // ...
}

Exceptions

Calls to String.split(regex) and String.split(regex, limit) will not raise an exception despite their use of a regular expression. These methods are used most of the time to split on simple regular expressions which don't create any vulnerabilities.

See

squid:S3331

A cookie's domain specifies which websites should be able to read it. Left blank, browsers are supposed to only send the cookie to sites that exactly match the sending domain. For example, if a cookie was set by lovely.dream.com, it should only be readable by that domain, and not by nightmare.com or even strange.dream.com. If you want to allow sub-domain access for a cookie, you can specify it by adding a dot in front of the cookie's domain, like so: .dream.com. But cookie domains should always use at least two levels.

Cookie domains can be set either programmatically or via configuration. This rule raises an issue when any cookie domain is set with a single level, as in .com.

Noncompliant Code Example

Cookie myCookie = new Cookie("name", "val");
myCookie.setDomain(".com"); // Noncompliant
java.net.HttpCookie myOtherCookie = new java.net.HttpCookie("name", "val");
myOtherCookie.setDomain(".com"); // Noncompliant

Compliant Solution

Cookie myCookie = new Cookie("name", "val"); // Compliant; by default, cookies are only returned to the server that sent them.

// or

Cookie myCookie = new Cookie("name", "val");
myCookie.setDomain(".myDomain.com"); // Compliant

java.net.HttpCookie myOtherCookie = new java.net.HttpCookie("name", "val");
myOtherCookie.setDomain(".myDomain.com"); // Compliant

See

squid:S4435

An XML External Entity or XSLT External Entity (XXE) vulnerability can occur when a javax.xml.transform.Transformer is created without enabling "Secure Processing" or when one is created without disabling external DTDs. If that external entity is hijacked by an attacker it may lead to the disclosure of confidential data, denial of service, server side request forgery, port scanning from the perspective of the machine where the parser is located, and other system impacts.

This rule raises an issue when a Transformer is created without either of these settings.

Noncompliant Code Example

Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(input, result);

Compliant Solution

TransformerFactory factory = TransformerFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

Transformer transformer = factory.newTransformer();

transformer.transform(input, result);

or

TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");

Transformer transformer = factory.newTransformer();

transformer.transform(input, result);

See

squid:S923

As stated per effective java :

Varargs methods are a convenient way to define methods that require a variable number of arguments, but they should not be overused. They can produce confusing results if used inappropriately.

Noncompliant Code Example

void fun ( String... strings )	// Noncompliant
{
  // ...
}
squid:S2258

By contract, the NullCipher class provides an "identity cipher" one that does not transform or encrypt the plaintext in any way. As a consequence, the ciphertext is identical to the plaintext. So this class should be used for testing, and never in production code.

Noncompliant Code Example

NullCipher nc = new NullCipher();

See

squid:S4434

JNDI supports the deserialization of objects from LDAP directories, which is fundamentally insecure and can lead to remote code execution.

This rule raises an issue when an LDAP search query is executed with SearchControls configured to allow deserialization.

Noncompliant Code Example

DirContext ctx = new InitialDirContext();
// ...
ctx.search(query, filter,
        new SearchControls(scope, countLimit, timeLimit, attributes,
            true, // Noncompliant; allows deserialization
            deref));

Compliant Solution

DirContext ctx = new InitialDirContext();
// ...
ctx.search(query, filter,
        new SearchControls(scope, countLimit, timeLimit, attributes,
            false,
            deref));

See

squid:S2257

The use of a non-standard algorithm is dangerous because a determined attacker may be able to break the algorithm and compromise whatever data has been protected. Standard algorithms like SHA-256, SHA-384, SHA-512, ... should be used instead.

This rule tracks creation of java.security.MessageDigest subclasses.

Recommended Secure Coding Practices

  • use a standard algorithm instead of creating a custom one.

Noncompliant Code Example

MyCryptographicAlgorithm extends MessageDigest {
  ...
}

See

squid:S2254

According to the Oracle Java API, the HttpServletRequest.getRequestedSessionId() method:

Returns the session ID specified by the client. This may not be the same as the ID of the current valid session for this request. If the client did not specify a session ID, this method returns null.

The session ID it returns is either transmitted in a cookie or a URL parameter so by definition, nothing prevents the end-user from manually updating the value of this session ID in the HTTP request.

Here is an example of a updated HTTP header:

GET /pageSomeWhere HTTP/1.1
Host: webSite.com
User-Agent: Mozilla/5.0
Cookie: JSESSIONID=Hacked_Session_Value'''">

Due to the ability of the end-user to manually change the value, the session ID in the request should only be used by a servlet container (E.G. Tomcat or Jetty) to see if the value matches the ID of an an existing session. If it does not, the user should be considered unauthenticated. Moreover, this session ID should never be logged to prevent hijacking of active sessions.

Noncompliant Code Example

if(isActiveSession(request.getRequestedSessionId()) ){
  ...
}

See

squid:S2255

Using cookies is security-sensitive. It has led in the past to the following vulnerabilities:

Attackers can use widely-available tools to read cookies, sensitive information written by the server will be exposed.

This rule flags code that writes cookies.

Ask Yourself Whether

  • sensitive information is stored inside the cookie.

You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

Cookies should only be used to manage the user session. The best practice is to keep all user-related information server-side and link them to the user session, never sending them to the client. In a very few corner cases, cookies can be used for non-sensitive information that need to live longer than the user session.

Do not try to encode sensitive information in a non human-readable format before writing them in a cookie. The encoding can be reverted and the original information will be exposed.

Using cookies only for session IDs doesn't make them secure. Follow OWASP best practices when you configure your cookies.

As a side note, every information read from a cookie should be Sanitized.

Sensitive Code Example

// === javax.servlet ===
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;

public class JavaxServlet {
    void aServiceMethodSettingCookie(HttpServletRequest request, HttpServletResponse response, String acctID) {
        Cookie cookie = new Cookie("userAccountID", acctID);  // Sensitive
        response.addCookie(cookie);  // Sensitive
    }
}
// === javax.ws ===
import java.util.Date;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.core.NewCookie;

class JavaxWs {
    void jaxRsCookie(String comment, int maxAge, boolean secure, Date expiry, boolean httpOnly, String name,
            String value, String path, String domain, int version) {
        Cookie cookie= new Cookie("name", "value");  // Sensitive

        new NewCookie(cookie);  // Sensitive
        new NewCookie(cookie, comment, maxAge, secure);  // Sensitive
        new NewCookie(cookie, comment, maxAge, expiry, secure, httpOnly);  // Sensitive
        new NewCookie(name, value);  // Sensitive
        new NewCookie(name, value, path, domain, version, comment, maxAge, secure);  // Sensitive
        new NewCookie(name, value, path, domain, version, comment, maxAge, expiry, secure, httpOnly);  // Sensitive
        new NewCookie(name, value, path, domain, comment, maxAge, secure);  // Sensitive
        new NewCookie(name, value, path, domain, comment, maxAge, secure, httpOnly);  // Sensitive
    }
}
// === java.net ===
import java.net.HttpCookie;

class JavaNet {
    void httpCookie(HttpCookie hc) {
        HttpCookie cookie = new HttpCookie("name", "value");  // Sensitive
        cookie.setValue("value");  // Sensitive
    }
}
// === apache.shiro ===
import org.apache.shiro.web.servlet.SimpleCookie;

class ApacheShiro {

    void shiroCookie(SimpleCookie cookie) {
        SimpleCookie sc = new SimpleCookie(cookie);  // Sensitive
        cookie.setValue("value");  // Sensitive
    }
}
// === Play ===
import play.mvc.Http.Cookie;
import play.mvc.Http.CookieBuilder;


class Play {
    void playCookie() {
        CookieBuilder builder = Cookie.builder("name", "value");  // Sensitive
        builder.withName("name")
          .withValue("value")  // Sensitive
          .build();

    }
}

See

squid:S4433

An un-authenticated LDAP connection can lead to transactions without access control. Authentication, and with it, access control, are the last line of defense against LDAP injections and should not be disabled.

This rule raises an issue when an LDAP connection is created with Context.SECURITY_AUTHENTICATION set to "none".

Noncompliant Code Example

// Set up the environment for creating the initial context
Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");

// Use anonymous authentication
env.put(Context.SECURITY_AUTHENTICATION, "none"); // Noncompliant

// Create the initial context
DirContext ctx = new InitialDirContext(env);

Compliant Solution

// Set up the environment for creating the initial context
Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");

// Use simple authentication
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=S. User, ou=NewHires, o=JNDITutorial");
env.put(Context.SECURITY_CREDENTIALS, getLDAPPassword());

// Create the initial context
DirContext ctx = new InitialDirContext(env);

See

squid:S4432

The Advanced Encryption Standard (AES) encryption algorithm can be used with various modes. Some combinations are not secured:

  • Electronic Codebook (ECB) mode: Under a given key, any given plaintext block always gets encrypted to the same ciphertext block. Thus, it does not hide data patterns well. In some senses, it doesn't provide serious message confidentiality, and it is not recommended for use in cryptographic protocols at all.
  • Cipher Block Chaining (CBC) with PKCS#5 padding (or PKCS#7) is susceptible to padding oracle attacks.

In both cases, Galois/Counter Mode (GCM) with no padding should be preferred.

This rule raises an issue when a Cipher instance is created with either ECB or CBC/PKCS5Padding mode.

Noncompliant Code Example

Cipher c1 = Cipher.getInstance("AES/ECB/NoPadding"); // Noncompliant
Cipher c2 = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Noncompliant

Compliant Solution

Cipher c = Cipher.getInstance("AES/GCM/NoPadding");

See

squid:S4790

Hashing data is security-sensitive. It has led in the past to the following vulnerabilities:

Cryptographic hash functions are used to uniquely identify information without storing their original form. When not done properly, an attacker can steal the original information by guessing it (ex: with a rainbow table), or replace the original data with another one having the same hash.

This rule flags code that initiates hashing.

Ask Yourself Whether

  • the hashed value is used in a security context.
  • the hashing algorithm you are using is known to have vulnerabilities.
  • salts are not automatically generated and applied by the hashing function.
  • any generated salts are cryptographically weak or not credential-specific.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

  • for security related purposes, use only hashing algorithms which are currently known to be strong. Avoid using algorithms like MD5 and SHA1 completely in security contexts.
  • do not define your own hashing- or salt algorithms as they will most probably have flaws.
  • do not use algorithms that compute too quickly, like SHA256, as it must remain beyond modern hardware capabilities to perform brute force and dictionary based attacks.
  • use a hashing algorithm that generate its own salts as part of the hashing. If you generate your own salts, make sure that a cryptographically strong salt algorithm is used, that generated salts are credential-specific, and finally, that the salt is applied correctly before the hashing.
  • save both the salt and the hashed value in the relevant database record; during future validation operations, the salt and hash can then be retrieved from the database. The hash is recalculated with the stored salt and the value being validated, and the result compared to the stored hash.
  • the strength of hashing algorithms often decreases over time as hardware capabilities increase. Check regularly that the algorithms you are using are still considered secure. If needed, rehash your data using a stronger algorithm.

Questionable Code Example

// === MessageDigest ===
import java.security.MessageDigest;
import java.security.Provider;

class A {
    void foo(String algorithm, String providerStr, Provider provider) throws Exception {
        MessageDigest.getInstance(algorithm); // Questionable
        MessageDigest.getInstance(algorithm, providerStr); // Questionable
        MessageDigest.getInstance(algorithm, provider); // Questionable
    }
}

Regarding SecretKeyFactory. Any call to SecretKeyFactory.getInstance("...") with an argument starting by "PBKDF2" will be highlighted. See OWASP guidelines, list of standard algorithms and algorithms on android.

// === javax.crypto ===
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.SecretKeyFactory;

class A {
    void foo(char[] password, byte[] salt, int iterationCount, int keyLength) throws Exception {
        // Questionable. Review this, even if it is the way recommended by OWASP
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
        PBEKeySpec spec = new PBEKeySpec(password, salt, iterationCount, keyLength);
        factory.generateSecret(spec).getEncoded();
    }
}

Regarding Guava, only the hashing functions which are usually misused for sensitive data will raise an issue, i.e. md5 and sha*.

// === Guava ===
import com.google.common.hash.Hashing;

class A {
    void foo() {
        Hashing.md5(); // Questionable
        Hashing.sha1(); // Questionable
        Hashing.sha256(); // Questionable
        Hashing.sha384(); // Questionable
        Hashing.sha512(); // Questionable
    }
}
// === org.apache.commons ===
import org.apache.commons.codec.digest.DigestUtils;

class A {
    void foo(String strName, byte[] data, String str, java.io.InputStream stream) throws Exception {
        new DigestUtils(strName); // Questionable
        new DigestUtils(); // Questionable

        DigestUtils.getMd2Digest(); // Questionable
        DigestUtils.getMd5Digest(); // Questionable
        DigestUtils.getShaDigest(); // Questionable
        DigestUtils.getSha1Digest(); // Questionable
        DigestUtils.getSha256Digest(); // Questionable
        DigestUtils.getSha384Digest(); // Questionable
        DigestUtils.getSha512Digest(); // Questionable


        DigestUtils.md2(data); // Questionable
        DigestUtils.md2(stream); // Questionable
        DigestUtils.md2(str); // Questionable
        DigestUtils.md2Hex(data); // Questionable
        DigestUtils.md2Hex(stream); // Questionable
        DigestUtils.md2Hex(str); // Questionable

        DigestUtils.md5(data); // Questionable
        DigestUtils.md5(stream); // Questionable
        DigestUtils.md5(str); // Questionable
        DigestUtils.md5Hex(data); // Questionable
        DigestUtils.md5Hex(stream); // Questionable
        DigestUtils.md5Hex(str); // Questionable

        DigestUtils.sha(data); // Questionable
        DigestUtils.sha(stream); // Questionable
        DigestUtils.sha(str); // Questionable
        DigestUtils.shaHex(data); // Questionable
        DigestUtils.shaHex(stream); // Questionable
        DigestUtils.shaHex(str); // Questionable

        DigestUtils.sha1(data); // Questionable
        DigestUtils.sha1(stream); // Questionable
        DigestUtils.sha1(str); // Questionable
        DigestUtils.sha1Hex(data); // Questionable
        DigestUtils.sha1Hex(stream); // Questionable
        DigestUtils.sha1Hex(str); // Questionable

        DigestUtils.sha256(data); // Questionable
        DigestUtils.sha256(stream); // Questionable
        DigestUtils.sha256(str); // Questionable
        DigestUtils.sha256Hex(data); // Questionable
        DigestUtils.sha256Hex(stream); // Questionable
        DigestUtils.sha256Hex(str); // Questionable

        DigestUtils.sha384(data); // Questionable
        DigestUtils.sha384(stream); // Questionable
        DigestUtils.sha384(str); // Questionable
        DigestUtils.sha384Hex(data); // Questionable
        DigestUtils.sha384Hex(stream); // Questionable
        DigestUtils.sha384Hex(str); // Questionable

        DigestUtils.sha512(data); // Questionable
        DigestUtils.sha512(stream); // Questionable
        DigestUtils.sha512(str); // Questionable
        DigestUtils.sha512Hex(data); // Questionable
        DigestUtils.sha512Hex(stream); // Questionable
        DigestUtils.sha512Hex(str); // Questionable
    }
}
squid:S4792

Configuring loggers is security-sensitive. It has led in the past to the following vulnerabilities:

Logs are useful before, during and after a security incident.

  • Attackers will most of the time start their nefarious work by probing the system for vulnerabilities. Monitoring this activity and stopping it is the first step to prevent an attack from ever happening.
  • In case of a successful attack, logs should contain enough information to understand what damage an attacker may have inflicted.

Logs are also a target for attackers because they might contain sensitive information. Configuring loggers has an impact on the type of information logged and how they are logged.

This rule flags for review code that initiates loggers configuration. The goal is to guide security code reviews.

Ask Yourself Whether

  • unauthorized users might have access to the logs, either because they are stored in an insecure location or because the application gives access to them.
  • the logs contain sensitive information on a production server. This can happen when the logger is in debug mode.
  • the log can grow without limit. This can happen when additional information is written into logs every time a user performs an action and the user can perform the action as many times as he/she wants.
  • the logs do not contain enough information to understand the damage an attacker might have inflicted. The loggers mode (info, warn, error) might filter out important information. They might not print contextual information like the precise time of events or the server hostname.
  • the logs are only stored locally instead of being backuped or replicated.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

  • Check that your production deployment doesn't have its loggers in "debug" mode as it might write sensitive information in logs.
  • Production logs should be stored in a secure location which is only accessible to system administrators.
  • Configure the loggers to display all warnings, info and error messages. Write relevant information such as the precise time of events and the hostname.
  • Choose log format which is easy to parse and process automatically. It is important to process logs rapidly in case of an attack so that the impact is known and limited.
  • Check that the permissions of the log files are correct. If you index the logs in some other service, make sure that the transfer and the service are secure too.
  • Add limits to the size of the logs and make sure that no user can fill the disk with logs. This can happen even when the user does not control the logged information. An attacker could just repeat a logged action many times.

Remember that configuring loggers properly doesn't make them bullet-proof. Here is a list of recommendations explaining on how to use your logs:

  • Don't log any sensitive information. This obviously includes passwords and credit card numbers but also any personal information such as user names, locations, etc... Usually any information which is protected by law is good candidate for removal.
  • Sanitize all user inputs before writing them in the logs. This includes checking its size, content, encoding, syntax, etc... As for any user input, validate using whitelists whenever possible. Enabling users to write what they want in your logs can have many impacts. It could for example use all your storage space or compromise your log indexing service.
  • Log enough information to monitor suspicious activities and evaluate the impact an attacker might have on your systems. Register events such as failed logins, successful logins, server side input validation failures, access denials and any important transaction.
  • Monitor the logs for any suspicious activity.

Sensitive Code Example

This rule supports the following libraries: Log4J, java.util.logging and Logback

// === Log4J 2 ===
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.*;
import org.apache.logging.log4j.core.config.*;

// Questionable: creating a new custom configuration
abstract class CustomConfigFactory extends ConfigurationFactory {
    // ...
}

class A {
    void foo(Configuration config, LoggerContext context, java.util.Map<String, Level> levelMap,
            Appender appender, java.io.InputStream stream, java.net.URI uri,
            java.io.File file, java.net.URL url, String source, ClassLoader loader, Level level, Filter filter)
            throws java.io.IOException {
        // Creating a new custom configuration
        ConfigurationBuilderFactory.newConfigurationBuilder();  // Questionable

        // Setting loggers level can result in writing sensitive information in production
        Configurator.setAllLevels("com.example", Level.DEBUG);  // Questionable
        Configurator.setLevel("com.example", Level.DEBUG);  // Questionable
        Configurator.setLevel(levelMap);  // Questionable
        Configurator.setRootLevel(Level.DEBUG);  // Questionable

        config.addAppender(appender); // Questionable: this modifies the configuration

        LoggerConfig loggerConfig = config.getRootLogger();
        loggerConfig.addAppender(appender, level, filter); // Questionable
        loggerConfig.setLevel(level); // Questionable

        context.setConfigLocation(uri); // Questionable

        // Load the configuration from a stream or file
        new ConfigurationSource(stream);  // Questionable
        new ConfigurationSource(stream, file);  // Questionable
        new ConfigurationSource(stream, url);  // Questionable
        ConfigurationSource.fromResource(source, loader);  // Questionable
        ConfigurationSource.fromUri(uri);  // Questionable
    }
}



// === java.util.logging ===
import java.util.logging.*;

class M {
    void foo(LogManager logManager, Logger logger, java.io.InputStream is, Handler handler)
            throws SecurityException, java.io.IOException {
        logManager.readConfiguration(is); // Questionable

        logger.setLevel(Level.FINEST); // Questionable
        logger.addHandler(handler); // Questionable
    }
}
// === Logback ===
import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.core.Appender;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.*;

class M {
    void foo(Logger logger, Appender<ILoggingEvent> fileAppender) {
        System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, "config.xml"); // Questionable
        JoranConfigurator configurator = new JoranConfigurator(); // Questionable

        logger.addAppender(fileAppender); // Questionable
        logger.setLevel(Level.DEBUG); // Questionable
    }
}

Exceptions

Log4J 1.x is not covered as it has reached end of life.

See

squid:AssignmentInSubExpressionCheck

Assignments within sub-expressions are hard to spot and therefore make the code less readable. Ideally, sub-expressions should not have side-effects.

Noncompliant Code Example

if ((str = cont.substring(pos1, pos2)).isEmpty()) {  // Noncompliant
  //...

Compliant Solution

str = cont.substring(pos1, pos2);
if (str.isEmpty()) {
  //...

Exceptions

Assignments in while statement conditions, and assignments enclosed in relational expressions are ignored.

BufferedReader br = new BufferedReader(/* ... */);
String line;
while ((line = br.readLine()) != null) {...}

Chained assignments, including compound assignments, are ignored.

int i = j = 0;
int k = (j += 1);
result = (bresult = new byte[len]);

See

  • MISRA C:2004, 13.1 - Assignment operators shall not be used in expressions that yield a Boolean value
  • MISRA C++:2008, 6-2-1 - Assignment operators shall not be used in sub-expressions
  • MISRA C:2012, 13.4 - The result of an assignment operator should not be used
  • MITRE, CWE-481 - Assigning instead of Comparing
  • CERT, EXP45-C. - Do not perform assignments in selection statements
  • CERT, EXP51-J. - Do not perform assignments in conditional expressions
squid:S1301

switch statements are useful when there are many different cases depending on the value of the same expression.

For just one or two cases however, the code will be more readable with if statements.

Noncompliant Code Example

switch (variable) {
  case 0:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Compliant Solution

if (variable == 0) {
  doSomething();
} else {
  doSomethingElse();
}

See

  • MISRA C:2012, 16.6 - Every switch statement shall have at least two switch-clauses
squid:S2638

Because a subclass instance may be cast to and treated as an instance of the superclass, overriding methods should uphold the aspects of the superclass contract that relate to the Liskov Substitution Principle. Specifically, if the parameters or return type of the superclass method are marked with any of the following: @Nullable, @CheckForNull, @NotNull, @NonNull, and @Nonnull, then subclass parameters are not allowed to tighten the contract, and return values are not allowed to loosen it.

Noncompliant Code Example

public class Fruit {

  private Season ripe;
  private String color;

  public void setRipe(@Nullable Season ripe) {
    this.ripe = ripe;
  }

  public @NotNull Integer getProtein() {
    return 12;
  }
}

public class Raspberry extends Fruit {

  public void setRipe(@NotNull Season ripe) {  // Noncompliant
    this.ripe = ripe;
  }

  public @Nullable Integer getProtein() {  // Noncompliant
    return null;
  }
}

See

squid:S4818

Using sockets is security-sensitive. It has led in the past to the following vulnerabilities:

Sockets are vulnerable in multiple ways:

  • They enable a software to interact with the outside world. As this world is full of attackers it is necessary to check that they cannot receive sensitive information or inject dangerous input.
  • The number of sockets is limited and can be exhausted. Which makes the application unresponsive to users who need additional sockets.

This rules flags code that creates sockets. It matches only the direct use of sockets, not use through frameworks or high-level APIs such as the use of http connections.

Ask Yourself Whether

  • sockets are created without any limit every time a user performs an action.
  • input received from sockets is used without being sanitized.
  • sensitive data is sent via sockets without being encrypted.

You are at risk if you answered yes to any of these questions.

Recommended Secure Coding Practices

  • In many cases there is no need to open a socket yourself. Use instead libraries and existing protocols.
  • Encrypt all data sent if it is sensitive. Usually it is better to encrypt it even if the data is not sensitive as it might change later.
  • Sanitize any input read from the socket.
  • Limit the number of sockets a given user can create. Close the sockets as soon as possible.

Sensitive Code Example

// === java.net ===
import java.net.Socket;
import java.net.InetAddress;
import java.net.Proxy;
import java.net.ServerSocket;
import javax.net.SocketFactory;

class A {
    void foo(SocketFactory factory, String address, int port, InetAddress localAddr, int localPort, boolean stream,
            String host, Proxy proxy, int backlog, InetAddress bindAddr)
            throws Exception {
        new Socket(); // Questionable.
        new Socket(address, port); // Questionable.
        new Socket(address, port, localAddr, localPort); // Questionable.
        new Socket(host, port, stream); // Questionable.
        new Socket(proxy); // Questionable.
        new Socket(host, port); // Questionable.
        new Socket(host, port, stream); // Questionable.
        new Socket(host, port, localAddr, localPort); // Questionable.

        new ServerSocket(); // Questionable.
        new ServerSocket(port); // Questionable.
        new ServerSocket(port, backlog); // Questionable.
        new ServerSocket(port, backlog, bindAddr); // Questionable.

        factory.createSocket(); // Questionable
    }
}

abstract class mySocketFactory extends SocketFactory { // Questionable. Review how the sockets are created.
    // ...
}
// === java.nio.channels ===
import java.net.SocketAddress;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.ServerSocketChannel;

class A {
    void foo(AsynchronousChannelGroup group, SocketAddress remote) throws Exception {
        AsynchronousServerSocketChannel.open(); // Questionable.
        AsynchronousServerSocketChannel.open(group); // Questionable.
        AsynchronousSocketChannel.open(); // Questionable.
        AsynchronousSocketChannel.open(group); // Questionable.
        SocketChannel.open(); // Questionable.
        SocketChannel.open(remote); // Questionable.
        ServerSocketChannel.open(); // Questionable.
    }
}
// === Netty ===
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;

class CustomChannelInitializer extends ChannelInitializer<ServerSocketChannel> { // Questionable. Review how the SocketChannel is used.
    @Override
    protected void initChannel(ServerSocketChannel ch) throws Exception {
    }
}

class A {
    void foo() {
        new ChannelInitializer<SocketChannel>() {  // Questionable
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
                // ...
            }
        };
    }
}

See

squid:S2755

Allowing external entities in untrusted documents to be processed could lay your systems bare to attackers. Imagine if these entities were parsed:

<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>
<!ENTITY xxe SYSTEM "http://www.attacker.com/text.txt" >]><foo>&xxe;</foo>

If you must parse untrusted XML, the best way to protect yourself is to use a local, static DTD during parsing and ignore any DTD's included in included in the document.

This rule raises an issue when any of the following are used without first disabling external entity processing: javax.xml.validation.Validator, JAXP's DocumentBuilderFactory, SAXParserFactory, Xerces 1 and Xerces 2 StAX's XMLInputFactory and XMLReaderFactory.

To disable external entity processing for XMLInputFactory, configure one of the properties XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES or XMLInputFactory.SUPPORT_DTD to false.

To disable external entity processing for SAXParserFactory, XMLReader or DocumentBuilderFactory configure one of the features XMLConstants.FEATURE_SECURE_PROCESSING or "http://apache.org/xml/features/disallow-doctype-decl" to true.

To disable external entity processing for Validator, configure both properties XMLConstants.ACCESS_EXTERNAL_DTD, XMLConstants.ACCESS_EXTERNAL_SCHEMA to the empty string "".

Noncompliant Code Example

/* Load XML stream and display content */
String maliciousSample = "xxe.xml";
XMLInputFactory factory = XMLInputFactory.newInstance();

try (FileInputStream fis = new FileInputStream(malicousSample)) {
  // Load XML stream
  XMLStreamReader xmlStreamReader = factory.createXMLStreamReader(fis);  // Noncompliant; reader is vulnerable

  //...

Compliant Solution

/* Load XML stream and display content */
String maliciousSample = "xxe.xml";
XMLInputFactory factory = XMLInputFactory.newInstance();

// disable external entities
factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);

try (FileInputStream fis = new FileInputStream(malicousSample)) {
    // Load XML stream
    XMLStreamReader xmlStreamReader = factory.createXMLStreamReader(fis);

See

squid:CommentedOutCodeLine

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
squid:S2976

Using File.createTempFile as the first step in creating a temporary directory causes a race condition and is inherently unreliable and insecure. Instead, Files.createTempDirectory (Java 7+) or a library function such as Guava's similarly-named Files.createTempDir should be used.

This rule raises an issue when the following steps are taken in immediate sequence:

  • call to File.createTempFile
  • delete resulting file
  • call mkdir on the File object

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 7.

Noncompliant Code Example

File tempDir;
tempDir = File.createTempFile("", ".");
tempDir.delete();
tempDir.mkdir();  // Noncompliant

Compliant Solution

Path tempPath = Files.createTempDirectory("");
File tempDir = tempPath.toFile();

See

squid:S3510

To prevent URL spoofing, HostnameVerifier.verify() methods should do more than simply return true. Doing so may get you quickly past an exception, but that comes at the cost of opening a security hole in your application.

Noncompliant Code Example

SSLContext sslcontext = SSLContext.getInstance( "TLS" );
sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
  public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
  public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
  public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }

}}, new java.security.SecureRandom());

Client client = ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(new HostnameVerifier() {
  @Override
  public boolean verify(String requestedHost, SSLSession remoteServerSession) {
    return true;  // Noncompliant
  }
}).build();

Compliant Solution

SSLContext sslcontext = SSLContext.getInstance( "TLSv1.2" );
sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
  @Override
  public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
  @Override
  public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
  @Override
  public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }

}}, new java.security.SecureRandom());

Client client = ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(new HostnameVerifier() {
  @Override
  public boolean verify(String requestedHost, SSLSession remoteServerSession) {
    return requestedHost.equalsIgnoreCase(remoteServerSession.getPeerHost()); // Compliant
  }
}).build();

See

squid:S3752

A @RequestMapping method handles all matching requests by default. That means that a method you intended only to be POST-ed to could also be called by a GET, thereby allowing hackers to call the method inappropriately. For example a "transferFunds" method might be invoked like so: <img src="http://bank.com/actions/transferFunds?reciepientRouting=000000&receipientAccount=11111111&amount=200.00" width="1" height="1"/>

For that reason, you should always explicitly list the single HTTP method with which you expect your @RequestMapping Java method to be called. This rule raises an issue when method is missing and when the method parameter is configured with more than one verb. Mixing GET and POST verbs can lead to information leakage. It's easier to setup Spring Security’s CSRF protection when there is only one verb per @RequestMapping.

Noncompliant Code Example

@RequestMapping("/greet")  // Noncompliant
public String greet(String greetee) {

Compliant Solution

  @RequestMapping("/greet", method = GET)
  public String greet(String greetee) {

See

squid:S4601

URL patterns configured on a HttpSecurity.authorizeRequests() method are considered in the order they were declared. It's easy to do a mistake and to declare a less restrictive configuration before a more restrictive one. Therefore, it's required to review the order of the "antMatchers" declarations. The /** one should be the last one if it is declared.

This rule raises an issue when:

- A pattern is preceded by another that ends with ** and has the same beginning. E.g.: /page*-admin/db/** is after /page*-admin/**

- A pattern without wildcard characters is preceded by another that matches. E.g.: /page-index/db is after /page*/**

Noncompliant Code Example

  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
      .antMatchers("/resources/**", "/signup", "/about").permitAll() // Compliant
      .antMatchers("/admin/**").hasRole("ADMIN")
      .antMatchers("/admin/login").permitAll() // Noncompliant; the pattern "/admin/login" should occurs before "/admin/**"
      .antMatchers("/**", "/home").permitAll()
      .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") // Noncompliant; the pattern "/db/**" should occurs before "/**"
      .and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();
  }

Compliant Solution

  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
      .antMatchers("/resources/**", "/signup", "/about").permitAll() // Compliant
      .antMatchers("/admin/login").permitAll()
      .antMatchers("/admin/**").hasRole("ADMIN") // Compliant
      .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
      .antMatchers("/**", "/home").permitAll() // Compliant; "/**" is the last one
      .and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();
  }

See

squid:S3751

A method with a @RequestMapping annotation part of a class annotated with @Controller (directly or indirectly through a meta annotation - @RestController from Spring Boot is a good example) will be called to handle matching web requests. That will happen even if the method is private, because Spring invokes such methods via reflection, without checking visibility.

So marking a sensitive method private may seem like a good way to control how such code is called. Unfortunately, not all Spring frameworks ignore visibility in this way. For instance, if you've tried to control web access to your sensitive, private, @RequestMapping method by marking it @Secured ... it will still be called, whether or not the user is authorized to access it. That's because AOP proxies are not applied to non-public methods.

In addition to @RequestMapping, this rule also considers the annotations introduced in Spring Framework 4.3: @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping.

Noncompliant Code Example

@RequestMapping("/greet", method = GET)
private String greet(String greetee) {  // Noncompliant

Compliant Solution

@RequestMapping("/greet", method = GET)
public String greet(String greetee) {

See

squid:S1219

Even if it is legal, mixing case and non-case labels in the body of a switch statement is very confusing and can even be the result of a typing error.

Noncompliant Code Example

switch (day) {
  case MONDAY:
  case TUESDAY:
  WEDNESDAY:   // Noncompliant; syntactically correct, but behavior is not what's expected
    doSomething();
    break;
  ...
}

switch (day) {
  case MONDAY:
    break;
  case TUESDAY:
    foo:for(int i = 0 ; i < X ; i++) {  // Noncompliant; the code is correct and behaves as expected but is barely readable
         /* ... */
        break foo;  // this break statement doesn't relate to the nesting case TUESDAY
         /* ... */
    }
    break;
    /* ... */
}

Compliant Solution

switch (day) {
  case MONDAY:
  case TUESDAY:
  case WEDNESDAY:
    doSomething();
    break;
  ...
}

switch (day) {
  case MONDAY:
    break;
  case TUESDAY:
    compute(args); // put the content of the labelled "for" statement in a dedicated method
    break;

    /* ... */
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
squid:S1226

While it is technically correct to assign to parameters from within method bodies, doing so before the parameter value is read is likely a bug. Instead, initial values of parameters, caught exceptions, and foreach parameters should be, if not treated as final, then at least read before reassignment.

Noncompliant Code Example

public void doTheThing(String str, int i, List<String> strings) {
  str = Integer.toString(i); // Noncompliant

  for (String s : strings) {
    s = "hello world"; // Noncompliant
  }
}

See

  • MISRA C:2012, 17.8 - A function parameter should not be modified
squid:ForLoopCounterChangedCheck

A for loop stop condition should test the loop counter against an invariant value (i.e. one that is true at both the beginning and ending of every loop iteration). Ideally, this means that the stop condition is set to a local variable just before the loop begins.

Stop conditions that are not invariant are slightly less efficient, as well as being difficult to understand and maintain, and likely lead to the introduction of errors in the future.

This rule tracks three types of non-invariant stop conditions:

  • When the loop counters are updated in the body of the for loop
  • When the stop condition depend upon a method call
  • When the stop condition depends on an object property, since such properties could change during the execution of the loop.

Noncompliant Code Example

for (int i = 0; i < 10; i++) {
  ...
  i = i - 1; // Noncompliant; counter updated in the body of the loop
  ...
}

Compliant Solution

for (int i = 0; i < 10; i++) {...}

See

  • MISRA C:2004, 13.6 - Numeric variables being used within a for loop for iteration counting shall not be modified in the body of the loop.
  • MISRA C++:2008, 6-5-3 - The loop-counter shall not be modified within condition or statement.
squid:S1313

Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:

Today's services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery and deployment:

  • The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
  • It forces the same address to be used in every environment (dev, sys, qa, prod).

Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service at this address or spoof the IP address. Such an attack is always possible, but in the case of a hardcoded IP address the fix will be much slower, which will increase an attack's impact.

Recommended Secure Coding Practices

  • make the IP address configurable.

Noncompliant Code Example

String ip = "192.168.12.42"; // Noncompliant
Socket socket = new Socket(ip, 6667);

Exceptions

No issue is reported for the following cases because they are not considered sensitive:

  • Loopback addresses 127.0.0.0/8 in CIDR notation (from 127.0.0.0 to 127.255.255.255)
  • Broadcast address 255.255.255.255
  • Non routable address 0.0.0.0
  • Strings of the form 2.5.<number>.<number> as they often match Object Identifiers (OID).

See

squid:S4829

Reading Standard Input is security-sensitive. It has led in the past to the following vulnerabilities:

It is common for attackers to craft inputs enabling them to exploit software vulnerabilities. Thus any data read from the standard input (stdin) can be dangerous and should be validated.

This rule flags code that reads from the standard input.

Ask Yourself Whether

  • data read from the standard input is not sanitized before being used.

You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

Sanitize all data read from the standard input before using it.

Sensitive Code Example

class A {
    void foo(String fmt, Object args) throws Exception {
        // Questionable. Check how the standard input is used.
        System.in.read();

        // Questionable. Check how safe this new InputStream is.
        System.setIn(new java.io.FileInputStream("test.txt"));

        java.io.Console console = System.console();
        // Questionable. All the following calls should be reviewed as they use the standard input.
        console.reader();
        console.readLine();
        console.readLine(fmt, args);
        console.readPassword();
        console.readPassword(fmt, args);
    }
}

Exceptions

All references to System.in will create issues except direct calls to System.in.close().

Command line parsing libraries such as JCommander often read standard input when asked for passwords. However this rule doesn't raise any issue in this case as another hotspot rule covers command line arguments.

See:

squid:S2647

Basic authentication's only means of obfuscation is Base64 encoding. Since Base64 encoding is easily recognized and reversed, it offers only the thinnest veil of protection to your users, and should not be used.

Noncompliant Code Example

// Using HttpPost from Apache HttpClient
String encoding = Base64Encoder.encode ("login:passwd");
org.apache.http.client.methods.HttpPost httppost = new HttpPost(url);
httppost.setHeader("Authorization", "Basic " + encoding);  // Noncompliant

or

// Using HttpURLConnection
String encoding = Base64.getEncoder().encodeToString(("login:passwd").getBytes(ā€Œ"UTFā€Œā€‹-8"​));
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Authorization", "Basic " + encoding); // Noncompliant

See

squid:S4823

Using command line arguments is security-sensitive. It has led in the past to the following vulnerabilities:

Command line arguments can be dangerous just like any other user input. They should never be used without being first validated and sanitized.

Remember also that any user can retrieve the list of processes running on a system, which makes the arguments provided to them visible. Thus passing sensitive information via command line arguments should be considered as insecure.

This rule raises an issue when on every program entry points (main methods) when command line arguments are used. The goal is to guide security code reviews.

Ask Yourself Whether

  • any of the command line arguments are used without being sanitized first.
  • your application accepts sensitive information via command line arguments.

If you answered yes to any of these questions you are at risk.

Recommended Secure Coding Practices

Sanitize all command line arguments before using them.

Any user or application can list running processes and see the command line arguments they were started with. There are safer ways of providing sensitive information to an application than exposing them in the command line. It is common to write them on the process' standard input, or give the path to a file containing the information.

Sensitive Code Example

This rule raises an issue as soon as there is a reference to argv, be it for direct use or via a CLI library like JCommander, GetOpt or Apache CLI.

public class Main {
    public static void main (String[] argv) {
        String option = argv[0];  // Questionable: check how the argument is used
    }
}
// === JCommander ===
import com.beust.jcommander.*;

public class Main {
    public static void main (String[] argv) {
        Main main = new Main();
        JCommander.newBuilder()
        .addObject(main)
        .build()
        .parse(argv); // Questionable
        main.run();
    }
}
// === GNU Getopt ===
import gnu.getopt.Getopt;

public class Main {
    public static void main (String[] argv) {
        Getopt g = new Getopt("myprog", argv, "ab"); // Questionable
    }
}
// === Apache CLI ===
import org.apache.commons.cli.*;

public class Main {
    public static void main (String[] argv) {
        Options options = new Options();
        CommandLineParser parser = new DefaultParser();
        try {
            CommandLine line = parser.parse(options, argv); // Questionable
        }
    }
}

In the case of Args4J, an issue is created on the public void run method of any class using org.kohsuke.args4j.Option or org.kohsuke.args4j.Argument.

Such a class is called directly by org.kohsuke.args4j.Starter outside of any public static void main method. If the class has no run method, no issue will be raised as there must be a public static void main and its argument is already highlighted.

// === argv4J ===
import org.kohsuke.args4j.Option;
import org.kohsuke.args4j.Argument;

public class Main {
    @Option(name="-myopt",usage="An option")
    public String myopt;

    @Argument(usage = "An argument", metaVar = "<myArg>")
    String myarg;

    String file;

    @Option(name="-file")
    public void setFile(String file) {
        this.file = file;
    }

    String arg2;

    @Argument(index=1)
    public void setArg2(String arg2) {
        this.arg2 = arg2;
    }

    public void run() { // Questionable: This function
        myarg; // check how this argument is used
    }
}

Exceptions

The support of Argv4J without the use of org.kohsuke.argv4j.Option is out of scope as there is no way to know which Bean will be used as the mainclass.

No issue will be raised on public static void main(String[] argv) if argv is not referenced in the method.

See

squid:S1314

Integer literals starting with a zero are octal rather than decimal values. While using octal values is fully supported, most developers do not have experience with them. They may not recognize octal values as such, mistaking them instead for decimal values.

Noncompliant Code Example

int myNumber = 010;   // Noncompliant. myNumber will hold 8, not 10 - was this really expected?

Compliant Solution

int myNumber = 8;

See

  • MISRA C:2004, 7.1 - Octal constants (other than zero) and octal escape sequences shall not be used.
  • MISRA C++:2008, 2-13-2 - Octal constants (other than zero) and octal escape sequences (other than "\0") shall not be used
  • MISRA C:2012, 7.1 - Octal constants shall not be used
  • CERT, DCL18-C. - Do not begin integer constants with 0 when specifying a decimal value
  • CERT, DCL50-J. - Use visually distinct identifiers
squid:S2653

There is no reason to have a main method in a web application. It may have been useful for debugging during application development, but such a method should never make it into production. Having a main method in a web application opens a door to the application logic that an attacker may never be able to reach (but watch out if one does!), but it is a sloppy practice and indicates that other problems may be present.

This rule raises an issue when a main method is found in a servlet or an EJB.

Noncompliant Code Example

public class MyServlet extends HttpServlet {
  public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    if (userIsAuthorized(req)) {
      updatePrices(req);
    }
  }

  public static void main(String[] args) { // Noncompliant
    updatePrices(req);
  }
}

See

squid:S3749

Spring @Controller, @Service, and @Repository classes are singletons by default, meaning only one instance of the class is ever instantiated in the application. Typically such a class might have a few static members, such as a logger, but all non-static members should be managed by Spring. That is, they should have one of these annotations: @Resource, @Inject, @Autowired or @Value.

Having non-injected members in one of these classes could indicate an attempt to manage state. Because they are singletons, such an attempt is almost guaranteed to eventually expose data from User1's session to User2.

This rule raises an issue when a singleton @Controller, @Service, or @Repository has non-static members that are not annotated with one of:

  • org.springframework.beans.factory.annotation.Autowired
  • org.springframework.beans.factory.annotation.Value
  • javax.annotation.Inject
  • javax.annotation.Resource

Noncompliant Code Example

@Controller
public class HelloWorld {

  private String name = null;

  @RequestMapping("/greet", method = GET)
  public String greet(String greetee) {

    if (greetee != null) {
      this.name = greetee;
    }

    return "Hello " + this.name;  // if greetee is null, you see the previous user's data
  }
}

See

squid:S4834

Controlling permissions is security-sensitive. It has led in the past to the following vulnerabilities:

Attackers can only damage what they have access to. Thus limiting their access is a good way to prevent them from wreaking havoc, but it has to be done properly.

This rule flags code that controls the access to resources and actions. The goal is to guide security code reviews.

More specifically it will raise issues on the following Spring code:

  • The definition of any class implementing interfaces

org.springframework.security.access.AccessDecisionVoter

org.springframework.security.access.AccessDecisionManager

org.springframework.security.access.AfterInvocationProvider

org.springframework.security.access.PermissionEvaluator

org.springframework.security.access.expression.SecurityExpressionOperations

org.springframework.security.access.expression.method.MethodSecurityExpressionHandler

org.springframework.security.core.GrantedAuthority

org.springframework.security.acls.model.PermissionGrantingStrategy

  • The definition of any class extending class

org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration

  • Any method annotated with

Pre-post annotations: @PreAuthorize, @PreFilter, @PostAuthorize or @PostFilter from org.springframework.security.access.prepost package.

@org.springframework.security.access.annotation.Secured

  • Calls to any of the following methods

org.springframework.security.acls.model.MutableAclService: createAcl, deleteAcl, updateAcl

org.springframework.security.config.annotation.web.builders.HttpSecurity: authorizeRequests

  • The instantiation of an anonymous class implementing org.springframework.security.core.GrantedAuthority or of any class implementing this interface directly.

It will also raise issue on JSR-250 annotations @RolesAllowed, @PermitAll and @DenyAll from javax.annotation.security package.

Ask Yourself Whether

  • at least one accessed action or resource is security-sensitive.
  • there is no access control in place or it does not cover all sensitive actions and resources.
  • users have permissions they don't need.
  • the access control is based on a user input or on some other unsafe data.
  • permissions are difficult to remove or take a long time to be updated.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

The first step is to restrict all sensitive actions to authenticated users.

Each user should have the lowest privileges possible. The access control granularity should match the sensitivity of each resource or action. The more sensitive it is, the less people should have access to it.

Do not base the access control on a user input or on a value which might have been tampered with. For example, the developer should not read a user's permissions from an HTTP cookie as it can be modified client-side.

Check that the access to each action and resource is properly restricted.

Enable administrators to swiftly remove permissions when necessary. This enables them to reduce the time an attacker can have access to your systems when a breach occurs.

Log and monitor refused access requests as they can reveal an attack.

See

squid:S1948

Fields in a Serializable class must themselves be either Serializable or transient even if the class is never explicitly serialized or deserialized. For instance, under load, most J2EE application frameworks flush objects to disk, and an allegedly Serializable object with non-transient, non-serializable data members could cause program crashes, and open the door to attackers. In general a Serializable class is expected to fulfil its contract and not have an unexpected behaviour when an instance is serialized.

This rule raises an issue on non-Serializable fields, and on collection fields when they are not private (because they could be assigned non-Serializable values externally), and when they are assigned non-Serializable types within the class.

Noncompliant Code Example

public class Address {
  //...
}

public class Person implements Serializable {
  private static final long serialVersionUID = 1905122041950251207L;

  private String name;
  private Address address;  // Noncompliant; Address isn't serializable
}

Compliant Solution

public class Address implements Serializable {
  private static final long serialVersionUID = 2405172041950251807L;
}

public class Person implements Serializable {
  private static final long serialVersionUID = 1905122041950251207L;

  private String name;
  private Address address;
}

Exceptions

The alternative to making all members serializable or transient is to implement special methods which take on the responsibility of properly serializing and de-serializing the object. This rule ignores classes which implement the following methods:

 private void writeObject(java.io.ObjectOutputStream out)
     throws IOException
 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;

See

squid:S5042

Expanding archive files is security-sensitive. For example, expanding archive files has led in the past to the following vulnerabilities:

Applications that expand archive files (zip, tar, jar, war, 7z, ...) should verify the path where the archive's files are expanded and not trust blindly the content of the archive. Archive's files should not be expanded outside of the root directory where the archive is supposed to be expanded. Also, applications should control the size of the expanded data to not be a victim of Zip Bomb attack. Failure to do so could allow an attacker to use a specially crafted archive that holds directory traversal paths (e.g. ../../attacker.sh) or the attacker could overload the file system, processors or memory of the operating system where the archive is expanded making the target OS completely unusable.

This rule raises an issue when code handle archives. The goal is to guide security code reviews.

Ask Yourself Whether

  • there is no validation of the name of the archive entry
  • there is no validation of the effective path where the archive entry is going to be expanded
  • there is no validation of the size of the expanded archive entry
  • there is no validation of the ratio between the compressed and uncompressed archive entry

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

  • Validate the full path of the extracted file against the full path of the directory where files are uncompressed.
    • the canonical path of the uncompressed file must start with the canonical path of the directory where files are extracted.
    • the name of the archive entry must not contain "..", i.e. reference to a parent directory.
String canonicalDirPath = outputDir.getCanonicalPath();
String canonicalDestPath = targetFile.getCanonicalPath();

if (!canonicalDestPath.startsWith(canonicalDirPath + File.separator)) { // Sanitizer
  throw new ArchiverException("Entry is trying to leave the target dir: " + zipEntry.getName());
}
  • Stop extracting the archive if any of its entries has been tainted with a directory traversal path.
  • Define and control the ratio between compressed and uncompress bytes.
  • Define and control the maximum allowed uncompressed file size.
  • Count the number of file entries extracted from the archive and abort the extraction if their number is greater than a predefined threshold.

Sensitive Code Example

java.util.zip.ZipFile zipFile = new ZipFile(zipFileName);

Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
  ZipEntry e = entries.nextElement(); // Questionable
  File f = new File(outputDir, e.getName());
  InputStream input = zipFile.getInputStream(e);
  extractFile(new ZipInputStream(input), outputDir, e.getName());
}

Exceptions

This rule doesn't raise an issue when a ZipEntry or a ArchiveEntry:

  • is declared as a class field
  • is a parameter of an abstract method of an interface or abstract class

See

squid:S1989

Even though the signatures for methods in a servlet include throws IOException, ServletException, it's a bad idea to let such exceptions be thrown. Failure to catch exceptions in a servlet could leave a system in a vulnerable state, possibly resulting in denial-of-service attacks, or the exposure of sensitive information because when a servlet throws an exception, the servlet container typically sends debugging information back to the user. And that information could be very valuable to an attacker.

This rule checks all exceptions in methods named "do*" are explicitly handled in servlet classes.

Noncompliant Code Example

public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws IOException, ServletException {
  String ip = request.getRemoteAddr();
  InetAddress addr = InetAddress.getByName(ip); // Noncompliant; getByName(String) throws UnknownHostException
  //...
}

Compliant Solution

public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws IOException, ServletException {
  try {
    String ip = request.getRemoteAddr();
    InetAddress addr = InetAddress.getByName(ip);
    //...
  }
  catch (UnknownHostException uhex) {
    //...
  }
}

See

squid:HiddenFieldCheck

Overriding or shadowing a variable declared in an outer scope can strongly impact the readability, and therefore the maintainability, of a piece of code. Further, it could lead maintainers to introduce bugs because they think they're using one variable but are really using another.

Noncompliant Code Example

class Foo {
  public int myField;

  public void doSomething() {
    int myField = 0;
    ...
  }
}

See

squid:S126

This rule applies whenever an if statement is followed by one or more else if statements; the final else if should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch statement.

Noncompliant Code Example

if (x == 0) {
  doSomething();
} else if (x == 1) {
  doSomethingElse();
}

Compliant Solution

if (x == 0) {
  doSomething();
} else if (x == 1) {
  doSomethingElse();
} else {
  throw new IllegalStateException();
}

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
squid:S128

When the execution is not explicitly terminated at the end of a switch case, it continues to execute the statements of the following case. While this is sometimes intentional, it often is a mistake which leads to unexpected behavior.

Noncompliant Code Example

switch (myVariable) {
  case 1:
    foo();
    break;
  case 2:  // Both 'doSomething()' and 'doSomethingElse()' will be executed. Is it on purpose ?
    doSomething();
  default:
    doSomethingElse();
    break;
}

Compliant Solution

switch (myVariable) {
  case 1:
    foo();
    break;
  case 2:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Exceptions

This rule is relaxed in the following cases:

switch (myVariable) {
  case 0:                                // Empty case used to specify the same behavior for a group of cases.
  case 1:
    doSomething();
    break;
  case 2:                                // Use of return statement
    return;
  case 3:                                // Use of throw statement
    throw new IllegalStateException();
  case 4:                                // Use of continue statement
    continue;
  default:                               // For the last case, use of break statement is optional
    doSomethingElse();
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.2 - An unconditional break statement shall terminate every non-empty switch clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-5 - An unconditional throw or break statement shall terminate every non-empty switch-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.3 - An unconditional break statement shall terminate every switch-clause
  • MITRE, CWE-484 - Omitted Break Statement in Switch
  • CERT, MSC17-C. - Finish every set of statements associated with a case label with a break statement
  • CERT, MSC52-J. - Finish every set of statements associated with a case label with a break statement
squid:S5194

Many existing switch statements are essentially simulations of switch expressions, where each arm either assigns to a common target variable or returns a value. Expressing this as a statement is roundabout, repetitive, and error-prone.

Java 12 added support for switch expressions, which provide more succinct and less error-prone version of switch.

Noncompliant Code Example

void day_of_week(DoW day) {
    int numLetters;
    switch (day) {  // Noncompliant
      case MONDAY:
      case FRIDAY:
      case SUNDAY:
        numLetters = 6;
        break;
      case TUESDAY:
        numLetters = 7;
        break;
      case THURSDAY:
      case SATURDAY:
        numLetters = 8;
        break;
      case WEDNESDAY:
        numLetters = 9;
        break;
      default:
        throw new IllegalStateException("Wat: " + day);
    }
}

int return_switch(int x) {
    switch (x) { // Noncompliant
      case 1:
        return 1;
      case 2:
        return 2;
      default:
        throw new IllegalStateException();
    }
}

Compliant Solution

int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
};
squid:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

Noncompliant Code Example

Connection conn = null;
try {
  conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
        "user=steve&password=blue"); // Noncompliant
  String uname = "steve";
  String password = "blue";
  conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
        "user=" + uname + "&password=" + password); // Noncompliant

  java.net.PasswordAuthentication pa = new java.net.PasswordAuthentication("userName", "1234".toCharArray());  // Noncompliant

Compliant Solution

Connection conn = null;
try {
  String uname = getEncryptedUser();
  String password = getEncryptedPass();
  conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
        "user=" + uname + "&password=" + password);

See

squid:S2184

When arithmetic is performed on integers, the result will always be an integer. You can assign that result to a long, double, or float with automatic type conversion, but having started as an int or long, the result will likely not be what you expect.

For instance, if the result of int division is assigned to a floating-point variable, precision will have been lost before the assignment. Likewise, if the result of multiplication is assigned to a long, it may have already overflowed before the assignment.

In either case, the result will not be what was expected. Instead, at least one operand should be cast or promoted to the final type before the operation takes place.

Noncompliant Code Example

float twoThirds = 2/3; // Noncompliant; int division. Yields 0.0
long millisInYear = 1_000*3_600*24*365; // Noncompliant; int multiplication. Yields 1471228928
long bigNum = Integer.MAX_VALUE + 2; // Noncompliant. Yields -2147483647
long bigNegNum =  Integer.MIN_VALUE-1; //Noncompliant, gives a positive result instead of a negative one.
Date myDate = new Date(seconds * 1_000); //Noncompliant, won't produce the expected result if seconds > 2_147_483
...
public long compute(int factor){
  return factor * 10_000;  //Noncompliant, won't produce the expected result if factor > 214_748
}

public float compute2(long factor){
  return factor / 123;  //Noncompliant, will be rounded to closest long integer
}

Compliant Solution

float twoThirds = 2f/3; // 2 promoted to float. Yields 0.6666667
long millisInYear = 1_000L*3_600*24*365; // 1000 promoted to long. Yields 31_536_000_000
long bigNum = Integer.MAX_VALUE + 2L; // 2 promoted to long. Yields 2_147_483_649
long bigNegNum =  Integer.MIN_VALUE-1L; // Yields -2_147_483_649
Date myDate = new Date(seconds * 1_000L);
...
public long compute(int factor){
  return factor * 10_000L;
}

public float compute2(long factor){
  return factor / 123f;
}

or

float twoThirds = (float)2/3; // 2 cast to float
long millisInYear = (long)1_000*3_600*24*365; // 1_000 cast to long
long bigNum = (long)Integer.MAX_VALUE + 2;
long bigNegNum =  (long)Integer.MIN_VALUE-1;
Date myDate = new Date((long)seconds * 1_000);
...
public long compute(long factor){
  return factor * 10_000;
}

public float compute2(float factor){
  return factor / 123;
}

See

  • MISRA C++:2008, 5-0-8 - An explicit integral or floating-point conversion shall not increase the size of the underlying type of a cvalue expression.
  • MITRE, CWE-190 - Integer Overflow or Wraparound
  • CERT, NUM50-J. - Convert integers to floating point for floating-point operations
  • CERT, INT18-C. - Evaluate integer expressions in a larger size before comparing or assigning to that size
  • SANS Top 25 - Risky Resource Management
squid:S5344

Storing users' passwords in clear-text in a database is definitely not safe as hackers may have read access to all user accounts stored in the database. It's common then to hash passwords and only store these hashes in the database. When running the authentication process, the hash of the password provided by the user is compared to the hash stored in the database. If both matches, the access is granted.

This looks like a perfect solution but some algorithms such as MD5 and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them.

That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160.

For this reason, when PasswordEncoder is used to authenticate user in a Spring application, it should use a secure algorithm. The following algorithms are considered not safe and should not be used:

  • org.springframework.security.authentication.encoding.ShaPasswordEncoder (Spring Security 4.2.x)
  • org.springframework.security.authentication.encoding.Md5PasswordEncoder (Spring Security 4.2.x)
  • org.springframework.security.crypto.password.LdapShaPasswordEncoder (Spring Security 5.0.x)
  • org.springframework.security.crypto.password.Md4PasswordEncoder (Spring Security 5.0.x)
  • org.springframework.security.crypto.password.MessageDigestPasswordEncoder (Spring Security 5.0.x)
  • org.springframework.security.crypto.password.NoOpPasswordEncoder (Spring Security 5.0.x)
  • org.springframework.security.crypto.password.StandardPasswordEncoder (Spring Security 5.0.x)
  • org.springframework.security.crypto.scrypt.SCryptPasswordEncoder (Spring Security 5.0.x)

Consider using safer alternatives, such as org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder (preferred) or org.springframework.security.crypto.password.Pbkdf2PasswordEncoder.

Noncompliant Code Example

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
        auth.jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery("SELECT * FROM users WHERE username = ?")
                .passwordEncoder(new StandardPasswordEncoder()); // Noncompliant
        // OR
        auth.jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery("SELECT * FROM users WHERE username = ?"); // Noncompliant; default uses plain-text
        // OR
        auth.userDetailsService(...); // Noncompliant; default uses plain-text
        // OR
        auth.userDetailsService(...).passwordEncoder(new StandardPasswordEncoder()); // Noncompliant
    }

Compliant Solution

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
        auth.jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery("Select * from users where username=?")
                .passwordEncoder(new BCryptPasswordEncoder());
        // or
        auth.userDetailsService(null).passwordEncoder(new BCryptPasswordEncoder());
    }

See

squid:S4499

This rule raises an issue when:

- a JavaMail's javax.mail.Session is created with a Properties object having no mail.smtp.ssl.checkserveridentity or mail.smtps.ssl.checkserveridentity not configured to true

- a Apache Common Emails's org.apache.commons.mail.SimpleEmail is used with setSSLOnConnect(true) or setStartTLSEnabled(true) or setStartTLSRequired(true) without a call to setSSLCheckServerIdentity(true)

Noncompliant Code Example

Email email = new SimpleEmail();
email.setSmtpPort(465);
email.setAuthenticator(new DefaultAuthenticator(username, password));
email.setSSLOnConnect(true); // Noncompliant; setSSLCheckServerIdentity(true) should also be called before sending the email
email.send();
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); // Noncompliant; Session is created without having "mail.smtp.ssl.checkserveridentity" set to true
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication("username@gmail.com", "password");
  }
});

Compliant Solution

Email email = new SimpleEmail();
email.setSmtpPort(465);
email.setAuthenticator(new DefaultAuthenticator(username, password));
email.setSSLOnConnect(true);
email.setSSLCheckServerIdentity(true); // Compliant
email.send();
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.ssl.checkserveridentity", true); // Compliant
Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication("username@gmail.com", "password");
  }
});

See

squid:EmptyStatementUsageCheck

Empty statements, i.e. ;, are usually introduced by mistake, for example because:

  • It was meant to be replaced by an actual statement, but this was forgotten.
  • There was a typo which lead the semicolon to be doubled, i.e. ;;.

Noncompliant Code Example

void doSomething() {
  ;                                                       // Noncompliant - was used as a kind of TODO marker
}

void doSomethingElse() {
  System.out.println("Hello, world!");;                     // Noncompliant - double ;
  ...
}

Compliant Solution

void doSomething() {}

void doSomethingElse() {
  System.out.println("Hello, world!");
  ...
  for (int i = 0; i < 3; i++) ; // compliant if unique statement of a loop
  ...
}

See

  • MISRA C:2004, 14.3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment provided that the first character following the null statement is a white-space character.
  • MISRA C++:2008, 6-2-3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment, provided that the first character following the null statement is a white-space character.
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • CERT, MSC51-J. - Do not place a semicolon immediately following an if, for, or while condition
  • CERT, EXP15-C. - Do not place a semicolon on the same line as an if, for, or while statement
squid:S2077

Formatting strings used as SQL queries is security-sensitive. It has led in the past to the following vulnerabilities:

SQL queries often need to use a hardcoded SQL string with a dynamic parameter coming from a user request. Formatting a string to add those parameters to the request is a bad practice as it can result in an SQL injection. The safe way to add parameters to a SQL query is to use SQL binding mechanisms.

This rule raises an issue when an SQL query is built by formatting Strings, even if there is no injection. This rule does not detect SQL injections. The goal is to guide security code reviews and to prevent a common bad practice.

The following method signatures from Java JDBC, JPA, JDO, Hibernate and Spring are tested:

  • org.hibernate.Session.createQuery
  • org.hibernate.Session.createSQLQuery
  • java.sql.Statement.executeQuery
  • java.sql.Statement.execute
  • java.sql.Statement.executeUpdate
  • java.sql.Statement.executeLargeUpdate
  • java.sql.Statement.addBatch
  • java.sql.Connection.prepareStatement
  • java.sql.Connection.prepareCall
  • java.sql.Connection.nativeSQL
  • javax.persistence.EntityManager.createNativeQuery
  • javax.persistence.EntityManager.createQuery
  • org.springframework.jdbc.core.JdbcOperations.batchUpdate
  • org.springframework.jdbc.core.JdbcOperations.execute
  • org.springframework.jdbc.core.JdbcOperations.query
  • org.springframework.jdbc.core.JdbcOperations.queryForList
  • org.springframework.jdbc.core.JdbcOperations.queryForMap
  • org.springframework.jdbc.core.JdbcOperations.queryForObject
  • org.springframework.jdbc.core.JdbcOperations.queryForRowSet
  • org.springframework.jdbc.core.JdbcOperations.queryForInt
  • org.springframework.jdbc.core.JdbcOperations.queryForLong
  • org.springframework.jdbc.core.JdbcOperations.update
  • org.springframework.jdbc.core.PreparedStatementCreatorFactory.<init>
  • org.springframework.jdbc.core.PreparedStatementCreatorFactory.newPreparedStatementCreator
  • javax.jdo.PersistenceManager.newQuery
  • javax.jdo.Query.setFilter
  • javax.jdo.Query.setGrouping

If a method is defined in an interface, implementations are also tested. For example this is the case for org.springframework.jdbc.core.JdbcOperations , which is usually used as org.springframework.jdbc.core.JdbcTemplate).

Ask Yourself Whether

  • the SQL query is built using string formatting technics, such as concatenating variables.
  • some of the values are coming from an untrusted source and are not sanitized.

You may be at risk if you answered yes to this question.

Recommended Secure Coding Practices

  • Avoid building queries manually using formatting technics. If you do it anyway, do not include user input in this building process.
  • Use parameterized queries, prepared statements, or stored procedures whenever possible.
  • You may also use ORM frameworks such as Hibernate which, if used correctly, reduce injection risks.
  • Avoid executing SQL queries containing unsafe input in stored procedures or functions.
  • Sanitize every unsafe input.

You can also reduce the impact of an attack by using a database account with low privileges.

Sensitive Code Example

public User getUser(Connection con, String user) throws SQLException {

  Statement stmt1 = null;
  Statement stmt2 = null;
  PreparedStatement pstmt;
  try {
    stmt1 = con.createStatement();
    ResultSet rs1 = stmt1.executeQuery("GETDATE()"); // No issue; hardcoded query

    stmt2 = con.createStatement();
    ResultSet rs2 = stmt2.executeQuery("select FNAME, LNAME, SSN " +
                 "from USERS where UNAME=" + user);  // Sensitive

    pstmt = con.prepareStatement("select FNAME, LNAME, SSN " +
                 "from USERS where UNAME=" + user);  // Sensitive
    ResultSet rs3 = pstmt.executeQuery();

    //...
}

public User getUserHibernate(org.hibernate.Session session, String data) {

  org.hibernate.Query query = session.createQuery(
            "FROM students where fname = " + data);  // Sensitive
  // ...
}

Compliant Solution

public User getUser(Connection con, String user) throws SQLException {

  Statement stmt1 = null;
  PreparedStatement pstmt = null;
  String query = "select FNAME, LNAME, SSN " +
                 "from USERS where UNAME=?"
  try {
    stmt1 = con.createStatement();
    ResultSet rs1 = stmt1.executeQuery("GETDATE()");

    pstmt = con.prepareStatement(query);
    pstmt.setString(1, user);  // Good; PreparedStatements escape their inputs.
    ResultSet rs2 = pstmt.executeQuery();

    //...
  }
}

public User getUserHibernate(org.hibernate.Session session, String data) {

  org.hibernate.Query query =  session.createQuery("FROM students where fname = ?");
  query = query.setParameter(0,data);  // Good; Parameter binding escapes all input

  org.hibernate.Query query2 =  session.createQuery("FROM students where fname = " + data); // Sensitive
  // ...

See

squid:S2070

The MD5 algorithm and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them. That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160.

The following APIs are tracked for use of obsolete crypto algorithms:

* java.security.AlgorithmParameters (JDK)

* java.security.AlgorithmParameterGenerator (JDK)

* java.security.MessageDigest (JDK)

* java.security.KeyFactory (JDK)

* java.security.KeyPairGenerator (JDK)

* java.security.Signature (JDK)

* javax.crypto.Mac (JDK)

* javax.crypto.KeyGenerator (JDK)

* org.apache.commons.codec.digest.DigestUtils (Apache Commons Codec)

* com.google.common.hash.Hashing (Guava)

* org.springframework.security.authentication.encoding.ShaPasswordEncoder (Spring Security 4.2.x)

* org.springframework.security.authentication.encoding.Md5PasswordEncoder (Spring Security 4.2.x)

* org.springframework.security.crypto.password.LdapShaPasswordEncoder (Spring Security 5.0.x)

* org.springframework.security.crypto.password.Md4PasswordEncoder (Spring Security 5.0.x)

* org.springframework.security.crypto.password.MessageDigestPasswordEncoder (Spring Security 5.0.x)

* org.springframework.security.crypto.password.NoOpPasswordEncoder (Spring Security 5.0.x)

* org.springframework.security.crypto.password.StandardPasswordEncoder (Spring Security 5.0.x)

Consider using safer alternatives, such as SHA-256, SHA-3 or adaptive one way functions like bcrypt or PBKDF2.

Noncompliant Code Example

MessageDigest md = MessageDigest.getInstance("SHA1");  // Noncompliant

Compliant Solution

MessageDigest md = MessageDigest.getInstance("SHA-256");

See

Deprecated

This rule is deprecated; use S4790 instead.

squid:S3281

Default interceptors, such as application security interceptors, must be listed in the ejb-jar.xml file, or they will not be treated as default.

This rule applies to projects that contain JEE Beans (any one of javax.ejb.Singleton, MessageDriven, Stateless or Stateful).

Noncompliant Code Example

// file: ejb-interceptors.xml
<assembly-descriptor>
 <interceptor-binding> <!-- should be declared in ejb-jar.xml -->
      <ejb-name>*</ejb-name>
      <interceptor-class>com.myco.ImportantInterceptor</interceptor-class><!-- Noncompliant; will NOT be treated as default -->
   </interceptor-binding>
</assembly-descriptor>

Compliant Solution

// file: ejb-jar.xml
<assembly-descriptor>
 <interceptor-binding>
      <ejb-name>*</ejb-name>
      <interceptor-class>com.myco.ImportantInterceptor</interceptor-class>
   </interceptor-binding>
</assembly-descriptor>

See

squid:S4347

The java.security.SecureRandom class provides a strong random number generator (RNG) appropriate for cryptography. However, seeding it with a constant or another predictable value will weaken it significantly. In general, it is much safer to rely on the seed provided by the SecureRandom implementation.

This rule raises an issue when SecureRandom.setSeed() or SecureRandom(byte[]) are called with a seed that is either of:

  • a constant
  • System.currentTimeMillis()

Noncompliant Code Example

SecureRandom sr = new SecureRandom();
sr.setSeed(123456L); // Noncompliant
int v = sr.next(32);

sr = new SecureRandom("abcdefghijklmnop".getBytes("us-ascii")); // Noncompliant
v = sr.next(32);

Compliant Solution

SecureRandom sr = new SecureRandom();
int v = sr.next(32);

See

squid:S3011

Changing or bypassing accessibility is security-sensitive. For example, it has led in the past to the following vulnerability:

private methods were made private for a reason, and the same is true of every other visibility level. Altering or bypassing the accessibility of classes, methods, or fields violates the encapsulation principle and could introduce security holes.

This rule raises an issue when reflection is used to change the visibility of a class, method or field, and when it is used to directly update a field value.

Ask Yourself Whether

  • there is a good reason to override the existing accessibility level of the method/field. This is very rarely the case. Accessing hidden fields and methods will make your code unstable as they are not part of the public API and may change in future versions.
  • this method is called by untrusted code. *
  • it is possible to modify or bypass the accessibility of sensitive methods or fields using this code. *
  • untrusted code can access the java reflection API. *

* You are at risk if you answered yes to those questions.

Recommended Secure Coding Practices

Don't change or bypass the accessibility of any method or field if possible.

If untrusted code can execute this method, make sure that it cannot decide which method or field's accessibility can be modified or bypassed.

Untrusted code should never have direct access to the java Reflection API. If this method can do it, make sure that it is an exception. Use ClassLoaders and SecurityManagers in order to sandbox any untrusted code and forbid access to the Reflection API.

Sensitive Code Example

public void makeItPublic(String methodName) throws NoSuchMethodException {

  this.getClass().getMethod(methodName).setAccessible(true); // Questionable
}

public void setItAnyway(String fieldName, int value) {
  this.getClass().getDeclaredField(fieldName).setInt(this, value); // Questionable; bypasses controls in setter
}

See

squid:S5326

Validating SSL/TLS connections is security-sensitive. For example, it has led in the past to the following vulnerabilities:

SSL/TLS protocols encrypt network connections. The server usually provides a digital certificate to prove its identity. Accepting all SSL/TLS certificates makes your application vulnerable to Man-in-the-middle attacks (MITM).

This rule will raise an issue when a method named onReceivedSslError with first argument of type android.webkit.WebView is defined.

Ask Yourself Whether

  • invalid SSL/TLS certificates are accepted automatically.
  • The user is asked to accept invalid SSL/TLS certificates.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

  • Accept only trusted SSL/TLS certificates.
  • Do not ask users to accept unsafe connections as they are unlikely to make an informed security decision.

Sensitive Code Example

Android (See also "How to address WebView SSL Error Handler alerts in your apps.")

package com.example.myapplication.rspec_5326;

import android.net.http.SslError;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.util.function.Function;

public class SSLTLSValidation extends WebViewClient {
    private final Function<SslError, Boolean> acceptSslError;

    SSLTLSValidation(Function<SslError, Boolean> acceptSslError) {
        this.acceptSslError = acceptSslError;
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { // Sensitive
        if (acceptSslError.apply(error)) {
            handler.proceed();
        } else {
            handler.cancel();
        }
    }
}

See

squid:S5322

In Android applications, receiving intents is security-sensitive. For example, it has led in the past to the following vulnerability:

Once a receiver is registered, any app can broadcast potentially malicious intents to your application.

This rule raises an issue when a receiver is registered without specifying any "broadcast permission".

Ask Yourself Whether

  • The data extracted from intents is not sanitized.
  • Intents broadcast is not restricted.

You may be at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Restrict the access to broadcasted intents. See Android documentation for more information.

Sensitive Code Example

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.RequiresApi;

public class MyIntentReceiver {

    @RequiresApi(api = Build.VERSION_CODES.O)
    public void register(Context context, BroadcastReceiver receiver,
                         IntentFilter filter,
                         String broadcastPermission,
                         Handler scheduler,
                         int flags) {
        context.registerReceiver(receiver, filter); // Sensitive
        context.registerReceiver(receiver, filter, flags); // Sensitive

        // Broadcasting intent with "null" for broadcastPermission
        context.registerReceiver(receiver, filter, null, scheduler); // Sensitive
        context.registerReceiver(receiver, filter, null, scheduler, flags); // Sensitive


        context.registerReceiver(receiver, filter,broadcastPermission, scheduler); // OK
        context.registerReceiver(receiver, filter,broadcastPermission, scheduler, flags); // OK
    }
}

See

squid:S5324

In Android applications, accessing external storage is security-sensitive. For example, it has led in the past to the following vulnerability:

Any application having the permissions WRITE_EXTERNAL_STORAGE or READ_EXTERNAL_STORAGE can access files stored on an external storage, be it a private or a public file.

This rule raises an issue when the following functions are called:

  • android.os.Environment.getExternalStorageDirectory
  • android.os.Environment.getExternalStoragePublicDirectory
  • android.content.Context.getExternalFilesDir
  • android.content.Context.getExternalFilesDirs
  • android.content.Context.getExternalMediaDirs
  • android.content.Context.getExternalCacheDir
  • android.content.Context.getExternalCacheDirs
  • android.content.Context.getObbDir
  • android.content.Context.getObbDirs

Ask Yourself Whether

  • Data written to the external storage is security-sensitive and is not encrypted.
  • Data read from files is not validated.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

Validate any data read from files.

Avoid writing sensitive information to an external storage. If this is required, make sure that the data is encrypted properly.

Sensitive Code Example

import android.content.Context;
import android.os.Environment;

public class AccessExternalFiles {

    public void accessFiles(Context context) {
        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); // Sensitive
        context.getExternalFilesDir(Environment.DIRECTORY_PICTURES); // Sensitive
    }
}

See

squid:S5320

In Android applications, broadcasting intents is security-sensitive. For example, it has led in the past to the following vulnerability:

By default, broadcasted intents are visible to every application, exposing all sensitive information they contain.

This rule raises an issue when an intent is broadcasted without specifying any "receiver permission".

Ask Yourself Whether

  • The intent contains sensitive information.
  • Intent reception is not restricted.

You are at risk if you answered yes to all those questions.

Recommended Secure Coding Practices

Restrict the access to broadcasted intents. See Android documentation for more information.

Sensitive Code Example

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.support.annotation.RequiresApi;

public class MyIntentBroadcast {
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public void broadcast(Intent intent, Context context, UserHandle user,
                          BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
                          String initialData, Bundle initialExtras,
                          String broadcastPermission) {
        context.sendBroadcast(intent); // Sensitive
        context.sendBroadcastAsUser(intent, user); // Sensitive

        // Broadcasting intent with "null" for receiverPermission
        context.sendBroadcast(intent, null); // Sensitive
        context.sendBroadcastAsUser(intent, user, null); // Sensitive
        context.sendOrderedBroadcast(intent, null); // Sensitive
        context.sendOrderedBroadcastAsUser(intent, user, null, resultReceiver,
                scheduler, initialCode, initialData, initialExtras); // Sensitive

        context.sendBroadcast(intent, broadcastPermission); // Ok
        context.sendBroadcastAsUser(intent, user, broadcastPermission); // Ok
        context.sendOrderedBroadcast(intent, broadcastPermission); // Ok
        context.sendOrderedBroadcastAsUser(intent, user,broadcastPermission, resultReceiver,
                scheduler, initialCode, initialData, initialExtras); // Ok
    }
}

See

squid:S2089

The fields in an HTTP request are putty in the hands of an attacker, and you cannot rely on them to tell you the truth about anything. While it may be safe to store such values after they have been neutralized, decisions should never be made based on their contents.

This rule flags uses of the referer header field.

Noncompliant Code Example

public class MyServlet extends HttpServlet {
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    String referer = request.getHeader("referer");  // Noncompliant
    if(isTrustedReferer(referer)){
      //..
    }
    //...
  }
}

See

squid:S888

Testing for loop termination using an equality operator (== and !=) is dangerous, because it could set up an infinite loop. Using a broader relational operator instead casts a wider net, and makes it harder (but not impossible) to accidentally write an infinite loop.

Noncompliant Code Example

for (int i = 1; i != 10; i += 2)  // Noncompliant. Infinite; i goes from 9 straight to 11.
{
  //...
}

Compliant Solution

for (int i = 1; i <= 10; i += 2)  // Compliant
{
  //...
}

Exceptions

Equality operators are ignored if the loop counter is not modified within the body of the loop and either:

  • starts below the ending value and is incremented by 1 on each iteration.
  • starts above the ending value and is decremented by 1 on each iteration.

Equality operators are also ignored when the test is against null.

for (int i = 0; arr[i] != null; i++) {
  // ...
}

for (int i = 0; (item = arr[i]) != null; i++) {
  // ...
}

See

  • MISRA C++:2008, 6-5-2
  • MITRE, CWE-835 - Loop with Unreachable Exit Condition ('Infinite Loop')
  • CERT, MSC21-C. - Use robust loop termination conditions
squid:S5122

Enabling Cross-Origin Resource Sharing (CORS) is security-sensitive. For example, it has led in the past to the following vulnerabilities:

Applications that enable CORS will effectively relax the same-origin policy in browsers, which is in place to prevent AJAX requests to hosts other than the one showing in the browser address bar. Being too permissive, CORS can potentially allow an attacker to gain access to sensitive information.

This rule flags code that enables CORS or specifies any HTTP response headers associated with CORS. The goal is to guide security code reviews.

Ask Yourself Whether

  • Any URLs responding with Access-Control-Allow-Origin: * include sensitive content.
  • Any domains specified in Access-Control-Allow-Origin headers are checked against a whitelist.

Recommended Secure Coding Practices

  • The Access-Control-Allow-Origin header should be set only on specific URLs that require access from other domains. Don't enable the header on the entire domain.
  • Don't rely on the Origin header blindly without validation as it could be spoofed by an attacker. Use a whitelist to check that the Origin domain (including protocol) is allowed before returning it back in the Access-Control-Allow-Origin header.
  • Use Access-Control-Allow-Origin: * only if your application absolutely requires it, for example in the case of an open/public API. For such endpoints, make sure that there is no sensitive content or information included in the response.

Sensitive Code Example

// === Java Servlet ===
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  resp.setHeader("Content-Type", "text/plain; charset=utf-8");
  resp.setHeader("Access-Control-Allow-Origin", "http://localhost:8080"); // Questionable
  resp.setHeader("Access-Control-Allow-Credentials", "true"); // Questionable
  resp.setHeader("Access-Control-Allow-Methods", "GET"); // Questionable
  resp.getWriter().write("response");
}
// === Spring MVC Controller annotation ===
@CrossOrigin(origins = "http://domain1.com") // Questionable
@RequestMapping("")
public class TestController {
    public String home(ModelMap model) {
        model.addAttribute("message", "ok ");
        return "view";
    }

    @CrossOrigin(origins = "http://domain2.com") // Questionable
    @RequestMapping(value = "/test1")
    public ResponseEntity<String> test1() {
        return ResponseEntity.ok().body("ok");
    }
}

See

squid:S899

When the return value of a function call contain the operation status code, this value should be tested to make sure the operation completed successfully.

This rule raises an issue when the return values of the following are ignored:

  • java.io.File operations that return a status code (except mkdirs)
  • Iterator.hasNext()
  • Enumeration.hasMoreElements()
  • Lock.tryLock()
  • non-void Condition.await* methods
  • CountDownLatch.await(long, TimeUnit)
  • Semaphore.tryAcquire
  • BlockingQueue: offer, remove

Noncompliant Code Example

public void doSomething(File file, Lock lock) {
  file.delete();  // Noncompliant
  // ...
  lock.tryLock(); // Noncompliant
}

Compliant Solution

public void doSomething(File file, Lock lock) {
  if (!lock.tryLock()) {
    // lock failed; take appropriate action
  }
  if (!file.delete()) {
    // file delete failed; take appropriate action
  }
}

See

  • MISRA C:2004, 16.10 - If a function returns error information, then that error information shall be tested
  • MISRA C++:2008, 0-1-7 - The value returned by a function having a non-void return type that is not an overloaded operator shall always be used.
  • MISRA C:2012, Dir. 4.7 - If a function returns error information, then that error information shall be tested
  • MISRA C:2012, 17.7 - The value returned by a function having non-void return type shall be used
  • CERT, ERR33-C. - Detect and handle standard library errors
  • CERT, POS54-C. - Detect and handle POSIX library errors
  • CERT, EXP00-J. - Do not ignore values returned by methods
  • CERT, EXP12-C. - Do not ignore values returned by functions
  • CERT, FIO02-J. - Detect and handle file-related errors
  • MITRE, CWE-754 - Improper Check for Unusual Exceptional Conditions
squid:S2092

The "secure" attribute prevents cookies from being sent over plaintext connections such as HTTP, where they would be easily eavesdropped upon. Instead, cookies with the secure attribute are only sent over encrypted HTTPS connections.

Recommended Secure Coding Practices

  • call setSecure(true) on the Cookie object

Noncompliant Code Example

Cookie c = new Cookie(SECRET, secret);  // Noncompliant; cookie is not secure
response.addCookie(c);

Compliant Solution

Cookie c = new Cookie(SECRET, secret);
c.setSecure(true);
response.addCookie(c);

See

squid:MaximumInheritanceDepth

Inheritance is certainly one of the most valuable concepts in object-oriented programming. It's a way to compartmentalize and reuse code by creating collections of attributes and behaviors called classes which can be based on previously created classes. But abusing this concept by creating a deep inheritance tree can lead to very complex and unmaintainable source code. Most of the time a too deep inheritance tree is due to bad object oriented design which has led to systematically use 'inheritance' when for instance 'composition' would suit better.

This rule raises an issue when the inheritance tree, starting from Object has a greater depth than is allowed.

typescript:S4822

An exception (including reject) thrown by a promise will not be caught be a nesting try block, due to the asynchronous nature of execution. Instead, use catch method of Promise or wrap it inside await expression.

Rule reports try-catch statements containing nothing else but call(s) to a function returning Promise (thus it's less likely that catch is intended to catch something else than Promise rejection).

Noncompliant Code Example

function runPromise() {
  return Promise.reject("rejection reason");
}

function foo() {
  try { // Noncompliant, the catch clause of the 'try' will not be executed for the code inside promise
    runPromise();
  } catch (e) {
    console.log("Failed to run promise", e);
  }
}

Compliant Solution

function foo() {
  runPromise().catch(e => console.log("Failed to run promise", e));
}

// or
async function foo() {
  try {
    await runPromise();
  } catch (e) {
    console.log("Failed to run promise", e);
  }
}
cobol:COBOL.AlterStatementUsageCheck

The ALTER statement should not be used. Trying to understand a program where the instruction as it appears may not be the actual instruction encountered by the program is very difficult, if not impossible.

If you need to change the processing sequence due to a certain condition, use PERFORM or GO TO instead.

tsql:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

See

tsql:S1659

Declaring multiple variable on one line is difficult to read.

Noncompliant Code Example

DECLARE @aaa AS INTEGER = 5, @bbb AS INTEGER = 42, @ccc AS CHAR(3) = 'foo'  -- Noncompliant

Compliant Solution

DECLARE @aaa AS INTEGER = 5
DECLARE @bbb AS INTEGER = 42
DECLARE @ccc AS CHAR(3) = 'foo'

See

  • MISRA C++:2008, 8-0-1 - An init-declarator-list or a member-declarator-list shall consist of a single init-declarator or member-declarator respectively
  • CERT, DCL52-J. - Do not declare more than one variable per declaration
  • CERT, DCL04-C. - Do not declare more than one variable per declaration
tsql:S907

A GOTO statement is an unstructured change in the control flow. They should be avoided and replaced by structured constructs.

See

  • MISRA C:2004, 14.4 - The goto statement shall not be used.
  • MISRA C:2012, 15.1 - The goto statement should not be used
tsql:S1172

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

Noncompliant Code Example

CREATE PROCEDURE SalesByCustomer
  @CustomerName nvarchar(50) -- Noncompliant
AS
SELECT c.customer_name, sum(ctr.amount) AS TotalAmount
  FROM customers c, contracts ctr
WHERE c.customer_id = ctr.customer_id
GROUP BY c.customer_name
ORDER BY c.customer_name

Compliant Solution

CREATE PROCEDURE SalesByCustomer
  @CustomerName nvarchar(50)
AS
SELECT c.customer_name, sum(ctr.amount) AS TotalAmount
  FROM customers c, contracts ctr
WHERE c.customer_id = ctr.customer_id
     AND c.customer_name = @CustomerName
GROUP BY c.customer_name
ORDER BY c.customer_name

See

  • MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions.
  • MISRA C:2012, 2.7 - There should be no unused parameters in functions
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
tsql:S121

While not technically incorrect, the omission of BEGIN...END can be misleading, and may lead to the introduction of errors during maintenance.

Noncompliant Code Example

IF @flag = 1 -- Noncompliant
  EXEC something;

Compliant Solution

IF @flag = 1
    BEGIN
        EXEC something;
    END;

See

  • MISRA C:2004, 14.8 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C:2004, 14.9 - An if (expression) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C++:2008, 6-3-1 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C++:2008, 6-4-1 - An if (condition) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C:2012, 15.6 - The body of an iteration-statement or a selection-statement shall be a compound-statement
  • CERT, EXP19-C. - Use braces for the body of an if, for, or while statement
  • CERT, EXP52-J. - Use braces for the body of an if, for, or while statement
tsql:S3641

A WHERE clause condition that uses NOT IN with a subquery will have unexpected results if that subquery returns NULL. On the other hand, NOT EXISTS subqueries work reliably under the same conditions.

This rule raises an issue when NOT IN is used with a subquery. This rule doesn't check if the selected column is a nullable column because the rules engine has no information about the table definition. It's up to the developer to review manually if the column is nullable.

Noncompliant Code Example

SELECT *
FROM my_table
WHERE my_column NOT IN (SELECT nullable_column FROM another_table)  -- Noncompliant; "nullable_column" may contain 'NULL' value and the whole SELECT query will return nothing

Compliant Solution

SELECT *
FROM my_table
WHERE NOT EXISTS (SELECT 1 FROM another_table WHERE nullable_column = my_table.my_column)
SELECT *
FROM my_table
WHERE my_column NOT IN (SELECT nullable_column FROM another_table WHERE nullable_column IS NOT NULL)
tsql:S1065

If a label is declared but not used in the program, it can be considered as dead code and should therefore be removed.

This will improve maintainability as developers will not wonder what this label is used for.

Noncompliant Code Example

label: -- Noncompliant
  PRINT 'hello world';
GO

Compliant Solution

PRINT 'hello world';
GO

See

  • MISRA C:2012, 2.6 - A function should not contain unused label declarations
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
tsql:S2070

The MD5 algorithm and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them. That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160.

Consider using safer alternatives, such as SHA-256, or SHA-3.

Noncompliant Code Example

SELECT HASHBYTES('SHA1', MyColumn) FROM dbo.MyTable;

Compliant Solution

SELECT HASHBYTES('SHA2_256', MyColumn) FROM dbo.MyTable;

See

tsql:S1313

Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:

Today's services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery and deployment:

  • The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
  • It forces the same address to be used in every environment (dev, sys, qa, prod).

Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service at this address or spoof the IP address. Such an attack is always possible, but in the case of a hardcoded IP address the fix will be much slower, which will increase an attack's impact.

Recommended Secure Coding Practices

  • make the IP address configurable.

Noncompliant Code Example

SET @IP = '192.168.12.42'; -- Noncompliant

Exceptions

No issue is reported for the following cases because they are not considered sensitive:

  • Loopback addresses 127.0.0.0/8 in CIDR notation (from 127.0.0.0 to 127.255.255.255)
  • Broadcast address 255.255.255.255
  • Non routable address 0.0.0.0
  • Strings of the form 2.5.<number>.<number> as they often match Object Identifiers (OID).

See

tsql:S131

The requirement for a final ELSE clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken.

Noncompliant Code Example

SELECT
  CASE category
    WHEN 'A' THEN 21
    WHEN 'B' THEN 33
END shipping_cost
FROM product

Compliant Solution

SELECT
  CASE category
    WHEN 'A' THEN 21
    WHEN 'B' THEN 33
    ELSE 42
END shipping_cost
FROM product

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
  • MITRE, CWE-478 - Missing Default Case in Switch Statement
  • CERT, MSC01-C. - Strive for logical completeness
tsql:S1116

Empty statements, i.e. ;, are usually introduced by mistake, for example because:

  • It was meant to be replaced by an actual statement, but this was forgotten.
  • There was a typo which lead the semicolon to be doubled, i.e. ;;.

See

  • MISRA C:2004, 14.3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment provided that the first character following the null statement is a white-space character.
  • MISRA C++:2008, 6-2-3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment, provided that the first character following the null statement is a white-space character.
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • CERT, MSC51-J. - Do not place a semicolon immediately following an if, for, or while condition
  • CERT, EXP15-C. - Do not place a semicolon on the same line as an if, for, or while statement
tsql:S125

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
tsql:S1590

UPDATE and DELETE statements should contain WHERE clauses to keep the modification of records under control. Otherwise unexpected data loss could result.

Noncompliant Code Example

DELETE FROM countries
UPDATE employee SET status = 'retired' FROM table1 AS employee

Compliant Solution

TRUNCATE TABLE countries
DELETE FROM countries WHERE CODE = @country_code
UPDATE employee SET status = 'retired' FROM table1 AS employee WHERE age > @maxAge

Exceptions

No issue is reported for statements made on temporary tables.

tsql:S126

This rule applies whenever an IF statement is followed by one or more ELSE IF statements; the final ELSE IF should be followed by an ELSE statement.

The requirement for a final ELSE statement is defensive programming.

The ELSE statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final ELSE clause in a CASE statement.

Noncompliant Code Example

IF @x = 1
  PRINT 'A'
ELSE IF @x = 2
  PRINT 'B'
ELSE IF @x = 3
  PRINT 'C'
-- Noncompliant; final ELSE is missing

Compliant Solution

IF @x = 1
  PRINT 'A'
ELSE IF @x = 2
  PRINT 'B'
ELSE IF @x = 3
  PRINT 'C'
ELSE
  PRINT 'Z'

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
tsql:S1763

Jump statements (BREAK, CONTINUE, RETURN, GOTO, and THROW), move control flow out of the current code block. So any statements that come after a jump are dead code.

Noncompliant Code Example

CREATE PROCEDURE
    AS
BEGIN
  ...
  RETURN -- Noncompliant, remove following statements

  PRINT 'End'
END

Compliant Solution

CREATE PROCEDURE
    AS
BEGIN
  ...
  RETURN
END

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code
  • MISRA C++:2008, 0-1-9 - There shall be no dead code
  • MISRA C:2012, 2.1 - A project shall not contain unreachable code
  • MISRA C:2012, 2.2 - There shall be no dead code
  • MITRE, CWE-561 - Dead Code
  • CERT, MSC56-J. - Detect and remove superfluous code and values
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
tsql:S1523

Executing code dynamically is security sensitive. It has led in the past to the following vulnerabilities:

Some APIs enable the execution of dynamic code by providing it as strings at runtime. These APIs might be useful in some very specific meta-programming use-cases. However most of the time their use is frowned upon as they also increase the risk of Injected Code. Such attacks can either run on the server or in the client (exemple: XSS attack) and have a huge impact on an application's security.

Both EXECUTE( ... ) and EXEC( ... ) execute as a command the string passed as an argument. They are safe only if the argument is composed of constant character string expressions. But if the command string is dynamically built using external parameters, then it is considered very dangerous because executing a random string allows the execution of arbitrary code.

This rule marks for review each occurrence of EXEC and EXECUTE. This rule does not detect code injections. It only highlights the use of APIs which should be used sparingly and very carefully. The goal is to guide security code reviews.

Ask Yourself Whether

  • the executed code may come from an untrusted source and hasn't been sanitized.
  • you really need to run code dynamically.

You are at risk if you answered yes to the first question. You are increasing the security risks for no reason if you answered yes to the second question.

Recommended Secure Coding Practices

The best solution is to not run code provided by an untrusted source. If you really need to build a command string using external parameters, you should use EXEC sp_executesql instead.

Do not try to create a blacklist of dangerous code. It is impossible to cover all attacks that way.

Noncompliant Code Example

CREATE PROCEDURE USER_BY_EMAIL(@email VARCHAR(255)) AS
BEGIN
  EXEC('USE AuthDB; SELECT id FROM user WHERE email = ''' + @email + ''' ;'); -- Noncompliant could inject code using @email
END

Compliant Solution

CREATE PROCEDURE USER_BY_EMAIL(@email VARCHAR(255)) AS
BEGIN
  EXEC sp_executesql 'USE AuthDB; SELECT id FROM user WHERE email = @user_email;',
                     '@user_email VARCHAR(255)',
                      @user_email = @email;
END

See

typescript:S4328

Dependencies should be explicitly listed in the package.json file. Importing a module that is not declared as a dependency makes it an implicit one and is bound to create problems.

vbnet:S4818

Using sockets is security-sensitive. It has led in the past to the following vulnerabilities:

Sockets are vulnerable in multiple ways:

  • They enable a software to interact with the outside world. As this world is full of attackers it is necessary to check that they cannot receive sensitive information or inject dangerous input.
  • The number of sockets is limited and can be exhausted. Which makes the application unresponsive to users who need additional sockets.

This rules flags code that creates sockets. It matches only the direct use of sockets, not use through frameworks or high-level APIs such as the use of http connections.

Ask Yourself Whether

  • sockets are created without any limit every time a user performs an action.
  • input received from sockets is used without being sanitized.
  • sensitive data is sent via sockets without being encrypted.

You are at risk if you answered yes to any of these questions.

Recommended Secure Coding Practices

  • In many cases there is no need to open a socket yourself. Use instead libraries and existing protocols.
  • Encrypt all data sent if it is sensitive. Usually it is better to encrypt it even if the data is not sensitive as it might change later.
  • Sanitize any input read from the socket.
  • Limit the number of sockets a given user can create. Close the sockets as soon as possible.

Sensitive Code Example

Imports System.Net.Sockets

Public Class Sockets

    Public Shared Sub Run()
        ' Sensitive
        Dim socket As Socket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

        ' TcpClient And UdpClient simply abstract the details of creating a Socket
        Dim client As TcpClient = New TcpClient("example.com", 80) ' Sensitive
        Dim listener As UdpClient = New UdpClient(80)   ' Sensitive
    End Sub

End Class

See

vbnet:S4507

Delivering code in production with debug features activated is security-sensitive. It has led in the past to the following vulnerabilities:

An application's debug features enable developers to find bugs more easily. It often gives access to detailed information on both the system running the application and users. Sometime it even enables the execution of custom commands. Thus deploying on production servers an application which has debug features activated is extremely dangerous.

Ask Yourself Whether

  • the code or configuration enabling the application debug features is deployed on production servers.
  • the application runs by default with debug features activated.

You are at risk if you answered yes to any of these questions.

Recommended Secure Coding Practices

Do not enable debug features on production servers.

The .Net Core framework offers multiple features which help during debug. Microsoft.AspNetCore.Builder.IApplicationBuilder.UseDeveloperExceptionPage and Microsoft.AspNetCore.Builder.IApplicationBuilder.UseDatabaseErrorPage are two of them. Make sure that those features are disabled in production.

Use If env.IsDevelopment() to disable debug code.

Sensitive Code Example

This rule raises issues when the following .Net Core methods are called: Microsoft.AspNetCore.Builder.IApplicationBuilder.UseDeveloperExceptionPage, Microsoft.AspNetCore.Builder.IApplicationBuilder.UseDatabaseErrorPage. No Issue is raised when those calls are disabled by if (env.IsDevelopment()).

Imports Microsoft.AspNetCore.Builder
Imports Microsoft.AspNetCore.Hosting

Namespace MyMvcApp
    Public Class Startup
        Public Sub Configure(ByVal app As IApplicationBuilder, ByVal env As IHostingEnvironment)
            If env.IsDevelopment() Then
                ' The following calls are ok because they are disabled in production
                app.UseDeveloperExceptionPage()
                app.UseDatabaseErrorPage()
            End If
            ' Those calls are Sensitive because it seems that they will run in production
            app.UseDeveloperExceptionPage() 'Sensitive
            app.UseDatabaseErrorPage() 'Sensitive
        End Sub
    End Class
End Namespace

Exceptions

This rule does not analyze configuration files. Make sure that debug mode is not enabled by default in those files.

See

vbnet:S4787

Encrypting data is security-sensitive. It has led in the past to the following vulnerabilities:

Proper encryption requires both the encryption algorithm and the key to be strong. Obviously the private key needs to remain secret and be renewed regularly. However these are not the only means to defeat or weaken an encryption.

This rule flags function calls that initiate encryption/decryption. The goal is to guide security code reviews.

Ask Yourself Whether

  • the private key might not be random, strong enough or the same key is reused for a long long time.
  • the private key might be compromised. It can happen when it is stored in an unsafe place or when it was transferred in an unsafe manner.
  • the key exchange is made without properly authenticating the receiver.
  • the encryption algorithm is not strong enough for the level of protection required. Note that encryption algorithms strength decreases as time passes.
  • the chosen encryption library is deemed unsafe.
  • a nonce is used, and the same value is reused multiple times, or the nonce is not random.
  • the RSA algorithm is used, and it does not incorporate an Optimal Asymmetric Encryption Padding (OAEP), which might weaken the encryption.
  • the CBC (Cypher Block Chaining) algorithm is used for encryption, and it's IV (Initialization Vector) is not generated using a secure random algorithm, or it is reused.
  • the Advanced Encryption Standard (AES) encryption algorithm is used with an unsecure mode. See the recommended practices for more information.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

  • Generate encryption keys using secure random algorithms.
  • When generating cryptographic keys (or key pairs), it is important to use a key length that provides enough entropy against brute-force attacks. For the Blowfish algorithm the key should be at least 128 bits long, while for the RSA algorithm it should be at least 2048 bits long.
  • Regenerate the keys regularly.
  • Always store the keys in a safe location and transfer them only over safe channels.
  • If there is an exchange of cryptographic keys, check first the identity of the receiver.
  • Only use strong encryption algorithms. Check regularly that the algorithm is still deemed secure. It is also imperative that they are implemented correctly. Use only encryption libraries which are deemed secure. Do not define your own encryption algorithms as they will most probably have flaws.
  • When a nonce is used, generate it randomly every time.
  • When using the RSA algorithm, incorporate an Optimal Asymmetric Encryption Padding (OAEP).
  • When CBC is used for encryption, the IV must be random and unpredictable. Otherwise it exposes the encrypted value to crypto-analysis attacks like "Chosen-Plaintext Attacks". Thus a secure random algorithm should be used. An IV value should be associated to one and only one encryption cycle, because the IV's purpose is to ensure that the same plaintext encrypted twice will yield two different ciphertexts.
  • The Advanced Encryption Standard (AES) encryption algorithm can be used with various modes. Galois/Counter Mode (GCM) with no padding should be preferred to the following combinations which are not secured:
    • Electronic Codebook (ECB) mode: Under a given key, any given plaintext block always gets encrypted to the same ciphertext block. Thus, it does not hide data patterns well. In some senses, it doesn't provide serious message confidentiality, and it is not recommended for use in cryptographic protocols at all.
    • Cipher Block Chaining (CBC) with PKCS#5 padding (or PKCS#7) is susceptible to padding oracle attacks.

Sensitive Code Example

Imports System
Imports System.Security.Cryptography

Namespace MyNamespace

    Public Class Class1

        Public Sub Main()

            Dim data As Byte() = {1, 1, 1}

            Dim myRSA As RSA = RSA.Create()
            Dim padding As RSAEncryptionPadding = RSAEncryptionPadding.CreateOaep(HashAlgorithmName.SHA1)

            ' Review all base RSA class' Encrypt/Decrypt calls
            myRSA.Encrypt(data, padding)  ' Sensitive
            myRSA.EncryptValue(data)      ' Sensitive
            myRSA.Decrypt(data, padding)  ' Sensitive
            myRSA.DecryptValue(data)      ' Sensitive

            Dim myRSAC As RSACryptoServiceProvider = New RSACryptoServiceProvider()
            ' Review the use of any TryEncrypt/TryDecrypt And specific Encrypt/Decrypt of RSA subclasses.
            myRSAC.Encrypt(data, False)    ' Sensitive
            myRSAC.Decrypt(data, False)    ' Sensitive

            Dim written As Integer
            myRSAC.TryEncrypt(data, Span<byte>.Empty, padding, out written) ' Sensitive
            myRSAC.TryDecrypt(data, Span<byte>.Empty, padding, out written) ' Sensitive

            Dim rgbKey As Byte() = {1, 2, 3}
            Dim rgbIV As Byte() = {4, 5, 6}
            Dim rijn = SymmetricAlgorithm.Create()

            ' Review the creation of Encryptors from any SymmetricAlgorithm instance.
            rijn.CreateEncryptor()   ' Sensitive
            rijn.CreateEncryptor(rgbKey, rgbIV)  ' Sensitive
            rijn.CreateDecryptor()  ' Sensitive
            rijn.CreateDecryptor(rgbKey, rgbIV)  ' Sensitive
        End Sub

        Public Class MyCrypto
            Inherits System.Security.Cryptography.AsymmetricAlgorithm ' Sensitive
            ' ...
        End Class

        Public Class MyCrypto2
            Inherits System.Security.Cryptography.SymmetricAlgorithm ' Sensitive
            ' ...
        End Class
    End Class
End Namespace

See

vbnet:S4829

Reading Standard Input is security-sensitive. It has led in the past to the following vulnerabilities:

It is common for attackers to craft inputs enabling them to exploit software vulnerabilities. Thus any data read from the standard input (stdin) can be dangerous and should be validated.

This rule flags code that reads from the standard input.

Ask Yourself Whether

  • data read from the standard input is not sanitized before being used.

You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

Sanitize all data read from the standard input before using it.

Sensitive Code Example

Imports System
Public Class C
    Public Sub Main()
        Dim x = Console.[In] ' Sensitive
        Console.Read() ' Sensitive
        Console.ReadKey() ' Sensitive
        Console.ReadLine() ' Sensitive
        Console.OpenStandardInput() ' Sensitive
    End Sub
End Class

Exceptions

This rule does not raise issues when the return value of the Console.Read Console.ReadKey or Console.ReadLine methods is ignored.

Imports System

Public Class C
    Public Sub Main()
        Console.ReadKey() ' Return value is ignored
        Console.ReadLine() ' Return value is ignored
    End Sub
End Class

See:

vbnet:S4823

Using command line arguments is security-sensitive. It has led in the past to the following vulnerabilities:

Command line arguments can be dangerous just like any other user input. They should never be used without being first validated and sanitized.

Remember also that any user can retrieve the list of processes running on a system, which makes the arguments provided to them visible. Thus passing sensitive information via command line arguments should be considered as insecure.

This rule raises an issue when on every program entry points (main methods) when command line arguments are used. The goal is to guide security code reviews.

Ask Yourself Whether

  • any of the command line arguments are used without being sanitized first.
  • your application accepts sensitive information via command line arguments.

If you answered yes to any of these questions you are at risk.

Recommended Secure Coding Practices

Sanitize all command line arguments before using them.

Any user or application can list running processes and see the command line arguments they were started with. There are safer ways of providing sensitive information to an application than exposing them in the command line. It is common to write them on the process' standard input, or give the path to a file containing the information.

Sensitive Code Example

Module Program
    Sub Main(args As String()) ' Sensitive as there is a reference to "args" in the procedure.
        Console.WriteLine(args(0))
    End Sub
End Module

See

vbnet:S4834

Controlling permissions is security-sensitive. It has led in the past to the following vulnerabilities:

Attackers can only damage what they have access to. Thus limiting their access is a good way to prevent them from wreaking havoc, but it has to be done properly.

This rule flags code that controls the access to resources and actions or configures this access. The goal is to guide security code reviews.

Ask Yourself Whether

  • at least one accessed action or resource is security-sensitive.
  • there is no access control in place or it does not cover all sensitive actions and resources.
  • users have permissions they don't need.
  • the access control is based on a user input or on some other unsafe data.
  • permissions are difficult to remove or take a long time to be updated.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

The first step is to restrict all sensitive actions to authenticated users.

Each user should have the lowest privileges possible. The access control granularity should match the sensitivity of each resource or action. The more sensitive it is, the less people should have access to it.

Do not base the access control on a user input or on a value which might have been tampered with. For example, the developer should not read a user's permissions from an HTTP cookie as it can be modified client-side.

Check that the access to each action and resource is properly restricted.

Enable administrators to swiftly remove permissions when necessary. This enables them to reduce the time an attacker can have access to your systems when a breach occurs.

Log and monitor refused access requests as they can reveal an attack.

Sensitive Code Example

Imports System.Threading
Imports System.Security.Permissions
Imports System.Security.Principal
Imports System.IdentityModel.Tokens

Class SecurityPrincipalDemo
    Class MyIdentity
        Implements IIdentity ' Sensitive, custom IIdentity implementations should be reviewed
    End Class

    Class MyPrincipal
        Implements IPrincipal ' Sensitive, custom IPrincipal implementations should be reviewed
    End Class

    <System.Security.Permissions.PrincipalPermission(SecurityAction.Demand, Role:="Administrators")> ' Sensitive. The access restrictions enforced by this attribute should be reviewed.
    Private Shared Sub CheckAdministrator()
        Dim MyIdentity As WindowsIdentity = WindowsIdentity.GetCurrent() ' Sensitive

        HttpContext.User = ... ' Sensitive: review all reference (set and get) to System.Web HttpContext.User

        Dim domain As AppDomain = AppDomain.CurrentDomain
        domain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal) ' Sensitive

        Dim identity As MyIdentity = New MyIdentity() ' Sensitive
        Dim MyPrincipal As MyPrincipal = New MyPrincipal(MyIdentity) ' Sensitive
        Thread.CurrentPrincipal = MyPrincipal ' Sensitive
        domain.SetThreadPrincipal(MyPrincipal) ' Sensitive

        Dim principalPerm As PrincipalPermission = New PrincipalPermission(Nothing, "Administrators")  ' Sensitive
        principalPerm.Demand()

        Dim handler As SecurityTokenHandler = ...
        Dim identities As ReadOnlyCollection(Of ClaimsIdentity) = handler.ValidateToken()  ' Sensitive, this creates identity
    End Sub

    ' Sensitive: review how this function uses the identity and principal.
    Private Sub modifyPrincipal(ByVal identity As MyIdentity, ByVal principal As MyPrincipal)
    End Sub
End Class

See

vbnet:S4790

Hashing data is security-sensitive. It has led in the past to the following vulnerabilities:

Cryptographic hash functions are used to uniquely identify information without storing their original form. When not done properly, an attacker can steal the original information by guessing it (ex: with a rainbow table), or replace the original data with another one having the same hash.

This rule flags code that initiates hashing.

Ask Yourself Whether

  • the hashed value is used in a security context.
  • the hashing algorithm you are using is known to have vulnerabilities.
  • salts are not automatically generated and applied by the hashing function.
  • any generated salts are cryptographically weak or not credential-specific.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

  • for security related purposes, use only hashing algorithms which are currently known to be strong. Avoid using algorithms like MD5 and SHA1 completely in security contexts.
  • do not define your own hashing- or salt algorithms as they will most probably have flaws.
  • do not use algorithms that compute too quickly, like SHA256, as it must remain beyond modern hardware capabilities to perform brute force and dictionary based attacks.
  • use a hashing algorithm that generate its own salts as part of the hashing. If you generate your own salts, make sure that a cryptographically strong salt algorithm is used, that generated salts are credential-specific, and finally, that the salt is applied correctly before the hashing.
  • save both the salt and the hashed value in the relevant database record; during future validation operations, the salt and hash can then be retrieved from the database. The hash is recalculated with the stored salt and the value being validated, and the result compared to the stored hash.
  • the strength of hashing algorithms often decreases over time as hardware capabilities increase. Check regularly that the algorithms you are using are still considered secure. If needed, rehash your data using a stronger algorithm.

Sensitive Code Example

Imports System.Security.Cryptography

Sub ComputeHash()

    ' Review all instantiations of classes that inherit from HashAlgorithm, for example:
    Dim hashAlgo As HashAlgorithm = HashAlgorithm.Create() ' Sensitive
    Dim hashAlgo2 As HashAlgorithm = HashAlgorithm.Create("SHA1") ' Sensitive
    Dim sha As SHA1 = New SHA1CryptoServiceProvider() ' Sensitive
    Dim md5 As MD5 = New MD5CryptoServiceProvider() ' Sensitive

    ' ...
End Sub

Class MyHashAlgorithm
    Inherits HashAlgorithm ' Sensitive

    ' ...
End Class

See

vbnet:S4792

Configuring loggers is security-sensitive. It has led in the past to the following vulnerabilities:

Logs are useful before, during and after a security incident.

  • Attackers will most of the time start their nefarious work by probing the system for vulnerabilities. Monitoring this activity and stopping it is the first step to prevent an attack from ever happening.
  • In case of a successful attack, logs should contain enough information to understand what damage an attacker may have inflicted.

Logs are also a target for attackers because they might contain sensitive information. Configuring loggers has an impact on the type of information logged and how they are logged.

This rule flags for review code that initiates loggers configuration. The goal is to guide security code reviews.

Ask Yourself Whether

  • unauthorized users might have access to the logs, either because they are stored in an insecure location or because the application gives access to them.
  • the logs contain sensitive information on a production server. This can happen when the logger is in debug mode.
  • the log can grow without limit. This can happen when additional information is written into logs every time a user performs an action and the user can perform the action as many times as he/she wants.
  • the logs do not contain enough information to understand the damage an attacker might have inflicted. The loggers mode (info, warn, error) might filter out important information. They might not print contextual information like the precise time of events or the server hostname.
  • the logs are only stored locally instead of being backuped or replicated.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

  • Check that your production deployment doesn't have its loggers in "debug" mode as it might write sensitive information in logs.
  • Production logs should be stored in a secure location which is only accessible to system administrators.
  • Configure the loggers to display all warnings, info and error messages. Write relevant information such as the precise time of events and the hostname.
  • Choose log format which is easy to parse and process automatically. It is important to process logs rapidly in case of an attack so that the impact is known and limited.
  • Check that the permissions of the log files are correct. If you index the logs in some other service, make sure that the transfer and the service are secure too.
  • Add limits to the size of the logs and make sure that no user can fill the disk with logs. This can happen even when the user does not control the logged information. An attacker could just repeat a logged action many times.

Remember that configuring loggers properly doesn't make them bullet-proof. Here is a list of recommendations explaining on how to use your logs:

  • Don't log any sensitive information. This obviously includes passwords and credit card numbers but also any personal information such as user names, locations, etc... Usually any information which is protected by law is good candidate for removal.
  • Sanitize all user inputs before writing them in the logs. This includes checking its size, content, encoding, syntax, etc... As for any user input, validate using whitelists whenever possible. Enabling users to write what they want in your logs can have many impacts. It could for example use all your storage space or compromise your log indexing service.
  • Log enough information to monitor suspicious activities and evaluate the impact an attacker might have on your systems. Register events such as failed logins, successful logins, server side input validation failures, access denials and any important transaction.
  • Monitor the logs for any suspicious activity.

Sensitive Code Example

.Net Core: configure programmatically

Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports Microsoft.AspNetCore
Imports Microsoft.AspNetCore.Builder
Imports Microsoft.AspNetCore.Hosting
Imports Microsoft.Extensions.Configuration
Imports Microsoft.Extensions.DependencyInjection
Imports Microsoft.Extensions.Logging
Imports Microsoft.Extensions.Options

Namespace MvcApp

    Public Class ProgramLogging

        Public Shared Function CreateWebHostBuilder(args As String()) As IWebHostBuilder

            WebHost.CreateDefaultBuilder(args) _
                .ConfigureLogging(Function(hostingContext, Logging) ' Sensitive
                                      ' ...
                                  End Function) _
            .UseStartup(Of StartupLogging)()

            '...
        End Function
    End Class


    Public Class StartupLogging

        Public Sub ConfigureServices(services As IServiceCollection)

            services.AddLogging(Function(logging) ' Sensitive
                                    '...
                                End Function)
        End Sub

        Public Sub Configure(app As IApplicationBuilder, env As IHostingEnvironment, loggerFactory As ILoggerFactory)

            Dim config As IConfiguration = Nothing
            Dim level As LogLevel = LogLevel.Critical
            Dim includeScopes As Boolean = False
            Dim filter As Func(Of String, Microsoft.Extensions.Logging.LogLevel, Boolean) = Nothing
            Dim consoleSettings As Microsoft.Extensions.Logging.Console.IConsoleLoggerSettings = Nothing
            Dim azureSettings As Microsoft.Extensions.Logging.AzureAppServices.AzureAppServicesDiagnosticsSettings = Nothing
            Dim eventLogSettings As Microsoft.Extensions.Logging.EventLog.EventLogSettings = Nothing

            ' An issue will be raised for each call to an ILoggerFactory extension methods adding loggers.
            loggerFactory.AddAzureWebAppDiagnostics() ' Sensitive
            loggerFactory.AddAzureWebAppDiagnostics(azureSettings) ' Sensitive
            loggerFactory.AddConsole() ' Sensitive
            loggerFactory.AddConsole(level) ' Sensitive
            loggerFactory.AddConsole(level, includeScopes) ' Sensitive
            loggerFactory.AddConsole(filter) ' Sensitive
            loggerFactory.AddConsole(filter, includeScopes) ' Sensitive
            loggerFactory.AddConsole(config) ' Sensitive
            loggerFactory.AddConsole(consoleSettings) ' Sensitive
            loggerFactory.AddDebug() ' Sensitive
            loggerFactory.AddDebug(level) ' Sensitive
            loggerFactory.AddDebug(filter) ' Sensitive
            loggerFactory.AddEventLog() ' Sensitive
            loggerFactory.AddEventLog(eventLogSettings) ' Sensitive
            loggerFactory.AddEventLog(level) ' Sensitive
            ' Only available for NET Standard 2.0 and above
            'loggerFactory.AddEventSourceLogger() ' Sensitive

            Dim providers As IEnumerable(Of ILoggerProvider) = Nothing
            Dim filterOptions1 As LoggerFilterOptions = Nothing
            Dim filterOptions2 As IOptionsMonitor(Of LoggerFilterOptions) = Nothing

            Dim factory As LoggerFactory = New LoggerFactory() ' Sensitive
            factory = New LoggerFactory(providers) ' Sensitive
            factory = New LoggerFactory(providers, filterOptions1) ' Sensitive
            factory = New LoggerFactory(providers, filterOptions2) ' Sensitive
        End Sub
    End Class
End Namespace

Log4Net

Imports System
Imports System.IO
Imports System.Xml
Imports log4net.Appender
Imports log4net.Config
Imports log4net.Repository

Namespace Logging
    Class Log4netLogging
        Private Sub Foo(ByVal repository As ILoggerRepository, ByVal element As XmlElement, ByVal configFile As FileInfo, ByVal configUri As Uri, ByVal configStream As Stream, ByVal appender As IAppender, ParamArray appenders As IAppender())
            log4net.Config.XmlConfigurator.Configure(repository) ' Sensitive
            log4net.Config.XmlConfigurator.Configure(repository, element) ' Sensitive
            log4net.Config.XmlConfigurator.Configure(repository, configFile) ' Sensitive
            log4net.Config.XmlConfigurator.Configure(repository, configUri) ' Sensitive
            log4net.Config.XmlConfigurator.Configure(repository, configStream) ' Sensitive
            log4net.Config.XmlConfigurator.ConfigureAndWatch(repository, configFile) ' Sensitive

            log4net.Config.DOMConfigurator.Configure() ' Sensitive
            log4net.Config.DOMConfigurator.Configure(repository) ' Sensitive
            log4net.Config.DOMConfigurator.Configure(element) ' Sensitive
            log4net.Config.DOMConfigurator.Configure(repository, element) ' Sensitive
            log4net.Config.DOMConfigurator.Configure(configFile) ' Sensitive
            log4net.Config.DOMConfigurator.Configure(repository, configFile) ' Sensitive
            log4net.Config.DOMConfigurator.Configure(configStream) ' Sensitive
            log4net.Config.DOMConfigurator.Configure(repository, configStream) ' Sensitive
            log4net.Config.DOMConfigurator.ConfigureAndWatch(configFile) ' Sensitive
            log4net.Config.DOMConfigurator.ConfigureAndWatch(repository, configFile) ' Sensitive

            log4net.Config.BasicConfigurator.Configure() ' Sensitive
            log4net.Config.BasicConfigurator.Configure(appender) ' Sensitive
            log4net.Config.BasicConfigurator.Configure(appenders) ' Sensitive
            log4net.Config.BasicConfigurator.Configure(repository) ' Sensitive
            log4net.Config.BasicConfigurator.Configure(repository, appender) ' Sensitive
            log4net.Config.BasicConfigurator.Configure(repository, appenders) ' Sensitive
        End Sub
    End Class
End Namespace

NLog: configure programmatically

Namespace Logging
    Class NLogLogging
        Private Sub Foo(ByVal config As NLog.Config.LoggingConfiguration)
            NLog.LogManager.Configuration = config ' Sensitive
        End Sub
    End Class
End Namespace

Serilog

Namespace Logging
    Class SerilogLogging
        Private Sub Foo()
            Dim config As Serilog.LoggerConfiguration = New Serilog.LoggerConfiguration() ' Sensitive
        End Sub
    End Class
End Namespace

See

csharpsquid:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

private int Divide(int numerator, int denominator)
{
    return numerator / denominator;  // FIXME denominator value might be  0
}

See

csharpsquid:S2234

When the names of parameters in a method call match the names of the method arguments, it contributes to clearer, more readable code. However, when the names match, but are passed in a different order than the method arguments, it indicates a mistake in the parameter order which will likely lead to unexpected results.

Noncompliant Code Example

public double Divide(int divisor, int dividend)
{
    return divisor/dividend;
}

public void DoTheThing()
{
    int divisor = 15;
    int dividend = 5;

    double result = Divide(dividend, divisor);  // Noncompliant; operation succeeds, but result is unexpected
    //...
}

Compliant Solution

public double Divide(int divisor, int dividend)
{
    return divisor/dividend;
}

public void DoTheThing()
{
    int divisor = 15;
    int dividend = 5;

    double result = Divide(divisor, dividend);
    //...
}
csharpsquid:S4507

Delivering code in production with debug features activated is security-sensitive. It has led in the past to the following vulnerabilities:

An application's debug features enable developers to find bugs more easily. It often gives access to detailed information on both the system running the application and users. Sometime it even enables the execution of custom commands. Thus deploying on production servers an application which has debug features activated is extremely dangerous.

Ask Yourself Whether

  • the code or configuration enabling the application debug features is deployed on production servers.
  • the application runs by default with debug features activated.

You are at risk if you answered yes to any of these questions.

Recommended Secure Coding Practices

Do not enable debug features on production servers.

The .Net Core framework offers multiple features which help during debug. Microsoft.AspNetCore.Builder.IApplicationBuilder.UseDeveloperExceptionPage and Microsoft.AspNetCore.Builder.IApplicationBuilder.UseDatabaseErrorPage are two of them. Make sure that those features are disabled in production.

Use if (env.IsDevelopment()) to disable debug code.

Sensitive Code Example

This rule raises issues when the following .Net Core methods are called: Microsoft.AspNetCore.Builder.IApplicationBuilder.UseDeveloperExceptionPage, Microsoft.AspNetCore.Builder.IApplicationBuilder.UseDatabaseErrorPage. No Issue is raised when those calls are disabled by if (env.IsDevelopment()).

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;

namespace mvcApp
{
    public class Startup2
    {
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                // The following calls are ok because they are disabled in production
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            // Those calls are Sensitive because it seems that they will run in production
            app.UseDeveloperExceptionPage(); // Sensitive
            app.UseDatabaseErrorPage(); // Sensitive
        }
    }
}

Exceptions

This rule does not analyze configuration files. Make sure that debug mode is not enabled by default in those files.

See

csharpsquid:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if (condition1)
{
    if (condition2)
    {
        // ...
    }
}

Compliant Solution

if (condition1 && condition2)
{
    // ...
}
csharpsquid:S4787

Encrypting data is security-sensitive. It has led in the past to the following vulnerabilities:

Proper encryption requires both the encryption algorithm and the key to be strong. Obviously the private key needs to remain secret and be renewed regularly. However these are not the only means to defeat or weaken an encryption.

This rule flags function calls that initiate encryption/decryption. The goal is to guide security code reviews.

Ask Yourself Whether

  • the private key might not be random, strong enough or the same key is reused for a long long time.
  • the private key might be compromised. It can happen when it is stored in an unsafe place or when it was transferred in an unsafe manner.
  • the key exchange is made without properly authenticating the receiver.
  • the encryption algorithm is not strong enough for the level of protection required. Note that encryption algorithms strength decreases as time passes.
  • the chosen encryption library is deemed unsafe.
  • a nonce is used, and the same value is reused multiple times, or the nonce is not random.
  • the RSA algorithm is used, and it does not incorporate an Optimal Asymmetric Encryption Padding (OAEP), which might weaken the encryption.
  • the CBC (Cypher Block Chaining) algorithm is used for encryption, and it's IV (Initialization Vector) is not generated using a secure random algorithm, or it is reused.
  • the Advanced Encryption Standard (AES) encryption algorithm is used with an unsecure mode. See the recommended practices for more information.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

  • Generate encryption keys using secure random algorithms.
  • When generating cryptographic keys (or key pairs), it is important to use a key length that provides enough entropy against brute-force attacks. For the Blowfish algorithm the key should be at least 128 bits long, while for the RSA algorithm it should be at least 2048 bits long.
  • Regenerate the keys regularly.
  • Always store the keys in a safe location and transfer them only over safe channels.
  • If there is an exchange of cryptographic keys, check first the identity of the receiver.
  • Only use strong encryption algorithms. Check regularly that the algorithm is still deemed secure. It is also imperative that they are implemented correctly. Use only encryption libraries which are deemed secure. Do not define your own encryption algorithms as they will most probably have flaws.
  • When a nonce is used, generate it randomly every time.
  • When using the RSA algorithm, incorporate an Optimal Asymmetric Encryption Padding (OAEP).
  • When CBC is used for encryption, the IV must be random and unpredictable. Otherwise it exposes the encrypted value to crypto-analysis attacks like "Chosen-Plaintext Attacks". Thus a secure random algorithm should be used. An IV value should be associated to one and only one encryption cycle, because the IV's purpose is to ensure that the same plaintext encrypted twice will yield two different ciphertexts.
  • The Advanced Encryption Standard (AES) encryption algorithm can be used with various modes. Galois/Counter Mode (GCM) with no padding should be preferred to the following combinations which are not secured:
    • Electronic Codebook (ECB) mode: Under a given key, any given plaintext block always gets encrypted to the same ciphertext block. Thus, it does not hide data patterns well. In some senses, it doesn't provide serious message confidentiality, and it is not recommended for use in cryptographic protocols at all.
    • Cipher Block Chaining (CBC) with PKCS#5 padding (or PKCS#7) is susceptible to padding oracle attacks.

Sensitive Code Example

using System;
using System.Security.Cryptography;

namespace MyNamespace
{
    public class MyClass
    {
        public void Main()
        {
            Byte[] data = {1,1,1};

            RSA myRSA = RSA.Create();
            RSAEncryptionPadding padding = RSAEncryptionPadding.CreateOaep(HashAlgorithmName.SHA1);
            // Review all base RSA class' Encrypt/Decrypt calls
            myRSA.Encrypt(data, padding); // Sensitive
            myRSA.EncryptValue(data); // Sensitive
            myRSA.Decrypt(data, padding); // Sensitive
            myRSA.DecryptValue(data); // Sensitive

            RSACryptoServiceProvider myRSAC = new RSACryptoServiceProvider();
            // Review the use of any TryEncrypt/TryDecrypt and specific Encrypt/Decrypt of RSA subclasses.
            myRSAC.Encrypt(data, false); // Sensitive
            myRSAC.Decrypt(data, false); // Sensitive
            int written;
            myRSAC.TryEncrypt(data, Span<byte>.Empty, padding, out written); // Sensitive
            myRSAC.TryDecrypt(data, Span<byte>.Empty, padding, out written); // Sensitive

            byte[] rgbKey = {1,2,3};
            byte[] rgbIV = {4,5,6};
            SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();
            // Review the creation of Encryptors from any SymmetricAlgorithm instance.
            rijn.CreateEncryptor(); // Sensitive
            rijn.CreateEncryptor(rgbKey, rgbIV); // Sensitive
            rijn.CreateDecryptor(); // Sensitive
            rijn.CreateDecryptor(rgbKey, rgbIV); // Sensitive
        }

        public class MyCrypto : System.Security.Cryptography.AsymmetricAlgorithm // Sensitive
        {
            // ...
        }

        public class MyCrypto2 : System.Security.Cryptography.SymmetricAlgorithm // Sensitive
        {
            // ...
        }
    }
}

See

csharpsquid:S4426

When generating cryptograpic keys (or key pairs), it is important to use a key length that provides enough entropy against brute-force attacks. For the RSA algorithm the key should be at

least 2048 bits long.

This rule raises an issue when a RSA key-pair generator is initialized with too small a length parameter.

Noncompliant Code Example

using System;
using System.Security.Cryptography;

namespace MyLibrary
{
    public class MyCryptoClass
    {
        static void Main()
        {
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024); // Noncompliant
            // ...
        }
    }
}

Compliant Solution

using System;
using System.Security.Cryptography;

namespace MyLibrary
{
    public class MyCryptoClass
    {
        static void Main()
        {
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048);
            // ...
        }
    }
}

See

csharpsquid:S3330

The HttpOnly cookie attribute tells the browser to prevent client-side scripts from reading cookies with the attribute, and its use can go a long way to defending against Cross-Site Scripting (XSS) attacks. Thus, as a precaution, the attribute should be set by default on all cookies set server-side, such as session id cookies.

When implementing Cross Site Request Forgery (XSRF) protection, a JavaScript-readable session cookie, generally named XSRF-TOKEN, should be created on the first HTTP GET request. For such a cookie, the HttpOnly attribute should be set to "false".

Setting the attribute can be done either programmatically, or globally via configuration files.

Noncompliant Code Example

HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie.HttpOnly = false; // Noncompliant; explicitly set to false
...
Response.Cookies.Add(myCookie);
HttpCookie myCookie = new HttpCookie("UserSettings"); // Noncompliant; the default value of 'HttpOnly' is used (=false)
...
Response.Cookies.Add(myCookie);

Compliant Solution

HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie.HttpOnly = true; // Compliant
...
Response.Cookies.Add(myCookie);

See

csharpsquid:S3220

The rules for method resolution are complex and perhaps not properly understood by all coders. The params keyword can make method declarations overlap in non-obvious ways, so that slight changes in the argument types of an invocation can resolve to different methods.

This rule raises an issue when an invocation resolves to a method declaration with params, but could also resolve to another non-params method too.

Noncompliant Code Example

public class MyClass
{
    private void Format(string a, params object[] b) { }

    private void Format(object a, object b, object c) { }
}

// ...
MyClass myClass = new MyClass();

myClass.Format("", null, null); // Noncompliant, resolves to the first Format with params, but was that intended?
csharpsquid:S4790

Hashing data is security-sensitive. It has led in the past to the following vulnerabilities:

Cryptographic hash functions are used to uniquely identify information without storing their original form. When not done properly, an attacker can steal the original information by guessing it (ex: with a rainbow table), or replace the original data with another one having the same hash.

This rule flags code that initiates hashing.

Ask Yourself Whether

  • the hashed value is used in a security context.
  • the hashing algorithm you are using is known to have vulnerabilities.
  • salts are not automatically generated and applied by the hashing function.
  • any generated salts are cryptographically weak or not credential-specific.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

  • for security related purposes, use only hashing algorithms which are currently known to be strong. Avoid using algorithms like MD5 and SHA1 completely in security contexts.
  • do not define your own hashing- or salt algorithms as they will most probably have flaws.
  • do not use algorithms that compute too quickly, like SHA256, as it must remain beyond modern hardware capabilities to perform brute force and dictionary based attacks.
  • use a hashing algorithm that generate its own salts as part of the hashing. If you generate your own salts, make sure that a cryptographically strong salt algorithm is used, that generated salts are credential-specific, and finally, that the salt is applied correctly before the hashing.
  • save both the salt and the hashed value in the relevant database record; during future validation operations, the salt and hash can then be retrieved from the database. The hash is recalculated with the stored salt and the value being validated, and the result compared to the stored hash.
  • the strength of hashing algorithms often decreases over time as hardware capabilities increase. Check regularly that the algorithms you are using are still considered secure. If needed, rehash your data using a stronger algorithm.

Sensitive Code Example

using System.Security.Cryptography;

void ComputeHash()
{
    // Review all instantiations of classes that inherit from HashAlgorithm, for example:
    HashAlgorithm hashAlgo = HashAlgorithm.Create(); // Sensitive
    HashAlgorithm hashAlgo2 = HashAlgorithm.Create("SHA1"); // Sensitive
    SHA1 sha = new SHA1CryptoServiceProvider(); // Sensitive
    MD5 md5 = new MD5CryptoServiceProvider(); // Sensitive
    // ...
}

class MyHashAlgorithm : HashAlgorithm // Sensitive
{
    // ...
}

See

csharpsquid:S4792

Configuring loggers is security-sensitive. It has led in the past to the following vulnerabilities:

Logs are useful before, during and after a security incident.

  • Attackers will most of the time start their nefarious work by probing the system for vulnerabilities. Monitoring this activity and stopping it is the first step to prevent an attack from ever happening.
  • In case of a successful attack, logs should contain enough information to understand what damage an attacker may have inflicted.

Logs are also a target for attackers because they might contain sensitive information. Configuring loggers has an impact on the type of information logged and how they are logged.

This rule flags for review code that initiates loggers configuration. The goal is to guide security code reviews.

Ask Yourself Whether

  • unauthorized users might have access to the logs, either because they are stored in an insecure location or because the application gives access to them.
  • the logs contain sensitive information on a production server. This can happen when the logger is in debug mode.
  • the log can grow without limit. This can happen when additional information is written into logs every time a user performs an action and the user can perform the action as many times as he/she wants.
  • the logs do not contain enough information to understand the damage an attacker might have inflicted. The loggers mode (info, warn, error) might filter out important information. They might not print contextual information like the precise time of events or the server hostname.
  • the logs are only stored locally instead of being backuped or replicated.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

  • Check that your production deployment doesn't have its loggers in "debug" mode as it might write sensitive information in logs.
  • Production logs should be stored in a secure location which is only accessible to system administrators.
  • Configure the loggers to display all warnings, info and error messages. Write relevant information such as the precise time of events and the hostname.
  • Choose log format which is easy to parse and process automatically. It is important to process logs rapidly in case of an attack so that the impact is known and limited.
  • Check that the permissions of the log files are correct. If you index the logs in some other service, make sure that the transfer and the service are secure too.
  • Add limits to the size of the logs and make sure that no user can fill the disk with logs. This can happen even when the user does not control the logged information. An attacker could just repeat a logged action many times.

Remember that configuring loggers properly doesn't make them bullet-proof. Here is a list of recommendations explaining on how to use your logs:

  • Don't log any sensitive information. This obviously includes passwords and credit card numbers but also any personal information such as user names, locations, etc... Usually any information which is protected by law is good candidate for removal.
  • Sanitize all user inputs before writing them in the logs. This includes checking its size, content, encoding, syntax, etc... As for any user input, validate using whitelists whenever possible. Enabling users to write what they want in your logs can have many impacts. It could for example use all your storage space or compromise your log indexing service.
  • Log enough information to monitor suspicious activities and evaluate the impact an attacker might have on your systems. Register events such as failed logins, successful logins, server side input validation failures, access denials and any important transaction.
  • Monitor the logs for any suspicious activity.

Sensitive Code Example

.Net Core: configure programmatically

using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore;

namespace MvcApp
{
    public class ProgramLogging
    {
        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .ConfigureLogging((hostingContext, logging) => // Sensitive
                {
                    // ...
                })
                .UseStartup<StartupLogging>();
    }

    public class StartupLogging
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddLogging(logging => // Sensitive
            {
                // ...
            });
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            IConfiguration config = null;
            LogLevel level = LogLevel.Critical;
            Boolean includeScopes = false;
            Func<string,Microsoft.Extensions.Logging.LogLevel,bool> filter = null;
            Microsoft.Extensions.Logging.Console.IConsoleLoggerSettings consoleSettings = null;
            Microsoft.Extensions.Logging.AzureAppServices.AzureAppServicesDiagnosticsSettings azureSettings = null;
            Microsoft.Extensions.Logging.EventLog.EventLogSettings eventLogSettings = null;

            // An issue will be raised for each call to an ILoggerFactory extension methods adding loggers.
            loggerFactory.AddAzureWebAppDiagnostics(); // Sensitive
            loggerFactory.AddAzureWebAppDiagnostics(azureSettings); // Sensitive
            loggerFactory.AddConsole(); // Sensitive
            loggerFactory.AddConsole(level); // Sensitive
            loggerFactory.AddConsole(level, includeScopes); // Sensitive
            loggerFactory.AddConsole(filter); // Sensitive
            loggerFactory.AddConsole(filter, includeScopes); // Sensitive
            loggerFactory.AddConsole(config); // Sensitive
            loggerFactory.AddConsole(consoleSettings); // Sensitive
            loggerFactory.AddDebug(); // Sensitive
            loggerFactory.AddDebug(level); // Sensitive
            loggerFactory.AddDebug(filter); // Sensitive
            loggerFactory.AddEventLog(); // Sensitive
            loggerFactory.AddEventLog(eventLogSettings); // Sensitive
            loggerFactory.AddEventLog(level); // Sensitive
            loggerFactory.AddEventSourceLogger(); // Sensitive

            IEnumerable<ILoggerProvider> providers = null;
            LoggerFilterOptions filterOptions1 = null;
            IOptionsMonitor<LoggerFilterOptions> filterOptions2 = null;

            LoggerFactory factory = new LoggerFactory(); // Sensitive
            new LoggerFactory(providers); // Sensitive
            new LoggerFactory(providers, filterOptions1); // Sensitive
            new LoggerFactory(providers, filterOptions2); // Sensitive
        }
    }
}

Log4Net

using System;
using System.IO;
using System.Xml;
using log4net.Appender;
using log4net.Config;
using log4net.Repository;

namespace Logging
{
    class Log4netLogging
    {
        void Foo(ILoggerRepository repository, XmlElement element, FileInfo configFile, Uri configUri, Stream configStream,
        IAppender appender, params IAppender[] appenders) {
            log4net.Config.XmlConfigurator.Configure(repository); // Sensitive
            log4net.Config.XmlConfigurator.Configure(repository, element); // Sensitive
            log4net.Config.XmlConfigurator.Configure(repository, configFile); // Sensitive
            log4net.Config.XmlConfigurator.Configure(repository, configUri); // Sensitive
            log4net.Config.XmlConfigurator.Configure(repository, configStream); // Sensitive
            log4net.Config.XmlConfigurator.ConfigureAndWatch(repository, configFile); // Sensitive

            log4net.Config.DOMConfigurator.Configure(); // Sensitive
            log4net.Config.DOMConfigurator.Configure(repository); // Sensitive
            log4net.Config.DOMConfigurator.Configure(element); // Sensitive
            log4net.Config.DOMConfigurator.Configure(repository, element); // Sensitive
            log4net.Config.DOMConfigurator.Configure(configFile); // Sensitive
            log4net.Config.DOMConfigurator.Configure(repository, configFile); // Sensitive
            log4net.Config.DOMConfigurator.Configure(configStream); // Sensitive
            log4net.Config.DOMConfigurator.Configure(repository, configStream); // Sensitive
            log4net.Config.DOMConfigurator.ConfigureAndWatch(configFile); // Sensitive
            log4net.Config.DOMConfigurator.ConfigureAndWatch(repository, configFile); // Sensitive

            log4net.Config.BasicConfigurator.Configure(); // Sensitive
            log4net.Config.BasicConfigurator.Configure(appender); // Sensitive
            log4net.Config.BasicConfigurator.Configure(appenders); // Sensitive
            log4net.Config.BasicConfigurator.Configure(repository); // Sensitive
            log4net.Config.BasicConfigurator.Configure(repository, appender); // Sensitive
            log4net.Config.BasicConfigurator.Configure(repository, appenders); // Sensitive
        }
    }
}

NLog: configure programmatically

namespace Logging
{
    class NLogLogging
    {
        void Foo(NLog.Config.LoggingConfiguration config) {
            NLog.LogManager.Configuration = config; // Sensitive, this changes the logging configuration.
        }
    }
}

Serilog

namespace Logging
{
    class SerilogLogging
    {
        void Foo() {
            new Serilog.LoggerConfiguration(); // Sensitive
        }
    }
}

See

csharpsquid:S4818

Using sockets is security-sensitive. It has led in the past to the following vulnerabilities:

Sockets are vulnerable in multiple ways:

  • They enable a software to interact with the outside world. As this world is full of attackers it is necessary to check that they cannot receive sensitive information or inject dangerous input.
  • The number of sockets is limited and can be exhausted. Which makes the application unresponsive to users who need additional sockets.

This rules flags code that creates sockets. It matches only the direct use of sockets, not use through frameworks or high-level APIs such as the use of http connections.

Ask Yourself Whether

  • sockets are created without any limit every time a user performs an action.
  • input received from sockets is used without being sanitized.
  • sensitive data is sent via sockets without being encrypted.

You are at risk if you answered yes to any of these questions.

Recommended Secure Coding Practices

  • In many cases there is no need to open a socket yourself. Use instead libraries and existing protocols.
  • Encrypt all data sent if it is sensitive. Usually it is better to encrypt it even if the data is not sensitive as it might change later.
  • Sanitize any input read from the socket.
  • Limit the number of sockets a given user can create. Close the sockets as soon as possible.

Sensitive Code Example

using System.Net.Sockets;

class TestSocket
{
    public static void Run()
    {
        // Sensitive
        Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        // TcpClient and UdpClient simply abstract the details of creating a Socket
        TcpClient client = new TcpClient("example.com", 80); // Sensitive
        UdpClient listener = new UdpClient(80); // Sensitive
    }
}

See

csharpsquid:S2070

The MD5 algorithm and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them. That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6.

This rule tracks usage of the System.Security.Cryptography.CryptoConfig.CreateFromName(), and System.Security.Cryptography.HashAlgorithm.Create() methods to instantiate MD5, DSA, HMACMD5, HMACRIPEMD160, RIPEMD-160 or SHA-1 algorithms, and of derived class instances of System.Security.Cryptography.SHA1 and System.Security.Cryptography.MD5.

Consider using safer alternatives, such as SHA-256, or SHA-3.

Noncompliant Code Example

var hashProvider1 = new MD5CryptoServiceProvider(); //Noncompliant
var hashProvider2 = (HashAlgorithm)CryptoConfig.CreateFromName("MD5"); //Noncompliant
var hashProvider3 = new SHA1Managed(); //Noncompliant
var hashProvider4 = HashAlgorithm.Create("SHA1"); //Noncompliant

Compliant Solution

var hashProvider1 = new SHA256Managed();
var hashProvider2 = (HashAlgorithm)CryptoConfig.CreateFromName("SHA256Managed");
var hashProvider3 = HashAlgorithm.Create("SHA256Managed");

See

Deprecated

This rule is deprecated; use S4790 instead.

csharpsquid:S2190

Recursion happens when control enters a loop that has no exit. This can happen a method invokes itself, when a pair of methods invoke each other, or when goto statements are used to move between two segments of code. It can be a useful tool, but unless the method includes a provision to break out of the recursion and return, the recursion will continue until the stack overflows and the program crashes.

Noncompliant Code Example

int Pow(int num, int exponent)   // Noncompliant; no condition under which pow isn't re-called
{
  num = num * Pow(num, exponent-1);
  return num;  // this is never reached
}

void InternalRecursion(int i)
{
  start:
    goto end;
  end:
    goto start; // Noncompliant; there's no way to break out of this method
}

Compliant Solution

int Pow(int num, int exponent)
{
  if (exponent > 1) // recursion now conditional and stop-able
  {
    num = num * Pow(num, exponent-1);
  }
  return num;
}
csharpsquid:S4829

Reading Standard Input is security-sensitive. It has led in the past to the following vulnerabilities:

It is common for attackers to craft inputs enabling them to exploit software vulnerabilities. Thus any data read from the standard input (stdin) can be dangerous and should be validated.

This rule flags code that reads from the standard input.

Ask Yourself Whether

  • data read from the standard input is not sanitized before being used.

You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

Sanitize all data read from the standard input before using it.

Sensitive Code Example

using System;
public class C
{
    public void Main()
    {
        Console.In; // Sensitive
        var code = Console.Read(); // Sensitive
        var keyInfo = Console.ReadKey(...); // Sensitive
        var text = Console.ReadLine(); // Sensitive
        Console.OpenStandardInput(...); // Sensitive
    }
}

Exceptions

This rule does not raise issues when the return value of the Console.Read Console.ReadKey or Console.ReadLine methods is ignored.

using System;
public class C
{
    public void Main()
    {
        Console.ReadKey(...); // Return value is ignored
        Console.ReadLine(); // Return value is ignored
    }
}

See:

csharpsquid:S4823

Using command line arguments is security-sensitive. It has led in the past to the following vulnerabilities:

Command line arguments can be dangerous just like any other user input. They should never be used without being first validated and sanitized.

Remember also that any user can retrieve the list of processes running on a system, which makes the arguments provided to them visible. Thus passing sensitive information via command line arguments should be considered as insecure.

This rule raises an issue when on every program entry points (main methods) when command line arguments are used. The goal is to guide security code reviews.

Ask Yourself Whether

  • any of the command line arguments are used without being sanitized first.
  • your application accepts sensitive information via command line arguments.

If you answered yes to any of these questions you are at risk.

Recommended Secure Coding Practices

Sanitize all command line arguments before using them.

Any user or application can list running processes and see the command line arguments they were started with. There are safer ways of providing sensitive information to an application than exposing them in the command line. It is common to write them on the process' standard input, or give the path to a file containing the information.

Sensitive Code Example

namespace MyNamespace
{
    class Program
    {
        static void Main(string[] args) // Sensitive if there is a reference to "args" in the method.
        {
            string myarg = args[0];
            // ...
        }
    }
}

See

csharpsquid:S4834

Controlling permissions is security-sensitive. It has led in the past to the following vulnerabilities:

Attackers can only damage what they have access to. Thus limiting their access is a good way to prevent them from wreaking havoc, but it has to be done properly.

This rule flags code that controls the access to resources and actions or configures this access. The goal is to guide security code reviews.

Ask Yourself Whether

  • at least one accessed action or resource is security-sensitive.
  • there is no access control in place or it does not cover all sensitive actions and resources.
  • users have permissions they don't need.
  • the access control is based on a user input or on some other unsafe data.
  • permissions are difficult to remove or take a long time to be updated.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

The first step is to restrict all sensitive actions to authenticated users.

Each user should have the lowest privileges possible. The access control granularity should match the sensitivity of each resource or action. The more sensitive it is, the less people should have access to it.

Do not base the access control on a user input or on a value which might have been tampered with. For example, the developer should not read a user's permissions from an HTTP cookie as it can be modified client-side.

Check that the access to each action and resource is properly restricted.

Enable administrators to swiftly remove permissions when necessary. This enables them to reduce the time an attacker can have access to your systems when a breach occurs.

Log and monitor refused access requests as they can reveal an attack.

Sensitive Code Example

using System.Threading;
using System.Security.Permissions;
using System.Security.Principal;
using System.IdentityModel.Tokens;

class SecurityPrincipalDemo
{
    class MyIdentity : IIdentity // Sensitive, custom IIdentity implementations should be reviewed
    {
        // ...
    }

    class MyPrincipal : IPrincipal // Sensitive, custom IPrincipal implementations should be reviewed
    {
        // ...
    }
    [System.Security.Permissions.PrincipalPermission(SecurityAction.Demand, Role = "Administrators")] // Sensitive. The access restrictions enforced by this attribute should be reviewed.
    static void CheckAdministrator()
    {
        WindowsIdentity MyIdentity = WindowsIdentity.GetCurrent(); // Sensitive
        HttpContext.User = ...; // Sensitive: review all reference (set and get) to System.Web HttpContext.User
        AppDomain domain = AppDomain.CurrentDomain;
        domain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal); // Sensitive
        MyIdentity identity = new MyIdentity(); // Sensitive
        MyPrincipal MyPrincipal = new MyPrincipal(MyIdentity); // Sensitive
        Thread.CurrentPrincipal = MyPrincipal; // Sensitive
        domain.SetThreadPrincipal(MyPrincipal); // Sensitive

        // All instantiation of PrincipalPermission should be reviewed.
        PrincipalPermission principalPerm = new PrincipalPermission(null, "Administrators"); // Sensitive
        principalPerm.Demand();

        SecurityTokenHandler handler = ...;
        // Sensitive: this creates an identity.
        ReadOnlyCollection<ClaimsIdentity> identities = handler.ValidateToken(…);
    }

     // Sensitive: review how this function uses the identity and principal.
    void modifyPrincipal(MyIdentity identity, MyPrincipal principal)
    {
        // ...
    }
}

See

tsql:S3633

Queries with contradictory WHERE clauses will always return empty result sets. This is clearly a bug.

Noncompliant Code Example

SELECT *
FROM fruit
WHERE type='apple' AND type='orange'  -- Noncompliant
Pylint:W0614
Used when an imported module or variable is not used from a `'from X import *'` style import.
php:S2115

Failure to password-protect a database is so careless or naive as to be almost negligent. Databases should always be password protected, but the use of a database connection with an empty password is a clear indication of a database that is not protected.

This rule flags database connections with empty passwords.

Noncompliant Code Example

<?php
  $servername = "localhost";
  $username = "AppLogin";
  $password = "";

  // MySQL
  $conn = new mysqli($servername, $username, $password);
  // MySQL
  $conn = mysqli_connect($servername, $username, $password);
  // PDO way
  $conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password);
  // Oracle
  $conn = oci_connect($username, $password, "//localhost/orcl");
  // MS SQL Server
  $sqlsrvName = "serverName\sqlexpress";
  $sqlsrvConnInfo = array( "Database"=>"myDB", "UID"=>$username, "PWD"=>$password);
  $conn = sqlsrv_connect( $sqlsrvName, $sqlsrvConnInfo);
  // PosgreSQL
  $pgConnInfo = "host=localhost port=5432 dbname=test user=" . $username . " password=" . $password;
  $conn = pg_connect($pgConnInfo);
?>

See

php:S4818

Using sockets is security-sensitive. It has led in the past to the following vulnerabilities:

Sockets are vulnerable in multiple ways:

  • They enable a software to interact with the outside world. As this world is full of attackers it is necessary to check that they cannot receive sensitive information or inject dangerous input.
  • The number of sockets is limited and can be exhausted. Which makes the application unresponsive to users who need additional sockets.

This rules flags code that creates sockets. It matches only the direct use of sockets, not use through frameworks or high-level APIs such as the use of http connections.

Ask Yourself Whether

  • sockets are created without any limit every time a user performs an action.
  • input received from sockets is used without being sanitized.
  • sensitive data is sent via sockets without being encrypted.

You are at risk if you answered yes to any of these questions.

Recommended Secure Coding Practices

  • In many cases there is no need to open a socket yourself. Use instead libraries and existing protocols.
  • Encrypt all data sent if it is sensitive. Usually it is better to encrypt it even if the data is not sensitive as it might change later.
  • Sanitize any input read from the socket.
  • Limit the number of sockets a given user can create. Close the sockets as soon as possible.

Questionable Code Example

function handle_sockets($domain, $type, $protocol, $port, $backlog, $addr, $hostname, $local_socket, $remote_socket, $fd) {
    socket_create($domain, $type, $protocol); // Questionable
    socket_create_listen($port, $backlog); // Questionable
    socket_addrinfo_bind($addr); // Questionable
    socket_addrinfo_connect($addr); // Questionable
    socket_create_pair($domain, $type, $protocol, $fd);

    fsockopen($hostname); // Questionable
    pfsockopen($hostname); // Questionable
    stream_socket_server($local_socket); // Questionable
    stream_socket_client($remote_socket); // Questionable
    stream_socket_pair($domain, $type, $protocol); // Questionable
}

See

php:S2070

The MD5 algorithm and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them. That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160.

Consider using safer alternatives, such as SHA-256, or SHA-3.

Noncompliant Code Example

$password = ...

if (md5($password) === '1f3870be274f6c49b3e31a0c6728957f') { // Noncompliant; md5() hashing algorithm is not secure for password management
   [...]
}

if (sha1($password) === 'd0be2dc421be4fcd0172e5afceea3970e2f3d940') { // Noncompliant; sha1() hashing algorithm is not secure for password management
   [...]
}

See

Deprecated

This rule is deprecated; use S4790 instead.

php:S4508

Deserializing objects is security-sensitive. For example, it has led in the past to the following vulnerabilities:

Object deserialization from an untrusted source can lead to unexpected code execution. Deserialization takes a stream of bits and turns it into an object. If the stream contains the type of object you expect, all is well. But if you're deserializing untrusted input, and an attacker has inserted some other type of object, you're in trouble. Why? There are a few different attack scenarios, but one widely-documented one goes like this: Deserialization first instantiates the Object, then PHP will automatically attempt to call the __wakeup() member to reconstruct any resources that the object may have. If the attacker has overridden __wakeup() then he is entirely in control of what code executes during that process.

Ask Yourself Whether

  • an attacker could have tampered with the source provided to the deserialization function
  • you are using an unsafe deserialization function

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

To prevent insecure deserialization, it is recommended to use a standard data interchange format such as JSON instead of relying on objects serialization.

You should also limit access to the serialized source. For example:

  • if it is a file, restrict the access to it.
  • if it comes from the network, restrict who has access to the process, such as with a Firewall or by authenticating the sender first.

See

php:S2964

sleep is sometimes used in a mistaken attempt to prevent Denial of Service (DoS) attacks by throttling response rate. But because it ties up a thread, each request takes longer to serve that it otherwise would, making the application more vulnerable to DoS attacks, rather than less.

Noncompliant Code Example

if (is_bad_ip($requester)) {
  sleep(5);  // Noncompliant
}

See

php:S4507

Delivering code in production with debug features activated is security-sensitive. It has led in the past to the following vulnerabilities:

An application's debug features enable developers to find bugs more easily. It often gives access to detailed information on both the system running the application and users. Sometime it even enables the execution of custom commands. Thus deploying on production servers an application which has debug features activated is extremely dangerous.

Ask Yourself Whether

  • the code or configuration enabling the application debug features is deployed on production servers.
  • the application runs by default with debug features activated.

You are at risk if you answered yes to any of these questions.

Recommended Secure Coding Practices

The application should run by default in the most secure mode, i.e. as on production servers. This is to prevent any mistake. Enabling debug mode should be explicitly asked via a command line argument, an environment variable or a configuration file.

Check that every aspect of the debug mode is controlled by only one configuration switch: logging, exception/error handling, access control, etc... It is otherwise very easy to forget one of them.

Do not enable debug mode on production servers.

Only the value "0" or "false" for CakePHP 3.x is suitable (production mode) to not leak sensitive data on the logs.

Noncompliant Code Example

CakePHP 1.x, 2.x:

Configure::write('debug', 1); // Noncompliant; development mode
or
Configure::write('debug', 2); // Noncompliant; development mode
or
Configure::write('debug', 3); // Noncompliant; development mode

CakePHP 3.0:

use Cake\Core\Configure;

Configure::config('debug', true);

Compliant Solution

CakePHP 1.2:

Configure::write('debug', 0); // Compliant; this is the production mode

CakePHP 3.0:

use Cake\Core\Configure;

Configure::config('debug', false);

See

php:S2053

In cryptography, "salt" is extra piece of data which is included in a hashing algorithm. It makes dictionary attacks more difficult. Using a cryptographic hash function without an unpredictable salt increases the likelihood that an attacker will be able to successfully guess a hashed value such as a password with a dictionary attack.

This rule raises an issue when a hashing function which has been specifically designed for hashing sensitive data, such as pbkdf2, is used with a non-random, reused or too short salt value. It does not raise an issue on base hashing algorithms such as sha1 or md5 as these are often used for other purposes.

Recommended Secure Coding Practices

  • use hashing functions generating their own salt or generate a long random salt of at least 32 bytes.
  • the salt is at least as long as the resulting hash value.
  • provide the salt to a safe hashing function such as PBKDF2.
  • save both the salt and the hashed value in the relevant database record; during future validation operations, the salt and hash can then be retrieved from the database. The hash is recalculated with the stored salt and the value being validated, and the result compared to the stored hash.

Noncompliant Code Example

function createMyAccount() {
  $email = $_GET['email'];
  $name = $_GET['name'];
  $password = $_GET['password'];

  $hash = hash_pbkdf2('sha256', $password, $email, 100000); // Noncompliant; salt (3rd argument) is predictable because initialized with the provided $email

  $hash = hash_pbkdf2('sha256', $password, '', 100000); // Noncompliant; salt is empty

  $hash = hash_pbkdf2('sha256', $password, 'D8VxSmTZt2E2YV454mkqAY5e', 100000); // Noncompliant; salt is hardcoded

  $hash = crypt($password); // Noncompliant; salt is not provided
  $hash = crypt($password, ""); // Noncompliant; salt is hardcoded

  $options = [
    'cost' => 11,
    'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM), // Noncompliant ; use salt generated by default
  ];
  echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options);
}

Compliant Solution

$salt = openssl_random_pseudo_bytes(16);
$hash = hash_pbkdf2("sha256", $password, $salt, $iterations, 20);

See

php:S2277

Without OAEP in RSA encryption, it takes less work for an attacker to decrypt the data or infer patterns from the ciphertext. This rule logs an issue when openssl_public_encrypt is used with one the following padding constants: OPENSSL_NO_PADDING or OPENSSL_PKCS1_PADDING or OPENSSL_SSLV23_PADDING.

Noncompliant Code Example

function encrypt($data, $key) {
  $crypted='';
  openssl_public_encrypt($data, $crypted, $key, OPENSSL_NO_PADDING); // Noncompliant
  return $crypted;
}

Compliant Solution

function encrypt($data, $key) {
  $crypted='';
  openssl_public_encrypt($data, $crypted, $key, OPENSSL_PKCS1_OAEP_PADDING);
  return $crypted;
}

See

php:S3336

PHP's session.use_trans_sid automatically appends the user's session id to urls when cookies are disabled. On the face of it, this seems like a nice way to let uncookie-able users use your site anyway. In reality, it makes those users vulnerable to having their sessions hijacked by anyone who might:

  • see the URL over the user's shoulder
  • be sent the URL by the user
  • retrieve the URL from browser history
  • ...

For that reason, it's better to practice a little "tough love" with your users and force them to turn on cookies.

Since session.use_trans_sid is off by default, this rule raises an issue when it is explicitly enabled.

Noncompliant Code Example

; php.ini
session.use_trans_sid=1  ; Noncompliant

See

php:S4787

Encrypting data is security-sensitive. It has led in the past to the following vulnerabilities:

Proper encryption requires both the encryption algorithm and the key to be strong. Obviously the private key needs to remain secret and be renewed regularly. However these are not the only means to defeat or weaken an encryption.

This rule flags function calls that initiate encryption/decryption. The goal is to guide security code reviews.

Ask Yourself Whether

  • the private key might not be random, strong enough or the same key is reused for a long long time.
  • the private key might be compromised. It can happen when it is stored in an unsafe place or when it was transferred in an unsafe manner.
  • the key exchange is made without properly authenticating the receiver.
  • the encryption algorithm is not strong enough for the level of protection required. Note that encryption algorithms strength decreases as time passes.
  • the chosen encryption library is deemed unsafe.
  • a nonce is used, and the same value is reused multiple times, or the nonce is not random.
  • the RSA algorithm is used, and it does not incorporate an Optimal Asymmetric Encryption Padding (OAEP), which might weaken the encryption.
  • the CBC (Cypher Block Chaining) algorithm is used for encryption, and it's IV (Initialization Vector) is not generated using a secure random algorithm, or it is reused.
  • the Advanced Encryption Standard (AES) encryption algorithm is used with an unsecure mode. See the recommended practices for more information.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

  • Generate encryption keys using secure random algorithms.
  • When generating cryptographic keys (or key pairs), it is important to use a key length that provides enough entropy against brute-force attacks. For the Blowfish algorithm the key should be at least 128 bits long, while for the RSA algorithm it should be at least 2048 bits long.
  • Regenerate the keys regularly.
  • Always store the keys in a safe location and transfer them only over safe channels.
  • If there is an exchange of cryptographic keys, check first the identity of the receiver.
  • Only use strong encryption algorithms. Check regularly that the algorithm is still deemed secure. It is also imperative that they are implemented correctly. Use only encryption libraries which are deemed secure. Do not define your own encryption algorithms as they will most probably have flaws.
  • When a nonce is used, generate it randomly every time.
  • When using the RSA algorithm, incorporate an Optimal Asymmetric Encryption Padding (OAEP).
  • When CBC is used for encryption, the IV must be random and unpredictable. Otherwise it exposes the encrypted value to crypto-analysis attacks like "Chosen-Plaintext Attacks". Thus a secure random algorithm should be used. An IV value should be associated to one and only one encryption cycle, because the IV's purpose is to ensure that the same plaintext encrypted twice will yield two different ciphertexts.
  • The Advanced Encryption Standard (AES) encryption algorithm can be used with various modes. Galois/Counter Mode (GCM) with no padding should be preferred to the following combinations which are not secured:
    • Electronic Codebook (ECB) mode: Under a given key, any given plaintext block always gets encrypted to the same ciphertext block. Thus, it does not hide data patterns well. In some senses, it doesn't provide serious message confidentiality, and it is not recommended for use in cryptographic protocols at all.
    • Cipher Block Chaining (CBC) with PKCS#5 padding (or PKCS#7) is susceptible to padding oracle attacks.

Questionable Code Example

Builtin functions

function myEncrypt($cipher, $key, $data, $mode, $iv, $options, $padding, $infile, $outfile, $recipcerts, $headers, $nonce, $ad, $pub_key_ids, $env_keys)
{
    mcrypt_ecb ($cipher, $key, $data, $mode); // Questionable
    mcrypt_cfb($cipher, $key, $data, $mode, $iv); // Questionable
    mcrypt_cbc($cipher, $key, $data, $mode, $iv); // Questionable
    mcrypt_encrypt($cipher, $key, $data, $mode); // Questionable

    openssl_encrypt($data, $cipher, $key, $options, $iv); // Questionable
    openssl_public_encrypt($data, $crypted, $key, $padding); // Questionable
    openssl_pkcs7_encrypt($infile, $outfile, $recipcerts, $headers); // Questionable
    openssl_seal($data, $sealed_data, $env_keys, $pub_key_ids); // Questionable

    sodium_crypto_aead_aes256gcm_encrypt ($data, $ad, $nonce, $key); // Questionable
    sodium_crypto_aead_chacha20poly1305_encrypt ($data, $ad, $nonce, $key); // Questionable
    sodium_crypto_aead_chacha20poly1305_ietf_encrypt ($data, $ad, $nonce, $key); // Questionable
    sodium_crypto_aead_xchacha20poly1305_ietf_encrypt ($data, $ad, $nonce, $key); // Questionable
    sodium_crypto_box_seal ($data, $key); // Questionable
    sodium_crypto_box ($data, $nonce, $key); // Questionable
    sodium_crypto_secretbox ($data, $nonce, $key); // Questionable
    sodium_crypto_stream_xor ($data, $nonce, $key); // Questionable
}

CakePHP

use Cake\Utility\Security;

function myCakeEncrypt($key, $data, $engine)
{
    Security::encrypt($data, $key); // Questionable

    // Do not use custom made engines and remember that Mcrypt is deprecated.
    Security::engine($engine); // Questionable. Setting the encryption engine.
}

CodeIgniter

class EncryptionController extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->library('encryption');
    }

    public function index()
    {
        $this->encryption->create_key(16); // Questionable. Review the key length.
        $this->encryption->initialize( // Questionable.
            array(
                'cipher' => 'aes-256',
                'mode' => 'ctr',
                'key' => 'the key',
            )
        );
        $this->encryption->encrypt("mysecretdata"); // Questionable.
    }
}

CraftCMS version 3

use Craft;

// This is similar to Yii as it used by CraftCMS
function craftEncrypt($data, $key, $password) {
    Craft::$app->security->encryptByKey($data, $key); // Questionable
    Craft::$app->getSecurity()->encryptByKey($data, $key); // Questionable
    Craft::$app->security->encryptByPassword($data, $password); // Questionable
    Craft::$app->getSecurity()->encryptByPassword($data, $password); // Questionable
}

Drupal 7 - Encrypt module

function drupalEncrypt() {
    $encrypted_text = encrypt('some string to encrypt'); // Questionable
}

Joomla

use Joomla\Crypt\CipherInterface;

abstract class MyCipher implements CipherInterface // Questionable. Implementing custom cipher class
{}

function joomlaEncrypt() {
    new Joomla\Crypt\Cipher_Sodium(); // Questionable
    new Joomla\Crypt\Cipher_Simple(); // Questionable
    new Joomla\Crypt\Cipher_Rijndael256(); // Questionable
    new Joomla\Crypt\Cipher_Crypto(); // Questionable
    new Joomla\Crypt\Cipher_Blowfish(); // Questionable
    new Joomla\Crypt\Cipher_3DES(); // Questionable
}
}

Laravel

use Illuminate\Support\Facades\Crypt;

function myLaravelEncrypt($data)
{
    Crypt::encryptString($data); // Questionable
    Crypt::encrypt($data); // Questionable
    // encrypt using the Laravel "encrypt" helper
    encrypt($data); // Questionable
}

PHP-Encryption library

use Defuse\Crypto\Crypto;
use Defuse\Crypto\File;

function mypPhpEncryption($data, $key, $password, $inputFilename, $outputFilename, $inputHandle, $outputHandle) {
    Crypto::encrypt($data, $key); // Questionable
    Crypto::encryptWithPassword($data, $password); // Questionable
    File::encryptFile($inputFilename, $outputFilename, $key); // Questionable
    File::encryptFileWithPassword($inputFilename, $outputFilename, $password); // Questionable
    File::encryptResource($inputHandle, $outputHandle, $key); // Questionable
    File::encryptResourceWithPassword($inputHandle, $outputHandle, $password); // Questionable
}

PhpSecLib

function myphpseclib($mode) {
    new phpseclib\Crypt\RSA(); // Questionable. Note: RSA can also be used for signing data.
    new phpseclib\Crypt\AES(); // Questionable
    new phpseclib\Crypt\Rijndael(); // Questionable
    new phpseclib\Crypt\Twofish(); // Questionable
    new phpseclib\Crypt\Blowfish(); // Questionable
    new phpseclib\Crypt\RC4(); // Questionable
    new phpseclib\Crypt\RC2(); // Questionable
    new phpseclib\Crypt\TripleDES(); // Questionable
    new phpseclib\Crypt\DES(); // Questionable

    new phpseclib\Crypt\AES($mode); // Questionable
    new phpseclib\Crypt\Rijndael($mode); // Questionable
    new phpseclib\Crypt\TripleDES($mode); // Questionable
    new phpseclib\Crypt\DES($mode); // Questionable
}

Sodium Compat library

function mySodiumCompatEncrypt($data, $ad, $nonce, $key) {
    ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_encrypt($data, $ad, $nonce, $key); // Questionable
    ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_ietf_encrypt($data, $ad, $nonce, $key); // Questionable
    ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_encrypt($data, $ad, $nonce, $key); // Questionable

    ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_encrypt($data, $ad, $nonce, $key); // Questionable

    ParagonIE_Sodium_Compat::crypto_box($data, $nonce, $key); // Questionable
    ParagonIE_Sodium_Compat::crypto_secretbox($data, $nonce, $key); // Questionable
    ParagonIE_Sodium_Compat::crypto_box_seal($data, $key); // Questionable
    ParagonIE_Sodium_Compat::crypto_secretbox_xchacha20poly1305($data, $nonce, $key); // Questionable
}

Yii version 2

use Yii;

// Similar to CraftCMS as it uses Yii
function YiiEncrypt($data, $key, $password) {
    Yii::$app->security->encryptByKey($data, $key); // Questionable
    Yii::$app->getSecurity()->encryptByKey($data, $key); // Questionable
    Yii::$app->security->encryptByPassword($data, $password); // Questionable
    Yii::$app->getSecurity()->encryptByPassword($data, $password); // Questionable
}

Zend

use Zend\Crypt\FileCipher;
use Zend\Crypt\PublicKey\DiffieHellman;
use Zend\Crypt\PublicKey\Rsa;
use Zend\Crypt\Hybrid;
use Zend\Crypt\BlockCipher;

function myZendEncrypt($key, $data, $prime, $options, $generator, $lib)
{
    new FileCipher; // Questionable. This is used to encrypt files

    new DiffieHellman($prime, $generator, $key); // Questionable

    $rsa = Rsa::factory([ // Questionable
        'public_key'    => 'public_key.pub',
        'private_key'   => 'private_key.pem',
        'pass_phrase'   => 'mypassphrase',
        'binary_output' => false,
    ]);
    $rsa->encrypt($data); // No issue raised here. The configuration of the Rsa object is the line to review.

    $hybrid = new Hybrid(); // Questionable

    BlockCipher::factory($lib, $options); // Questionable
}

See

php:S3337

enable_dl is on by default and allows open_basedir restrictions, which limit the files a script can access, to be ignored. For that reason, it's a dangerous option and should be explicitly turned off.

This rule raises an issue when enable_dl is not explicitly set to 0 in php.ini.

Noncompliant Code Example

; php.ini
enable_dl=1  ; Noncompliant

Compliant Solution

; php.ini
enable_dl=0

See

php:S4423

Not all SSL protocols are created equal and some legacy ones like "SSL", have been proven to be insecure.

This rule raises an issue when an SSL context is created with an insecure protocol (ie: a protocol different from "TLSv1.2" or "DTLSv1.2").

Noncompliant Code Example

$ctx = stream_context_create([
  'ssl' => [
    'crypto_method' =>
      STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT // Noncompliant
  ],
]);

Compliant Solution

$ctx = stream_context_create([
    'ssl' => [
        'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
    ],
]);

See

php:S3334

allow_url_fopen and allow_url_include allow code to be read into a script from URL's. The ability to suck in executable code from outside your site, coupled with imperfect input cleansing could lay your site bare to attackers. Even if your input filtering is perfect today, are you prepared to bet your site that it will always be perfect in the future?

This rule raises an issue when either property is explicitly enabled in php.ini and when allow_url_fopen, which defaults to enabled, is not explicitly disabled.

Noncompliant Code Example

; php.ini  Noncompliant; allow_url_fopen not explicitly disabled
allow_url_include=1  ; Noncompliant

Compliant Solution

; php.ini
allow_url_fopen=0
allow_url_include=0

See

php:S4426

When generating cryptographic keys (or key pairs), it is important to use a key length that provides enough entropy against brute-force attacks. For the RSA algorithm, it should be at least 2048 bits long.

This rule raises an issue when an RSA key-pair generator is initialized with too small a length parameter.

Noncompliant Code Example

$config = array(
    "digest_alg" => "sha512",
    "private_key_bits" => 1024, // Noncompliant
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
);
$res = openssl_pkey_new($config);

Compliant Solution

$config = array(
    "digest_alg" => "sha512",
    "private_key_bits" => 4096, // Compliant
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
);
$res = openssl_pkey_new($config);

See

php:S3335

The cgi.force_redirect php.ini configuration is on by default, and it prevents unauthenticated access to scripts when PHP is running as a CGI. Unfortunately, it must be disabled on IIS, OmniHTTPD and Xitami, but in all other cases it should be on.

This rule raises an issue when when cgi.force_redirect is explicitly disabled.

Noncompliant Code Example

; php.ini
cgi.force_redirect=0  ; Noncompliant

See

php:S3332

Cookies without fixed lifetimes or expiration dates are known as non-persistent, or "session" cookies, meaning they last only as long as the browser session, and poof away when the browser closes. Cookies with expiration dates, "persistent" cookies, are stored/persisted until those dates.

Non-persistent cookies should be used for the management of logged-in sessions on web sites. To make a cookie non-persistent, simply omit the expires attribute.

This rule raises an issue when expires is set for a session cookie, either programmatically or via configuration, such as session.cookie_lifetime.

See

php:S3333

The open_basedir configuration in php.ini limits the files the script can access using, for example, include and fopen(). Leave it out, and there is no default limit, meaning that any file can be accessed. Include it, and PHP will refuse to access files outside the allowed path.

open_basedir should be configured with a directory, which will then be accessible recursively. However, the use of . (current directory) as an open_basedir value should be avoided since it's resolved dynamically during script execution, so a chdir('/') command could lay the whole server open to the script.

This is not a fool-proof configuration; it can be reset or overridden at the script level. But its use should be seen as a minimum due diligence step. This rule raises an issue when open_basedir is not present in php.ini, and when open_basedir contains root, or the current directory (.) symbol.

Noncompliant Code Example

; php.ini try 1
; open_basedir="${USER}/scripts/data"  Noncompliant; commented out

; php.ini try 2
open_basedir="/:${USER}/scripts/data"  ; Noncompliant; root directory in the list

Compliant Solution

; php.ini try 1
open_basedir="${USER}/scripts/data"

See

php:S3330

The HttpOnly cookie attribute tells the browser to prevent client-side scripts from reading cookies with the attribute, and its use can go a long way to defending against Cross-Site Scripting (XSS) attacks. Thus, as a precaution, the attribute should be set by default on all cookies set server-side, such as session id cookies.

Setting the attribute can be done either programmatically, or globally via configuration files.

This rule raises an issue:

  • when HttpOnly is missing from php.ini or explicitly set to false
  • when setcookie()'s last parameter is explicitly set to false

Noncompliant Code Example

; php.ini
session.cookie_httponly=false  ; Noncompliant; explicitly set to false

// file.php
setcookie($name, $value, $expire, $path, $domain, $secure, false);  // Noncompliant; explicitly set to false

See

php:S3331

A cookie's domain specifies which websites should be able to read it. Left blank, browsers are supposed to only send the cookie to sites that exactly match the sending domain. For example, if a cookie was set by lovely.dream.com, it should only be readable by that domain, and not by nightmare.com or even strange.dream.com. If you want to allow sub-domain access for a cookie, you can specify it by adding a dot in front of the cookie's domain, like so: .dream.com. But cookie domains should always use at least two levels.

Cookie domains can be set either programmatically or via configuration. This rule raises an issue when any cookie domain is set with a single level, as in .com.

Noncompliant Code Example

setcookie("TestCookie", $value, time()+3600, "/~path/", ".com", 1); // Noncompliant
session_set_cookie_params(3600, "/~path/", ".com"); // Noncompliant

// inside php.ini
session.cookie_domain=".com"; // Noncompliant

Compliant Solution

setcookie("TestCookie", $value, time()+3600, "/~path/", ".myDomain.com", 1);
session_set_cookie_params(3600, "/~path/", ".myDomain.com");

// inside php.ini
session.cookie_domain=".myDomain.com";

See

php:S4828

Signalling processes is security-sensitive. It has led in the past to the following vulnerabilities:

* CVE-2009-0390

* CVE-2002-0839

* CVE-2008-1671

Sending signals without checking properly which process will receive it can cause a denial of service.

Ask Yourself Whether

* the PID of the process to which the signal will be sent is coming from an untrusted source. It could for example come from a world-writable file.

* users who are asking for the signal to be sent might not have the permission to send those signals.

You are at risk if you answered yes to any of these questions.

Recommended Secure Coding Practices

* If the signal is sent because of a user's request. Check that the user is allowed to send this signal. You can for example forbid it if the user doesn't own the process.

* Secure the source from which the process PID is read.

* Run the process sending the signals with minimal permissions.

Questionable Code Example

posix_kill(42, 42); // Questionable

See

* MITRE, CWE-283 - Unverified Ownership

php:S4823

Using command line arguments is security-sensitive. It has led in the past to the following vulnerabilities:

Command line arguments can be dangerous just like any other user input. They should never be used without being first validated and sanitized.

Remember also that any user can retrieve the list of processes running on a system, which makes the arguments provided to them visible. Thus passing sensitive information via command line arguments should be considered as insecure.

This rule raises an issue when on every program entry points (main methods) when command line arguments are used. The goal is to guide security code reviews.

Ask Yourself Whether

  • any of the command line arguments are used without being sanitized first.
  • your application accepts sensitive information via command line arguments.

If you answered yes to any of these questions you are at risk.

Recommended Secure Coding Practices

Sanitize all command line arguments before using them.

Any user or application can list running processes and see the command line arguments they were started with. There are safer ways of providing sensitive information to an application than exposing them in the command line. It is common to write them on the process' standard input, or give the path to a file containing the information.

Questionable Code Example

Builtin access to $argv

function globfunc() {
    global $argv; // Questionable. Reference to global $argv
    foreach ($argv as $arg) { // Questionable.
        // ...
    }
}

function myfunc($argv) {
    $param = $argv[0]; // OK. Reference to local $argv parameter
    // ...
}

foreach ($argv as $arg) { // Questionable. Reference to $argv.
    // ...
}

$myargv = $_SERVER['argv']; // Questionable. Equivalent to $argv.

function serve() {
    $myargv = $_SERVER['argv']; // Questionable.
    // ...
}

myfunc($argv); // Questionable

$myvar = $HTTP_SERVER_VARS[0]; // Questionable. Note: HTTP_SERVER_VARS has ben removed since PHP 5.4.

$options = getopt('a:b:'); // Questionable. Parsing arguments.

$GLOBALS["argv"]; // Questionable. Equivalent to $argv.

function myglobals() {
    $GLOBALS["argv"]; // Questionable
}

$argv = [1,2,3]; // Questionable. It is a bad idea to override argv.

Zend Console

new Zend\Console\Getopt(['myopt|m' => 'this is an option']); // Questionable

Getopt-php library

new \GetOpt\Option('m', 'myoption', \GetOpt\GetOpt::REQUIRED_ARGUMENT); // Questionable

See

php:S3338

file_uploads is an on-by-default PHP configuration that allows files to be uploaded to your site. Since accepting candy files from strangers is inherently dangerous, this feature should be disabled unless it is absolutely necessary for your site.

This rule raises an issue when file_uploads is not explicitly disabled.

Noncompliant Code Example

; php.ini
file_uploads=1  ; Noncompliant

Compliant Solution

; php.ini
file_uploads=0

See

php:S4830

Disabling SSL/TLS certificates chain of trust verification is similar to trust every one in the chain and so to expose the application to man-in-the-middle (MITM) attacks.

Noncompliant Code Example

curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, TRUE); // Noncompliant; TRUE is casted to 1 which is not a secure configuration
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);

// and/or

curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);

Compliant Solution

curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // Compliant; default value is 2 to "check the existence of a common name and also verify that it matches the hostname provided" according to PHP's documentation

// and/or

curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, TRUE); // Compliant; default value is TRUE
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1);

See

php:S4834

Controlling permissions is security-sensitive. It has led in the past to the following vulnerabilities:

Attackers can only damage what they have access to. Thus limiting their access is a good way to prevent them from wreaking havoc, but it has to be done properly.

This rule flags code that controls the access to resources and actions or configures this access. The goal is to guide security code reviews.

Ask Yourself Whether

  • at least one accessed action or resource is security-sensitive.
  • there is no access control in place or it does not cover all sensitive actions and resources.
  • users have permissions they don't need.
  • the access control is based on a user input or on some other unsafe data.
  • permissions are difficult to remove or take a long time to be updated.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

The first step is to restrict all sensitive actions to authenticated users.

Each user should have the lowest privileges possible. The access control granularity should match the sensitivity of each resource or action. The more sensitive it is, the less people should have access to it.

Do not base the access control on a user input or on a value which might have been tampered with. For example, the developer should not read a user's permissions from an HTTP cookie as it can be modified client-side.

Check that the access to each action and resource is properly restricted.

Enable administrators to swiftly remove permissions when necessary. This enables them to reduce the time an attacker can have access to your systems when a breach occurs.

Log and monitor refused access requests as they can reveal an attack.

Questionable Code Example

CakePHP

use Cake\Auth\BaseAuthorize;
use Cake\Controller\Controller;

abstract class MyAuthorize extends BaseAuthorize { // Questionable. Method extending Cake\Auth\BaseAuthorize.
    // ...
}

// Note that "isAuthorized" methods will only be detected in direct subclasses of Cake\Controller\Controller.
abstract class MyController extends Controller {
    public function isAuthorized($user) { // Questionable. Method called isAuthorized in a Cake\Controller\Controller.
        return false;
    }
}

See

php:S4790

Hashing data is security-sensitive. It has led in the past to the following vulnerabilities:

Cryptographic hash functions are used to uniquely identify information without storing their original form. When not done properly, an attacker can steal the original information by guessing it (ex: with a rainbow table), or replace the original data with another one having the same hash.

This rule creates an issue when one of the following functions are called: hash, hash_init, crypt, password_hash, hash_pbkdf2, openssl_pbkdf2, md5, sha1

Ask Yourself Whether

  • the hashed value is used in a security context.
  • the hashing algorithm you are using is known to have vulnerabilities.
  • salts are not automatically generated and applied by the hashing function.
  • any generated salts are cryptographically weak or not credential-specific.

You are at risk if you answered yes to the first question and any of the following ones.

Recommended Secure Coding Practices

If the hashed data is sensitive, just use the functions officially recommended by PHP, i.e. password_hash, password_verify and password_needs_rehash.

Alternatively you can use the crypt function or hash_pbkdf2 functions. Do not use the md5 or sha1 for sensitive values, and avoid hash and hash_init whenever possible.

If you use hash_pbkdf2 or crypt choose a hashing algorithms which is known to be strong. Check regularly that this is still the case as hashing algorithms often lose strength over time.

It is recommended to use a hashing function that generate salts automatically, but if you generate salts separately:

  • generate a cryptographically strong and random salt that is unique for every credential being hashed.
  • the salt is applied correctly before the hashing.
  • save both the salt and the hashed value in the relevant database record; during future validation operations, the salt and hash can then be retrieved from the database. The hash is recalculated with the stored salt and the value being validated, and the result compared to the stored hash.

Note that password_hash generates strong salts automatically.

Remember to rehash your data regularly as the hashing algorithms become less secure over time. The password_needs_rehash function helps you with that.

Exceptions

HMAC computing is out of the scope of this rule. Thus no issue will be raised when the hash_init function is called with HASH_HMAC given as second parameter.

See

php:S4792

Configuring loggers is security-sensitive. It has led in the past to the following vulnerabilities:

Logs are useful before, during and after a security incident.

  • Attackers will most of the time start their nefarious work by probing the system for vulnerabilities. Monitoring this activity and stopping it is the first step to prevent an attack from ever happening.
  • In case of a successful attack, logs should contain enough information to understand what damage an attacker may have inflicted.

Logs are also a target for attackers because they might contain sensitive information. Configuring loggers has an impact on the type of information logged and how they are logged.

This rule flags for review code that initiates loggers configuration. The goal is to guide security code reviews.

Ask Yourself Whether

  • unauthorized users might have access to the logs, either because they are stored in an insecure location or because the application gives access to them.
  • the logs contain sensitive information on a production server. This can happen when the logger is in debug mode.
  • the log can grow without limit. This can happen when additional information is written into logs every time a user performs an action and the user can perform the action as many times as he/she wants.
  • the logs do not contain enough information to understand the damage an attacker might have inflicted. The loggers mode (info, warn, error) might filter out important information. They might not print contextual information like the precise time of events or the server hostname.
  • the logs are only stored locally instead of being backuped or replicated.

You are at risk if you answered yes to any of those questions.

Recommended Secure Coding Practices

  • Check that your production deployment doesn't have its loggers in "debug" mode as it might write sensitive information in logs.
  • Production logs should be stored in a secure location which is only accessible to system administrators.
  • Configure the loggers to display all warnings, info and error messages. Write relevant information such as the precise time of events and the hostname.
  • Choose log format which is easy to parse and process automatically. It is important to process logs rapidly in case of an attack so that the impact is known and limited.
  • Check that the permissions of the log files are correct. If you index the logs in some other service, make sure that the transfer and the service are secure too.
  • Add limits to the size of the logs and make sure that no user can fill the disk with logs. This can happen even when the user does not control the logged information. An attacker could just repeat a logged action many times.

Remember that configuring loggers properly doesn't make them bullet-proof. Here is a list of recommendations explaining on how to use your logs:

  • Don't log any sensitive information. This obviously includes passwords and credit card numbers but also any personal information such as user names, locations, etc... Usually any information which is protected by law is good candidate for removal.
  • Sanitize all user inputs before writing them in the logs. This includes checking its size, content, encoding, syntax, etc... As for any user input, validate using whitelists whenever possible. Enabling users to write what they want in your logs can have many impacts. It could for example use all your storage space or compromise your log indexing service.
  • Log enough information to monitor suspicious activities and evaluate the impact an attacker might have on your systems. Register events such as failed logins, successful logins, server side input validation failures, access denials and any important transaction.
  • Monitor the logs for any suspicious activity.

Questionable Code Example

Basic PHP configuration:

function configure_logging() {
  error_reporting(E_RECOVERABLE_ERROR); // Questionable
  error_reporting(32); // Questionable

  ini_set('docref_root', '1'); // Questionable
  ini_set('display_errors', '1'); // Questionable
  ini_set('display_startup_errors', '1'); // Questionable
  ini_set('error_log', "path/to/logfile"); // Questionable - check logfile is secure
  ini_set('error_reporting', E_PARSE ); // Questionable
  ini_set('error_reporting', 64); // Questionable
  ini_set('log_errors', '0'); // Questionable
  ini_set('log_errors_max_length', '512'); // Questionable
  ini_set('ignore_repeated_errors', '1'); // Questionable
  ini_set('ignore_repeated_source', '1'); // Questionable
  ini_set('track_errors', '0'); // Questionable

  ini_alter('docref_root', '1'); // Questionable
  ini_alter('display_errors', '1'); // Questionable
  ini_alter('display_startup_errors', '1'); // Questionable
  ini_alter('error_log', "path/to/logfile"); // Questionable - check logfile is secure
  ini_alter('error_reporting', E_PARSE ); // Questionable
  ini_alter('error_reporting', 64); // Questionable
  ini_alter('log_errors', '0'); // Questionable
  ini_alter('log_errors_max_length', '512'); // Questionable
  ini_alter('ignore_repeated_errors', '1'); // Questionable
  ini_alter('ignore_repeated_source', '1'); // Questionable
  ini_alter('track_errors', '0'); // Questionable
}

Definition of custom loggers with psr/log

abstract class MyLogger implements \Psr\Log\LoggerInterface { // Questionable
    // ...
}

abstract class MyLogger2 extends \Psr\Log\AbstractLogger { // Questionable
    // ...
}

abstract class MyLogger3 {
    use \Psr\Log\LoggerTrait; // Questionable
    // ...
}

Exceptions

No issue will be raised for logger configuration when it follows recommended settings for production servers. The following examples are all valid:

  ini_set('docref_root', '0');
  ini_set('display_errors', '0');
  ini_set('display_startup_errors', '0');

  error_reporting(E_ALL);
  error_reporting(32767);
  error_reporting(-1);
  ini_set('error_reporting', E_ALL);
  ini_set('error_reporting', 32767);
  ini_set('error_reporting', -1);

  ini_set('log_errors', '1');
  ini_set('log_errors_max_length', '0');
  ini_set('ignore_repeated_errors', '0');
  ini_set('ignore_repeated_source', '0');
  ini_set('track_errors', '1');

See

javasecurity:S2631

Evaluating regular expressions against input strings can be an extremely CPU-intensive task. For example, a specially crafted regular expression such as (a+)++ will take several seconds to evaluate the input string, aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!. The problem is that every additional "a" added to the input doubles the time required to evaluate the regex. However, the equivalent regular expression, a (without grouping), is efficiently evaluated in milliseconds and scales linearly with the input size.

Evaluating user-provided strings as regular expressions opens the door for Denial Of Service attacks. In the context of a web application, attackers can force the web server to spend all of its resources evaluating regular expressions thereby making the service inaccessible to genuine users.

Noncompliant Code Example

public boolean validate(javax.servlet.http.HttpServletRequest request) {
  String regex = request.getParameter("regex");
  String input = request.getParameter("input");

  // Enables attackers to force the web server to evaluate
  // regex such as "(a+)+" on inputs such as "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!"

  input.matches(regex);  // Noncompliant
}

Compliant Solution

public boolean validate(javax.servlet.http.HttpServletRequest request) {
  String input = request.getParameter("input");

  input.matches("a+");  // Compliant - use a safe hardcoded regex
}

See

javasecurity:S5146

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Applications performing HTTP redirects based on tainted data could enable an attacker to redirect users to a malicious site to, for example, steal login credentials.

This problem could be mitigated in any of the following ways:

  • Validate the user provided data based on a whitelist and reject input not matching.
  • Redesign the application to not perform redirects based on user provided data.

Noncompliant Code Example

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String location = req.getParameter("url");
  resp.sendRedirect(location); // Noncompliant
}

Compliant Solution

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String location = req.getParameter("url");

  // Match the incoming URL against a whitelist
  if (!urlWhiteList.contains(location))
    throw new IOException();

  resp.sendRedirect(location);
}

See

javasecurity:S2078

User provided data such as URL parameters should always be considered as untrusted and tainted. Constructing LDAP names or search filters directly from tainted data enables attackers to inject specially crafted values that changes the initial meaning of the name or filter itself. Successful LDAP injections attacks can read, modify or delete sensitive information from the directory service.

Within LDAP names, the special characters ' ', '#', '"', '+', ',', ';', '<', '>', '\' and null must be escaped according to RFC 4514, for example by replacing them with the backslash character '\' followed by the two hex digits corresponding to the ASCII code of the character to be escaped. Similarly, LDAP search filters must escape a different set of special characters (including but not limited to '*', '(', ')', '\' and null) according to RFC 4515.

Noncompliant Code Example

public boolean authenticate(javax.servlet.http.HttpServletRequest request, DirContext ctx) throws NamingException {
  String user = request.getParameter("user");
  String pass = request.getParameter("pass");

  String filter = "(&(uid=" + user + ")(userPassword=" + pass + "))"; // Unsafe

  // If the special value "*)(uid=*))(|(uid=*" is passed as user, authentication is bypassed
  // Indeed, if it is passed as a user, the filter becomes:
  // (&(uid=*)(uid=*))(|(uid=*)(userPassword=...))
  // as uid=* match all users, it is equivalent to:
  // (|(uid=*)(userPassword=...))
  // again, as uid=* match all users, the filter becomes useless

  NamingEnumeration<SearchResult> results = ctx.search("ou=system", filter, new SearchControls()); // Noncompliant
  return results.hasMore();
}

Compliant Solution

public boolean authenticate(javax.servlet.http.HttpServletRequest request, DirContext ctx) throws NamingException {
  String user = request.getParameter("user");
  String pass = request.getParameter("pass");

  String filter = "(&(uid={0})(userPassword={1}))"; // Safe

  NamingEnumeration<SearchResult> results = ctx.search("ou=system", filter, new String[]{user, pass}, new SearchControls());
  return results.hasMore();
}

See

javasecurity:S5145

User provided data, such as URL parameters, POST data payloads or cookies, should always be considered untrusted and tainted. Applications logging tainted data could enable an attacker to inject characters that would break the log file pattern. This could be used to block monitors and SIEM (Security Information and Event Management) systems from detecting other malicious events.

This problem could be mitigated by sanitizing the user provided data before logging it.

Noncompliant Code Example

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String param1 = req.getParameter("param1");
  Logger.info("Param1: " + param1 + " " + Logger.getName()); // Noncompliant
  // ...
}

Compliant Solution

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String param1 = req.getParameter("param1");

  // Replace pattern-breaking characters
  param1 = param1.replaceAll("[\n|\r|\t]", "_");

  Logger.info("Param1: " + param1 + " " + Logger.getName());
  // ...
}

See

javasecurity:S5167

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Applications constructing HTTP response headers based on tainted data could allow attackers to inject characters that would be interpreted as a new line in some browsers. This could, for example, enable Cross-Site Scripting (XSS) attacks.

Most modern web application frameworks and servers mitigate this type of attack by default, but there might be rare cases where older versions are still vulnerable. As a best practice, applications that use user provided data to construct the response header should always validate the data first. Validation should be based on a whitelist.

Noncompliant Code Example

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String value = req.getParameter("value");
  resp.addHeader("X-Header", value); // Noncompliant
  // ...
}

Compliant Solution

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String value = req.getParameter("value");

  // Allow only alphanumeric characters
  if (!value.matches("[a-zA-Z0-9]++"))
    throw new IOException();

  resp.addHeader("X-Header", value);
  // ...
}

See

javasecurity:S2076

Applications that execute operating system commands or execute commands that interact with the underlying system should neutralize any externally-provided values used in those commands. Failure to do so could allow an attacker to include input that executes unintended commands or exposes sensitive data.

The mitigation strategy should be based on whitelisting of allowed characters or commands.

Noncompliant Code Example

public void run(javax.servlet.http.HttpServletRequest request) throws IOException {
  String binary = request.getParameter("binary");

  // If the value "/sbin/shutdown" is passed as binary and the web server is running as root,
  // then the machine running the web server will be shut down and become unavailable for future requests

  Runtime.getRuntime().exec(binary); // Noncompliant
}

Compliant Solution

public void run(javax.servlet.http.HttpServletRequest request) throws IOException {
  String binary = request.getParameter("binary");

  // Restrict to binaries within the current working directory whose name only contains letters
  if (!binary.matches("[a-zA-Z]++")) {
    throw new IllegalArgumentException();
  }

  Runtime.getRuntime().exec(binary);
}

See

javasecurity:S5131

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Endpoints reflecting back tainted data could allow attackers to inject code that would eventually be executed in the user's browser. This could enable a wide range of serious attacks like accessing/modifying sensitive information or impersonating other users.

Typically, the solution is one of the following:

  • Validate user provided data based on a whitelist and reject input that's not whitelisted.
  • Sanitize user provided data from any characters that can be used for malicious purposes.
  • Encode user provided data being reflected as output. Adjust the encoding to the output context so that, for example, HTML encoding is used for HTML content, HTML attribute encoding is used for attribute values, and JavaScript encoding is used for server-generated JavaScript.

When sanitizing or encoding data, it is recommended to only use libraries specifically designed for security purposes. Also, make sure that the library you are using is being actively maintained and is kept up-to-date with the latest discovered vulnerabilities.

Noncompliant Code Example

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String name = req.getParameter("name");
  PrintWriter out = resp.getWriter();
  out.write("Hello " + name); // Noncompliant
}

Compliant Solution

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String name = req.getParameter("name");
  String encodedName = org.owasp.encoder.Encode.forHtml(name);
  PrintWriter out = resp.getWriter();
  out.write("Hello " + encodedName);
}

See

  • OWASP Cheat Sheet - XSS Prevention Cheat Sheet
  • OWASP Top 10 2017 Category A7 - Cross-Site Scripting (XSS)
  • MITRE, CWE-79 - Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
  • MITRE, CWE-80 - Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)
  • MITRE, CWE-81 - Improper Neutralization of Script in an Error Message Web Page
  • MITRE, CWE-82 - Improper Neutralization of Script in Attributes of IMG Tags in a Web Page
  • MITRE, CWE-83 - Improper Neutralization of Script in Attributes in a Web Page
  • MITRE, CWE-84 - Improper Neutralization of Encoded URI Schemes in a Web Page
  • MITRE, CWE-85 - Doubled Character XSS Manipulations
  • MITRE, CWE-86 - Improper Neutralization of Invalid Characters in Identifiers in Web Pages
  • MITRE, CWE-87 - Improper Neutralization of Alternate XSS Syntax
  • SANS Top 25 - Insecure Interaction Between Components
javasecurity:S5144

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. A remote server making requests to URLs based on tainted data could enable attackers to make arbitrary requests to the internal network or to the local file system.

The problem could be mitigated in any of the following ways:

  • Validate the user provided data based on a whitelist and reject input not matching.
  • Redesign the application to not send requests based on user provided data.

Noncompliant Code Example

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  URL url = new URL(req.getParameter("url"));
  HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // Noncompliant
  // ...
}

Compliant Solution

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  URL url = new URL(req.getParameter("url"));

  // The safest way is to match the incoming URL against a whitelist
  if (!urlWhiteList.contains(url.toString()))
    throw new IOException();

  // If whitelisting is not possible, at least make sure that things like file:// and http://localhost are blocked
  InetAddress inetAddress = InetAddress.getByName(url.getHost());
  if (!url.getProtocol().startsWith("http") ||
      inetAddress.isAnyLocalAddress() ||
      inetAddress.isLoopbackAddress() ||
      inetAddress.isLinkLocalAddress())
    throw new IOException();

  HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  // ...
}

See

javasecurity:S2083

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Constructing file system paths directly from tainted data could enable an attacker to inject specially crafted values, such as '../', that change the initial path and, when accessed, resolve to a path on the filesystem where the user should normally not have access.

A successful attack might give an attacker the ability to read, modify, or delete sensitive information from the file system and sometimes even execute arbitrary operating system commands. This is often referred to as a "path traversal" or "directory traversal" attack.

The mitigation strategy should be based on the whitelisting of allowed paths or characters.

Noncompliant Code Example

public boolean authenticate(javax.servlet.http.HttpServletRequest request) {
  String user = request.getParameter("user");

  // If the special value "../bin" is passed as user, authentication is bypassed
  // Indeed, if it passed as a user, the path becomes:
  // /bin
  // which exists on most Linux / BSD / Mac OS distributions

  return Files.exists(Paths.get("/home/", user)); // Noncompliant
}

Compliant Solution

public boolean authenticate(javax.servlet.http.HttpServletRequest request) {
  String user = request.getParameter("user");

  // Restrict the username to letters and digits only
  if (!user.matches("[a-zA-Z0-9]++")) {
    return false;
  }

  return Files.exists(Paths.get("/home/", user));
}

See

javasecurity:S2091

User provided data, such as URL parameters, should always be considered untrusted and tainted. Constructing XPath expressions directly from tainted data enables attackers to inject specially crafted values that changes the initial meaning of the expression itself. Successful XPath injection attacks can read sensitive information from XML documents.

Noncompliant Code Example

public boolean authenticate(javax.servlet.http.HttpServletRequest request, javax.xml.xpath.XPath xpath, org.w3c.dom.Document doc) throws XPathExpressionException {
  String user = request.getParameter("user");
  String pass = request.getParameter("pass");

  String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']"; // Unsafe

  // An attacker can bypass authentication by setting user to this special value
  user = "' or 1=1 or ''='";

  return (boolean)xpath.evaluate(expression, doc, XPathConstants.BOOLEAN); // Noncompliant
}

Compliant Solution

public boolean authenticate(javax.servlet.http.HttpServletRequest request, javax.xml.xpath.XPath xpath, org.w3c.dom.Document doc) throws XPathExpressionException {
  String user = request.getParameter("user");
  String pass = request.getParameter("pass");

  String expression = "/users/user[@name=$user and @pass=$pass]";

  xpath.setXPathVariableResolver(v -> {
    switch (v.getLocalPart()) {
      case "user":
        return user;
      case "pass":
        return pass;
      default:
        throw new IllegalArgumentException();
    }
  });

  return (boolean)xpath.evaluate(expression, doc, XPathConstants.BOOLEAN);
}

See

roslyn.sonaranalyzer.security.cs:S2631

Evaluating regular expressions against input strings can be an extremely CPU-intensive task. For example, a specially crafted regular expression such as (a+)++ will take several seconds to evaluate the input string, aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!. The problem is that every additional "a" added to the input doubles the time required to evaluate the regex. However, the equivalent regular expression, a (without grouping), is efficiently evaluated in milliseconds and scales linearly with the input size.

Evaluating user-provided strings as regular expressions opens the door for Denial Of Service attacks. In the context of a web application, attackers can force the web server to spend all of its resources evaluating regular expressions thereby making the service inaccessible to genuine users.

Noncompliant Code Example

public class RegexDoS : Controller
{
  // GET /RegexDoS/Validate
  public IActionResult Validate(string regex, string input)
  {
    // Enables attackers to force the web server to evaluate
    // regex such as "^(a+)+$" on inputs such as "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!"

    bool match = Regex.IsMatch(input, regex); // Noncompliant

    return Content("Valid? " + match);
  }
}

Compliant Solution

public class RegexDoS : Controller
{
  // GET /RegexDoS/Validate
  public IActionResult Validate(string regex, string input)
  {
    // Option 1: Use a hardcoded regex
    bool match = Regex.IsMatch(input, "^a+$");

    // Option 2: Set a timeout on the regex's evaluation
    match = new Regex(regex, RegexOptions.None, TimeSpan.FromMilliseconds(100)).IsMatch(input);

    return Content("Valid? " + match);
  }
}

See

roslyn.sonaranalyzer.security.cs:S5146

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Applications performing HTTP redirects based on tainted data could enable an attacker to redirect users to a malicious site to, for example, steal login credentials.

This problem could be mitigated in any of the following ways:

  • Validate the user provided data based on a whitelist and reject input not matching.
  • Redesign the application to not perform redirects based on user provided data.

Noncompliant Code Example

public class OpenRedirect : Controller
{
  public IActionResult Test(string url)
  {
    return Redirect(url); // Noncompliant
  }
}

Compliant Solution

public class OpenRedirect : Controller
{
  private string[] whiteList = { "https://www.sonarsource.com" };

  public IActionResult Test(string url)
  {
    // Match the incoming URL against a whitelist
    if (!whiteList.Contains(url))
    {
      return BadRequest();
    }

    return Redirect(url);
  }
}

See

roslyn.sonaranalyzer.security.cs:S5145

User provided data, such as URL parameters, POST data payloads or cookies, should always be considered untrusted and tainted. Applications logging tainted data could enable an attacker to inject characters that would break the log file pattern. This could be used to block monitors and SIEM (Security Information and Event Management) systems from detecting other malicious events.

This problem could be mitigated by sanitizing the user provided data before logging it.

Noncompliant Code Example

public class LogForging : Controller
{
  public IActionResult Test(string id)
  {
    logger.Info("ID: {0}", id); // Noncompliant
    // ...
  }
}

Compliant Solution

public class LogForging : Controller
{
  public IActionResult Test(string id)
  {
    // Replace pattern-breaking characters
    id = id.Replace('\n', '_').Replace('\r', '_').Replace('\t', '_');

    logger.Info("ID: {0}", id);
    // ...
  }
}

See

roslyn.sonaranalyzer.security.cs:S5167

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Applications constructing HTTP response headers based on tainted data could allow attackers to inject characters that would be interpreted as a new line in some browsers. This could, for example, enable Cross-Site Scripting (XSS) attacks.

Most modern web application frameworks and servers mitigate this type of attack by default, but there might be rare cases where older versions are still vulnerable. As a best practice, applications that use user provided data to construct the response header should always validate the data first. Validation should be based on a whitelist.

Noncompliant Code Example

string value = Request.QueryString["value"];
Response.AddHeader("X-Header", value); // Noncompliant

Compliant Solution

string value = Request.QueryString["value"];
// Allow only alphanumeric characters
if (value == null || !Regex.IsMatch(value, "^[a-zA-Z0-9]+$"))
{
  throw new Exception("Invalid value");
}
Response.AddHeader("X-Header", value);

See

roslyn.sonaranalyzer.security.cs:S2076

Applications that execute operating system commands or execute commands that interact with the underlying system should neutralize any externally-provided values used in those commands. Failure to do so could allow an attacker to include input that executes unintended commands or exposes sensitive data.

The mitigation strategy should be based on whitelisting of allowed characters or commands.

Noncompliant Code Example

public class CommandInjection : Controller
{
  // GET /CommandInjection/Run
  public IActionResult Run(string binary)
  {
    // If the value "/sbin/shutdown" is passed as binary and the web server is running as root,
    // then the machine running the web server will be shut down and become unavailable for future requests

    Process p = new Process();
    p.StartInfo.FileName = binary; // Noncompliant
    p.StartInfo.RedirectStandardOutput = true;
    p.Start();
    string output = p.StandardOutput.ReadToEnd();
    return Content(output);
  }
}

Compliant Solution

public class CommandInjection : Controller
{
  // GET /CommandInjection/Run
  public IActionResult Run(string binary)
  {
    // Restrict to binaries within the current working directory whose name only contains letters
    if (binary == null || !Regex.IsMatch(binary, "^[a-zA-Z]+$"))
    {
      return BadRequest();
    }

    Process p = new Process();
    p.StartInfo.FileName = binary; // Now safe
    p.StartInfo.RedirectStandardOutput = true;
    p.Start();
    string output = p.StandardOutput.ReadToEnd();
    return Content(output);
  }
}

See

roslyn.sonaranalyzer.security.cs:S5131

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Endpoints reflecting back tainted data could allow attackers to inject code that would eventually be executed in the user's browser. This could enable a wide range of serious attacks like accessing/modifying sensitive information or impersonating other users.

Typically, the solution is one of the following:

  • Validate user provided data based on a whitelist and reject input that's not whitelisted.
  • Sanitize user provided data from any characters that can be used for malicious purposes.
  • Encode user provided data being reflected as output. Adjust the encoding to the output context so that, for example, HTML encoding is used for HTML content, HTML attribute encoding is used for attribute values, and JavaScript encoding is used for server-generated JavaScript.

When sanitizing or encoding data, it is recommended to only use libraries specifically designed for security purposes. Also, make sure that the library you are using is being actively maintained and is kept up-to-date with the latest discovered vulnerabilities.

Noncompliant Code Example

string name = Request.QueryString["name"];
Response.Write("Hello " + name); // Noncompliant

Compliant Solution

string name = Request.QueryString["name"];
name = System.Web.Security.AntiXss.AntiXssEncoder.HtmlEncode(name, true);
Response.Write("Hello " + name);

See

  • OWASP Cheat Sheet - XSS Prevention Cheat Sheet
  • OWASP Top 10 2017 Category A7 - Cross-Site Scripting (XSS)
  • MITRE, CWE-79 - Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
  • MITRE, CWE-80 - Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)
  • MITRE, CWE-81 - Improper Neutralization of Script in an Error Message Web Page
  • MITRE, CWE-82 - Improper Neutralization of Script in Attributes of IMG Tags in a Web Page
  • MITRE, CWE-83 - Improper Neutralization of Script in Attributes in a Web Page
  • MITRE, CWE-84 - Improper Neutralization of Encoded URI Schemes in a Web Page
  • MITRE, CWE-85 - Doubled Character XSS Manipulations
  • MITRE, CWE-86 - Improper Neutralization of Invalid Characters in Identifiers in Web Pages
  • MITRE, CWE-87 - Improper Neutralization of Alternate XSS Syntax
  • SANS Top 25 - Insecure Interaction Between Components
roslyn.sonaranalyzer.security.cs:S5144

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. A remote server making requests to URLs based on tainted data could enable attackers to make arbitrary requests to the internal network or to the local file system.

The problem could be mitigated in any of the following ways:

  • Validate the user provided data based on a whitelist and reject input not matching.
  • Redesign the application to not send requests based on user provided data.

Noncompliant Code Example

public class SSRF : Controller
{
  public IActionResult Test(string url)
  {
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); // Noncompliant
    // ...
  }
}

Compliant Solution

public class SSRF : Controller
{
  private string[] whiteList = { "https://www.sonarsource.com" };

  public IActionResult Test(string url)
  {
    // Match the incoming URL against a whitelist
    if (!whiteList.Contains(url))
    {
      return BadRequest();
    }

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    // ...
  }
}

See

roslyn.sonaranalyzer.security.cs:S2083

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Constructing file system paths directly from tainted data could enable an attacker to inject specially crafted values, such as '../', that change the initial path and, when accessed, resolve to a path on the filesystem where the user should normally not have access.

A successful attack might give an attacker the ability to read, modify, or delete sensitive information from the file system and sometimes even execute arbitrary operating system commands. This is often referred to as a "path traversal" or "directory traversal" attack.

The mitigation strategy should be based on the whitelisting of allowed paths or characters.

Noncompliant Code Example

public class PathTraversal : Controller
{
  // GET /PathTraversal/Authenticate
  public IActionResult Authenticate(string user)
  {
    bool userExists = System.IO.File.Exists("/home/" + user); // Noncompliant

    // If the special value "../bin" is passed as user, authentication is bypassed
    // Indeed, if it passed as a user, the path becomes:
    // /bin
    // which exists on most Linux / BSD / Mac OS distributions

    return Content(userExists ? "success" : "fail");
  }
}

Compliant Solution

public class PathTraversal : Controller
{
  // GET /PathTraversal/Authenticate
  public IActionResult Authenticate(string user)
  {
    // Restrict the username to letters and digits only
    if (!Regex.IsMatch(user, "^[a-zA-Z0-9]+$"))
    {
        return BadRequest();
    }

    bool userExists = System.IO.File.Exists("/home/" + user); // Now safe
    return Content(userExists ? "success" : "fail");
  }
}

See

phpsecurity:S5146

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Applications performing HTTP redirects based on tainted data could enable an attacker to redirect users to a malicious site to, for example, steal login credentials.

This problem could be mitigated in any of the following ways:

  • Validate the user provided data based on a whitelist and reject input not matching.
  • Redesign the application to not perform redirects based on user provided data.

Noncompliant Code Example

$url = $this->request->getQuery("url");
return $this->redirect($url); // Noncompliant

Compliant Solution

$whitelist = array(
  "https://www.sonarsource.com/"
);
$url = $this->request->getQuery("url");
if (in_array($url, $whitelist)) {
  return $this->redirect($url);
} else {
  throw new ForbiddenException();
}

See

phpsecurity:S5145

User provided data, such as URL parameters, POST data payloads or cookies, should always be considered untrusted and tainted. Applications logging tainted data could enable an attacker to inject characters that would break the log file pattern. This could be used to block monitors and SIEM (Security Information and Event Management) systems from detecting other malicious events.

This problem could be mitigated by sanitizing the user provided data before logging it.

Noncompliant Code Example

$data = $_GET["data"];
error_log($data); // Noncompliant

Compliant Solution

$data = $_GET["data"];
$badchars = array("\n", "\r", "\t");
$safedata = str_replace($badchars, "", $data);
error_log($safedata);

See

phpsecurity:S5167

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Applications constructing HTTP response headers based on tainted data could allow attackers to inject characters that would be interpreted as a new line in some browsers. This could, for example, enable Cross-Site Scripting (XSS) attacks.

Most modern web application frameworks and servers mitigate this type of attack by default, but there might be rare cases where older versions are still vulnerable. As a best practice, applications that use user provided data to construct the response header should always validate the data first. Validation should be based on a whitelist.

Noncompliant Code Example

$value = $_GET["value"];
header("X-Header: $value"); // Noncompliant

Compliant Solution

$value = $_GET["value"];
if (ctype_alnum($value)) {
  header("X-Header: $value"); // Compliant
} else {
  // Error
}

See

phpsecurity:S5131

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Endpoints reflecting back tainted data could allow attackers to inject code that would eventually be executed in the user's browser. This could enable a wide range of serious attacks like accessing/modifying sensitive information or impersonating other users.

Typically, the solution is one of the following:

  • Validate user provided data based on a whitelist and reject input that's not whitelisted.
  • Sanitize user provided data from any characters that can be used for malicious purposes.
  • Encode user provided data being reflected as output. Adjust the encoding to the output context so that, for example, HTML encoding is used for HTML content, HTML attribute encoding is used for attribute values, and JavaScript encoding is used for server-generated JavaScript.

When sanitizing or encoding data, it is recommended to only use libraries specifically designed for security purposes. Also, make sure that the library you are using is being actively maintained and is kept up-to-date with the latest discovered vulnerabilities.

Noncompliant Code Example

$name = $_GET["name"];
echo "Welcome $name"; // Noncompliant

Compliant Solution

$name = $_GET["name"];
$safename = htmlspecialchars($name);
echo "Welcome $safename";

See

  • OWASP Cheat Sheet - XSS Prevention Cheat Sheet
  • OWASP Top 10 2017 Category A7 - Cross-Site Scripting (XSS)
  • MITRE, CWE-79 - Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
  • MITRE, CWE-80 - Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)
  • MITRE, CWE-81 - Improper Neutralization of Script in an Error Message Web Page
  • MITRE, CWE-82 - Improper Neutralization of Script in Attributes of IMG Tags in a Web Page
  • MITRE, CWE-83 - Improper Neutralization of Script in Attributes in a Web Page
  • MITRE, CWE-84 - Improper Neutralization of Encoded URI Schemes in a Web Page
  • MITRE, CWE-85 - Doubled Character XSS Manipulations
  • MITRE, CWE-86 - Improper Neutralization of Invalid Characters in Identifiers in Web Pages
  • MITRE, CWE-87 - Improper Neutralization of Alternate XSS Syntax
  • SANS Top 25 - Insecure Interaction Between Components
phpsecurity:S5144

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. A remote server making requests to URLs based on tainted data could enable attackers to make arbitrary requests to the internal network or to the local file system.

The problem could be mitigated in any of the following ways:

  • Validate the user provided data based on a whitelist and reject input not matching.
  • Redesign the application to not send requests based on user provided data.

Noncompliant Code Example

$url = $_GET["url"];
$resp = file_get_contents($url); // Noncompliant
// ...

Compliant Solution

$whitelist = array(
  "https://www.sonarsource.com"
);
$url = $_GET["url"];
if (in_array($url, $whitelist)) {
  $resp = file_get_contents($url);
  // ...
}

See

squid:S2757

The use of operators pairs ( =+, =- or =! ) where the reversed, single operator was meant (+=, -= or !=) will compile and run, but not produce the expected results.

This rule raises an issue when =+, =-, or =! is used without any spacing between the two operators and when there is at least one whitespace character after.

Noncompliant Code Example

int target = -5;
int num = 3;

target =- num;  // Noncompliant; target = -3. Is that really what's meant?
target =+ num; // Noncompliant; target = 3

Compliant Solution

int target = -5;
int num = 3;

target = -num;  // Compliant; intent to assign inverse value of num is clear
target += num;
objc:SideEffectInSizeOf

A possible programming error in C++ is to apply the sizeof operator to an expression and expect the expression to be evaluated. However, the expression is not evaluated because sizeof only acts on the type of the expression. To avoid this error, sizeof should not be used on expressions that would contain side effects if they were used elsewhere, since the side effects will not occur.

Noncompliant Code Example

j = sizeof( i = 1234 ); // Noncompliant - j is set to the sizeof the type of i which is an int. i is not set to 1234.

j = sizeof ( b[i++] ); // Noncompliant - i won't be incremented.

j = sizeof( isPtr(e) ); // Compliant

Compliant Solution

i = 1234;
j = sizeof( i );

i++;
j = sizeof ( b[i] );

j = sizeof( isPtr(e) );

See

  • MISRA C 2004, 12.3 - The sizeof operator shall not be used on expressions that contain side effects.
  • MISRA C++ 2008, 5-3-4 - Evaluation of the operand to the sizeof operator shall not contain side effects.
  • MISRA C 2012, 13.6 - The operand of the sizeof operator shall not contain any expression which has potential side effects
objc:S5297

__attribute__ is a GNU extension that allows to decorate functions, parameters, variables... with some attributes. It may help for compiler optimizations or for the writer of some code to better state his intent (and have the compiler check it).

If this extension is used incorrectly, it will usually not break the build, but it still means that the code may not behave as the developer expects. This rule reports such occurrences of bad use of __attribute__.

Noncompliant Code Example

int f1() __attribute__((returns_nonnull)); // Noncompliant; "returns_nonnull" only applies to return values which are pointers

void g(int *a) __attribute__((nonnull(1))){} // Noncompliant; "nonnull" position in the function definition is not allowed

void h() __attribute__((warn_unused_result)); // Noncompliant; "warn_unused_result" does not work with function without return value

void test() {
  int __declspec(empty_bases)i; // Noncompliant; "empty_bases" only applies to classes
  char c = (char __attribute__((aligned(8)))) i; // Noncompliant, attribute is ignored
}}
objc:S5293

The possibilities of ISO C printf format strings are limited, this is why many extensions have been added by several implementations. Even though they are widespread and similar in many implementations, they are not standard, which means that using them may create portability issues.

This rule reports an issue when format strings do not comply with ISO C standards.

Noncompliant Code Example

void test() {
  printf("%1$d", 1); // Noncompliant; positional arguments are not supported by ISO C
  printf("%qd", (long long)1); // Noncompliant; length specifier "q" is not supported by ISO C
}
objc:S5278

The memory functions memset, memcpy, memmove, and memcmp take as last argument the number of bytes they will work on. If this size argument is badly defined (eg it is greater than the size of the destination object), it can lead to undefined behavior.

This rule raises an issue when the size argument of a memory function seems inconsistent with the other arguments of the function.

Noncompliant Code Example 

struct A {};

void f() {
  struct A dest;
  memset(&dest, 0, sizeof(&dest)); // Noncompliant; size is based on "A*" when the destination is of type "A"
  struct A src;
  memcpy(&dest, &src, sizeof(&dest)); // Noncompliant; size is based on "A*" when the source is of type "A"

  if (memset(&dest, 0, sizeof(dest) != 0)) { // Noncompliant; size argument is a comparison
    // ...
  }
}

Compliant Solution

struct A {};

void f() {
  struct A dest;
  memset(&dest, 0, sizeof(dest)); // Compliant
  struct A src;
  memcpy(&dest, &src, sizeof(dest)); // Compliant

  if (memset(&dest, 0, sizeof(dest)) != 0) { // Compliant
    // ...
  }
}
objc:S5279

Operands of sizeof, noexcept and decltype are unevaluated. So side effects in these operands (which are all the effects an expression can have in addition to producing a value), will not be applied. And that may be surprising to the reader.

Additionally, the operand of typeid may or may not be evaluated, depending on its type: it will be evaluated if it is a function call that returns reference to a polymorphic type, but it will not be evaluated in all the other cases. This difference of behavior is tricky to apprehend and that is why both cases are reported here.

This rules reports an issue when operands of such operators have side-effects.

Noncompliant Code Example

class A {
public:
  virtual ~A();
  /*...*/
};
class B : public A { /* ....*/ };
A& create(string const &xml);

void test(string const &xml) {
  int i = 0;
  cout << noexcept(++i); // Noncompliant, "i" is not incremented
  cout << typeid(++i).name(); // Noncompliant, "i" is not incremented
  auto p1 = malloc(sizeof(i = 5)); // Noncompliant, "i" is not changed

  cout << typeid(create(xml)).name(); // Noncompliant, even if the side-effects will be evaluated in this case
}

Compliant Solution

class A {
public:
  virtual ~A();
  /*...*/
};
class B : public A { /* ....*/ };
A& create(string const &xml);

void test(string const &xml) {
  int i = 0;
  ++i;
  cout << noexcept(i); // Compliant
  ++i;
  cout << typeid(i).name(); // Compliant
  i = 5;
  auto p1 = malloc(sizeof(i)); // Compliant

  auto a = create(xml);
  cout << typeid(a).name(); // Compliant
}
objc:S5270

Variadic arguments allow a function to accept any number of arguments (in this rule, we are not talking about variadic templates, but about functions with ellipses). But these arguments have to respect some criteria to be handled properly.

This rules reports an issue if the type of the argument: 

  • is a non trivially copyable, movable or deletable type: there is no guarantee that it will work.
  • is a class type that is trivially copyable, movable and deletable: in this case, we consider that the user intention was probably not to directly pass it as an argument but to call a method on it (c_str() for example)

Noncompliant Code Example

class A {
  char* toStr();
};
void v(...);

void f() {
  A a;
  v(a); // Noncompliant

  std::string myString = "foo";
  v(myString); // Noncompliant; string is not a POD type
}

Compliant Solution

class A {
  char* toStr();
}
void v(...);

void f() {
  A a;
  v(a.toStr()); // Compliant

  std::string myString = "foo";
  v(myString.c_str()); // Compliant
}
objc:S5273

Size argument of strncat, strlcat and strlcpy should define the size of the destination to prevent buffer overflow.

Moreover, strncat always adds a terminating null character at the end of the appended characters so the size argument should be smaller than the size of the destination to let enough space for it.

Noncompliant Code Example

void f(char* src) {
  char dest[10];
  strlcpy(dest, src, sizeof(src)); // Noncompliant; size argument is the size of the source instead of the size of the destination

  strncat(dest, src, sizeof(src)); // Noncompliant; size of the source instead of the size of the destination
  strncat(dest, src, sizeof(dest)); // Noncompliant; size argument is too large
}

Compliant Solution

void f(char* src) {
  char dest[10];
  strncat(dest, src, sizeof(dest) - 1); // Compliant
}

 

objc:S5271

The attribute noreturn indicates that a function does not return. This information clarifies the behavior of the function and it allows the compiler to do optimizations.

It can also help the compiler (and static analyzer tools, i.e. us) provide better error messages:

__attribute__((noreturn)) void f();

int g(int b) {
  if (b == 5) {
    f();
    printf("Hello world\n"); // This is dead code, the compiler/static analyzer can now detect it
    // There is no returned value, but it is fine, the compiler/static analyzer knows not to warn about it
  } else {
    return 3;
  }
}

This rule detects when the attribute noreturn can be added to a function.

Noncompliant Code Example

void g() { // Noncompliant
  abort();
}

Compliant Solution

__attribute__((noreturn)) void g() { // or [[noreturn]] for C++
  abort(); // Compliant
}
objc:S1481

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

int numberOfMinutes(int hours) {
  int seconds = 0; // Noncompliant, never used
  return hours * 60;
}

Compliant Solution

int numberOfMinutes(int hours) {
  return hours * 60;
}

Exceptions

No issue is raised on local variables having the attribute "unused" and on object declarations with non-empty arguments.

objc:S853

When ~ and << are applied to small integer types (unsigned char or unsigned short), the operations are preceded by integral promotion, and the result may contain high-order bits which have not been anticipated.

Noncompliant Code Example

unsigned char port = 0x5aU;
unsigned char result_8;
unsigned short result_16;
unsigned short mode;
result_8 = (~port) >> 4; // Noncompliant; '~port' is 0xFFA5 on a 16-bit machine but 0xFFFFFFA5 on a 32-bit machine. Result is 0xFA for both, but 0x0A may have been expected.
result_16 = ((port << 4) & mode) >> 6; // Noncompliant; result_16 value depends on the implemented size of an int.

Compliant Solution

result_8 = ((unsigned char)(~port)) >> 4; // Compliant
result_16 = ((unsigned short)((unsigned short) port << 4) & mode) >> 6; // Compliant

See

  • MISRA C:2004, 10.5 - If the bitwise operators ~ and << are applied to an operand of underlying type unsigned char or unsigned short, the result shall be immediately cast to the underlying type of the operand.
  • MISRA C++:2008, 5-0-10 - If the bitwise operators ~ and << are applied to an operand with an underlying type of unsigned char or unsigned short, the result shall be immediately cast to the underlying type of the operand.
objc:S5281

It is a security vulnerability to call printf with a unique string argument which is not a string literal. Indeed, if this argument comes from a user input, this user can :

  • make the program crash, by executing code equivalent to: printf("%s%s%s%s%s%s%s%s")
  • view the stack or a memory at any location, by executing code equivalent to: printf("%08x %08x %08x %08x %08x\n")

Noncompliant Code Example

void f(char* userInput) {
  printf(userInput); // Noncompliant
}

Compliant Solution

void f(char* userInput) {
  printf("%s", userInput); // Compliant
}

See

Owasp: format string attack

objc:S5280

mktemp, mkstemp, mkstemps or mkdtemp are useful functions to create temporary files and directories. They accept a template parameter which defines the path where the file should be created and which should contain at least six trailing "X"s to ensure the uniqueness of the filename.

Noncompliant Code Example

mkstemp("/tmp/file_XXXX"); // Noncompliant

Compliant Solution

mkstemp("/tmp/file_XXXXXX"); // Compliant
objc:S5283

Variable length arrays should have a well-defined, positive size.

Noncompliant Code Example

void f1() {
  int n;
  int a[n]; // Noncompliant; n is undefined
}

void f2() {
  int n = 0;
  int a[n]; // Noncompliant; array of zero size
}
objc:S2275

Because printf format strings are interpreted at runtime, rather than validated by the compiler, they can contain errors that lead to unexpected behavior or runtime errors. This rule statically validates the good behavior of printf formats.

The related rule S3457 is about errors that produce an unexpected string, while this rule is about errors that will create undefined behavior.

Noncompliant Code Example

printf("%d", 1.2); // Noncompliant, an "int" is expected rather than a "double"
printf("%d %d", 1); // Noncompliant, the second argument is missing
printf("%0$d ", 1); // Noncompliant, arguments are numbered starting from 1
printf("%1$d %d", 1, 2); // Noncompliant, positional and non-positional arguments can not be mixed
printf("%*d", 1.1, 2); // Noncompliant, field width should be an integer
printf("ab\0cd"); // Noncompliant, format string contains null char

int x;
printf("%+p", (void*)&x); // Noncompliant, flag "+" has undefined behavior with conversion specifier "p"
printf("%vd", x); //Noncompliant, conversion specifier "v" is not valid

Compliant Solution

printf("%f", 1.2); // Compliant, format is consistent with the corresponding argument
printf("%d", 1); // Compliant, number of specifiers is consistent with number of arguments
printf("%1$d ", 1); // Compliant, number of positional argument is consistent

Exceptions

This rule will only work if the format string is provided as a string literal.

See

objc:S5308

setuid family of functions are used to change the user identity of the caller process in order to change privileges for the following actions. If the function call returns with an error, the rest of the program will execute with unexpected privileges leading to unexpected behaviour.

Noncompliant Code Example

void f() {
  ...
  setuid(0); // Noncompliant
  ...
}

Compliant Solution

void f() {
  ...
  if (setuid(0)) {
    // fail
  }
  ...
}
objc:S3457

Because printf format strings are interpreted at runtime, rather than validated by the compiler, they can contain errors that result in the wrong strings being created. This rule statically validates the correlation of printf format strings to their arguments.

The related rule S2275 is about errors that will create undefined behavior, while this rule is about errors that produce an unexpected string.

Noncompliant Code Example

printf("%d", 1, 2); // Noncompliant; the second argument "2" is unused
printf("%0-f", 1.2); // Noncompliant; flag "0" is ignored because of "-"

Compliant Solution

printf("%d %d", 1, 2); // Compliant
printf("%-f", 1.2); // Compliant

Exceptions

This rule will only work if the format string is provided as a string literal.

See

objc:S109

A magic number is a number that comes out of nowhere, and is directly used in a statement. Magic numbers are often used, for instance to limit the number of iterations of a loops, to test the value of a property, etc.

Using magic numbers may seem obvious and straightforward when you're writing a piece of code, but they are much less obvious and straightforward at debugging time.

That is why magic numbers must be demystified by first being assigned a name. This is classically done by using a constant (constexpr or const if your compiler does not support constexpr yet) or an enumeration.

-1, 0 and 1 are not considered magic numbers.

Noncompliant Code Example

void doSomething(int var) {
  for(int i = 0; i < 42; i++) { // Noncompliant - 42 is a magic number
    // ...
  }

  if (var == 42) { // Noncompliant - magic number
    // ...
  }
}

Compliant Solution

enum Status {
STATUS_KO = 0,
STATUS_OK = 42,
};

void doSomething(Status var) {
  constexpr int maxIterations = 42; // Compliant - in a declaration
  for(int i = 0; i < maxIterations ; i++){ // Compliant: 0 is excluded, and maxIterations is a named constant
    // ...
  }

  if (STATUS_OK == var) { // Compliant - number comes from an enum
    // ...
  }
}
objc:S2753

Just as comparing apples and oranges is seen as a classic folly, comparing values from different enumerations against each other or converting them into one another is nonsensical. True, at root enums are simply named numbers, and it's certainly valid to compare numbers. But an added layer of meaning is created by an enum, one that goes beyond simple numerical values.

Ignoring that extra layer of meaning is at best a trap for maintainers, who are likely to be hopelessly confused by the code. At worst, it is a bug, which will lead to unexpected results.

Noncompliant Code Example

enum apple {BRAEBURN, FUJI, GRANNY_SMITH, RED_DELICIOUS};
enum orange {BLOOD, NAVEL, BITTER, BERGAMOT, MANDARIN};

void makeCider(apple v);

bool fun(apple v1, orange v2) {
  makeCider((apple)v2); // Noncompliant
  return v1 != v2;  // Noncompliant
}
objc:S2190

Recursion happens when control enters a loop that has no exit. This can happen a method invokes itself, when a pair of methods invoke each other, or when goto statements are used to move between two segments of code. It can be a useful tool, but unless the method includes a provision to break out of the recursion and return, the recursion will continue until the stack overflows and the program crashes.

Noncompliant Code Example

int pow(int num, int exponent) {  // Noncompliant; no condition under which pow isn't re-called
  num = num * pow(num, exponent-1);
  return num;  // this is never reached
}

void internalRecursion(int i) {
  start:
    goto end;
  end:
    goto start;  // Noncompliant; there's no way to break out of this method
}

Compliant Solution

int pow(int num, int exponent) {
  if (exponent > 1) {  // recursion now conditional and stop-able
    num = num * pow(num, exponent-1);
  }
  return num;
}
objc:S5259

Include guards, wrapping around the entire content of a header file, are a best practice that ensure that no matter how many times the header is actually included in a translation unit, its content will only be seen once. 

The include guard pattern is made up of four parts:

* #ifndef at the top of the file, with a unique macro name (usually the name relates to the name of the file, to ensure uniqueness).

* #define with the same macro name.

* The content of the file

* #endif at the end of the file

The rule raises an issue when the name in the second part differs from the name in the first (usually because of a typo or a copy/paste issue).

Noncompliant Code Example

#ifndef MYFILE_H
#define MY_FILE_H // Noncompliant
//...
#endif

Compliant Solution

#ifndef MYFILE_H
#define MYFILE_H
//...
#endif
objc:ObsoletePosixFunction

To ensure future code portability, obsolete POSIX functions should be removed. Those functions, with their replacements are listed below:

Obsolete Use Instead
asctime strftime
asctime_r strftime
bcmp memcmp
bcopy memmove memcpy
bsd_signal sigaction
bzero memset
ctime strftime
ecvt sprintf
fcvt sprintf
ftime no replacement function
gcvt sprintf
getcontext Rewrite to use POSIX threads.
gethostbyaddr getnameinfo
gethostbyname getaddrinfo
getwd getcwd
index strchr
makecontext Rewrite to use POSIX threads.
mktemp mkstemp
pthread_attr_getstackaddr pthread_attr_getstack
pthread_attr_setstackaddr pthread_attr_setstack
rand_r rand
rindex strrchr
scalb scalbln', 'scalblnf' or 'scalblnl' instead of this function
swapcontext Rewrite to use POSIX threads.
tmpnam 'tmpfile', 'mkstemp', or 'mkdtemp' instead for this function
tmpnam_r tmpfile', 'mkstemp', or 'mkdtemp' instead for this function
ualarm 'timer_create', 'timer_delete', 'timer_getoverrun', 'timer_gettime', or 'timer_settime' instead of this function
usleep 'nanosleep' or 'setitimer' function
utime utimensat
vfork fork
wcswcs wcsstr

See

objc:S5267

The attribute noreturn indicates that a function does not return.

Using this attribute allows the compiler to do some assumptions that can lead to optimizations. However, if a function with this attribute ever returns, the behavior becomes undefined.

Noncompliant Code Example

__attribute__((noreturn)) void f () {
  while (1) {
    // ...
    if (/* something*/) {
      return; // Noncompliant, this function should not return
    }
  }
}

Compliant Solution

__attribute__((noreturn)) void f() {  // Compliant
  while (true) {
    // ...
  }
}

Or

void f() {
  while (true) {
    // ...
    if (/* something*/) {
      return; // Compliant
    }
  }
}
objc:S5262

Dereferencing a null pointer has undefined behavior, and it is particularly harmful if a reference is then bound to the result, because a reference is assumed to refer to a valid object.

Noncompliant Code Example

void doSomething(A& a);
void f() {
  A* a = nullptr;
  // ...
  doSomething(*a); // Noncompliant
}
objc:S5263

While working with bitwise operators & or | it is easy to make a typo and write the equivalent logical operators && or ||. This rule is raising issues when the right operand of a logical expression && or || is a constant of integral type, as the developer probably meant to use the corresponding bitwise operator & or |.

Noncompliant Code Example

int fun(int a) {
  return a || 4; // Noncompliant, did you mean to use bitwise operator '|'?
}

Compliant Solution

int fun(int a) {
 return a | 4;
}
objc:S5261

The dangling else problem appears when nested if/else statements are written without curly braces. In this case, else is associated with the nearest if but that is not always obvious and sometimes the indentation can also be misleading.

This rules reports else statements that are difficult to understand, because they are inside nested if statements without curly braces.

Adding curly braces can generally make the code clearer (S121), and in this situation of dangling else, it really clarifies the intention of the code.

Noncompliant Code Example

 if (a)
   if (b)
     d++;
 else     // Noncompliant, is the "else" associated with "if(a)" or "if (b)"? (the answer is "if(b)")
   e++;

Compliant Solution

 if (a) {
   if (b) {
     d++;
   }
 } else { // Compliant, there is no doubt the "else" is associated with "if(a)"
   e++;
 }

See

* https://en.wikipedia.org/wiki/Dangling_else

c:SideEffectInSizeOf

A possible programming error in C++ is to apply the sizeof operator to an expression and expect the expression to be evaluated. However, the expression is not evaluated because sizeof only acts on the type of the expression. To avoid this error, sizeof should not be used on expressions that would contain side effects if they were used elsewhere, since the side effects will not occur.

Noncompliant Code Example

j = sizeof( i = 1234 ); // Noncompliant - j is set to the sizeof the type of i which is an int. i is not set to 1234.

j = sizeof ( b[i++] ); // Noncompliant - i won't be incremented.

j = sizeof( isPtr(e) ); // Compliant

Compliant Solution

i = 1234;
j = sizeof( i );

i++;
j = sizeof ( b[i] );

j = sizeof( isPtr(e) );

See

  • MISRA C 2004, 12.3 - The sizeof operator shall not be used on expressions that contain side effects.
  • MISRA C++ 2008, 5-3-4 - Evaluation of the operand to the sizeof operator shall not contain side effects.
  • MISRA C 2012, 13.6 - The operand of the sizeof operator shall not contain any expression which has potential side effects
c:S5297

__attribute__ is a GNU extension that allows to decorate functions, parameters, variables... with some attributes. It may help for compiler optimizations or for the writer of some code to better state his intent (and have the compiler check it).

If this extension is used incorrectly, it will usually not break the build, but it still means that the code may not behave as the developer expects. This rule reports such occurrences of bad use of __attribute__.

Noncompliant Code Example

int f1() __attribute__((returns_nonnull)); // Noncompliant; "returns_nonnull" only applies to return values which are pointers

void g(int *a) __attribute__((nonnull(1))){} // Noncompliant; "nonnull" position in the function definition is not allowed

void h() __attribute__((warn_unused_result)); // Noncompliant; "warn_unused_result" does not work with function without return value

void test() {
  int __declspec(empty_bases)i; // Noncompliant; "empty_bases" only applies to classes
  char c = (char __attribute__((aligned(8)))) i; // Noncompliant, attribute is ignored
}}
c:S5293

The possibilities of ISO C printf format strings are limited, this is why many extensions have been added by several implementations. Even though they are widespread and similar in many implementations, they are not standard, which means that using them may create portability issues.

This rule reports an issue when format strings do not comply with ISO C standards.

Noncompliant Code Example

void test() {
  printf("%1$d", 1); // Noncompliant; positional arguments are not supported by ISO C
  printf("%qd", (long long)1); // Noncompliant; length specifier "q" is not supported by ISO C
}
c:S5278

The memory functions memset, memcpy, memmove, and memcmp take as last argument the number of bytes they will work on. If this size argument is badly defined (eg it is greater than the size of the destination object), it can lead to undefined behavior.

This rule raises an issue when the size argument of a memory function seems inconsistent with the other arguments of the function.

Noncompliant Code Example 

struct A {};

void f() {
  struct A dest;
  memset(&dest, 0, sizeof(&dest)); // Noncompliant; size is based on "A*" when the destination is of type "A"
  struct A src;
  memcpy(&dest, &src, sizeof(&dest)); // Noncompliant; size is based on "A*" when the source is of type "A"

  if (memset(&dest, 0, sizeof(dest) != 0)) { // Noncompliant; size argument is a comparison
    // ...
  }
}

Compliant Solution

struct A {};

void f() {
  struct A dest;
  memset(&dest, 0, sizeof(dest)); // Compliant
  struct A src;
  memcpy(&dest, &src, sizeof(dest)); // Compliant

  if (memset(&dest, 0, sizeof(dest)) != 0) { // Compliant
    // ...
  }
}
c:S5279

Operands of sizeof, noexcept and decltype are unevaluated. So side effects in these operands (which are all the effects an expression can have in addition to producing a value), will not be applied. And that may be surprising to the reader.

Additionally, the operand of typeid may or may not be evaluated, depending on its type: it will be evaluated if it is a function call that returns reference to a polymorphic type, but it will not be evaluated in all the other cases. This difference of behavior is tricky to apprehend and that is why both cases are reported here.

This rules reports an issue when operands of such operators have side-effects.

Noncompliant Code Example

class A {
public:
  virtual ~A();
  /*...*/
};
class B : public A { /* ....*/ };
A& create(string const &xml);

void test(string const &xml) {
  int i = 0;
  cout << noexcept(++i); // Noncompliant, "i" is not incremented
  cout << typeid(++i).name(); // Noncompliant, "i" is not incremented
  auto p1 = malloc(sizeof(i = 5)); // Noncompliant, "i" is not changed

  cout << typeid(create(xml)).name(); // Noncompliant, even if the side-effects will be evaluated in this case
}

Compliant Solution

class A {
public:
  virtual ~A();
  /*...*/
};
class B : public A { /* ....*/ };
A& create(string const &xml);

void test(string const &xml) {
  int i = 0;
  ++i;
  cout << noexcept(i); // Compliant
  ++i;
  cout << typeid(i).name(); // Compliant
  i = 5;
  auto p1 = malloc(sizeof(i)); // Compliant

  auto a = create(xml);
  cout << typeid(a).name(); // Compliant
}
c:S5270

Variadic arguments allow a function to accept any number of arguments (in this rule, we are not talking about variadic templates, but about functions with ellipses). But these arguments have to respect some criteria to be handled properly.

This rules reports an issue if the type of the argument: 

  • is a non trivially copyable, movable or deletable type: there is no guarantee that it will work.
  • is a class type that is trivially copyable, movable and deletable: in this case, we consider that the user intention was probably not to directly pass it as an argument but to call a method on it (c_str() for example)

Noncompliant Code Example

class A {
  char* toStr();
};
void v(...);

void f() {
  A a;
  v(a); // Noncompliant

  std::string myString = "foo";
  v(myString); // Noncompliant; string is not a POD type
}

Compliant Solution

class A {
  char* toStr();
}
void v(...);

void f() {
  A a;
  v(a.toStr()); // Compliant

  std::string myString = "foo";
  v(myString.c_str()); // Compliant
}
c:S5273

Size argument of strncat, strlcat and strlcpy should define the size of the destination to prevent buffer overflow.

Moreover, strncat always adds a terminating null character at the end of the appended characters so the size argument should be smaller than the size of the destination to let enough space for it.

Noncompliant Code Example

void f(char* src) {
  char dest[10];
  strlcpy(dest, src, sizeof(src)); // Noncompliant; size argument is the size of the source instead of the size of the destination

  strncat(dest, src, sizeof(src)); // Noncompliant; size of the source instead of the size of the destination
  strncat(dest, src, sizeof(dest)); // Noncompliant; size argument is too large
}

Compliant Solution

void f(char* src) {
  char dest[10];
  strncat(dest, src, sizeof(dest) - 1); // Compliant
}

 

c:S5271

The attribute noreturn indicates that a function does not return. This information clarifies the behavior of the function and it allows the compiler to do optimizations.

It can also help the compiler (and static analyzer tools, i.e. us) provide better error messages:

__attribute__((noreturn)) void f();

int g(int b) {
  if (b == 5) {
    f();
    printf("Hello world\n"); // This is dead code, the compiler/static analyzer can now detect it
    // There is no returned value, but it is fine, the compiler/static analyzer knows not to warn about it
  } else {
    return 3;
  }
}

This rule detects when the attribute noreturn can be added to a function.

Noncompliant Code Example

void g() { // Noncompliant
  abort();
}

Compliant Solution

__attribute__((noreturn)) void g() { // or [[noreturn]] for C++
  abort(); // Compliant
}
c:S1481

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

int numberOfMinutes(int hours) {
  int seconds = 0; // Noncompliant, never used
  return hours * 60;
}

Compliant Solution

int numberOfMinutes(int hours) {
  return hours * 60;
}

Exceptions

No issue is raised on local variables having the attribute "unused" and on object declarations with non-empty arguments.

c:S853

When ~ and << are applied to small integer types (unsigned char or unsigned short), the operations are preceded by integral promotion, and the result may contain high-order bits which have not been anticipated.

Noncompliant Code Example

unsigned char port = 0x5aU;
unsigned char result_8;
unsigned short result_16;
unsigned short mode;
result_8 = (~port) >> 4; // Noncompliant; '~port' is 0xFFA5 on a 16-bit machine but 0xFFFFFFA5 on a 32-bit machine. Result is 0xFA for both, but 0x0A may have been expected.
result_16 = ((port << 4) & mode) >> 6; // Noncompliant; result_16 value depends on the implemented size of an int.

Compliant Solution

result_8 = ((unsigned char)(~port)) >> 4; // Compliant
result_16 = ((unsigned short)((unsigned short) port << 4) & mode) >> 6; // Compliant

See

  • MISRA C:2004, 10.5 - If the bitwise operators ~ and << are applied to an operand of underlying type unsigned char or unsigned short, the result shall be immediately cast to the underlying type of the operand.
  • MISRA C++:2008, 5-0-10 - If the bitwise operators ~ and << are applied to an operand with an underlying type of unsigned char or unsigned short, the result shall be immediately cast to the underlying type of the operand.
c:S5281

It is a security vulnerability to call printf with a unique string argument which is not a string literal. Indeed, if this argument comes from a user input, this user can :

  • make the program crash, by executing code equivalent to: printf("%s%s%s%s%s%s%s%s")
  • view the stack or a memory at any location, by executing code equivalent to: printf("%08x %08x %08x %08x %08x\n")

Noncompliant Code Example

void f(char* userInput) {
  printf(userInput); // Noncompliant
}

Compliant Solution

void f(char* userInput) {
  printf("%s", userInput); // Compliant
}

See

Owasp: format string attack

c:S5280

mktemp, mkstemp, mkstemps or mkdtemp are useful functions to create temporary files and directories. They accept a template parameter which defines the path where the file should be created and which should contain at least six trailing "X"s to ensure the uniqueness of the filename.

Noncompliant Code Example

mkstemp("/tmp/file_XXXX"); // Noncompliant

Compliant Solution

mkstemp("/tmp/file_XXXXXX"); // Compliant
c:S5283

Variable length arrays should have a well-defined, positive size.

Noncompliant Code Example

void f1() {
  int n;
  int a[n]; // Noncompliant; n is undefined
}

void f2() {
  int n = 0;
  int a[n]; // Noncompliant; array of zero size
}
c:S3590

Stack allocated memory, like memory allocated with the functions alloca, _alloca, _malloca, __builtin_alloca, is automatically released at the end of the function, and should not be released with free. Explicitly free-ing such memory results in undefined behavior.

This rule raises issues when trying to release pointers to memory which is not owned, like stack allocated memory and function pointers.

Noncompliant Code Example

void fun() {
  char *name = (char *) alloca(size);
  // ...
  free(name); // Noncompliant, memory allocated on the stack
  char *name2 = "name";
  // ...
  free(name2); // Noncompliant, memory allocated on the stack
}

Compliant Solution

void fun() {
  char *name = (char *) alloca(size);
  // ...
  char *name2 = "name";
  // ...
}
c:S2275

Because printf format strings are interpreted at runtime, rather than validated by the compiler, they can contain errors that lead to unexpected behavior or runtime errors. This rule statically validates the good behavior of printf formats.

The related rule S3457 is about errors that produce an unexpected string, while this rule is about errors that will create undefined behavior.

Noncompliant Code Example

printf("%d", 1.2); // Noncompliant, an "int" is expected rather than a "double"
printf("%d %d", 1); // Noncompliant, the second argument is missing
printf("%0$d ", 1); // Noncompliant, arguments are numbered starting from 1
printf("%1$d %d", 1, 2); // Noncompliant, positional and non-positional arguments can not be mixed
printf("%*d", 1.1, 2); // Noncompliant, field width should be an integer
printf("ab\0cd"); // Noncompliant, format string contains null char

int x;
printf("%+p", (void*)&x); // Noncompliant, flag "+" has undefined behavior with conversion specifier "p"
printf("%vd", x); //Noncompliant, conversion specifier "v" is not valid

Compliant Solution

printf("%f", 1.2); // Compliant, format is consistent with the corresponding argument
printf("%d", 1); // Compliant, number of specifiers is consistent with number of arguments
printf("%1$d ", 1); // Compliant, number of positional argument is consistent

Exceptions

This rule will only work if the format string is provided as a string literal.

See

c:S5308

setuid family of functions are used to change the user identity of the caller process in order to change privileges for the following actions. If the function call returns with an error, the rest of the program will execute with unexpected privileges leading to unexpected behaviour.

Noncompliant Code Example

void f() {
  ...
  setuid(0); // Noncompliant
  ...
}

Compliant Solution

void f() {
  ...
  if (setuid(0)) {
    // fail
  }
  ...
}
c:S3457

Because printf format strings are interpreted at runtime, rather than validated by the compiler, they can contain errors that result in the wrong strings being created. This rule statically validates the correlation of printf format strings to their arguments.

The related rule S2275 is about errors that will create undefined behavior, while this rule is about errors that produce an unexpected string.

Noncompliant Code Example

printf("%d", 1, 2); // Noncompliant; the second argument "2" is unused
printf("%0-f", 1.2); // Noncompliant; flag "0" is ignored because of "-"

Compliant Solution

printf("%d %d", 1, 2); // Compliant
printf("%-f", 1.2); // Compliant

Exceptions

This rule will only work if the format string is provided as a string literal.

See

c:S109

A magic number is a number that comes out of nowhere, and is directly used in a statement. Magic numbers are often used, for instance to limit the number of iterations of a loops, to test the value of a property, etc.

Using magic numbers may seem obvious and straightforward when you're writing a piece of code, but they are much less obvious and straightforward at debugging time.

That is why magic numbers must be demystified by first being assigned a name. This is classically done by using a constant (constexpr or const if your compiler does not support constexpr yet) or an enumeration.

-1, 0 and 1 are not considered magic numbers.

Noncompliant Code Example

void doSomething(int var) {
  for(int i = 0; i < 42; i++) { // Noncompliant - 42 is a magic number
    // ...
  }

  if (var == 42) { // Noncompliant - magic number
    // ...
  }
}

Compliant Solution

enum Status {
STATUS_KO = 0,
STATUS_OK = 42,
};

void doSomething(Status var) {
  constexpr int maxIterations = 42; // Compliant - in a declaration
  for(int i = 0; i < maxIterations ; i++){ // Compliant: 0 is excluded, and maxIterations is a named constant
    // ...
  }

  if (STATUS_OK == var) { // Compliant - number comes from an enum
    // ...
  }
}
c:S2753

Just as comparing apples and oranges is seen as a classic folly, comparing values from different enumerations against each other or converting them into one another is nonsensical. True, at root enums are simply named numbers, and it's certainly valid to compare numbers. But an added layer of meaning is created by an enum, one that goes beyond simple numerical values.

Ignoring that extra layer of meaning is at best a trap for maintainers, who are likely to be hopelessly confused by the code. At worst, it is a bug, which will lead to unexpected results.

Noncompliant Code Example

enum apple {BRAEBURN, FUJI, GRANNY_SMITH, RED_DELICIOUS};
enum orange {BLOOD, NAVEL, BITTER, BERGAMOT, MANDARIN};

void makeCider(apple v);

bool fun(apple v1, orange v2) {
  makeCider((apple)v2); // Noncompliant
  return v1 != v2;  // Noncompliant
}
c:S2190

Recursion happens when control enters a loop that has no exit. This can happen a method invokes itself, when a pair of methods invoke each other, or when goto statements are used to move between two segments of code. It can be a useful tool, but unless the method includes a provision to break out of the recursion and return, the recursion will continue until the stack overflows and the program crashes.

Noncompliant Code Example

int pow(int num, int exponent) {  // Noncompliant; no condition under which pow isn't re-called
  num = num * pow(num, exponent-1);
  return num;  // this is never reached
}

void internalRecursion(int i) {
  start:
    goto end;
  end:
    goto start;  // Noncompliant; there's no way to break out of this method
}

Compliant Solution

int pow(int num, int exponent) {
  if (exponent > 1) {  // recursion now conditional and stop-able
    num = num * pow(num, exponent-1);
  }
  return num;
}
c:S5259

Include guards, wrapping around the entire content of a header file, are a best practice that ensure that no matter how many times the header is actually included in a translation unit, its content will only be seen once. 

The include guard pattern is made up of four parts:

* #ifndef at the top of the file, with a unique macro name (usually the name relates to the name of the file, to ensure uniqueness).

* #define with the same macro name.

* The content of the file

* #endif at the end of the file

The rule raises an issue when the name in the second part differs from the name in the first (usually because of a typo or a copy/paste issue).

Noncompliant Code Example

#ifndef MYFILE_H
#define MY_FILE_H // Noncompliant
//...
#endif

Compliant Solution

#ifndef MYFILE_H
#define MYFILE_H
//...
#endif
c:ObsoletePosixFunction

To ensure future code portability, obsolete POSIX functions should be removed. Those functions, with their replacements are listed below:

Obsolete Use Instead
asctime strftime
asctime_r strftime
bcmp memcmp
bcopy memmove memcpy
bsd_signal sigaction
bzero memset
ctime strftime
ecvt sprintf
fcvt sprintf
ftime no replacement function
gcvt sprintf
getcontext Rewrite to use POSIX threads.
gethostbyaddr getnameinfo
gethostbyname getaddrinfo
getwd getcwd
index strchr
makecontext Rewrite to use POSIX threads.
mktemp mkstemp
pthread_attr_getstackaddr pthread_attr_getstack
pthread_attr_setstackaddr pthread_attr_setstack
rand_r rand
rindex strrchr
scalb scalbln', 'scalblnf' or 'scalblnl' instead of this function
swapcontext Rewrite to use POSIX threads.
tmpnam 'tmpfile', 'mkstemp', or 'mkdtemp' instead for this function
tmpnam_r tmpfile', 'mkstemp', or 'mkdtemp' instead for this function
ualarm 'timer_create', 'timer_delete', 'timer_getoverrun', 'timer_gettime', or 'timer_settime' instead of this function
usleep 'nanosleep' or 'setitimer' function
utime utimensat
vfork fork
wcswcs wcsstr

See

c:S5267

The attribute noreturn indicates that a function does not return.

Using this attribute allows the compiler to do some assumptions that can lead to optimizations. However, if a function with this attribute ever returns, the behavior becomes undefined.

Noncompliant Code Example

__attribute__((noreturn)) void f () {
  while (1) {
    // ...
    if (/* something*/) {
      return; // Noncompliant, this function should not return
    }
  }
}

Compliant Solution

__attribute__((noreturn)) void f() {  // Compliant
  while (true) {
    // ...
  }
}

Or

void f() {
  while (true) {
    // ...
    if (/* something*/) {
      return; // Compliant
    }
  }
}
c:S5262

Dereferencing a null pointer has undefined behavior, and it is particularly harmful if a reference is then bound to the result, because a reference is assumed to refer to a valid object.

Noncompliant Code Example

void doSomething(A& a);
void f() {
  A* a = nullptr;
  // ...
  doSomething(*a); // Noncompliant
}
c:S5263

While working with bitwise operators & or | it is easy to make a typo and write the equivalent logical operators && or ||. This rule is raising issues when the right operand of a logical expression && or || is a constant of integral type, as the developer probably meant to use the corresponding bitwise operator & or |.

Noncompliant Code Example

int fun(int a) {
  return a || 4; // Noncompliant, did you mean to use bitwise operator '|'?
}

Compliant Solution

int fun(int a) {
 return a | 4;
}
c:S5261

The dangling else problem appears when nested if/else statements are written without curly braces. In this case, else is associated with the nearest if but that is not always obvious and sometimes the indentation can also be misleading.

This rules reports else statements that are difficult to understand, because they are inside nested if statements without curly braces.

Adding curly braces can generally make the code clearer (S121), and in this situation of dangling else, it really clarifies the intention of the code.

Noncompliant Code Example

 if (a)
   if (b)
     d++;
 else     // Noncompliant, is the "else" associated with "if(a)" or "if (b)"? (the answer is "if(b)")
   e++;

Compliant Solution

 if (a) {
   if (b) {
     d++;
   }
 } else { // Compliant, there is no doubt the "else" is associated with "if(a)"
   e++;
 }

See

* https://en.wikipedia.org/wiki/Dangling_else

cpp:SideEffectInSizeOf

A possible programming error in C++ is to apply the sizeof operator to an expression and expect the expression to be evaluated. However, the expression is not evaluated because sizeof only acts on the type of the expression. To avoid this error, sizeof should not be used on expressions that would contain side effects if they were used elsewhere, since the side effects will not occur.

Noncompliant Code Example

j = sizeof( i = 1234 ); // Noncompliant - j is set to the sizeof the type of i which is an int. i is not set to 1234.

j = sizeof ( b[i++] ); // Noncompliant - i won't be incremented.

j = sizeof( isPtr(e) ); // Compliant

Compliant Solution

i = 1234;
j = sizeof( i );

i++;
j = sizeof ( b[i] );

j = sizeof( isPtr(e) );

See

  • MISRA C 2004, 12.3 - The sizeof operator shall not be used on expressions that contain side effects.
  • MISRA C++ 2008, 5-3-4 - Evaluation of the operand to the sizeof operator shall not contain side effects.
  • MISRA C 2012, 13.6 - The operand of the sizeof operator shall not contain any expression which has potential side effects
cpp:S5297

__attribute__ is a GNU extension that allows to decorate functions, parameters, variables... with some attributes. It may help for compiler optimizations or for the writer of some code to better state his intent (and have the compiler check it).

If this extension is used incorrectly, it will usually not break the build, but it still means that the code may not behave as the developer expects. This rule reports such occurrences of bad use of __attribute__.

Noncompliant Code Example

int f1() __attribute__((returns_nonnull)); // Noncompliant; "returns_nonnull" only applies to return values which are pointers

void g(int *a) __attribute__((nonnull(1))){} // Noncompliant; "nonnull" position in the function definition is not allowed

void h() __attribute__((warn_unused_result)); // Noncompliant; "warn_unused_result" does not work with function without return value

void test() {
  int __declspec(empty_bases)i; // Noncompliant; "empty_bases" only applies to classes
  char c = (char __attribute__((aligned(8)))) i; // Noncompliant, attribute is ignored
}}
cpp:S5293

The possibilities of ISO C printf format strings are limited, this is why many extensions have been added by several implementations. Even though they are widespread and similar in many implementations, they are not standard, which means that using them may create portability issues.

This rule reports an issue when format strings do not comply with ISO C standards.

Noncompliant Code Example

void test() {
  printf("%1$d", 1); // Noncompliant; positional arguments are not supported by ISO C
  printf("%qd", (long long)1); // Noncompliant; length specifier "q" is not supported by ISO C
}
cpp:S5184

The RAII idiom associates the lifetime of a resource with the lifetime of an object: The resource is acquired when the object is created, and released when it is destroyed.

If the object that controls the resource lifetime is a temporary, chances are that it will get destroyed while the resource should still be in use, leading to resource corruption. This rules detects temporaries that look like RAII objects.

Noncompliant Code Example

void f() {
  scoped_lock{myMutex}; // Non compliant. The mutex will be locked then immediately unlocked
  protectedCode(); // This code is not protected by the mutex
}

Compliant Solution

void f() {
  scoped_lock lock{myMutex}; // Compliant
  protectedCode();
  // The mutex is correctly released at this point
}

See

cpp:S5278

The memory functions memset, memcpy, memmove, and memcmp take as last argument the number of bytes they will work on. If this size argument is badly defined (eg it is greater than the size of the destination object), it can lead to undefined behavior.

This rule raises an issue when the size argument of a memory function seems inconsistent with the other arguments of the function.

Noncompliant Code Example 

struct A {};

void f() {
  struct A dest;
  memset(&dest, 0, sizeof(&dest)); // Noncompliant; size is based on "A*" when the destination is of type "A"
  struct A src;
  memcpy(&dest, &src, sizeof(&dest)); // Noncompliant; size is based on "A*" when the source is of type "A"

  if (memset(&dest, 0, sizeof(dest) != 0)) { // Noncompliant; size argument is a comparison
    // ...
  }
}

Compliant Solution

struct A {};

void f() {
  struct A dest;
  memset(&dest, 0, sizeof(dest)); // Compliant
  struct A src;
  memcpy(&dest, &src, sizeof(dest)); // Compliant

  if (memset(&dest, 0, sizeof(dest)) != 0) { // Compliant
    // ...
  }
}
cpp:S5277

If a function is defined with a [[nodiscard]] attribute or if it returns an object which is [[nodiscard]], its return value is very important and should not be silently ignored.

Noncompliant Code Example

struct [[nodiscard]] ErrorInfo{ /* ... */};
ErrorInfo getStatus();

[[nodiscard]] int getInfo();

void f() {
  getStatus(); // Noncompliant; we should read the returned struct which is "nodiscard"
  getInfo(); // Noncompliant; we should read the return value of this "nodiscard" function
  // ...
}

Compliant Solution

struct[[nodiscard]] ErrorInfo{ /* ... */};
ErrorInfo getStatus();

[[nodiscard]] int getInfo();

void f() {
  int status = getStatus(); // Compliant
  if (getInfo() != 0) { /*...*/ } // Compliant
  // ...
}

Exceptions

This rule will ignore return values that are not used, but are cast into void, since this is the standard-approved way to suppress this check.

[[nodiscard]] int getInfo();

void f() {
  (void) getInfo(); // Compliant
  // ...
}
cpp:S5279

Operands of sizeof, noexcept and decltype are unevaluated. So side effects in these operands (which are all the effects an expression can have in addition to producing a value), will not be applied. And that may be surprising to the reader.

Additionally, the operand of typeid may or may not be evaluated, depending on its type: it will be evaluated if it is a function call that returns reference to a polymorphic type, but it will not be evaluated in all the other cases. This difference of behavior is tricky to apprehend and that is why both cases are reported here.

This rules reports an issue when operands of such operators have side-effects.

Noncompliant Code Example

class A {
public:
  virtual ~A();
  /*...*/
};
class B : public A { /* ....*/ };
A& create(string const &xml);

void test(string const &xml) {
  int i = 0;
  cout << noexcept(++i); // Noncompliant, "i" is not incremented
  cout << typeid(++i).name(); // Noncompliant, "i" is not incremented
  auto p1 = malloc(sizeof(i = 5)); // Noncompliant, "i" is not changed

  cout << typeid(create(xml)).name(); // Noncompliant, even if the side-effects will be evaluated in this case
}

Compliant Solution

class A {
public:
  virtual ~A();
  /*...*/
};
class B : public A { /* ....*/ };
A& create(string const &xml);

void test(string const &xml) {
  int i = 0;
  ++i;
  cout << noexcept(i); // Compliant
  ++i;
  cout << typeid(i).name(); // Compliant
  i = 5;
  auto p1 = malloc(sizeof(i)); // Compliant

  auto a = create(xml);
  cout << typeid(a).name(); // Compliant
}
cpp:S1238

To pass an input parameter to a function, there are two possibilities: pass by value, or pass by reference to const. Which one is best depends of the size of the object, which is an indicator of the cost to copy it. A small one, with cheap copy constructors, should be passed by value, while a larger one should be passed by reference to const.

This rule detects when a parameter has been passed by value, while it should have been passed by reference to const:

- Because it is too large

- Because it contains virtual functions and passing it by value will slice the extra members if you happen to pass an object of a derived class.

In some cases, you may want to pass by value a large object, if you modify it in the function but you don't want the initial object to be impacted by these changes. We do not detect such a situation, which will be a false positive.

There are other ways to pass input parameters for sinks (for instance by rvalue references), but this rule is only about the choice between pass by value and pass by reference to const.

Noncompliant Code Example

struct Student {string firstName; string lastName; Date birthDate;};
class XmlNode {
  virtual ~XmlNode();
  virtual string toString();
};
void registerStudent(School &school, Student p); // Noncompliant, Student is a large object
void dump(ostream &out, XmlNode node); // Noncompliant, XmlNode is a polymorphic type

Compliant Solution

struct Student {string firstName; string lastName; Date birthDate;};
class XmlNode {
  virtual ~XmlNode();
  virtual string toString();
};
void registerStudent(School &school, Student const & p); // Compliant, avoids useless copy
void dump(ostream &out, XmlNode const &node); // Compliant, no slicing

See

  • C++ Core Guidelines F.16 - For ā€œinā€ parameters, pass cheaply-copied types by value and others by reference to const
cpp:S5274

Copy elision is a compiler optimization that prevents useless copies of objects: in some cases, copy and move constructors are omitted even if they have side-effects.

Each compiler has its own specifications but is nevertheless required to do copy elision in the following cases:

  • in a return statement if the returned object is a prvalue of the same class type as the function return type
  • in the initialization of a variable if the initializer expression is a prvalue of the same class type as the variable type

This rule reports an issue when the use of std::move prevents the copy elision from happening.

Noncompliant Code Example

class A {};
A getA();

A f() {
  A a = std::move(getA()); // Noncompliant
  return std::move(a); // Noncompliant
}

Compliant Solution

class A {};
void test(A a);

A f() {
  A a = getA(); // Compliant
  return a; // Compliant
}
cpp:S5273

Size argument of strncat, strlcat and strlcpy should define the size of the destination to prevent buffer overflow.

Moreover, strncat always adds a terminating null character at the end of the appended characters so the size argument should be smaller than the size of the destination to let enough space for it.

Noncompliant Code Example

void f(char* src) {
  char dest[10];
  strlcpy(dest, src, sizeof(src)); // Noncompliant; size argument is the size of the source instead of the size of the destination

  strncat(dest, src, sizeof(src)); // Noncompliant; size of the source instead of the size of the destination
  strncat(dest, src, sizeof(dest)); // Noncompliant; size argument is too large
}

Compliant Solution

void f(char* src) {
  char dest[10];
  strncat(dest, src, sizeof(dest) - 1); // Compliant
}

 

cpp:S5275

Because reinterpret_cast ignores the type system, it is capable of performing dangerous conversions between unrelated types which can lead to undefined behavior.

This rule reports an issue for two problematic uses of reinterpret_cast:

* when it is used to make the compiler believes that an object in memory is from a different type from its real type (for instance, casting a long* to double*, because accessing a long as if it was a double is undefined behavior (even if sizeof(long) == sizeof(double)),

* when it is used to cast between different levels of a complex inheritance hierarchy (a static_cast would apply pointer offsets to take into account multiple inheritance, for instance, but reinterpret_cast does not)

Noncompliant Code Example

class X {};
class Y : virtual X {};

void test() {
  long l;
  auto a = reinterpret_cast<double&>(l); // Noncompliant: undefined behavior

  Y* y;
  auto x = reinterpret_cast<X*>(y); // Noncompliant
}
cpp:S5270

Variadic arguments allow a function to accept any number of arguments (in this rule, we are not talking about variadic templates, but about functions with ellipses). But these arguments have to respect some criteria to be handled properly.

This rules reports an issue if the type of the argument: 

  • is a non trivially copyable, movable or deletable type: there is no guarantee that it will work.
  • is a class type that is trivially copyable, movable and deletable: in this case, we consider that the user intention was probably not to directly pass it as an argument but to call a method on it (c_str() for example)

Noncompliant Code Example

class A {
  char* toStr();
};
void v(...);

void f() {
  A a;
  v(a); // Noncompliant

  std::string myString = "foo";
  v(myString); // Noncompliant; string is not a POD type
}

Compliant Solution

class A {
  char* toStr();
}
void v(...);

void f() {
  A a;
  v(a.toStr()); // Compliant

  std::string myString = "foo";
  v(myString.c_str()); // Compliant
}
cpp:S5272

By specification, objects supporting move operations will be left in a valid but unspecified state after the move. Even if in a valid state, the fact of being in an unspecified state leads to undefined behavior, you should not rely on their value.

Noncompliant Code Example

void f() {
  A a;

  A a2 = std::move(a);
  a.fun(); // Noncompliant, a is moved-from
}

Compliant Solution

void f() {
  A a;

  A a2 = std::move(a);
  a2.fun();
}

See

cpp:S5271

The attribute noreturn indicates that a function does not return. This information clarifies the behavior of the function and it allows the compiler to do optimizations.

It can also help the compiler (and static analyzer tools, i.e. us) provide better error messages:

__attribute__((noreturn)) void f();

int g(int b) {
  if (b == 5) {
    f();
    printf("Hello world\n"); // This is dead code, the compiler/static analyzer can now detect it
    // There is no returned value, but it is fine, the compiler/static analyzer knows not to warn about it
  } else {
    return 3;
  }
}

This rule detects when the attribute noreturn can be added to a function.

Noncompliant Code Example

void g() { // Noncompliant
  abort();
}

Compliant Solution

__attribute__((noreturn)) void g() { // or [[noreturn]] for C++
  abort(); // Compliant
}
cpp:S1242

An inherited member function can be hidden in a derived class and that creates a class that behaves differently depending on which interface is used to manipulate it.

Overriding happens when the inherited method is virtual and a method declared in the derived class uses the same identifier as well as the same signature (the return types can be different, as long as they are covariant). However, if the inherited method is non-virtual or if the two declarations of the method do not share the same signature, the method of the base class will be hidden.

Such a class increases the inheritance complexity, and confuses consumers with its non-polymorphic behavior, which can lead to errors.

Noncompliant Code Example

class Base {
public:
  void shutdown();
  virtual void log(int a);
};

class Derived : public Base {
public:
  void shutdown(); //Noncompliant
  void log(float a); //Noncompliant
};

void stopServer(Base *obj, Derived *obj2) {
  obj->shutdown(); // always calls Base::shutdown even if the given object's type is Derived
  obj->log(2); // calls Base::log(int) even if the given object's type is Derived
  obj2->shutdown(); // calls Derived::shutdown
  obj2->log(2); // calls Derived::log(float), even if this requires a conversion int->float.
}

Compliant Solution

class Base {
public:
  void shutdown();
  virtual void log(int a);
};

class Derived : public Base {
public:
  void shutdownAndUpdate(); // Define a method with a different name
  void log(int a) override; // Or make the method a proper override
};

void stopServer(Base *obj) {
  obj->shutdown(); // calls Base::shutdown and there is no confusion
  obj->log(2); // calls Derived::log(int) if the given object's type is Derived
}
cpp:S1481

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

int numberOfMinutes(int hours) {
  int seconds = 0; // Noncompliant, never used
  return hours * 60;
}

Compliant Solution

int numberOfMinutes(int hours) {
  return hours * 60;
}

Exceptions

No issue is raised on local variables having the attribute "unused" and on object declarations with non-empty arguments.

cpp:S853

When ~ and << are applied to small integer types (unsigned char or unsigned short), the operations are preceded by integral promotion, and the result may contain high-order bits which have not been anticipated.

Noncompliant Code Example

unsigned char port = 0x5aU;
unsigned char result_8;
unsigned short result_16;
unsigned short mode;
result_8 = (~port) >> 4; // Noncompliant; '~port' is 0xFFA5 on a 16-bit machine but 0xFFFFFFA5 on a 32-bit machine. Result is 0xFA for both, but 0x0A may have been expected.
result_16 = ((port << 4) & mode) >> 6; // Noncompliant; result_16 value depends on the implemented size of an int.

Compliant Solution

result_8 = ((unsigned char)(~port)) >> 4; // Compliant
result_16 = ((unsigned short)((unsigned short) port << 4) & mode) >> 6; // Compliant

See

  • MISRA C:2004, 10.5 - If the bitwise operators ~ and << are applied to an operand of underlying type unsigned char or unsigned short, the result shall be immediately cast to the underlying type of the operand.
  • MISRA C++:2008, 5-0-10 - If the bitwise operators ~ and << are applied to an operand with an underlying type of unsigned char or unsigned short, the result shall be immediately cast to the underlying type of the operand.
cpp:S5281

It is a security vulnerability to call printf with a unique string argument which is not a string literal. Indeed, if this argument comes from a user input, this user can :

  • make the program crash, by executing code equivalent to: printf("%s%s%s%s%s%s%s%s")
  • view the stack or a memory at any location, by executing code equivalent to: printf("%08x %08x %08x %08x %08x\n")

Noncompliant Code Example

void f(char* userInput) {
  printf(userInput); // Noncompliant
}

Compliant Solution

void f(char* userInput) {
  printf("%s", userInput); // Compliant
}

See

Owasp: format string attack

cpp:S5280

mktemp, mkstemp, mkstemps or mkdtemp are useful functions to create temporary files and directories. They accept a template parameter which defines the path where the file should be created and which should contain at least six trailing "X"s to ensure the uniqueness of the filename.

Noncompliant Code Example

mkstemp("/tmp/file_XXXX"); // Noncompliant

Compliant Solution

mkstemp("/tmp/file_XXXXXX"); // Compliant
cpp:S5283

Variable length arrays should have a well-defined, positive size.

Noncompliant Code Example

void f1() {
  int n;
  int a[n]; // Noncompliant; n is undefined
}

void f2() {
  int n = 0;
  int a[n]; // Noncompliant; array of zero size
}
cpp:S3590

Stack allocated memory, like memory allocated with the functions alloca, _alloca, _malloca, __builtin_alloca, is automatically released at the end of the function, and should not be released with free. Explicitly free-ing such memory results in undefined behavior.

This rule raises issues when trying to release pointers to memory which is not owned, like stack allocated memory and function pointers.

Noncompliant Code Example

void fun() {
  char *name = (char *) alloca(size);
  // ...
  free(name); // Noncompliant, memory allocated on the stack
  char *name2 = "name";
  // ...
  free(name2); // Noncompliant, memory allocated on the stack
}

Compliant Solution

void fun() {
  char *name = (char *) alloca(size);
  // ...
  char *name2 = "name";
  // ...
}
cpp:S2275

Because printf format strings are interpreted at runtime, rather than validated by the compiler, they can contain errors that lead to unexpected behavior or runtime errors. This rule statically validates the good behavior of printf formats.

The related rule S3457 is about errors that produce an unexpected string, while this rule is about errors that will create undefined behavior.

Noncompliant Code Example

printf("%d", 1.2); // Noncompliant, an "int" is expected rather than a "double"
printf("%d %d", 1); // Noncompliant, the second argument is missing
printf("%0$d ", 1); // Noncompliant, arguments are numbered starting from 1
printf("%1$d %d", 1, 2); // Noncompliant, positional and non-positional arguments can not be mixed
printf("%*d", 1.1, 2); // Noncompliant, field width should be an integer
printf("ab\0cd"); // Noncompliant, format string contains null char

int x;
printf("%+p", (void*)&x); // Noncompliant, flag "+" has undefined behavior with conversion specifier "p"
printf("%vd", x); //Noncompliant, conversion specifier "v" is not valid

Compliant Solution

printf("%f", 1.2); // Compliant, format is consistent with the corresponding argument
printf("%d", 1); // Compliant, number of specifiers is consistent with number of arguments
printf("%1$d ", 1); // Compliant, number of positional argument is consistent

Exceptions

This rule will only work if the format string is provided as a string literal.

See

cpp:S5308

setuid family of functions are used to change the user identity of the caller process in order to change privileges for the following actions. If the function call returns with an error, the rest of the program will execute with unexpected privileges leading to unexpected behaviour.

Noncompliant Code Example

void f() {
  ...
  setuid(0); // Noncompliant
  ...
}

Compliant Solution

void f() {
  ...
  if (setuid(0)) {
    // fail
  }
  ...
}
cpp:S3457

Because printf format strings are interpreted at runtime, rather than validated by the compiler, they can contain errors that result in the wrong strings being created. This rule statically validates the correlation of printf format strings to their arguments.

The related rule S2275 is about errors that will create undefined behavior, while this rule is about errors that produce an unexpected string.

Noncompliant Code Example

printf("%d", 1, 2); // Noncompliant; the second argument "2" is unused
printf("%0-f", 1.2); // Noncompliant; flag "0" is ignored because of "-"

Compliant Solution

printf("%d %d", 1, 2); // Compliant
printf("%-f", 1.2); // Compliant

Exceptions

This rule will only work if the format string is provided as a string literal.

See

cpp:S5213

To configure an algorithm with a function in C++, you can use one of the following techniques:

- A function pointer (see S5205 that explains why it is a bad idea)

- A std::function

- A template argument

How do you select between those two solutions?

std::function offers the most flexibility. You can store them in a variable, in a container (as std::map<string, std::function<void(void)>> for instance... This flexibility is provided by type erasure: A single std::function can wrap any kind of functor, as long as the signature is compatible. It also come with a cost: Due to this type erasure, a compiler will typically not be able to inline a call to a std::function.

Template parameters, on the other hand, are less flexible. Each functor has its own type, which prevents storing several of them together, even if they all have compatible signatures. But since each template instance knows the type of the functor, calls can be inlined, making this a zero-cost abstraction.

As a conclusion, if the functor can be known at compile-time, you should prefer using a template parameter, if it has to be dynamic, std::function will give you greater flexibility.

This rule detects function parameters of type std::function that would probably benefit from being replaced by a template parameter. It does so by looking if the functor is only called inside the function, or if it participates in other operations.

using Criterion = std::function<bool(DataPoint const&)>;
void filter(DataSet* data, Criterion criterion) { // Noncompliant
  for (auto &dataPoint : data) {
    if (criterion(dataPoint)) {
      data.markForRemoval(dataPoint);
    }
  }
}

Compliant Solution

template<class Criterion>
void filter(DataSet* data, Criterion criterion) { // Compliant
  for (auto &dataPoint : data) {
    if (criterion(dataPoint)) {
      data.markForRemoval(dataPoint);
    }
  }
}

Exceptions

This rule ignores virtual functions, that don't work well with templates.

See

cpp:S109

A magic number is a number that comes out of nowhere, and is directly used in a statement. Magic numbers are often used, for instance to limit the number of iterations of a loops, to test the value of a property, etc.

Using magic numbers may seem obvious and straightforward when you're writing a piece of code, but they are much less obvious and straightforward at debugging time.

That is why magic numbers must be demystified by first being assigned a name. This is classically done by using a constant (constexpr or const if your compiler does not support constexpr yet) or an enumeration.

-1, 0 and 1 are not considered magic numbers.

Noncompliant Code Example

void doSomething(int var) {
  for(int i = 0; i < 42; i++) { // Noncompliant - 42 is a magic number
    // ...
  }

  if (var == 42) { // Noncompliant - magic number
    // ...
  }
}

Compliant Solution

enum Status {
STATUS_KO = 0,
STATUS_OK = 42,
};

void doSomething(Status var) {
  constexpr int maxIterations = 42; // Compliant - in a declaration
  for(int i = 0; i < maxIterations ; i++){ // Compliant: 0 is excluded, and maxIterations is a named constant
    // ...
  }

  if (STATUS_OK == var) { // Compliant - number comes from an enum
    // ...
  }
}
cpp:S2753

Just as comparing apples and oranges is seen as a classic folly, comparing values from different enumerations against each other or converting them into one another is nonsensical. True, at root enums are simply named numbers, and it's certainly valid to compare numbers. But an added layer of meaning is created by an enum, one that goes beyond simple numerical values.

Ignoring that extra layer of meaning is at best a trap for maintainers, who are likely to be hopelessly confused by the code. At worst, it is a bug, which will lead to unexpected results.

Noncompliant Code Example

enum apple {BRAEBURN, FUJI, GRANNY_SMITH, RED_DELICIOUS};
enum orange {BLOOD, NAVEL, BITTER, BERGAMOT, MANDARIN};

void makeCider(apple v);

bool fun(apple v1, orange v2) {
  makeCider((apple)v2); // Noncompliant
  return v1 != v2;  // Noncompliant
}
cpp:S2190

Recursion happens when control enters a loop that has no exit. This can happen a method invokes itself, when a pair of methods invoke each other, or when goto statements are used to move between two segments of code. It can be a useful tool, but unless the method includes a provision to break out of the recursion and return, the recursion will continue until the stack overflows and the program crashes.

Noncompliant Code Example

int pow(int num, int exponent) {  // Noncompliant; no condition under which pow isn't re-called
  num = num * pow(num, exponent-1);
  return num;  // this is never reached
}

void internalRecursion(int i) {
  start:
    goto end;
  end:
    goto start;  // Noncompliant; there's no way to break out of this method
}

Compliant Solution

int pow(int num, int exponent) {
  if (exponent > 1) {  // recursion now conditional and stop-able
    num = num * pow(num, exponent-1);
  }
  return num;
}
cpp:S5205

When you want to define a function that can accept a function pointer as an argument, there are three ways in C++ to declare the parameter type:

- A function pointer: void f(void (*callback)());

- A std::function: void f(std::function<void()> callback);

- A template argument: template<class Callback> void f(Callback callback);

Using a function pointer is an inferior solution, for the following reasons:

- Only a function pointer can be passed as an argument, while the other options offer the caller more flexibility because they can take more advanced functors, such as lambdas with some captured state

- The syntax is obscure

- It typically has worse performance than the template parameter solution.

See S5213 for a discussion of how to choose between std::function and a template parameter.

Noncompliant Code Example

using Criterion = bool (*)(DataPoint const&);
void filter(DataSet* data, Criterion criterion); // Noncompliant

using Callback = void (*)(EventInfo const&);
class Button {
public:
    void addOnClick(Callback c) {myOnClickHandler = c;} // Noncompliant
private:
    Callback myOnClickHandler;
};

Compliant Solution

template<class Criterion>
void filter(DataSet* data, Criterion criterion); // Compliant, uses the more efficient template argument

using Callback = std::function<void(EventInfo const&)>;
class Button {
public:
    void addOnClick(Callback c) {myOnClickHandler = c;} // Compliant, uses the more flexible std::function
private:
    Callback myOnClickHandler;
};

See

cpp:S5259

Include guards, wrapping around the entire content of a header file, are a best practice that ensure that no matter how many times the header is actually included in a translation unit, its content will only be seen once. 

The include guard pattern is made up of four parts:

* #ifndef at the top of the file, with a unique macro name (usually the name relates to the name of the file, to ensure uniqueness).

* #define with the same macro name.

* The content of the file

* #endif at the end of the file

The rule raises an issue when the name in the second part differs from the name in the first (usually because of a typo or a copy/paste issue).

Noncompliant Code Example

#ifndef MYFILE_H
#define MY_FILE_H // Noncompliant
//...
#endif

Compliant Solution

#ifndef MYFILE_H
#define MYFILE_H
//...
#endif
cpp:S1699

Calling methods or fields which are not initialized in constructors or destructors can lead to undefined behavior.

For example:

Calling an overridable member function from a constructor or destructor could result in unexpected behavior when instantiating a subclass which overrides the member function.

  • By contract, the subclass class constructor starts by calling the parent class constructor.
  • The parent class constructor calls the parent member function and not the one overridden in the child class, which is confusing for child class' developer.
  • It can produce an undefined behavior if the member function is pure virtual in the parent class.

Noncompliant Code Example

class Parent {
  public:
    Parent() {
      method1();
      method2(); // Noncompliant; confusing because Parent::method2() will always been called even if the method is overridden
    }
    Parent(int i):field(i) {}
    virtual ~Parent() {
      method3(); // Noncompliant; undefined behavior (ex: throws a "pure virtual method called" exception)
    }
  protected:
    int field;

    int          method1() { /*...*/ }
    virtual void method2() { /*...*/ }
    virtual void method3() = 0; // pure virtual
};

class Child : public Parent {
  public:
    Child() { // leads to a call to Parent::method2(), not Child::method2()
    }
    Child() : Parent(field) {} // Noncompliant; "field" is not initialized yet
    Child() : Parent(method1()) {} // Noncompliant; "method1" is not initialized yet
    virtual ~Child() {
      method3(); // Noncompliant; Child::method3() will always be called even if a child class overrides method3
    }
  protected:
    void method2() override { /*...*/ }
    void method3() override { /*...*/ }
};

Compliant Solution

class Parent {
  public:
    Parent() {
      method1();
      Parent::method2(); // acceptable but poor design
    }
    virtual ~Parent() {
      // call to pure virtual function removed
    }
  protected:
    void         method1() { /*...*/ }
    virtual void method2() { /*...*/ }
    virtual void method3() = 0;
};

class Child : public Parent {
  public:
    Child() {
    }
    virtual ~Child() {
      method3(); // method3() is now final so this is okay
    }
  protected:
    void method2() override { /*...*/ }
    void method3() final    { /*...*/ } // this virtual function is "final"
};

See

  • CERT, MET05-J. - Ensure that constructors do not call overridable methods
  • CERT, OOP50-CPP. - Do not invoke virtual functions from constructors or destructors
cpp:ObsoletePosixFunction

To ensure future code portability, obsolete POSIX functions should be removed. Those functions, with their replacements are listed below:

Obsolete Use Instead
asctime strftime
asctime_r strftime
bcmp memcmp
bcopy memmove memcpy
bsd_signal sigaction
bzero memset
ctime strftime
ecvt sprintf
fcvt sprintf
ftime no replacement function
gcvt sprintf
getcontext Rewrite to use POSIX threads.
gethostbyaddr getnameinfo
gethostbyname getaddrinfo
getwd getcwd
index strchr
makecontext Rewrite to use POSIX threads.
mktemp mkstemp
pthread_attr_getstackaddr pthread_attr_getstack
pthread_attr_setstackaddr pthread_attr_setstack
rand_r rand
rindex strrchr
scalb scalbln', 'scalblnf' or 'scalblnl' instead of this function
swapcontext Rewrite to use POSIX threads.
tmpnam 'tmpfile', 'mkstemp', or 'mkdtemp' instead for this function
tmpnam_r tmpfile', 'mkstemp', or 'mkdtemp' instead for this function
ualarm 'timer_create', 'timer_delete', 'timer_getoverrun', 'timer_gettime', or 'timer_settime' instead of this function
usleep 'nanosleep' or 'setitimer' function
utime utimensat
vfork fork
wcswcs wcsstr

See

cpp:S5267

The attribute noreturn indicates that a function does not return.

Using this attribute allows the compiler to do some assumptions that can lead to optimizations. However, if a function with this attribute ever returns, the behavior becomes undefined.

Noncompliant Code Example

__attribute__((noreturn)) void f () {
  while (1) {
    // ...
    if (/* something*/) {
      return; // Noncompliant, this function should not return
    }
  }
}

Compliant Solution

__attribute__((noreturn)) void f() {  // Compliant
  while (true) {
    // ...
  }
}

Or

void f() {
  while (true) {
    // ...
    if (/* something*/) {
      return; // Compliant
    }
  }
}
cpp:S5025

If you manage memory manually, it's your responsibility to delete all memory created with new, and to make sure it's deleted once and only once. Ensuring this is done is error-prone, especially when your function can have early exit points.

Fortunately, the C++ language provides tools that automatically manage memory for you. Using them systematically makes the code simpler and more robust without sacrificing performance.

This rule raises an issue when you use:

- new - you should prefer a factory function that returns a smart pointer, such as std::make_unique or, if shared ownership is required, std::make_shared,

- new[] - you should prefer a container class, such as std::vector,

- delete or delete[] - if you followed the previous advice, there is no need to manually release memory.

If your compiler does not support make_unique, it's easy to write your own:

template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

Noncompliant Code Example

void f() {
  auto c = new Circle(0, 0, 5);
  c->draw();
  delete c;
}

Compliant Solution

void f() {
  auto c = make_unique<Circle>(0, 0, 5);
  c->draw();
  unique_ptr<Circle> c2{new Circle(0, 0, 5)}; // Clumsy, but still compliant by exception
}

Exceptions

If the result of a new is immediately passed as an argument to a function, we assume that the function takes ownership of the newly created object, and won't raise an issue.

See

cpp:S5269

Special attention should be paid when initializing class members: it is easy to get it wrong and initialize them with references which are going to be invalidated at the end of the constructor, known as dangling references.

Noncompliant Code Example

struct S {
  int *x;
  int &y;
  S(int i, int j) :
    x(&i),  // Noncompliant, initializing x to the stack address of i
    y(j)  // Noncompliant, y is bound to variable j which has a shorter lifetime
  {}
};

Compliant Solution

struct S {
  int *x;
  int &y;
  S(int *i, int &j) : x(i), y(j) {}
};
cpp:S5263

While working with bitwise operators & or | it is easy to make a typo and write the equivalent logical operators && or ||. This rule is raising issues when the right operand of a logical expression && or || is a constant of integral type, as the developer probably meant to use the corresponding bitwise operator & or |.

Noncompliant Code Example

int fun(int a) {
  return a || 4; // Noncompliant, did you mean to use bitwise operator '|'?
}

Compliant Solution

int fun(int a) {
 return a | 4;
}
cpp:S5262

Dereferencing a null pointer has undefined behavior, and it is particularly harmful if a reference is then bound to the result, because a reference is assumed to refer to a valid object.

Noncompliant Code Example

void doSomething(A& a);
void f() {
  A* a = nullptr;
  // ...
  doSomething(*a); // Noncompliant
}
cpp:S5265

When calling delete on an object of incomplete type, the calling code does not have enough information to do the action properly (it does not know if this object has a trivial or a nontrivial destructor, if it has overloaded the delete operator...). Therefore, deleting a pointer to such an object can lead to undefined behavior.

Noncompliant Code Example

class Body;

class Handle {
  public:
    Handle();
    ~Handle() {
      delete impl; // Noncompliant, Body is incomplete
    }
  private:
    Body * impl;
};

Compliant Solution

// In header file
class Body;

class Handle {
  public:
    Handle();
    ~Handle();
    // Add other special member functions to respect the rule of five
  private:
    Body * impl;
};

// In implementation file
#include "Handle.h"
#include "Body.h" // Now Body is complete

Handle::~Handle(){
  delete impl; // Compliant, at this point "Body" is a complete class
}

Or, with modern resource handling:

// In header file
class Body;

class Handle {
  public:
    Handle();
    ~Handle();
  private:
    std::unique_ptr<Body> impl; //Compliant
};

// In implementation file
#include "Handle.h"
#include "Body.h" // Now Body is complete

Handle::Handle() : impl{new Body{}} {}
Handle::~Handle() = default; // since "Body" is complete, it can be destroyed by unique_ptr
cpp:S5261

The dangling else problem appears when nested if/else statements are written without curly braces. In this case, else is associated with the nearest if but that is not always obvious and sometimes the indentation can also be misleading.

This rules reports else statements that are difficult to understand, because they are inside nested if statements without curly braces.

Adding curly braces can generally make the code clearer (S121), and in this situation of dangling else, it really clarifies the intention of the code.

Noncompliant Code Example

 if (a)
   if (b)
     d++;
 else     // Noncompliant, is the "else" associated with "if(a)" or "if (b)"? (the answer is "if(b)")
   e++;

Compliant Solution

 if (a) {
   if (b) {
     d++;
   }
 } else { // Compliant, there is no doubt the "else" is associated with "if(a)"
   e++;
 }

See

* https://en.wikipedia.org/wiki/Dangling_else

Pylint:E1603
Python3 will not allow implicit unpacking of exceptions in except clauses. See http://www.python.org/dev/peps/pep-3110/
Pylint:W0712
Python3 will not allow implicit unpacking of exceptions in except clauses. See http://www.python.org/dev/peps/pep-3110/ This message can't be emitted when using Python >= 3.0.

This rule was added in Pylint 1.0.0.

csharpsquid:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

The headerFormat must end with an empty line if you want to have an empty line between the file header and the first line for your source file (using, namespace...).

For example, if you want the source file to look like this

// Copyright (c) SonarSource. All Rights Reserved. Licensed under the LGPL License.  See License.txt in the project root for license information.

namespace Foo
{
}

then the headerFormat parameter should end with an empty line like this

// Copyright (c) SonarSource. All Rights Reserved. Licensed under the LGPL License.  See License.txt in the project root for license information.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
csharpsquid:S2699

A test case without assertions ensures only that no exceptions are thrown. Beyond basic runnability, it ensures nothing about the behavior of the code under test.

This rule raises an exception when no assertions from any of the following frameworks are found in a test:

  • MSTest
  • NUnit
  • XUnit
  • FluentAssertions

Noncompliant Code Example

[TestMethod]
public void MyMethod_WhenSomething_ExpectsSomething()
{
    var myClass = new Class();
    var result = myClass.GetFoo();
}

Compliant Solution

[TestMethod]
public void MyMethod_WhenSomething_ExpectsSomething()
{
    var myClass = new Class();
    var result = myClass.GetFoo();
    Assert.IsTrue(result);
}
csharpsquid:S3937

The use of punctuation characters to separate subgroups in a number can make the number more readable. For instance consider 1,000,000,000 versus 1000000000. But when the grouping is irregular, such as 1,000,00,000; it indicates an error.

This rule raises an issue when underscores (_) are used to break a number into irregular subgroups.

Noncompliant Code Example

int duos = 1_00_00;
int million = 1_000_00_000;  // Noncompliant
int thousand = 1000;
int tenThousand = 100_00;  // Noncompliant
apex:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
squid:S2301

A selector argument is a boolean argument that's used to determine which of two paths to take through a method. Specifying such a parameter may seem innocuous, particularly if it's well named.

Unfortunately, the maintainers of the code calling the method won't see the parameter name, only its value. They'll be forced either to guess at the meaning or to take extra time to look the method up.

Instead, separate methods should be written.

This rule finds methods with a boolean that's used to determine which path to take through the method.

Noncompliant Code Example

public String tempt(String name, boolean ofAge) {
  if (ofAge) {
    offerLiquor(name);
  } else {
    offerCandy(name);
  }
}

// ...
public void corrupt() {
  tempt("Joe", false); // does this mean not to temp Joe?
}

Compliant Solution

public void temptAdult(String name) {
  offerLiquor(name);
}

public void temptChild(String name) {
    offerCandy(name);
}

// ...
public void corrupt() {
  age < legalAge ? temptChild("Joe") : temptAdult("Joe");
}
squid:S3553

The Java language authors have been quite frank that Optional was intended for use only as a return type, as a way to convey that a method may or may not return a value.

And for that, it's valuable but using Optional on the input side increases the work you have to do in the method without really increasing the value. With an Optional parameter, you go from having 2 possible inputs: null and not-null, to three: null, non-null-without-value, and non-null-with-value. Add to that the fact that overloading has long been available to convey that some parameters are optional, and there's really no reason to have Optional parameters.

The rule also checks for Guava's Optional, as it was the inspiration for the JDK Optional. Although it is different in some aspects (serialization, being recommended for use as collection elements), using it as a parameter type causes exactly the same problems as for JDK Optional.

Noncompliant Code Example

public String sayHello(Optional<String> name) {  // Noncompliant
  if (name == null || !name.isPresent()) {
    return "Hello World";
  } else {
    return "Hello " + name;
  }
}

Compliant Solution

public String sayHello(String name) {
  if (name == null) {
    return "Hello World";
  } else {
    return "Hello " + name;
  }
}
squid:S2175

The java.util.Collection API has methods that accept Object parameters such as Collection.remove(Object o), and Collection.contains(Object o). When the actual type of the object provided to these methods is not consistent with the type declared on the Collection instantiation, those methods will always return false or null. This is most likely unintended and hides a design problem.

This rule raises an issue when the type of the argument of the following APIs is unrelated to the type used for the Collection declaration:

- Collection.remove(Object o)

- Collection.contains(Object o)

- List.indexOf(Object o)

- List.lastIndexOf(Object o)

- Map.containsKey(Object key)

- Map.containsValue(Object value)

- Map.get(Object key)

- Map.getOrDefault(Object key, V defaultValue)

- Map.remove(Object key)

- Map.remove(Object key, Object value)

Noncompliant Code Example

public class S2175 {

  public static void main(String[] args) {
    String foo = "42";
    Map<Integer, Object> map = new HashMap<>();
    map.remove(foo); // Noncompliant; will return 'null' for sure because 'map' is handling only Integer keys

    // ...

    List<String> list = new ArrayList<String>();
    Integer integer = Integer.valueOf(1);
    if (list.contains(integer)) { // Noncompliant; always false.
      list.remove(integer); // Noncompliant; list.add(integer) doesn't compile, so this will always return 'false'
    }
  }

}

See

  • CERT, EXP04-J. - Do not pass arguments to certain Java Collections Framework methods that are a different type than the collection parameter type
squid:S5128

Bean Validation as per defined by JSR 380 can be triggered programmatically or also executed by the Bean Validation providers. However something should tell the Bean Validation provider that a variable must be validated otherwise no validation will happen. This can be achieved by annotating a variable with javax.validation.Valid and unfortunally it's easy to forget to add this annotation on complex Beans.

Not annotating a variable with @Valid means Bean Validation will not be triggered for this variable, but readers may overlook this omission and assume the variable will be validated.

This rule will run by default on all Class'es and therefore can generate a lot of noise. This rule should be restricted to run only on certain layers. For this reason, the "Restrict Scope of Coding Rules" feature should be used to check for missing @Valid annotations only on some packages of the application.

Noncompliant Code Example

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

public class User {
  @NotNull
  private String name;
}

public class Group {
  @NotNull
  private List<User> users; // Noncompliant; User instances are not validated
}

public class MyService {
  public void login(User user) { // Noncompliant; parameter "user" is not validated
  }
}

Compliant Solution

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

public class User {
  @NotNull
  private String name;
}

public class Group {
  @Valid
  @NotNull
  private List<User> users; // Compliant; User instances are validated

  @NotNull
  // preferred style as of Bean Validation 2.0
  private List<@Valid User> users2; // Compliant; User instances are validated
}

public class MyService {
  public void login(@Valid User user) { // Compliant
  }
}

See

csharpsquid:S3216

After an awaited Task has executed, you can continue execution in the original, calling thread or any arbitrary thread. Unless the rest of the code needs the context from which the Task was spawned, Task.ConfigureAwait(false) should be used to keep execution in the Task thread to avoid the need for context switching and the possibility of deadlocks.

This rule raises an issue when code in a class library awaits a Task and continues execution in the original calling thread.

Noncompliant Code Example

var response = await httpClient.GetAsync(url);  // Noncompliant

Compliant Solution

var response = await httpClient.GetAsync(url).ConfigureAwait(false);
python:S101

Shared coding conventions allow teams to collaborate effectively. This rule allows to check that all class names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression ^[A-Z][a-zA-Z0-9]*$:

class myClass:
   ...

Compliant Solution

class MyClass:
   ...
vbnet:S2551

Shared resources should not be used for locking as it increases the chance of deadlocks. Any other thread could acquire (or attempt to acquire) the same lock for another unrelated purpose.

Instead, a dedicated object instance should be used for each shared resource, to avoid deadlocks or lock contention.

The following objects are considered as shared resources:

  • Me
  • a Type object
  • a string literal
  • a string instance

Noncompliant Code Example

Public Sub MyLockingMethod()
    SyncLock Me 'Noncompliant
        ' ...
    End SyncLock
End Sub

Compliant Solution

Class MyClass
    Dim lockObj As New Object()

    Public Sub MyLockingMethod()
        SyncLock lockObj
            ' ...
        End SyncLock
    End Sub
End Class

See

Microsoft Documentation: Managed Threading Best Practices

csharpsquid:S3440

There's no point in checking a variable against the value you're about to assign it. Save the cycles and lines of code, and simply perform the assignment.

Noncompliant Code Example

if (x != a)  // Noncompliant; why bother?
{
    x = a;
}

Compliant Solution

x = a;

Exceptions

Properties and checks inside setters are excluded from this rule because they could have side effects and removing the check could lead to undesired side effects.

if (MyProperty != a)
{
    MyProperty = a; // Compliant because the setter could be expensive call
}
private int myField;
public int SomeProperty
{
    get
    {
        return myField;
    }
    set
    {
        if (myField != value)
        {
            myField = value;
        }
    }
}
csharpsquid:S2325

Methods and properties that don't access instance data can be static to prevent any misunderstanding about the contract of the method.

Noncompliant Code Example

public class Utilities
{
    public int MagicNum // Noncompliant
    {
        get
        {
            return 42;
        }
    }

    private static string magicWord = "please";
    public string MagicWord  // Noncompliant
    {
        get
        {
            return magicWord;
        }
        set
        {
            magicWord = value;
        }
  }

    public int Sum(int a, int b)  // Noncompliant
    {
        return a + b;
    }
}

Compliant Solution

public class Utilities
{
    public static int MagicNum
    {
        get
        {
            return 42;
        }
    }

    private static string magicWord = "please";
    public static string MagicWord
    {
        get
        {
            return magicWord;
        }
        set
        {
            magicWord = value;
        }
    }

    public static int Sum(int a, int b)
    {
        return a + b;
    }
}

Exceptions

Methods with the following names are excluded because they can't be made static:

  • Application_AuthenticateRequest
  • Application_BeginRequest
  • Application_End
  • Application_EndRequest
  • Application_Error
  • Application_Init
  • Application_Start
  • Session_End
  • Session_Start
csharpsquid:S1905

Unnecessary casting expressions make the code harder to read and understand.

Noncompliant Code Example

public int Example(int i)
{
    return (int) (i + 42); // Noncompliant
}

public IEnumerable<int> ExampleCollection(IEnumerable<int> coll)
{
    return coll.Reverse().OfType<int>(); // Noncompliant
}

Compliant Solution

public int Example(int i)
{
    return i + 42;
}

public IEnumerable<int> ExampleCollection(IEnumerable<int> coll)
{
    return coll.Reverse();
}

Exceptions

Issues are not raised against C# 7.1 `default` literal.

bool b = (bool)default; // Doesn't raise an issue
csharpsquid:S2933

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

public class Person
{
    private int _birthYear;  // Noncompliant

    Person(int birthYear)
    {
        _birthYear = birthYear;
    }
}

Compliant Solution

public class Person
{
    private readonly int _birthYear;

    Person(int birthYear)
    {
        _birthYear = birthYear;
    }
}

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.

See

* Mutating readonly structs

csharpsquid:S3900

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.

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

Noncompliant Code Example

public class MyClass
{
    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)
    {
        this.other = other.Clone(); // Noncompliant
    }
}

Compliant Solution

public class MyClass
{
    private MyOtherClass other;

    public void Foo(MyOtherClass other)
    {
        this.other = other;
    }

    public void Bar(MyOtherClass other)
    {
        if (other != null)
        {
            this.other = other.Clone();
        }
    }

    protected void FooBar(MyOtherClass other)
    {
        if (other != null)
        {
            this.other = other.Clone();
        }
    }
}

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;

public sealed class ValidatedNotNullAttribute : Attribute { }

public static class Guard
{
    public static void NotNull<T>([ValidatedNotNullAttribute] this T value, string name) where T : class
    {
        if (value == null)
            throw new ArgumentNullException(name);
    }
}

public static class Utils
{
    public static string ToUpper(string value)
    {
        Guard.NotNull(value, nameof(value));
        if (value == null)
        {
            return value.ToString();
        }
        return value.ToUpper(); // Compliant
    }
}
csharpsquid:S101

Shared naming conventions allow teams to collaborate efficiently. This rule checks whether or not type names are using PascalCase. To reduce noise, two consecutive upper case characters are allowed unless they form the whole type name. So, MyXClass is compliant, but XC on its own is not.

Noncompliant Code Example

class my_class {...}
class SOMEName42 {...}

Compliant Solution

class MyClass {...}
class SomeName42 {...}

Exceptions

  • The rule ignores types that are marked with ComImportAttribute or InterfaceTypeAttribute.
  • The rule allows for two-letter acronyms in which both letters are capitalized, as shown in the following identifier: IOStream
  • The rule allows having '_' characters in class names inside test projects.
class Some_Name___42 {...} // valid in test
class Some_name___42 {...} // still not valid
class Some_Name_XC {...} // invalid because of XC, should be Some_Name_Xc

See

csharpsquid:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks whether or not method and property names are PascalCased. To reduce noise, two consecutive upper case characters are allowed unless they form the whole name. So, MyXMethod is compliant, but XM on its own is not.

Noncompliant Code Example

public int doSomething() {...}

Compliant Solution

public int DoSomething() {...}

Exceptions

  • The rule ignores members in types that are marked with ComImportAttribute or InterfaceTypeAttribute.
  • The rule ignores extern methods.
  • The rule allows for two-letter acronyms in which both letters are capitalized, as shown in the following identifier: ExecuteOnUIThread.
  • Furthermore, when '_' character is found in a name, the camel casing is not enforced.
void My_method(){...} // valid
void My_method_(){...} // invalid, leading and trailing underscores are reported

See

Microsoft Capitalization Conventions

csharpsquid:S3874

Passing a parameter by reference, which is what happens when you use the out or ref parameter modifiers, means that the method will receive a pointer to the argument, rather than the argument itself. If the argument was a value type, the method will be able to change the argument's values. If it was a reference type, then the method receives a pointer to a pointer, which is usually not what was intended. Even when it is what was intended, this is the sort of thing that's difficult to get right, and should be used with caution.

This rule raises an issue when out or ref is used on a non-Optional parameter in a public method. Optional parameters are covered by S3447.

Noncompliant Code Example

public void GetReply(
         ref MyClass input, // Noncompliant
         out string reply)  // Noncompliant
{ ... }

Compliant Solution

public string GetReply(MyClass input)
{ ... }

public bool TryGetReply(MyClass input, out string reply)
{ ... }

public ReplyData GetReply(MyClass input)
{ ... }

internal void GetReply(ref MyClass input, out string reply)
{ ... }

Exceptions

This rule will not raise issues for:

- non-public methods

- methods with only 'out' parameters, name starting with "Try" and return type bool.

- interface implementation methods

csharpsquid:S2551

Shared resources should not be used for locking as it increases the chance of deadlocks. Any other thread could acquire (or attempt to acquire) the same lock for another unrelated purpose.

Instead, a dedicated object instance should be used for each shared resource, to avoid deadlocks or lock contention.

The following objects are considered as shared resources:

  • this
  • a Type object
  • a string literal
  • a string instance

Noncompliant Code Example

public void MyLockingMethod()
{
    lock (this) // Noncompliant
    {
        // ...
    }
}

Compliant Solution

private readonly object lockObj = new object();

public void MyLockingMethod()
{
    lock (lockObj)
    {
        // ...
    }
}

See

Microsoft Documentation: Managed Threading Best Practices

php:S2757

The use of operators pairs ( =+, =- or =! ) where the reversed, single operator was meant (+=, -= or !=) will compile and run, but not produce the expected results.

This rule raises an issue when =+, =-, or =! is used without any spacing between the two operators and when there is at least one whitespace character after.

Noncompliant Code Example

$target = -5;
$num = 3;

$target =- $num;  // Noncompliant; target = -3. Is that really what's meant?
$target =+ $num; // Noncompliant; target = 3

Compliant Solution

$target = -5;
$num = 3;

$target = -$num;  // Compliant; intent to assign inverse value of num is clear
$target += $num;
ruby:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

See

ruby:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if !filename.nil?
  if File.file?(filename) || File.directory?(filename)
    # ...
  end
end

if a then
  unless b then
    # ...
  end
end

Compliant Solution

def isFileOrDirectory(filename)
  File.file?(filename) || File.directory?(filename)
end
# ...

if !filename.nil? && isFileOrDirectory(filename)
  # ...
end

if a && !b then
  # ...
end
scala:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

See

python:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

def divide(numerator, denominator):
  return numerator / denominator              # FIXME denominator value might be 0

See

cobol:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

DIVIDE 5 BY DIVISOR GIVING QUOTIENT. *> TODO ensure DIVISOR is not zero

See

cobol:S2589

If a boolean expression doesn't change the evaluation of the condition, then it is entirely unnecessary, and can be removed. If it is gratuitous because it does not match the programmer's intent, then it's a bug and the expression should be fixed.

Noncompliant Code Example

   IF BAR = 4
*  Noncompliant: due to the nesting IF statement, we know that BAR = 4 here and so
*  what's the point of testing again that BAR = 4 ?
     IF FOO = "a" AND BAR = 4
       DISPLAY "something"
     END-IF.
     ...
   END-IF
*  Noncompliant: by definition BAR is greater than 0 if BAR = 4,
*  so the condition BAR > 0 should be removed
   IF BAR = 4 AND > 0 THEN DISPLAY "something".

Compliant Solution

   IF BAR = 4
     IF FOO = "a"
       DISPLAY "something"
     END-IF.
     ...
   END-IF
   IF BAR = 4 THEN DISPLAY "something".

See

  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
  • MITRE, CWE-571 - Expression is Always True
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
cobol:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

DIVIDE 5 BY DIVISOR GIVING QUOTIENT. *> FIXME ensure DIVISOR is not zero

See

cobol:COBOL.DataItemInitialValueCheck

Initializing a data item with a value of the wrong type will lead to runtime errors. The rule checks that numeric data items are not initialized with alphanumeric/alphabetic values and that alphanumeric /alphabetic data items are not initialized with numeric values.

Noncompliant Code Example

       WORKING-STORAGE SECTION.
         EJECT
       01  TAB-POS.
           02  FILLER  PIC A(14) VALUE 0.  *> Noncompliant
           02  FILLER  PIC 9(14) VALUE 'ASDFJKL;QWERTY'.  *> Noncompliant

       01 MYGROUP PIC 9(1).
          88 X VALUE 1,2.
          88 Y VALUE 3, "BLUE".  *> Noncompliant; BLUE is alphanumeric

Compliant Solution

       WORKING-STORAGE SECTION.
         EJECT
       01  TAB-POS.
           02  FILLER  PIC A(14)  VALUE 'ASDFJKL;QWERTY'.
           02  FILLER  PIC 9(14)  VALUE 0.

       01 MYGROUP PIC 9(1).
          88 X VALUE 1,2.
          88 Y VALUE 3, 4.
cobol:S4882

Some COBOL compilers such as IBM one will assume that the minimum value of OCCURS DEPENDING ON is 1 but nothing is enforcing that and this behaviour can change or be different when using another compiler.

Setting the minimum value of OCCURS DEPENDING ON makes the code more readable, and less dependent on compiler.

Noncompliant Code Example

01 MY-TABLE-COUNT PIC S9(4) BINARY.
01 MY-TABLE.
   03 MY-ITEM OCCURS 500 TIMES          *> Noncompliant
       DEPENDING ON MY-TABLE-COUNT.
      05 MY-FIELD-01 PIC X(08).
      05 MY-FIELD-02 PIC 9(05).

Compliant Solution

01 MY-TABLE-COUNT PIC S9(4) BINARY.
01 MY-TABLE.
   03 MY-ITEM OCCURS 1 TO 500 TIMES          *> Compliant; minimum value is 1
       DEPENDING ON MY-TABLE-COUNT.
      05 MY-FIELD-01 PIC X(08).
      05 MY-FIELD-02 PIC 9(05).
cobol:COBOL.TransformStatementCheck

The TRANSFORM statement is only supported by OS/VS COBOL, and should be replaced by the INSPECT CONVERTING statement to prevent portability issues.

cobol:S3671

When the size of a variable-length table is DEPENDING ON a non-BINARY/COMP variable, use of that table is inefficient because a conversion must be done every time the table is used.

Noncompliant Code Example

01 VARS
    05 TABLE_SIZE   PIC 9(4).
    05 MY_TABLE OCCURS 1 TO 10
                        DEPENDING ON TABLE_SIZE  *> Noncompliant; TABLE-SIZE isn't BINARY or COMP
                        PIC X(10).

Compliant Solution

01 VARS
    05 TABLE_SIZE   PIC 9(4) BINARY.
    05 MY_TABLE OCCURS 1 TO 10
                        DEPENDING ON TABLE_SIZE
                        PIC X(10).
cobol:S4884

PERFORM is used to execute a paragraph located somewhere in the program and then, once executed, the execution flow will continue on the line following the PERFORM statement. This is the expected behaviour that can be broken if a GO TO is added in the called paragraph. When mixing PERFORM and GO TO you can quickly be lost on the execution flow and finally don't get the one you expect. For this reason, calling PERFORM with paragraphs that used GO TO should be avoided.

Noncompliant Code Example

PROCEDURE DIVISION.
DISPLAY-9-LETTERS.
    PERFORM ABC.
    DISPLAY "END OF DISPLAY-9-LETTERS".
    STOP RUN.

    ABC.
        DISPLAY "ABC".
        GO TO XYZ.

    DEF.
        DISPLAY "DEF".

    XYZ.
        DISPLAY "XYZ".

Compliant Solution

PROCEDURE DIVISION.
DISPLAY-9-LETTERS.
    PERFORM ABC.
    PERFORM DEF.
    PERFORM XYZ.
    DISPLAY "END OF DISPLAY-9-LETTERS".
    STOP RUN.

    ABC.
        DISPLAY "ABC".

    DEF.
        DISPLAY "DEF".

    XYZ.
        DISPLAY "XYZ".

See

cobol:S2583

Conditional statements using a condition which cannot be anything but FALSE have the effect of making blocks of code non-functional. If the condition cannot evaluate to anything but TRUE, the conditional statement is completely redundant, and makes the code less readable.

It is quite likely that the code does not match the programmer's intent.

Either the condition should be removed or it should be updated so that it does not always evaluate to TRUE or FALSE.

Noncompliant Code Example

IF FOO IS NUMERIC AND FOO = "a"   *> Noncompliant, FOO cannot be both numeric and equal to "a"
  DISPLAY "..."
END-IF.

IF BAR = 4
  IF FOO = "a" AND BAR = 5        *> Noncompliant, BAR cannot be equal to 5
    DISPLAY "..."
  END-IF.
  ...
END-IF.

01 BAR PIC 9.
IF BAR > 30                       *> Noncompliant, BAR cannot be greater than 9
  DISPLAY "..."
END-IF.

See

  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
cobol:S4883

This rule is a more precise version of S1308 preventing the use of GO TO. The flow of a program is already complicated to understand with simple GO TOs. It's even worse when a GO TO is executed conditionally like this is the case with GO TO DEPENDING ON.

Noncompliant Code Example

PROCEDURE DIVISION.
   ...
   GO TO PARAGRAPH-10
         PARAGRAPH-20
         PARAGRAPH-30
   DEPENDING ON WS-PARA-NUMBER *> Noncompliant
   ...

Compliant Solution

PROCEDURE DIVISION.
   ...
   EVALUATE WS-PARA-NUMBER
      WHEN 1
         PERFORM PARAGRAPH-10
      WHEN 2
         PERFORM PARAGRAPH-20
      WHEN 3
         PERFORM PARAGRAPH-30
      WHEN OTHER
         PERFORM PARAGRAPH-99
   END-EVALUATE
   ...
cobol:SQL.CursorOpenedMustBeClosedCheck

If you do not explicitly close a cursor, it will be closed at the end of the task. But if you try to re-open this cursor to process it, you will get an error. That is why a cursor should be explicitly closed after it has been processed.

See

cobol:COBOL.LogicalFileNamingCheck

Shared coding conventions allow teams to collaborate efficiently. This rule checks that logical file names conform to a provided regular expression.

Noncompliant Code Example

Given the regular expression FILE-.*:

 INPUT-OUTPUT SECTION.
 FILE-CONTROL.

     SELECT Y27MVTS       ASSIGN  TO     S1       >Noncompliant
                          FILE STATUS IS FS-S1.

Compliant Solution

 INPUT-OUTPUT SECTION.
 FILE-CONTROL.

     SELECT FILE-X345      ASSIGN  TO     S1
                          FILE STATUS IS FS-S1.
cobol:S1138

SQL queries that use EXISTS subqueries are inefficient because the subquery is re-run for every row in the outer query's table. There are more efficient ways to write most queries, ways that do not use the EXISTS condition.

Noncompliant Code Example

SELECT e.name
FROM employee e
WHERE EXISTS (SELECT * FROM department d WHERE e.department_id = d.id AND d.name = 'Marketing')

Compliant Solution

SELECT e.name
FROM employee e INNER JOIN department d
  ON e.department_id = d.id AND d.name = 'Marketing'
cobol:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

SET NAME TO NAME.    *> Noncompliant
MOVE NAME TO NAME.   *> Noncompliant
COMPUTE NAME = NAME. *> Noncompliant
EXEC SQL
  UPDATE PERSON
    SET NAME = NAME  -- Noncompliant
  WHERE ID = :PERSON_ID
END-EXEC.

Compliant Solution

SET NAME TO NEW_NAME.
MOVE NEW_NAME TO NAME.
COMPUTE NAME = NEW_NAME.
EXEC SQL
  UPDATE PERSON
    SET NAME = :NEW_NAME
  WHERE ID = :PERSON_ID
END-EXEC.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
cobol:COBOL.ParsingErrorCheck

When the parser fails, it is possible to record the failure as an issue on the file. This way, not only is it possible to track the number of files that do not parse but also to easily find out why they do not parse.

cobol:SQL.GroupByUsageCheck

Using GROUP BY in SQL SELECT statements should be avoided because it makes queries complex. Complex queries are generally not performant and are difficult to understand and therefore to maintain.

cobol:CICS.LinkOrXctlWithoutLengthClauseCheck

When using CICS XCTL or CICS LINK, it is a bad practice not to specify the length of the communication area.

Noncompliant Code Example

  EXEC CICS LINK PROGRAM ('SPI2TCV') COMMAREA (SPI-PARMCICS)  RESP (WS-RESP)  *> Noncompliant

  EXEC CICS XCTL PROGRAM ('P4DERROR') COMMAREA (Y4DERROR)  *> Noncompliant

Compliant Solution

  EXEC CICS LINK PROGRAM ('SPI2TCV') COMMAREA (SPI-PARMCICS) LENGTH (SPI-LONG) RESP (WS-RESP)

  EXEC CICS XCTL PROGRAM ('P4DERROR') COMMAREA (Y4DERROR) LENGTH (Y4FLFIC-Y4DERROR)
cobol:COBOL.ProgramNameCheck

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all [report/]program names match a provided regular expression.

Noncompliant Code Example

With the regular expression ^([A-Z0-9_]*|[a-z0-9_]*)$:

    IDENTIFICATION DIVISION.
       PROGRAM-ID. MY-PROGRAM.      *> Noncompliant

Compliant Solution

    IDENTIFICATION DIVISION.
       PROGRAM-ID. MY_PROGRAM.
cobol:COBOL.MergeStatementUsageCheck

You should avoid using the MERGE statement because it is inefficient. Instead, external tools should be used to merge.

cobol:S3394

The ACCEPT keyword does no editing or error checking of the data it stores, therefore its use can be dangerous. For this reason, ACCEPT should be avoided.

Noncompliant Code Example

 01 USER-INPUT PIC X(4).

  GET-USER-INPUT.
       MOVE 'N' TO WS-NUMERIC.
       PERFORM UNTIL WS-NUMERIC = 'Y'
           DISPLAY 'ENTER YOUR 4 DIGIT RECORD NUMBER: ' NO ADVANCING
           ACCEPT USER-RECORD *> Noncompliant

Exceptions

This rule ignores uses of ACCEPT FROM with date/time-related inputs.

See

  • OWASP Top 10 2017 Category A1 - Injection
cobol:COBOL.IdentifierCharacterCheck

Portability issues may restrict which characters should be used in an identifier.

This rule checks identifier names against a regular expression of disallowed characters. Due to a technical limitation, the COBOL analyzer is not able for the time-being to differentiate lowercase from uppercase characters.

Noncompliant Code Example

With the default regular expression [^a-zA-Z0-9-]:

MOVE DATA-1 TO DATA_2 *> Noncompliant; '_' not allowed

Compliant Solution

MOVE DATA-1 TO DATA-2
cobol:S105

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

cobol:S864

The rules of operator precedence are complicated and can lead to errors. For this reason, parentheses should be used for clarification in complex statements.

This rule raises an issue when more than the allowed number of non-like operators are used in a statement without parentheses to make execution order explicit.

Noncompliant Code Example

With the default threshold of 2:

COMPUTE WSRESULT = WS1 + 5 * WS2 - WS3**2 END-COMPUTE  *> Noncompliant
COMPUTE WSRESULT2 = WS1 + 5 + WS2 + WS3 + WS4 END-COMPUTE

Compliant Solution

COMPUTE WSRESULT = WS1 + (5 * WS2) - (WS3**2) END-COMPUTE
COMPUTE WSRESULT2 = WS1 + 5 + WS2 + WS3 + WS4 END-COMPUTE

See

  • MISRA C:2004, 12.1 - Limited dependence should be placed on C's operator precedence rules in expressions
  • MISRA C:2004, 12.2 - The value of an expression shall be the same under any order of evaluation that the standard permits.
  • MISRA C:2004, 12.5 - The operands of a logical && or || shall be primary-expressions.
  • MISRA C++:2008, 5-0-1 - The value of an expression shall be the same under any order of evaluation that the standard permits.
  • MISRA C++:2008, 5-0-2 - Limited dependence should be placed on C++ operator precedence rules in expressions
  • MISRA C++:2008, 5-2-1 - Each operand of a logical && or || shall be a postfix-expression.
  • MISRA C:2012, 12.1 - The precedence of operators within expressions should be made explicit
  • CERT, EXP00-C. - Use parentheses for precedence of operation
  • CERT, EXP53-J. - Use parentheses for precedence of operation
  • MITRE, CWE-783 - Operator Precedence Logic Error
cobol:COBOL.ExhibitStatementUsageCheck

OS/VS COBOL accepted the EXHIBIT statement, but IBM Enterprise COBOL does not. With IBM Enterprise COBOL, the DISPLAY statement must be used instead.

Noncompliant Code Example

       IDENTIFICATION DIVISION.
       PROGRAM-ID. foo.

       DATA DIVISION.

       WORKING-STORAGE SECTION.
         01 WS-FOO PIC X(42).
         01 WS-BAR PIC X(42).

       PROCEDURE DIVISION.
      * Non-Compliant
         EXHIBIT NAMED WS-FOO WS-BAR.
       END PROGRAM foo.

Compliant Solution

       IDENTIFICATION DIVISION.
       PROGRAM-ID. foo.

       DATA DIVISION.

       WORKING-STORAGE SECTION.
         01 WS-FOO PIC X(42).
         01 WS-BAR PIC X(42).

       PROCEDURE DIVISION.
      * Compliant
         DISPLAY "WS-FOO = " WS-FOO
             "WS-BAR = " WS-BAR.
       END PROGRAM foo.
cobol:COBOL.PerformThruExitParagraphCheck

The EXIT statement is useful for documenting the end point in a series of paragraphs. It identifies the point at which control will be transferred.

cobol:CICS.StatementWithUntestedReturnCodeCheck

After calling CICS commands with the RESP or NOHANDLE options, the return code should be tested.

Noncompliant Code Example

  EXEC CICS DELETEQ TS        *> Noncompliant; WS-STATUS should have been tested before the MOVE
    QNAME(WS-TS5FTARF-NAME)
    RESP(WS-STATUS)
  END-EXEC.
  MOVE WS-EIBTASKN (4:4) TO WS-TS5FTAR1-NAME-TSKID.

Compliant Solution

  EXEC CICS DELETEQ TS
    QNAME(WS-TS5FTARF-NAME)
    RESP(WS-STATUS)
  END-EXEC.
  IF WS-STATUS ...

  MOVE WS-EIBTASKN (4:4) TO WS-TS5FTAR1-NAME-TSKID.
cobol:S1302

The cyclomatic complexity of a section should not exceed a defined threshold. Complex code is difficult to understand and therefore to maintain.

cobol:S1300

A section that grows too large tends to aggregate too many responsibilities.

Such sections inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller sections which focus on well-defined tasks. Those smaller sections will not only be easier to understand, but also probably easier to test.

cobol:SQL.LockTableStatementCheck

The SQL LOCK command can be used to lock a DB table. Even if the use of the command can be fully justified, it should be done rarely, and very carefully.

cobol:COBOL.NoSonarCheck

Any issue to quality rule can be deactivated with the NOSONAR marker. This marker is pretty useful to exclude false-positive results but it can also be used abusively to hide real quality flaws.

This rule raises an issue when NOSONAR is used.

cobol:S122

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

MOVE '1' TO OCTET-1 MOVE '2' TO OCTET-2

Compliant Solution

MOVE '1' TO OCTET-1
MOVE '2' TO OCTET-2

Exceptions

Control flow statements with a single nested statement are ignored.

IF x > 0 THEN DISPLAY "positive". *> Compliant
cobol:COBOL.IfStatementFormattingCheck

Aligning opening and ending words of statements is critical to keep the code readable, especially when blocks contain nested statements.

For IF statements, this rule also checks the alignment of the ELSE word.

Noncompliant Code Example

IF SOME-STATUS = 1
  DISPLAY something
      END-IF.  *> Noncompliant

Compliant Solution

IF SOME-STATUS = 1
  DISPLAY something
END-IF.
cobol:S1308

Unstructured programming has been strongly criticized for producing barely readable (spaghetti) code. It offers programmers great freedom, but is considered a bad approach for creating major projects.

In COBOL, the use of GO TO statements can lead to unstructured control flows. Eliminating GO TO statements in favor of PERFORM statements will aid adherence to a procedural programming approach. However, this change could require heavy refactoring.

cobol:S1307

It is fairly normal for COBOL development teams to decide to work either with sections or with paragraphs and to make this choice a standard.

When sections are used, it is also normal to define another standard: "End every section definition with an empty paragraph definition, or a paragraph containing only a terminating statement".

This empty paragraph can then be jumped to with a GO TO statement to stop the execution of a section.

Accepted terminating statements in the otherwise-empty ending paragraph are: EXIT, EXIT PROGRAM, STOP RUN, and GO BACK.

Noncompliant Code Example

In this example, an empty paragraph is missing at the end of the first section definition.

FIRST_SECTION SECTION.
  ...

SECOND_SECTION SECTION.
  ...
SECOND_SECTION_END.

Compliant Solution

FIRST_SECTION SECTION.
  ...
FIRST_SECTION_END.

SECOND_SECTION SECTION.
  ...
SECOND_SECTION_END.
cobol:S3606

Program/file names offer only very limited space for indicating program function, which is why you should take advantage of the ability to specify a program TITLE. Omitting the TITLE statement will result in a default, uncommunicative TITLE value being printed at the top of each page of the source listing. Instead, you should write an expressive title that gives a clear impression of the program's function.

This rule raises an issue when a there is no TITLE before the IDENTIFICATION DIVISION. Ideally, TITLE will be the first line of a program, but it cannot be placed before compiler options.

Noncompliant Code Example

      * Copyright (c) 2012 MyCo. All rights reserved.  *> Noncompliant
       IDENTIFICATION DIVISION.

Compliant Solution

       TITLE 'IntradayPosition.ExecutePostProcessing'
      * Copyright (c) 2012 MyCo. All rights reserved.
       IDENTIFICATION DIVISION.
cobol:S1306

Call stacks containing lot of PERFORM statements is a key ingredient for making what's known as "Spaghetti code".

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

This rule supports both sections and paragraphs.

Noncompliant Code Example

With a threshold of 3:

PERFORM FIRST.

FIRST.
  PERFORM SECOND.

SECOND.
  PERFORM THIRD.

THIRD.
  PERFORM FOURTH.  *> Noncompliant

FOURTH.
  DISPLAY something.
cobol:SQL.DistinctUsageCheck

Using DISTINCT in SQL SELECT statements should be avoided. Not only is this command to remove duplicates not efficient, but a SELECT DISTINCT query indicates that something is not quite right. That is because using the DISTINCT keyword means that redundant data is being pulled from the database and then discarded.

cobol:S1305

Every section should be commented to explain its goal and how it works. This comment can be placed either just before or just after the section label.

Noncompliant Code Example

    UNCOMMENTED-SECTION SECTION.

Compliant Solution

* Some comments
    CORRECTLY-COMMENTED-SECTION SECTION.

    ANOTHER-CORRECTLY-COMMENTED-SECTION SECTION.
* Some comments
cobol:COBOL.InitializeStatementUsageCheck

The INITIALIZE statement should not be used because it does not properly manage the initialization of REDEFINE and fillers.

cobol:S1303

There is no good reason to keep an empty and therefore valueless section. Such sections should be removed.

Noncompliant Code Example

FIRST SECTION.
  MOVE A TO B.

SECOND SECTION.  *> Noncompliant; empty

THIRD SECTION.

someParagraph.
  DISPLAY B.

Compliant Solution

FIRST SECTION.
  MOVE A TO B.

THIRD SECTION.

someParagraph.
  DISPLAY B.
cobol:WhereClauseLinesCheck

SQL queries with large WHERE clauses are complex. Complex queries are generally not performant, in addition to being difficult to understand and therefore to maintain.

cobol:COBOL.ClosableStatementCheck

When a closable statement contains nested statements, it can quickly become difficult to see which statements are nested and which are not. That's why ending a list of nested statements with END-${STATEMENT-NAME} is advised.

Noncompliant Code Example

READ DF-PARAM-SPILOTE AT END
  GO TO F-LECT-SPILOTE.

Compliant Solution

READ DF-PARAM-SPILOTE AT END
  GO TO F-LECT-SPILOTE
END-READ.
cobol:COBOL.ParagraphUncommentedCheck

Every paragraph should be commented to explain its goal and how it works. This comment can be placed either just before or just after the paragraph label. Moreover paragraphs used to close a module can be left uncommented.

Noncompliant Code Example

 PROCEDURE DIVISION.

    PARAGRAPH1.           *> Noncompliant
    ...

*-------
    PARAGRAPH2.           *> Noncompliant; the comment is empty
    ...

      PERFORM P1 THRU P2.
    ...

*Some comments                                  *> Compliant
    P1.
      ....

    P2.                                         *> No violation as the this P2 paragraph close a module
       MOVE A TO B.
       ...
       EXIT.

Compliant Solution

 PROCEDURE DIVISION.

* Some comments
    PARAGRAPH1.     *>  Compliant; the comment is just before
    ...

    PARAGRAPH2.     *>  Compliant; the comment is just after
* Some comments
    ...
      PERFORM P1 THRU P2.
    ...

*Some comments
    P1.
      ....

    P2.
       MOVE A TO B.
       ...
       EXIT.
cobol:S1476

When using some transaction managers like IBM IMS, each COBOL program is in fact considered a sub-program by the transaction manager. The GOBACK statement returns control to the transaction manager, but using STOP RUN might cause unpredictable results or abnormal termination.

Noncompliant Code Example

STOP RUN

Compliant Solution

GOBACK
cobol:S1631

When you need access to data from multiple tables, it is more efficient, effective, and understandable to use pre-built views than to select the data from a large number of tables - effectively creating in-memory views - at runtime.

Noncompliant Code Example

With a maximum number of 3 joined tables:

SELECT PERSONS.NAME, COUNTRIES.NAME, GENRES.NAME, PROFESSIONS.NAME
FROM PERSONS
  INNER JOIN COUNTRIES ON COUNTRIES.ID = PERSON.COUNTRY_ID
  INNER JOIN GENRES ON GENRES.ID = PERSONS.GENRE_ID
  INNER JOIN PROFESSIONS ON PROFESSIONS.ID = PERSONS.PROFESSIONS_ID  -- Noncompliant; this is table #4
WHERE COUNTRIES.CODE = 'US'

SELECT PERSONS.NAME, COUNTRIES.NAME, GENRES.NAME, PROFESSIONS.NAME
FROM PERSONS, COUNTRIES, GENRES, PROFESSIONS -- Noncompliant
WHERE COUNTRIES.CODE = 'US' AND COUNTRIES.ID = PERSON.COUNTRY_ID AND GENRES.ID = PERSONS.GENRE_ID AND PROFESSIONS.ID = PERSONS.PROFESSIONS_ID
cobol:COBOL.FileDataItemSizeCheck

This a limit of the Microfocus COBOL compiler.

See

cobol:S1474

The worst nightmare of every COBOL maintenance programmer is a program where you have to follow 12 concatenated PERFORM statements before you get to the actual processing. This is considered to be the GOTO-less version of spaghetti programming.

This situation can be avoided by having a mainline procedure at the beginning of the procedure division which concentrates all program control, and which reads like a map of the program. This mainline procedure should be free from detailed operations such as moving fields, calculations, I/O operations, and so on.

This rule helps ensure that most program control is concentrated in the mainline procedure (the first one in the program) by preventing the other procedures from having more than a predefined threshold of "PERFORM" statements.

cobol:S1871

Having two WHEN clauses in the same EVALUATE statement or two 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 they should be combined, for an IF structure or one should fall through to the other for an EVALUATE.

Noncompliant Code Example

EVALUATE X
  WHEN 1
    MOVE A TO B.
    PERFORM SECTION1
  WHEN 2
    MOVE A TO C.
    PERFORM SECTION2
  WHEN 3              *> Noncompliant; duplicates WHEN 1's implementation
    MOVE A TO B.
    PERFORM SECTION1
END-EVALUATE.

IF X = 1
  MOVE A TO B.
  PERFORM SECTION1
ELSE
  IF X > 10
    PERFORM SECTION2
  ELSE                *> Noncompliant
    MOVE A TO B.
    PERFORM SECTION1
  END-IF
END-IF.

Exceptions

Blocks in an IF chain that contain a single line of code are ignored, as are blocks in a EVALUATE statement that contain a single line of code.

EVALUATE X
  WHEN 1
    PERFORM SECTION1
  WHEN 2
    PERFORM SECTION2
  WHEN 3              *> no issue, usually this is done on purpose to increase the readability
    PERFORM SECTION1
END-EVALUATE.

But this exception does not apply to IF chains without ELSE-s, or to EVALUATE-s without WHEN OTHER clauses when all branches have the same single line of code. In case of IF chains with ELSE-s, or of EVALUATE-es with WHEN OTHER clauses, rule S3923 raises a bug.

EVALUATE X
  WHEN 1
    PERFORM SECTION1
  WHEN 3              *> Noncompliant, this might have been done on purpose but probably not
    PERFORM SECTION1
END-EVALUATE.
cobol:S1473

To improve source code readability and reusability, SQL operations should be located in dedicated procedures (sections or paragraphs) and should not be mixed with other SQL requests.

Noncompliant Code Example

MAIN_PARAGRAPH.
  ...
  LOAD_SALARY.
  ...

LOAD_SALARY.
  EXEC SQL CONNECT :UID IDENTIFIED BY :PASS END-EXEC.
  EXEC SQL USE tempdb END-EXEC.   *< Noncompliant
  EXEC SQL
    SELECT   SALARY
        INTO  :HV-SALARY
      FROM EMPLOYEE
        WHERE EMPNAME = 'XXXXXXX'
  END-EXEC.
  EXIT.

Compliant Solution

MAIN_PARAGRAPH.
  ...
  CONNECT_TO_DB.
  USE_TMP_DB_SCHEMA.
  ...
  LOAD_SALARY.
  ...
CONNECT_TO_DB.
  EXEC SQL CONNECT :UID IDENTIFIED BY :PASS END-EXEC.
  EXIT.

USE_TMP_DB_SCHEMA.
  EXEC SQL USE tempdb END-EXEC.
  EXIT.

LOAD_SALARY.
  EXEC SQL
    SELECT   SALARY
        INTO  :HV-SALARY
      FROM EMPLOYEE
        WHERE EMPNAME = 'XXXXXXX'
  END-EXEC.
  EXIT
cobol:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

COMPUTE x = (y / 2 + 1).  *> Compliant even if the parenthesis are ignored by the compiler
COMPUTE y = 2 * ((x + 1)).  *> Noncompliant

Compliant Solution

COMPUTE x = (y / 2 + 1).
COMPUTE y = 2 * (x + 1).
cobol:S3891

The number of RECORDS or CHARACTERS specified in a BLOCK CONTAINS clause is used to determine block size. Specify 10 RECORDS, and the block will be exactly 10x the length of the record. But that may not be the right size, depending on the environment. Instead, it is considered a best practice to specify 0 RECORDS, so the block size will be calculated automatically.

Noncompliant Code Example

       FD OUTFILE1
           BLOCK CONTAINS 32760 RECORDS     >* Noncompliant
           RECORDING MODE V.
       FD OUTFILE2
           BLOCK CONTAINS 1024 CHARACTERS.  >* Noncompliant

Compliant Solution

       FD OUTFILE1
           BLOCK CONTAINS 0 RECORDS
           RECORDING MODE V.
       FD OUTFILE2
           BLOCK CONTAINS 0 RECORDS.

Exceptions

0 CHARACTERS is compliant.

cobol:S3892

COPY ... SUPPRESS suppresses the inclusion of the copybook contents from the source listing, making it very difficult to gain a complete understanding of what's happening in the code. This could hinder both maintenance and debugging.

Noncompliant Code Example

COPY XX001234 SUPPRESS.  <* Noncompliant

Compliant Solution

COPY XX001234.
cobol:S3938

This rule allows banning certain statements.

Noncompliant Code Example

Given a parameter of CANCEL for this rule:

DISPLAY "Cancelling action".
CANCEL PROGRAM1. *> Noncompliant
cobol:S3939

OCCURS DEPENDING ON clauses are complicated to use correctly and do not provide any benefits with regard to memory consumption. It is best to avoid them.

Noncompliant Code Example

01  MYTABLEACCOUNT PIC S9(4) BINARY.
01  MYTABLE.
  05  MYITEM OCCURS 1 to 1000 DEPENDING ON MYTABLEACCOUNT.
    10  MYFIELD1 PIC X(8).
    10  MYFIELD2 PIC S9(4) BINARY.

Compliant Solution

01  MYTABLE.
  05  MYITEM OCCURS 1000.
    10  MYFIELD1 X(8).
    10  MYFIELD2 PIC S9(4) BINARY.
cobol:COBOL.PerformThruParagraphMandatoryCheck

In most companies the choice is done either to work with PERFORM paragraph1 or with PERFORM paragraph1 THRU paragraph2. Mixing the two approches is error prone when creating a new paragraph in the middle of an existing source code because there is no easy way to know if an existing execution flow might go through this new paragraph. This rule helps sustain the use of PERFORM ... THRU....

cobol:COBOL.FirstLevelDataItemNamingCheck

Shared coding conventions allow teams to collaborate efficiently. This rule checks that first level data item names match a provided regular expression.

Noncompliant Code Example

Given an regular expression of WS-.*:

       WORKING-STORAGE SECTION.
            01 WRONG.                                       > Noncompliant; name doesn't match the pattern "WS-.*"
              02  LINK.                                     > Compliant; this is not first level

       LINKAGE SECTION.
             01     DFHCOMMAREA PIC X(1500).                > Compliant; the data item is defined in the LINKAGE SECTION

Compliant Solution

       WORKING-STORAGE SECTION.
            01 WS-LINK.
              02  LINK.

       LINKAGE SECTION.
             01     DFHCOMMAREA PIC X(1500).
cobol:COBOL.UnusedParagraphOrSectionLabelCheck

An unused paragraph is never called explicitly with help of the GO TO or PERFORM statements.

There are only two reasons for such a paragraph:

  • It is really unused, and should be removed
  • It is used as a kind of comment to clearly delimit a block of code, which is bad practice

The remediation action should be:

  • Replace the paragraph by a comment line
  • Refactor the code to make an explicit call to this paragraph instead of letting the execution flow going through it implicitly
cobol:S1755

COBOL files containing a large number of sections are by definition difficult to understand and therefore to maintain.

Exceptions

Sections contained in copybooks are not taken into account when computing the total number of sections in a program.

cobol:SQL.CursorOpenedInsideLoopCheck

You should avoid opening a cursor inside a PERFORM statement because doing so could impact performance, or lead to unexpected behavior if the the closing of the cursor is not defined in the same loop.

Noncompliant Code Example

  PERFORM UNTIL (NOT DA-OK) OR (Y00CIA-CD-RET-PGM = ZERO)
    EXEC SQL OPEN C2
    END-EXEC
  END-PERFORM.
cobol:COBOL.EvaluateStatementUsageCheck

The EVALUATE statement allows implementing case structures in Cobol. Each case is managed by a WHEN phrase activated by specific test of a variable.The WHEN OTHER phrase allows managing all the cases which have not been taken into account by the previous WHEN phrases. If the variable to be tested contains a new value that is not currently managed then the absence of the WHEN OTHER phrase will lead a situation in which no process will be performed for this value and the program may have uncontrolled or undefined behavior.

Noncompliant Code Example

       A010-PRINCIPAL.
         EVALUATE  Y5FTAR-PER-ECN-CTS
           WHEN '01'
             MOVE 'A' TO WS-CD-PER-CTS
           WHEN '02'
             MOVE 'S' TO WS-CD-PER-CTS
           WHEN '04'
             MOVE 'T' TO WS-CD-PER-CTS
           WHEN '12'
             MOVE 'M' TO WS-CD-PER-CTS
         END-EVALUATE.

Compliant Solution

       A010-PRINCIPAL.
         EVALUATE  Y5FTAR-PER-ECN-CTS
           WHEN '01'
             MOVE 'A' TO WS-CD-PER-CTS
           WHEN '02'
             MOVE 'S' TO WS-CD-PER-CTS
           WHEN '04'
             MOVE 'T' TO WS-CD-PER-CTS
           WHEN '12'
             MOVE 'M' TO WS-CD-PER-CTS
           WHEN OTHERS
             MOVE 'O' TO WS-CD-PER-CTS
         END-EVALUATE.

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
  • MITRE, CWE-478 - Missing Default Case in Switch Statement
  • CERT, MSC01-C. - Strive for logical completeness
cobol:COBOL.IdentationCheck

Paragraphs, sections and statements must be correctly indented for better code readability.

Noncompliant Code Example

       IDENTIFICATION DIVISION.
       PROGRAM-ID. foo.

       PROCEDURE DIVISION.
           IF "foo" = "bar" THEN
           DISPLAY "foo = bar!"      *> Noncompliant
           ELSE
           DISPLAY "foo <> bar!".      *> Noncompliant
       END PROGRAM foo.

Compliant Solution

       IDENTIFICATION DIVISION.
       PROGRAM-ID. foo.

       PROCEDURE DIVISION.
           IF "foo" = "bar" THEN
              DISPLAY "foo = bar!"
           ELSE
              DISPLAY "foo <> bar!".
       END PROGRAM foo.
cobol:COBOL.SectionUsageCheck

Having SECTIONs can lead to having paragraphs with the same name (one in each section), which could become confusing.

cobol:COBOL.PerformThruProcedureNamingConventionCheck

In a PERFORM prodecure1 THRU procedure2 statement, the two procedures should share a naming convention because they are strongly related and there should be a way to quickly see this relationship while reading the source code. Otherwise, the source code might quickly become very complex to maintain. To this end, procedure2 should contain the name of procedure1 and either a prefix or a suffix. For instance: PERFORM my-paragraph THRU end-my-paragraph.

cobol:S3890

After the execution of each SQL statement (other than DECLARE CURSOR, DECLARE TABLE and DECLARE VARIABLE), the value of SQLCODE or SQLSTATE should be checked before proceeding. A 0 SQLCODE value means the statement succeeded, a positive value means success with a warning, and a negative value indicates an error. Proceeding without checking could put your program or your data in a bad state.

Noncompliant Code Example

EXEC SQL
  SELECT name INTO :username FROM user WHERE id = :userid
END-EXEC.

DISPLAY username.    *> Noncompliant

Compliant Solution

EXEC SQL
  SELECT name INTO :username FROM user WHERE id = :userid
END-EXEC.

IF SQLCODE = 0 THEN
  DISPLAY username
END-IF.

Exceptions

When the value of SQLCODE or SQLSTATE is not checked but transferred to another variable for later use, no issue is raised.

EXEC SQL
  SELECT name INTO :username FROM user WHERE id = :userid
END-EXEC.
MOVE SQLCODE TO SQL-RETURN-CODE
cobol:S1590

UPDATE and DELETE statements should contain WHERE clauses to keep the modification of records under control. Otherwise unexpected data loss could result.

cobol:COBOL.ParagraphUsageCheck

Sections should be used instead of paragraphs. Sections have better defined scopes for returning to the caller. Paragraphs have more flexible flow control but this flexibility incurs additional risk.

cobol:S1192

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

With the default threshold of 3:

       PROCEDURE DIVISION.

       DISPLAY "Firstname: ".
      *...
       DISPLAY "Firstname: ".
      *...
       DISPLAY "Firstname: ".

Compliant Solution

       WORKING-STORAGE SECTION.
         01 FIRST-NAME-HEADER PIC X(42) VALUE "Firstname: ".
       PROCEDURE DIVISION.

       DISPLAY FIRST-NAME-HEADER
      *...
       DISPLAY FIRST-NAME-HEADER
      *...
       DISPLAY FIRST-NAME-HEADER

Exceptions

Literals with fewer than 7 characters are ignored.

Only duplications located in a PROCEDURE DIVISION, not those contained in copybooks are reported.

cobol:COBOL.SortStatementUsageCheck

You should avoid using the SORT statement because it is inefficient. Use external tools to sort large numbers of records instead.

cobol:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of arithmetic operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Noncompliant Code Example

* always true
  IF X = X
    PERFORM SECTION1.
  END-IF.

* always false
  IF X <> X
    PERFORM SECTION2.
  END-IF.

* if the first one is true, the second one is too
  IF X = Y AND X = Y
    PERFORM SECTION3.
  END-IF.

* if the first one is true, the second one is too
  IF X = Y OR X = Y
    PERFORM SECTION4.
  END-IF.

* always 1
  COMPUTE X = Y / Y.

* always 0
  COMPUTE X = Y - Y.

Exceptions

This rule ignores * and +.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
cobol:COBOL.COMPUsageCheck

The way computational fields are managed varies greatly between platforms, so for portability reasons they should not be used. The COMP-5 type is the only exception.

cobol:COBOL.MagicNumberCheck

A magic number is a number that comes out of nowhere, and is directly used in a statement. Magic numbers are often used, for instance to limit the number of iterations of a loops, to test the value of a property, etc.

Using magic numbers may seem obvious and straightforward when you're writing a piece of code, but they are much less obvious and straightforward at debugging time.

That is why magic numbers must be demystified by first being assigned to clearly named variables before being used.

cobol:SQL.CursorClosedInsideLoopCheck

You should avoid closing a CURSOR inside a PERFORM statement, because it could impact performance or lead to unexpected behavior if the cursor was not opened in the same loop.

Noncompliant Code Example

 PERFORM UNTIL (NOT DA-OK)
       OR (Y00CIA-CD-RET-PGM = ZERO)
    EXEC SQL CLOSE C2
    END-EXEC
  END-PERFORM.
cobol:COBOL.ExamineStatementUsageCheck

The COBOL EXAMINE statement is a specific OS/VS extension to the ANSI COBOL standard. To prevent portability issues, it should not be used anymore.

cobol:COBOL.ParagraphOrSectionLinesCheck

A paragraph that grows too large tends to aggregate too many responsibilities. Such paragraphs inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller paragraphs which focus on well-defined tasks. Those smaller paragraphs will not only be easier to understand, but also probably easier to test.

cobol:COBOL.FileCodeNamingCheck

Shared coding conventions allow teams to collaborate efficiently. This rule checks that file-code names conform to a specified regular expression.

Noncompliant Code Example

Given a pattern of FC-.*:

 INPUT-OUTPUT SECTION.
 FILE-CONTROL.

     SELECT Y27MVTS       ASSIGN  TO     S1        >Noncompliant; S1 doesn't match "FC-.*" pattern
                          FILE STATUS IS S1.

Compliant Solution

 INPUT-OUTPUT SECTION.
 FILE-CONTROL.

     SELECT Y27MVTS     ASSIGN  TO     FC-S1     >OK as FC-S1 matches "FC-.*" pattern
                          FILE STATUS IS FS-S1.
cobol:COBOL.LinkageSectionUsageCheck

The LINKAGE section describes data made available from another program through the CALL statement. The data structure defined in a LINKAGE section should be located in a COPYBOOK. Otherwise, at runtime multiple COBOL programs may try to share data structures which are not similar.

First level data items can also be defined in the main program as long as there are no structural pieces of information attached to this first level like the length, the format, and so on.

This rule raises an issue only on the first invalid data item of a LINKAGE section.

Noncompliant Code Example

LINKAGE SECTION.

01 LK-DATA.  *> Noncompliant
  05 LK-LENGTH     PIC S9(04) COMP.
   05 LK-VARIABLE  PIC X(08).

Compliant Solution

LINKAGE SECTION.

COPY MY_COPYBOOK.

or

LINKAGE SECTION.

01 LK-DATA.
  COPY MY_COPYBOOK.
cobol:COBOL.ProgramComplexityCheck

The cyclomatic complexity of a program should not exceed a defined threshold, otherwise it will be too complex. Complex code can perform poorly, and will be difficult to understand and therefore to maintain.

Deprecated

This rule is deprecated, and will eventually be removed.

cobol:S1731

When the FILE STATUS is not specified on a file, any read operations on the file should handle the "AT END" or "INVALID KEY" conditions.

Noncompliant Code Example

SELECT MY_FILE
  ASSIGN TO 'foobar.txt'
  ORGANIZATION IS SEQUENTIAL.
...
READ MY_FILE
  NOT AT END PERFORM COMPUTE_LINE
END-READ.

Compliant Solution

SELECT MY_FILE
  ASSIGN TO 'foobar.txt'
  ORGANIZATION IS SEQUENTIAL.
...
READ MY_FILE
  NOT AT END PERFORM COMPUTE_LINE
  AT END MOVE 'Y' TO EOF-FLAG
END-READ.
cobol:S3633

Queries with contradictory WHERE clauses will always return empty result sets. This is clearly a bug.

Noncompliant Code Example

SELECT *
FROM fruit
WHERE type='apple' AND type='orange'  -- Noncompliant
cobol:S2269

To ensure future code portability, obsolete keywords should not be used. The following keywords were declared obsolete in the COBOL ANSI-85 standard and removed in the ISO/IEC 1989:2002 standard:

  • Paragraphs: AUTHOR, INSTALLATION, DATE-WRITTEN, DATE-COMPILED, SECURITY
  • Clauses: DATA RECORD(S), LABEL RECORD(S), MEMORY SIZE, MULTIPLE FILE (TAPE), RERUN, VALUE OF, CODE SEGMENT-LIMIT
  • Statements: ALTER, ENTER, STOP literal, GO TO without an argument
  • Phrases: REVERSED phrase of the OPEN statement
  • Special registers: DEBUG-ITEM
  • Sections: Debugging sections
  • Declarative: USE FOR DEBUGGING

The following keywords were declared obsolete in the ISO/IEC 1989:2002 standard:

  • Phrase: DEBUGGING MODE
  • Clause: PADDING CHARACTER

Noncompliant Code Example

IDENTIFICATION DIVISION.
PROGRAM-ID.  AcceptAndDisplay.
AUTHOR.  Michael Coughlan.  *> Noncompliant

Compliant Solution

IDENTIFICATION DIVISION.
PROGRAM-ID.  AcceptAndDisplay.
cobol:S3632

In general, the clause INDEXED BY should be used whenever possible when handling COBOL tables. If it's not possible, then avoid using a numeric display variable to access the table's elements. Instead, use a BINARY/COMP variable, which the processor can handle more efficiently.

Noncompliant Code Example

       01 SUBS PIC 9(5).
       01 INVENTORY-RECORD.
          05 Field-A PIC X OCCURS 10000 TIMES.
       ...
       PERFORM VARYING SUBS FROM 1 BY 1 UNTIL SUBS > 10000
         MOVE ITEM1 TO Field-A (SUBS)      *> Noncompliant
       END-PERFORM.

Compliant Solution

       01 SUBS PIC 9(5) COMP.
       01 INVENTORY-RECORD.
          05 Field-A PIC X OCCURS 10000 TIMES.
       ...
       PERFORM VARYING SUBS FROM 1 BY 1 UNTIL SUBS > 10000
         MOVE ITEM1 TO Field-A (SUBS)
       END-PERFORM.

or

       01 INVENTORY-RECORD.
          05 Field-A PIC X OCCURS 10000 TIMES INDEXED BY IDX1.
       ...
       PERFORM VARYING IDX1 FROM 1 BY 1 UNTIL IDX1 > 10000
         MOVE ITEM1 TO Field-A (IDX1)
       END-PERFORM.
cobol:COBOL.TypedefUsageCheck

The TYPEDEF keyword creates new user-defined data types. It should only be used in copybooks, which can be shared among programs, not in the programs themselves.

cobol:S1693

Programs that depend on a lot of different subprograms tend to aggregate too many responsibilities, and inevitably become harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor the program into several smaller programs which focus on well-defined topics.

cobol:SQL.SelectWithNoWhereClauseCheck

Although the WHERE condition is optional in a SELECT statement, for performance and security reasons, a WHERE clause should always be specified to prevent reading the whole table.

Noncompliant Code Example

SELECT * FROM db_persons INTO us_persons

Compliant Solution

SELECT * FROM db_persons INTO us_persons WHERE country IS 'US'

Exceptions

Not having a WHERE clause is acceptable in read-only cursors as results are generally sorted and it is possible to stop processing in the middle.

cobol:S1692

COBOL files containing a large number of paragraphs are by definition difficult to understand and therefore to maintain.

Exceptions

Paragraphs contained in copybooks are ignored when computing the total number of paragraphs in a program.

cobol:S1691

Programs that include a lot of copybooks tend to aggregate too many responsibilities and inevitably become harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor the program into smaller ones which focus on well-defined topics.

cobol:S3595

The binary algorithm used by SEARCH ALL is far more efficient for large tables than the one used by SEARCH. While it's not always possible to use SEARCH ALL, it should be the preferred algorithm.

This rule raises an issue when tables with more than the specified number of possible entries are searched using SEARCH.

Noncompliant Code Example

Using the default threshold of 500:

01  MY-TABLE.
05 MY-TAB-ELEM OCCURS 300000
     INDEXED BY MY-TAB-IND.
  10 MY-ATTR1                        PIC X(07).
  10 MY-ATTR2                        PIC X(07).
  10 MY-ATTR3                        PIC X(07).

01  MY-TAB2.
05 MY-TAB2-ELEM          OCCURS 300000
     ASCENDING MY-ATTR1  *> Key is defined. Why not use it?
     INDEXED BY MY-TAB-IND.
  10 MY-ATTR1                        PIC X(07).
  10 MY-ATTR2                        PIC X(07).
  10 MY-ATTR3                        PIC X(07).

01  MY-TAB-IND             PIC 9(08).


SEARCH MY-TAB-ELEM.  *> Noncompliant; define a key & use binary search
       AT END...

SEARCH MY-TAB2-ELEM.  *> Noncompliant
       AT END...

Compliant Solution

01  MY-TABLE.
05 MY-TAB-ELEM OCCURS 300000
     ASCENDING MY-ATTR1
     INDEXED BY MY-TAB-IND.
  10 MY-ATTR1                        PIC X(07).
  10 MY-ATTR2                        PIC X(07).
  10 MY-ATTR3                        PIC X(07).

01  MY-TAB2.
05 MY-TAB2-ELEM          OCCURS 300000
     ASCENDING MY-ATTR1
     INDEXED BY MY-TAB-IND.
  10 MY-ATTR1                        PIC X(07).
  10 MY-ATTR2                        PIC X(07).
  10 MY-ATTR3                        PIC X(07).

01  MY-TAB-IND             PIC 9(08).


SEARCH ALL MY-TAB-ELEM.
       AT END...

SEARCH ALL MY-TAB2-ELEM.
       AT END...
cobol:S1738

The main motivation for this rule is to improve the readability of relevant SQL code. From one database optimiser to another, the performance of IN and OR clauses to specify a list of possible values for a column can be slightly different, but this difference is usually very minor. What is not minor is the difference in readability between the two styles, which is why an IN clause is preferred.

Noncompliant Code Example

SELECT * FROM PERSONS
WHERE AGE = 10 OR AGE = 13 OR AGE = 18 OR AGE < 5

Compliant Solution

SELECT * FROM PERSONS
WHERE AGE IN (10, 13, 18) OR AGE < 5
cobol:S1739

When the value of a LIKE clause starts with '%' or '_', indexes on the searched column are ignored, and a full table scan is performed instead.

Noncompliant Code Example

SELECT FIRST_NAME, LAST_NAME FROM PERSONS
WHERE LAST_NAME LIKE '%PONT'
cobol:S1737

According to SQL-92:

"X BETWEEN Y AND Z" is equivalent to "X>=Y AND X<=Z"

Even if the BETWEEN predicate is simply syntactic sugar, using it can improve the readability of a SQL WHERE clause, and is therefore preferred.

Noncompliant Code Example

SELECT * FROM PERSONS
WHERE AGE >=18 and AGE <=60

Compliant Solution

SELECT * FROM PERSONS
WHERE AGE BETWEEN 18 and 60
cobol:COBOL.ConditionComplexityCheck

The number of distinct data items used in a condition (IF, EVALUATE, ...) should not exceed a defined threshold.

Noncompliant Code Example

With the default default threshold of 3:

IF WS-FOO(1) = 1 OR *> 1st data item
WS-FOO(2) = 2 OR
WS-FOO(3) = 3 OR
WS-BAR = 4 OR *> 2nd data item
WS-BAZ = 5 OR *> 3rd data item
WS-QUX = 42 *> Noncompliant; 4th data item
END-IF.

Compliant Solution

IF WS-FOO(1) = 1 OR
WS-FOO(2) = 2 OR
WS-FOO(3) = 3 OR
WS-BAR = 4 OR
WS-BAZ = 42
END-IF.
cobol:S1735

Even though the ORDER BY clause supports using column numbers, doing so makes the code difficult to read and maintain. Therefore the use of column names is preferred.

Noncompliant Code Example

SELECT FIRST_NAME, LAST_NAME, REGION
FROM PERSONS
ORDER BY 2, 1

Compliant Solution

SELECT FIRST_NAME, LAST_NAME, REGION
FROM PERSONS
ORDER BY LAST_NAME, FIRST_NAME
cobol:COBOL.PerformThruSectionMandatoryCheck

Unless direct calls to paragraphs are forbidden, using PERFORM section1 is usually error prone. Indeed, in that case, when creating a new paragraph in the middle of an existing source code there is no easy way to know if an existing execution flow can go through this new paragraph.

cobol:COBOL.FileUnusedCheck

You should avoid keeping in programs files that are declared but never used. This is visual pollution and makes the program less readable.

cobol:S1732

Explicitly defining a cursor as read-only can improve performance by avoiding table locking. This allows other SQL requests to execute in parallel. Therefore when a cursor will only be used to read data, without modifying anything, the FOR READ ONLY clause or its synonyn, FOR FETCH ONLY, should be used.

Conversely when a cursor will modify data, that too should be specified using the FOR UPDATE clause.

In short, it's better to always explicitly define the purpose of the cursor with help of the FOR READ ONLY, FOR FETCH ONLY or FOR UPDATE clauses.

Noncompliant Code Example

EXEC SQL DECLARE CMAJ_0A CURSOR
  FOR SELECT C_BQ
    FROM       S1ORDCOU
    WHERE C_BQ = :TORD-C-BQ
END-EXEC

Compliant Solution

EXEC SQL DECLARE CMAJ_0A CURSOR
  FOR SELECT C_BQ
    FROM       S1ORDCOU
    WHERE C_BQ = :TORD-C-BQ
  FOR READ ONLY
END-EXEC
cobol:S4727

88-level variables, also known as "condition name" variables, represent possible values of the "conditional variables" they're tied to. An unused "condition name" variable is dead code. Such variables should be removed to increase the maintainability of the program.

Noncompliant Code Example

01 COLOR PIC X.
  88 COL-YELLOW VALUE 'Y'.
  88 COL-GREEN VALUE 'G'. *> Noncompliant; not used
  88 COL-RED VALUE 'R'.

* ...
IF COL-YELLOW
* ...
END-IF
IF COL-RED
* ...
END-IF

Compliant Solution

01 COLOR PIC X.
  88 COL-YELLOW VALUE 'Y'.
  88 COL-RED VALUE 'R'.

* ...
IF COL-YELLOW
* ...
END-IF
IF COL-RED
* ...
END-IF
cobol:S3515

Updating the value of a column that is part of a partitioning index could force the database to move a row from one partition to another. The move operation itself might be costly, but even worse without regularly updating the DB statistics, many updates like this might impact the performance of subsequent SQL requests that use the partitioning index.

Note This rule raises issues only when a database catalog is provided during the SonarQube analysis.

cobol:COBOL.RecursivePerformCheck

Most COBOL environments do not support recursive PERFORM calls, since they can cause unpredictable results. This rule raises an issue when recursive PERFORM calls are used.

Noncompliant Code Example

PARAGRAPH1.
  PERFORM PARAGRAPH2.

PARAGRAPH2.
  PERFORM PARAGRAPH3.

PARAGRAPH3.
  PERFORM PARAGRAPH1.

Compliant Solution

PARAGRAPH1.
  PERFORM PARAGRAPH2.

PARAGRAPH2.
  PERFORM PARAGRAPH3.

PARAGRAPH3.
  DISPLAY "THIS IS PARAGRAPH3".

See

  • MISRA C:2004, 16.2 - Functions shall not call themselves, either directly or indirectly.
  • MISRA C++:2008, 7-5-4 - Functions should not call themselves, either directly or indirectly.
  • MISRA C:2012, 17.2 - Functions shall not call themselves, either directly or indirectly
cobol:SQL.CursorDeclaredInsideProcedureDivisionCheck

It is a bad practice to declare a cursor inside a procedure division, so you should avoid it.

cobol:COBOL.ParagraphComplexityCheck

The cyclomatic complexity of a paragraph should not exceed a defined threshold. Complex code can perform poorly and will in any case be difficult to understand and therefore to maintain.

cobol:S1729

Using more than one OF clause to access a data item can quickly decrease the readability of the source code. Either some OF clauses are optional and should be removed, or there are too many intersections between several data structures and those intersections should be removed.

Noncompliant Code Example

01 EMPLOYEE.
  05 MOTHER-IN-LAW.
    10 NAME PIC X(20).
  05 FATHER-IN-LAW.
    10 NAME PIC X(20).
...
01 CUSTOMER.
  05 MOTHER-IN-LAW.
    10 NAME PIC X(20).
  05 FATHER-IN-LAW.
    10 NAME PIC X(20).
...

MOVE MY_VALUE TO NAME OF MOTHER-IN-LAW OF CUSTOMER
cobol:SQL.SelectStatementsNestedCheck

Having several levels of nested SQL SELECT statements makes the code difficult to read and should therefore be avoided.

Noncompliant Code Example

With an allowed nesting level of 2:

*> Non-Compliant
EXEC SQL
  SELECT * FROM my_table1 WHERE
    my_column1 IN
      (SELECT my_column2 FROM my_table2
        WHERE my_column3 IN
          (SELECT my_column4 FROM my_table3))
END-EXEC.

Compliant Solution

EXEC SQL
  SELECT * FROM my_table
END-EXEC.
cobol:S3592

88-level variables, also known as "condition name" variables, represent possible values of the "conditional variables" they're tied to. Because a condition name can be used to test the value of its conditional variable without any other contextual references to the conditional variable being tested, it makes the code easier to understand if the name of the 88-level variable references its conditional variable.

This rule raises an issue when the name of an 88-level variable does not start with the first characters of the name of its conditional variable.

Noncompliant Code Example

With the default minimum of 3:

01 COLOR PIC X.
  88 YELLOW VALUE 'Y'. *> Noncompliant
  88 GREEN VALUE 'G'. *> Noncompliant
  88 RED VALUE 'R'. *> Noncompliant

* ...
IF GREEN  *> What does this mean?
* ...
END-IF

Compliant Solution

01 COLOR PIC X.
  88 COL-YELLOW VALUE 'Y'.
  88 COL-GREEN VALUE 'G'.
  88 COL-RED VALUE 'R'.

* ...
IF COL-GREEN
* ...
END-IF
cobol:COBOL.ParagraphEmptyCheck

You should avoid leaving paragraphs that contain no statements as this makes the program less readable.

cobol:SQL.SelectStarUsageCheck

SELECT * should be avoided because it releases control of the returned columns and could therefore lead to errors and potentially to performance issues.

Noncompliant Code Example

SELECT *
       FROM persons
       INTO newyorkers
       WHERE city = 'NEW YORK'

Compliant Solution

SELECT firstname, lastname
       FROM persons
       INTO newyorkers
       WHERE city = 'NEW YORK'
cobol:COBOL.GotoTransferControlOutsideCurrentModuleCheck

GO TO should not be used to transfer control outside the current module, because any implied EXIT points will then be ignored. A module is either a section, a paragraph, or a set of paragraphs called with the PERFORM ... THRU ... statement.

Noncompliant Code Example

         PERFORM PARAGRAPH1 THRU PARAGRAPH3.     > code contained between PARAGRAPH1 and PARAGRAPH3 is now considered as a module
         EXIT PROGRAM.

        PARAGRAPH1.
         MOVE A TO B.
         IF SOMETHING
           GO TO PARAGRAPH3     >OK
         END-IF.
         IF SOMETHING-ELSE
           GO TO PARAGRAPH4     >NOK as we leave the module called with "PERFORM PARGRAPH1 THRU PARAGRAPH3" statement
         END-IF.

        PARAGRAPH2.
         MOVE A TO B.

        PARAGRAPH3.
         EXIT.

        PARAGRAPH4.
cobol:S1741

Since ANSI SQL-92, explicit joins using the JOIN keyword have been possible, and are preferred. Therefore table joins should be done with help of the one of the following clauses: JOIN, INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, and FULL OUTER JOIN. The old way to join tables is deprecated and should not be used anymore.

Noncompliant Code Example

SELECT *
FROM PARTS, PRODUCTS
WHERE PARTS.PROD = PRODUCTS.PROD

Compliant Solution

SELECT *
FROM PARTS
INNER JOIN PRODUCTS ON PARTS.PROD = PRODUCTS.PROD
cobol:S1742

To prevent portability issues !=, !> and !< operators should be replaced by the ANSI standard operators: <>, <= or >=.

Noncompliant Code Example

SELECT C1 FROM S1TESTMD WHERE BIRTHDATE != 2000

Compliant Solution

SELECT C1 FROM S1TESTMD WHERE BIRTHDATE <> 2000
cobol:SQL.DynamicSqlCheck

It is a bad practice to use Dynamic SQL. It differs from static embedded SQL in that part or all of the actual SQL commands may be stored in a host variable that is built on the fly during execution of the program. In the extreme case, the SQL commands are generated in their entirety by the application program at run time. While dynamic SQL is more flexible than static embedded SQL, it does require additional overhead and is much more difficult to understand and to maintain.

Moreover, dynamic SQL may expose the application to SQL injection vulnerabilities.

This rule raises an issue when PREPARE or EXECUTE IMMEDIATE is used.

Noncompliant Code Example

EXEC SQL PREPARE SEL INTO :SQLDA FROM :STMTBUF END-EXEC.

See

  • MITRE, CWE-89 - SQL Injection
  • OWASP Top 10 2017 Category A1 - Injection
  • SANS Top 25 - Insecure Interaction Between Components
cobol:S1069

Allowing an application to dynamically change the structure of a database at runtime is very dangerous because the application can become unstable under unexpected conditions. Best practices dictate that applications only manipulate data.

Noncompliant Code Example

EXEC SQL
  CREATE TABLE INVENTORY
                 (PARTNO         SMALLINT     NOT NULL,
                  DESCR          VARCHAR(24 ),
                  PRIMARY KEY(PARTNO))
END-EXEC.

EXEC SQL
  DROP TABLE EMPLOYEE RESTRICT
END-EXEC.

EXEC SQL
  ALTER TABLE EQUIPMENT
     DROP COLUMN LOCATION CASCADE
END-EXEC.

Exceptions

Creating global temporary tables, creating indexes on those tables, and then dropping those indices and tables is allowed.

EXEC SQL
   DECLARE GLOBAL TEMPORARY TABLE SESSION.TBT09SCO ...
END-EXEC.

EXEC SQL
   CREATE UNIQUE INDEX X1T09SCO ON SESSION.TBT09SCO ...
END-EXEC.

...
EXEC SQL
   DROP INDEX X1T09SCO
END-EXEC.

EXEC SQL
   DROP TABLE SESSION.TBT09SCO
END-EXEC.
cobol:S1862

A EVALUATE and a chain of IF/ELSE IF statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

Noncompliant Code Example

EVALUATE X
   WHEN 1
       ...
   WHEN 5
       ...
   WHEN 3
       ...
   WHEN 1     *> Noncompliant
       ...
END-EVALUATE.

IF X = 1
  ...
ELSE
  IF X = 2
    ...
  ELSE
    IF X = 1    *> Noncompliant
      ...
    END-IF
  END-IF
END-IF.

Compliant Solution

EVALUATE X
   WHEN 1
       ...
   WHEN 5
       ...
   WHEN 3
       ...
END-EVALUATE.

IF X = 1
  ...
ELSE
  IF X = 2
    ...
  ELSE
    IF X = 3
      ...
    END-IF
  END-IF
END-IF.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
cobol:S1740

Using a scalar function or an arithmetic expression in a WHERE condition can prevent the database from using indexes on the relevant column(s), and could therefore lead to performance issues.

Noncompliant Code Example

SELECT * FROM MY_TABE WHERE C2 = C3 + :HostVar1  -- Noncompliant

SELECT * FROM MY_TABLE WHERE YEAR(BIRTHDATE) > 2000  -- Noncompliant
cobol:S3004

A primary key uniquely identifies a row in a database table, and should be considered immutable. Primary key values may be used in foreign keys in other tables, as well as in external systems. Changing such a value, even with the best of motivations, is likely to wreak havoc on the system's data integrity and potentially across other systems as well.

Note That this rule raises issues only when a database catalog is provided during the SonarQube analysis.

Noncompliant Code Example

UPDATE USERS
  SET USER_ID = :new-id, USER_NAME = :new-name  *> Noncompliant
  WHERE USER_ID = :input
cobol:S3643

The use of LIKE in a SQL query without one or more wildcards in the sought value is suspicious. A maintainer can suppose that either = was meant instead, or that the wildcard was unintentionally omitted.

Note that in some cases using LIKE without a wildcard may return different results than the use of =. Thus, the use of LIKE without a wildcard may be intentional. However, it is highly likely to confuse maintainers who either are unaware of this fact, or don't understand that such circumstances apply to the query in question.

Noncompliant Code Example

SELECT name
FROM product
WHERE name LIKE 'choc'

Compliant Solution

SELECT name
FROM product
WHERE name LIKE 'choc%'

or

SELECT name
FROM product
WHERE name = 'choc'
cobol:COBOL.CopyInsideProcedureDivisionCheck

Changing procedural copybooks may potentially cause issues where many programs are pulled into a package for recompile and then a potential for bind issues during turnover. Having to edit procedural copybooks frequently causes delays in program maintenance as developers have to wait for another developer to complete their work. This also causes double work when programs get out of sync and a recent change could potentially be lost in a program.

Noncompliant Code Example

PROCEDURE DIVISION.
  ...
  COPY MY_COPYBOOK.        <- Noncompliant
  ...

Compliant Solution

PROCEDURE DIVISION.
  ...
  CALL MY_MACRO.        <- Compliant
  ...
cobol:S1066

Merging collapsible IF statements increases the code's readability.

Noncompliant Code Example

       IF CONDITION1 THEN
         IF CONDITION2 THEN
           ...
         END-IF
       END-IF.

Compliant Solution

       IF CONDITION1 AND CONDITION2 THEN
         ...
       END-IF.
cobol:COBOL.ProgramLinesOfCodeCheck

Because they are very difficult to maintain, programs with too many lines of code should be split into smaller programs or subprograms.

cobol:S1461

An unused section is never called explicitly with help of the GO TO or PERFORM statements.

There can be only two reasons for having such a section:

  • It is really unused and should be removed
  • It is only used as a kind of comment to clearly delimit a block of code, which is a bad practice

The remediation action should be:

  • Replace the section by a comment line
  • Refactor the code to make an explicit call to this section instead of letting the execution flow going through it implicitly
cobol:S1747

Level 77 identifies data items that are not subdivisions of other items, and that have no subdivisions. They are atomic by declaration. To make future subdivision possible, level 01 should be used instead of level 77.

Noncompliant Code Example

77 CAR            PIC 999.

Compliant Solution

01 CAR            PIC 999.
cobol:S1745

An INSERT statement that does not explicitly list the columns being inserted into, as well as the values being inserted, is dependent for correct functioning on the structure of the table not changing. Additionally, not having the explicit column list degrades the readability and understandability of the code. Therefore, INSERT statements should always contain an explicit column list.

Noncompliant Code Example

INSERT INTO PERSONS VALUES (1, 'DUPONT', 'Marcel')

Compliant Solution

INSERT INTO PERSONS (ID, LAST_NAME, FIRST_NAME)
VALUES (1, 'DUPONT', 'Marcel')
cobol:S3923

Having all branches in an EVALUATE or IF chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be an EVALUATE/IF chain at all.

Noncompliant Code Example

EVALUATE X *> Noncompliant
  WHEN 1
    PERFORM SECTION1
  WHEN OTHER
    PERFORM SECTION1
END-EVALUATE.

IF X = 1 THEN *> Noncompliant
  PERFORM SECTION1
ELSE
  PERFORM SECTION1
END-IF.

Exceptions

Note that this rule does not apply to IF chains without ELSE-s, or to EVALUATE-s without WHEN OTHER clauses.

IF X = 1 THEN *> //no issue, this could have been done on purpose to make the code more readable
  PERFORM SECTION1
ELSE-IF X = 2 THEN
  PERFORM SECTION1
END-IF.
cobol:COBOL.EvaluateWhenBlockWithConditionalLogicCheck

Having conditional logic within an EVALUATE ... WHEN statement often leads to large and difficult to read EVALUATE statements. In many cases the presence of conditional logic indicates that the code block within the WHEN clause should be split.

cobol:S3767

CAST(... AS CHAR/VARCHAR) can be a source of incompatibilities between database versions: the behavior of CAST may not be the same depending on the version of the database system. Such incompatibilities can cause unexpected output from applications that CAST decimal data to CHAR or VARCHAR, it's therefore best to avoid using CAST(... AS CHAR/VARCHAR).

Noncompliant Code Example

  DELETE product
  WHERE CAST(status_code AS CHAR(2)) = '42' -- Noncompliant
cobol:S3921

Moving a large string into a small field will result in data truncation with data lost from the right side of the string.

Noncompliant Code Example

01 ALPHA   PIC X(4).
*> ...

    MOVE "Now is the time" TO ALPHA *> Noncompliant. Becomes "Now "

Compliant Solution

01 ALPHA   PIC X(15).
*> ...

    MOVE "Now is the time" TO ALPHA

See

See Also

  • S1967 - for truncation of numeric values
cobol:SQL.CursorDeclaredInsideLoopCheck

You should avoid declaring a cursor inside a PERFORM statement because doing so could impact performance. It could also lead to unexpected behavior if the opening and closing of the cursor are not defined in the same loop.

Noncompliant Code Example

  PERFORM UNTIL (NOT DA-OK) OR (Y00CIA-CD-RET-PGM = ZERO)
    EXEC SQL  DECLARE C2 CURSOR FOR
      SELECT DEPTNO, DEPTNAME, MGRNO FROM DEPARTMENT WHERE ADMRDEPT = 'A00'
    END-EXEC
  END-PERFORM.
cobol:S1619

The storage of a packed numeric field is most efficient when you code an odd number of digits in the PICTURE description, so that the leftmost byte is fully used. Packed-decimal items are handled as fixed-point numbers for arithmetic purposes.

Noncompliant Code Example

 01 VAL PIC 9(6) COMP-3.

Compliant Solution

 01 VAL PIC 9(5) COMP-3.
cobol:S4054

Using FETCH FIRST n ROWS ONLY in a SELECT without ordering the results from which the "n first" results are chosen will return a seemingly random set of rows, and is surely a mistake.

Noncompliant Code Example

SELECT fname, lname, city
  FROM people
  WHERE city IS NOT NULL
  FETCH FIRST 10 ROWS ONLY; -- Noncompliant selects 10 random rows

Compliant Solution

SELECT fname, lname, city
  FROM people
  WHERE city IS NOT NULL
  ORDER BY birthdate DESC
  FETCH FIRST 10 ROWS ONLY;
cobol:S3482

While it is possible to manually set a primary key value, doing so almost guarantees a key clash at some point. Instead, primary key values should be set by (in descending order of desirability):

  • automatic generation by the database via a column definition such as PROD_ID INT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1, NO CACHE)
  • the Generate_Unique() function
  • a value pulled directly from a sequence, like so: nextval for SEQ_PRODUCT

This rule raises an issue when an INSERT statement assigns values to identity columns that are configured to always generate their values.

Note That this rule raises issues only when a database catalog is provided during the SonarQube analysis.

Noncompliant Code Example

CREATE table my_table (
     column_a integer GENERATED ALWAYS AS IDENTITY primary key not null,
     column_b varchar(50)
);

INSERT into my_table (column_a, column_b)
VALUES (1, 'Hello World');  -- Noncompliant
cobol:COBOL.CommentedOutCodeCheck

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
cobol:S3483

There can't be any good reason to do a full table scan on large database tables due to the cost of such operation and the scalability issue that might raise. This rule raises an issue when a SELECT statement doesn't use at least one indexed column in its WHERE clause.

Note That this rule raises issues only when a database catalog is provided during the SonarQube analysis.

Noncompliant Code Example

SELECT * FROM USERS WHERE NAME = :name  -- non compliant when NAME column is not indexed

Exceptions

This rule ignores SELECT statements not having any WHERE clauses; they are covered by other rules: S1590, SQL.SelectWithNoWhereClauseCheck

cobol:COBOL.OnStatementUsageCheck

OS/VS COBOL accepted the ON statement, but IBM Enterprise COBOL does not accept it anymore. The ON statement allows the selective execution of statements it contains. Similar functions are provided in Enterprise COBOL by EVALUATE and IF

Noncompliant Code Example

       IDENTIFICATION DIVISION.
       PROGRAM-ID. foo.

       PROCEDURE DIVISION.
      * Non-Compliant
         ON 1
           DISPLAY 'First time'
         ELSE
           DISPLAY 'Other times'.
       END PROGRAM foo.
cobol:S3481

Since databases don't offer "Are you sure?" dialogs, it's best to be very certain of what you're changing before you do it. UPDATE and DELETE statements that don't precisely limit their effects to single rows risk changing more than was intended. That's why they should be reviewed carefully.

This rule raises an issue when an UPDATE or DELETE statement's WHERE clause does not use precisely either a unique index or all parts of the table's primary key. That includes both cases where they are omitted in whole or in part, and when they are used but could still describe multiple rows. E.G. WHERE AGE = 34, and WHERE TABLE_ID > 0 AND TABLE_ID < 40.

Note That this rule raises issues only when a database catalog is provided during the SonarQube analysis.

Noncompliant Code Example

CREATE table my_table (
     compound_a integer not null,
     compound_b integer not null,
     column_c varchar(50),
     primary key (compound_a, compound_b)
);

DELETE FROM my_table
WHERE compound_b=4;  -- Noncompliant

Exceptions

Statements using a cursor and WHERE CURRENT OF are ignored.

cobol:SQL.UnionUsageCheck

Using UNION in SQL SELECT statements should be avoided because it makes queries complex. Complex queries are generally not performant and are difficult to understand and therefore to maintain.

cobol:COBOL.ExitProgramUsageCheck

There should not be any statements after EXIT PROGRAM. Such statements cannot be reached, and are therefore dead code. Dead code makes a program more complex and therefore more difficult to maintain.

Noncompliant Code Example

  PROCEDURE DIVISION.
    PARAGRAPH1.
      MOVE A TO B.
      EXIT PROGRAM.   >NOK as the following "MOVE B TO C" statement will never be called
      MOVE B TO C.

Compliant Solution

  PROCEDURE DIVISION.
    PARAGRAPH1.
      MOVE A TO B.
      EXIT PROGRAM.
cobol:S3573

Because statically-called programs must be relinked before they reflect changes in the code, it makes sense to prefer dynamic calls instead. Further, since statically-called programs are included in the caller's load module, those modules could require more main storage than if the calls were dynamic, and the called programs could reside in memory multiple times - one for each caller.

While static calls are faster, their other disadvantages make dynamic calls the preferred method. Thus, this rule raises an issue when the program to CALL is hard-coded, rather than specified in a variable.

Noncompliant Code Example

CALL 'MYPRGM01' USING PARAM1.  *> Noncompliant

Compliant Solution

77 PRGM-NAME      PIC X(8) VALUE 'MYPRGM01'.
[...]
CALL PRGM-NAME USING PARAM1.
cobol:COBOL.UnusedDataItem

An unused data item block is dead code. Such data item blocks should be removed to increase the maintainability of the program.

Noncompliant Code Example

IDENTIFICATION DIVISION.
PROGRAM-ID. foo.

DATA DIVISION.
WORKING-STORAGE SECTION.
  01 PERSON PIC X(42).        *> Compliant as sub data item FIRST_NAME is used
    02 FIRST_NAME PIC X(21).
    02 LAST_NAME PIC X(21).

  01 ADDR PIC X(100).   *> Noncompliant as no data item in this block is used
    02 STREET PIC X(50).
    02 TOWN PIC X(50).

PROCEDURE DIVISION.

MOVE "John" TO FIRST_NAME.

Exceptions

FILLER top level data items and top level data items which have sub data items with a VALUE clause are not checked by this rule.

cobol:S1713

PERFORM paragraph1 is preferred over PERFORM paragraph1 THRU paragraph2 because it adheres more closely to the structured programming precepts of having a single entry point and a single exit point. Additionally, mixing the two approaches can lead to errors.

cobol:S3618

Any insert which omits a value for a NOT NULL column in a database table will be automatically rejected by the database unless a default value has been specified for the column.

Note that this rule raises issues only when a database catalog is provided during the SonarQube analysis.

Noncompliant Code Example

With the table MY_TABLE having a NOT NULL column N2 without default value and a NOT NULL column N3 with default value:

EXEC SQL
  INSERT INTO MY_TABLE  *> Noncompliant; N2 value omitted
  (
    N1
  )
  VALUES
  (
    :ITQ1-NUMBER,
  )
END-EXEC.

Compliant Solution

EXEC SQL
  INSERT INTO MY_TABLE  *> Compliant even though N3 value not supplied
  (
    N1,
    N2
  )
  VALUES
  (
    :ITQ1-NUMBER,
    :ITQ2-NUMBER,
  )
END-EXEC.
cobol:S2527

In a Zen-like manner, "NULL" is never equal to anything, even itself. Therefore comparisons using equality operators will always return False, even when the value actually IS NULL.

For that reason, comparison operators should never be used to make comparisons with NULL; IS NULL and IS NOT NULL should be used instead. This extends as well to empty string (""), which is equivalent to NULL for some database engines.

Noncompliant Code Example

UPDATE books
SET title = 'unknown'
WHERE title = NULL -- Noncompliant

Compliant Solution

UPDATE books
SET title = 'unknown'
WHERE title IS NULL
cobol:COBOL.ProgramIdAndFileNameCheck

The PROGRAM-ID declaration at the top of a program must exactly match the filename of the program. If these do not match, functions like CANCEL may not be able to cancel the program, leaving it resident in memory. Debugging can also be affected because program breakpoints may not match the program name.

cobol:S3613

There's no point in selecting columns in a cursor that aren't actually referenced in the relevant FETCH statement. Instead, either pare down the cursor to select only what you actually need, or FETCH the other columns.

Noncompliant Code Example

      EXEC SQL
        DECLARE C-SQL-CURSOR CURSOR
          SELECT COLUMN1
                ,COLUMN2  -- Not fetched
                ,COLUMN3  -- Not fetched
            FROM TBLWTABLE
          WITH UR
      END-EXEC.

      …

      EXEC SQL
        FETCH C-SQL-CURSOR  -- Noncompliant
        INTO  :H-COLUMN1
      END-EXEC

Compliant Solution

      EXEC SQL
        DECLARE C-SQL-CURSOR CURSOR
          SELECT COLUMN1
                ,COLUMN2
                ,COLUMN3
            FROM TBLWTABLE
          WITH UR
      END-EXEC.

      …

      EXEC SQL
        FETCH C-SQL-CURSOR
        INTO  :H-COLUMN1, :H-COLUMN2, :H-COLUMN3
      END-EXEC

or

      EXEC SQL
        DECLARE C-SQL-CURSOR CURSOR
          SELECT COLUMN1
            FROM TBLWTABLE
          WITH UR
      END-EXEC.

      …

      EXEC SQL
        FETCH C-SQL-CURSOR
        INTO  :H-COLUMN1
      END-EXEC
cobol:COBOL.PerformThruParagraphOrderCheck

If the second procedure of a PERFORM THRU is not defined after the first one, the source code is semantically incorrect and the program doesn't behave as expected.

Noncompliant Code Example

  PERFORM SECOND-P THRU FIRST-P.
  ...

 FIRST-P.
   ...

 SECOND-P.
   ...

Compliant Solution

  PERFORM FIRST-P THRU SECOND-P.
  ...

 FIRST-P.
   ...

 SECOND-P.
   ...
cobol:S3614

The number of columns in a FETCH statement should match the number actually selected in the relevant cursor. Use more columns in the FETCH than the cursor, and you've got a data problem, because the variables you expect to be updated by the cursor are never actually touched, and neither are their null indicators. Instead, they retain whatever value they had before the fetch. Meaning you're operating with bad data.

Noncompliant Code Example

      EXEC SQL
        DECLARE C-SQL-CURSOR CURSOR
          SELECT COLUMN1
                ,COLUMN2
                ,COLUMN3
            FROM TBLWTABLE
          WITH UR
      END-EXEC.

      …

      EXEC SQL
        FETCH C-SQL-CURSOR
        INTO  :H-COLUMN1 :H-COLUMN1-IND  -- Noncompliant
             ,:H-COLUMN2 :H-COLUMN2-IND
             ,:H-COLUMN3 :H-COLUMN3-IND
             ,:H-COLUMN4 :H-COLUMN4-IND  -- Not selected
             ,:H-COLUMN5 :H-COLUMN5-IND  -- Not selected

Compliant Solution

      EXEC SQL
        DECLARE C-SQL-CURSOR CURSOR
          SELECT COLUMN1
                ,COLUMN2
                ,COLUMN3
                ,COLUMN4
                ,COLUMN5
            FROM TBLWTABLE
          WITH UR
      END-EXEC.

      …

      EXEC SQL
        FETCH C-SQL-CURSOR
        INTO  :H-COLUMN1 :H-COLUMN1-IND
             ,:H-COLUMN2 :H-COLUMN2-IND
             ,:H-COLUMN3 :H-COLUMN3-IND
             ,:H-COLUMN4 :H-COLUMN4-IND
             ,:H-COLUMN5 :H-COLUMN5-IND

or

      EXEC SQL
        DECLARE C-SQL-CURSOR CURSOR
          SELECT COLUMN1
                ,COLUMN2
                ,COLUMN3
            FROM TBLWTABLE
          WITH UR
      END-EXEC.

      …

      EXEC SQL
        FETCH C-SQL-CURSOR
        INTO  :H-COLUMN1 :H-COLUMN1-IND
             ,:H-COLUMN2 :H-COLUMN2-IND
             ,:H-COLUMN3 :H-COLUMN3-IND
cobol:COBOL.ParagraphNamingCheck

Shared coding conventions allow teams to collaborate efficiently. This rule checks that paragraph names match a provided regular expression.

Noncompliant Code Example

With a regular expression of [A-Z-]+:

 PROCEDURE DIVISION.

    Do_The_Thing.           *> Noncompliant

Compliant Solution

 PROCEDURE DIVISION.

    DO-THE-THING           *> Noncompliant
cobol:COBOL.StopRunUsageCheck

Any statement after a STOP RUN or GOBACK is unreachable and therefore dead code which should be removed.

Noncompliant Code Example

PARAGRAPH1.
  MOVE A TO B.
  STOP RUN.
  MOVE B TO C.

or

PARAGRAPH1.
  MOVE A TO B.
  GOBACK.
  MOVE B TO C.

Compliant Solution

PARAGRAPH1.
  MOVE A TO B.
  MOVE B TO C.
  STOP RUN.

or

PARAGRAPH1.
  MOVE A TO B.
  MOVE B TO C.
  GOBACK.
cobol:SQL.CursorDeclaredWithNoOrderByClauseCheck

When performing cursor processing, the ORDER BY clause not only helps to process the cursor, but it also it insures reproducibility at runtime.

cobol:COBOL.FileStatusUsageCheck

When a FILE STATUS is declared on a file, it should be tested immediately after IO operations.

Noncompliant Code Example

       IDENTIFICATION DIVISION.
       PROGRAM-ID. foo.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
         SELECT TEST-FILE
           ASSIGN TO 'foobar.txt'
           ORGANIZATION IS SEQUENTIAL
           FILE STATUS WS-TEST-FILE-STATUS.

       DATA DIVISION.
       FILE SECTION.
       FD TEST-FILE
         LABEL RECORDS ARE STANDARD.
         01 TEST-RECORD.
         05 USERNAME PIC XX.

       WORKING-STORAGE SECTION.
         01 WS-TEST-FILE-STATUS PIC X(42).

       PROCEDURE DIVISION.

      * Non-Compliant, TEST-FILE has a FILE STATUS variable which must be used
        OPEN INPUT TEST-FILE.

       END PROGRAM foo.

Compliant Solution

       IDENTIFICATION DIVISION.
       PROGRAM-ID. foo.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
         SELECT TEST-FILE
           ASSIGN TO 'foobar.txt'
           ORGANIZATION IS SEQUENTIAL
           FILE STATUS WS-TEST-FILE-STATUS.

       DATA DIVISION.
       FILE SECTION.
       FD TEST-FILE
         LABEL RECORDS ARE STANDARD.
         01 TEST-RECORD.
         05 USERNAME PIC XX.

       WORKING-STORAGE SECTION.
         01 WS-TEST-FILE-STATUS PIC X(42).

       PROCEDURE DIVISION.

      * Compliant, errors of the IO operation are propery handled
        OPEN INPUT TEST-FILE.
        IF WS-TEST-FILE-STATUS <> "00" THEN
          DISPLAY "Error while opening foobar.txt as input.".

       END PROGRAM foo.
cobol:COBOL.RedefineUsageCheck

The use of the REDEFINES clause introduces type safety and portability risks, and as such its usage should be avoided where possible.

Redefines have traditionally been used to solve 2 types of problems:

  1. Redefines are sometimes used to conserve memory or disk space by compacting many different data types into the same physical data block. However, these days memory and disk size limitations are no longer key concerns, and the priority of this type of optimisation has declined significantly. Where space optimisation is still important, normalisation of data schemas should be considered instead.
  2. Redefines are sometimes used as a quick way of reinterpreting data. A good example would be a date which can be interpretted as a single string, or separate day-month-year components. In high-performance areas this will give the fastest reformatting, though where performance is not a concern, a more explicit function gives better long-term flexibility. For instance, if a future change required one of the elements to become variable length rather than fixed length, the redefine approach would not be able to accomodate the change
cobol:COBOL.SqlUsageCheck

Whatever is the reason like an abstraction layer over database, some organizations forbid using SQL inside COBOL source code. This rule raises an issue for each use of SQL.

cobol:S1685

Debug statements (ones with 'D' or 'd' in the indicator area) should not be executed in production, but the WITH DEBUGGING MODE clause activates all debug lines, which could expose sensitive information to attackers. Therefore the WITH DEBUGGING MODE clause should be removed.

Noncompliant Code Example

SOURCE-COMPUTER. IBM-370 WITH DEBUGGING MODE.

Compliant Solution

SOURCE-COMPUTER. IBM-370.

See

  • MITRE, CWE-489 - Leftover Debug Code
  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
cobol:S1686

Defining a subprogram to be called at runtime is possible but ill-advised. This extremely powerful feature can quite easily be misused, and even when used correctly, it highly increases the overall complexity of the program, and makes it impossible before runtime to know exactly what will be executed. Therefore defining the subprogram to be called at runtime is a feature that should be avoided.

Noncompliant Code Example

MOVE SOMETHING TO MY_SUBPROG.
...
CALL MY_SUBPROG.

Compliant Solution

01 MY_SUBPROG PIC X(10) VALUE "SUB123".
....
CALL MY_SUBPROG.
cobol:COBOL.NextSentenceUsageCheck

You should avoid using the NEXT SENTENCE statement because it breaks the process execution flow. Further, it maintainers may not understand where control flow picks up after NEXT SENTENCE. CONTINUE should be used instead.

cobol:S3620

There's no point in including the default value of a column in an insert statement. It simply clutters the code to no additional benefit.

Note that this rule raises issues only when a database catalog is provided during the SonarQube analysis.

Noncompliant Code Example

With the table PRODUCT having a column INV_COUNT with default 0:

EXEC SQL
  INSERT INTO PRODUCT
  (
    NAME,
    INV_COUNT  -- Noncompliant
  )
  VALUES
  (
    :PROD-NAME,
    0  -- this is the default value
  )
END-EXEC

Compliant Solution

EXEC SQL
  INSERT INTO PRODUCT
  (
    NAME
  )
  VALUES
  (
    :PROD-NAME
  )
END-EXEC
cobol:COBOL.DisplayStatementUsageCheck

The DISPLAY statement outputs data to standard out or some other destination and could reveal sensitive information. Therefore, it should be avoided.

Noncompliant Code Example

DISPLAY "hello world"  *> Noncompliant

See

  • MITRE, CWE-489 - Leftover Debug Code
  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
cobol:S3621

When a SELECT returns null from a nullable column, the relevant host variable isn't updated; it simply retains its previous value. The only way you'll ever know the column value was null is to check the relevant null indicator included in the SELECT for a negative (null) value.

This rule raises an issue when a SELECT omits a null indicator for a nullable column.

Note that this rule raises issues only when a database catalog is provided during the SonarQube analysis.

Noncompliant Code Example

With the table PRODUCT having a nullable column NAME:

EXEC SQL
  SELECT
    PROD_ID,
    NAME
  INTO
    :P-ID,
    :P-NAME                 -- Noncompliant; No null indicator
  FROM PRODUCT
END-EXEC

Compliant Solution

EXEC SQL
  SELECT
    PROD_ID,
    NAME
  INTO
    :P-ID,
    :P-NAME :P-NAME-NULL  -- Compliant
  FROM PRODUCT
END-EXEC
cobol:SQL.LikeUsageCheck

Using the LIKE operator in SQL WHERE conditions can highly impact the performance of the request. The use of this operator should be strongly indicated.

Noncompliant Code Example

SELECT *
       FROM doktl
       INTO TABLE text_tab
       WHERE doktext LIKE srch_str.
cobol:S1683

Copybooks should be used only to share data definitions or logic. The following keywords relate to the nature or structure of a COBOL program, and should be defined directly in the source code of the COBOL program:

  • IDENTIFICATION DIVISION.
  • PROGRAM-ID xxxxxxxx.
  • AUTHOR. yyyyyyyyyyy.
  • INSTALLATION. zzzzzz.
  • DATE-WRITTEN. zzzzzz.
  • DATE-COMPILED. zzzzzz.
  • ENVIRONNEMENT DIVISION.
  • CONFIGURATION SECTION.
  • SOURCE-COMPUTER. xxxxxx.
  • OBJECT-COMPUTER. xxxxxx.
  • SPECIAL-NAMES. DECIMAL-POINT IS COMMA.
  • I-O CONTROL.
  • FILE-CONTROL.
  • SELECT …
  • DATA DIVISION.
  • FILE SECTION.
  • WORKING-STORAGE SECTION.
  • SCREEN.
  • REPORT.
  • INPUT-OUTPUT SECTION.
  • LINKAGE SECTION.
  • PROCEDURE DIVISION.

Noncompliant Code Example

LINKAGE SECTION.
COPY CSCEMOD1.
MOVE A TO B

Compliant Solution

LINKAGE SECTION.
COPY CSCEMOD1.
PROCEDURE DIVISION
COPY CSCEMOD2.
MOVE A TO B
cobol:COBOL.HeaderCheck

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

 *
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
cobol:S1682

The use of an array structure is useless when the array only has one element. Using an array structure anyway can impact performance and decrease the readability of the source code.

Noncompliant Code Example

03 WS-LIBELLE OCCURS 1.

Compliant Solution

03 WS-LIBELLE.
cobol:COBOL.ProgramNamingCheck

Shared coding conventions allow teams to collaborate effectively. For that reason, file names should conform to a defined standard. This rule raises an issue when the names of analyzed files don't match the provided regular expression.

See

cobol:S1728

Shared coding conventions allow teams to collaborate efficiently. For maximum readability, this rule checks that the levels, names and PICTURE clauses for all items of the same level and which are subordinate to the same item start in the same column.

Noncompliant Code Example

01  ZONE1.
    03  ZONE2  PIC X(10).
    03   ZONE3 PIC X(10).    *> Noncompliant; name out of line
     03 ZONE4  PIC X(10).    *> Noncompliant; level out of line
    03  ZONE5   PIC X(10).   *> Noncompliant; PIC out of line

Compliant Solution

01  ZONE1.
    03 ZONE2  PIC X(10).
    03 ZONE3  PIC X(10).
    03 ZONE4  PIC X(10).
    03 ZONE5  PIC X(10).
cobol:COBOL.IfStatementNestedUsageCheck

Nesting too many control flow statements (such as IF, PERFORM, EVALUATE...) should be avoided as it makes the code complex and therefore difficult to maintain.

Noncompliant Code Example

With a threshold (maximum allowed control flow statement nesting depth) of 3:

IF A = 1
    PERFORM
        MOVE A TO B
        PERFORM
            IF B = 1 *> Noncompliant
              MOVE "HI" TO S1
            END-IF
        END-PERFORM
    END-PERFORM
END-IF.
cobol:S1969

The name of each section should be unique within a program because section names cannot be qualified. Often code with duplicate section names will not compile. When it does, sections with duplicate names are ignored, meaning those sections are dead code. Even if dead code were not an anti-pattern on its own, having two sections with the same name will inevitably lead to maintenance mistakes. Therefore duplicative section names should be changed, or the extra sections should be removed.

cobol:S1726

Aligning common keywords in a series of statements makes the code easier to read. therefore, it is better to align the TO keywords in a series of successive MOVE statements.

Noncompliant Code Example

MOVE "Hi There" TO field
MOVE temp TO b
MOVE 123 TO item

Compliant Solution

MOVE "Hi There" TO field
MOVE temp       TO b
MOVE 123        TO item
cobol:S1967

Moving a large number into a small field will result in data truncation. Generally, numeric values are truncated from the left. However, in the case of floating point values, when the target field has too little precision to hold the value being moved to it, decimals will be truncated (not rounded!) from the right.

In any case, data loss is always the result when too-large values are moved to too-small fields.

Noncompliant Code Example

01 NUM-A   PIC 9(2)V9.
*> ...

    MOVE 88.89   TO NUM-A  *> Noncompliant. Becomes 88.8
    MOVE 178.7   TO NUM-A  *> Noncompliant. Becomes 78.7
    MOVE 999.99 TO NUM-A  *> Noncompliant. Truncated on both ends; becomes 99.9

Compliant Solution

01 NUM-A   PIC 9(3)V99.
*> ...

    MOVE 88.89   TO NUM-A
    MOVE 178.7   TO NUM-A
    MOVE 999.99 TO NUM-A

See

See Also

  • S3921 - for truncation of string values
cobol:S1725

Even though closing an open file isn't always mandatory (for instance when stopping the execution of a COBOL program with the STOP RUN statement), it's good coding practice to always explicitly close any open files. This rule checks that for every OPEN statement there is a corresponding CLOSE statement somewhere in the program.

Noncompliant Code Example

OPEN INPUT my-file

Compliant Solution

OPEN INPUT my-file
...
CLOSE my-file

See

cobol:S1966

An alphanumeric value should not be moved to a numeric field. Because alphanumeric values are stored differently than numeric values, simply moving the bits from one field to the other will yield strange results at best, and crashes at worst.

Instead, NUMVAL should be used to explicitly convert the alphanumeric value to a numeric one.

Noncompliant Code Example

01  MY-STR          PIC X(3) VALUE SPACES.
01  MY-NUM         PIC 9(3) VALUE ZEROES.
*> ...
    MOVE '1'         TO MY-STR
    MOVE MY-STR  TO MY-NUM  *> Noncompliant

Compliant Solution

01  MY-STR          PIC X(3) VALUE SPACES.
01  MY-NUM         PIC 9(3) VALUE ZEROES.
*> ...
    MOVE '1'         TO MY-STR
    COMPUTE MY-NUM = FUNCTION NUMVAL(MY-STR)

or

01  MY-STR         PIC X(3) VALUE SPACES.
01  MY-STR-RED     REDEFINES MY-STR PIC 9(3).
01  MY-NUM         PIC 9(3) VALUE ZEROES.
*> ...
IF MY-STR NUMERIC
   MOVE MY-STR-RED  TO MY-NUM
END-IF

See

cobol:S1723

Having two paragraphs with the same name in the same section or in no section at all is bad practice. At best, each copy contains the same code, and the redefinition is simply useless, duplicated code. At worst, the paragraphs contain different logic, potentially leading to confusion and unexpected results as a programmer who was aware of the first paragraph definition inadvertently invokes the second. For these reasons, paragraphs with duplicated names should be either removed or renamed.

Noncompliant Code Example

 LOAD-DATA.
     EXEC SQL
         INSERT INTO EMP (EMPNO, ENAME, DEPTNO)
             VALUES (:EMP-NUMBER, :EMP-NAME, :DEPT-NUMBER)
     END-EXEC.

 LOAD-DATA.
     IF EMP-NUMBER = ZERO
         MOVE FALSE TO VALID-DATA
         PERFORM GET-EMP-NUM UNTIL VALID-DATA = TRUE
     ELSE
         EXEC SQL DELETE FROM EMP
             WHERE EMPNO = :EMP-NUMBER
         END-EXEC
         ADD 1 TO DELETE-TOTAL.
     END-IF.

 LOAD-DATA.
     EXEC SQL
         INSERT INTO EMP (EMPNO, ENAME, DEPTNO)
             VALUES (:EMP-NUMBER, :EMP-NAME, :DEPT-NUMBER)
     END-EXEC.

Compliant Solution

 LOAD-DATA.
     EXEC SQL
         INSERT INTO EMP (EMPNO, ENAME, DEPTNO)
             VALUES (:EMP-NUMBER, :EMP-NAME, :DEPT-NUMBER)
     END-EXEC.

 CLEAR-EMP.
     IF EMP-NUMBER = ZERO
         MOVE FALSE TO VALID-DATA
         PERFORM GET-EMP-NUM UNTIL VALID-DATA = TRUE
     ELSE
         EXEC SQL DELETE FROM EMP
             WHERE EMPNO = :EMP-NUMBER
         END-EXEC
         ADD 1 TO DELETE-TOTAL.
     END-IF.
cobol:CICS.StatementWithoutRespOptionCheck

When calling a CICS command other than RETURN, ADDRESS, or ABEND, either RESP should be used to specify where the response code should be written, or NOHANDLE should be used to specify that abnormal conditions should be ignored.

Noncompliant Code Example

           EXEC CICS DELETEQ TS        *> Noncompliant
             QNAME(WS-TS5FTARF-NAME)
           END-EXEC.

Compliant Solution

           EXEC CICS DELETEQ TS
             QNAME(WS-TS5FTARF-NAME)
             RESP(WS-STATUS)
           END-EXEC.
cobol:COBOL.ModuleLinesOfCodeCheck

A module (set of paragraphs called with PERFORM ... THRU ... statement) with too many lines of code should be split to smaller modules as they are very difficult to maintain.

cobol:S3625

If a SQL TABLE is declared but not used in the program, it can be considered dead code and should therefore be removed. This will improve maintainability because developers will not wonder what the variable is used for.

Noncompliant Code Example

EXEC SQL
 DECLARE DSN8B10.DEPT TABLE  -- Noncompliant
   ( ...  )
END-EXEC.
cobol:COBOL.CallParameterInitializationCheck

To prevent any unexpected behavior, data items must be initialized before being used by a CALL statement. A data item is considered to be initialized in the three following cases :

  • One of its parents has been initialized
  • It has been defined in the LINKAGE-SECTION
  • The MOVE SPACE[S] TO ... and then the INITIALIZE statements have been sequentially executed on this data item. Both statements are required in that order because the INITIALIZE statement doesn't initialize FILLERs and non-named fields.

Be aware that activating this rule will impact the overall performance of the analysis.

Deprecated

This rule is deprecated, and will eventually be removed.

cobol:COBOL.NoteStatementUsageCheck

OS/VS COBOL accepted the NOTE statement, but IBM Enterprise COBOL does not. Therefore all NOTE statements should be replaced by standard comment lines.

Noncompliant Code Example

       IDENTIFICATION DIVISION.
       PROGRAM-ID. foo.

       PROCEDURE DIVISION.
      * Non-Compliant
         NOTE This is a comment.

      * This is a compliant comment.
       END PROGRAM foo.

Compliant Solution

       IDENTIFICATION DIVISION.
       PROGRAM-ID. foo.

       PROCEDURE DIVISION.
      * Compliant
      * This is a comment.
       END PROGRAM foo.
cobol:COBOL.CorrespondingClauseUsageCheck

Using the CORRESPONDING option in MOVE, ADD, and SUBTRACT statements may seem like a good way of sparing source code because this single statement will represent several actual statements. However, it can lead to unexpected behavior due to the fact that fields might not be named the same, or might be named the same but not have the same data type.

It is therefore recommended to explicitly name the fields when using ADD, SUBTRACT, and MOVE statements.

cobol:COBOL.DataValueClauseLinkageSectionCheck

Using a data value clause in the LINKAGE SECTION can lead to unexpected behavior at runtime.

Noncompliant Code Example

LINKAGE SECTION.

01 CAR-ID PIC X(20) VALUE IS "VOLVO".   *> Noncompliant

01  EMP-TYPE     PIC X.
   88   FULL-TIME-EMPLOYEE VALUE "F".   *> Compliant; this is a condition name
   88   PART-TIME-EMPLOYEE VALUE "P".

01 TRAIN-ID PIC X(20)
cobol:COBOL.OpenStatementInLoopUsageCheck

Using the OPEN file statement is costly, and therefore be avoided inside loops. Instead, the file can be saved into a buffer to increase performance.

Noncompliant Code Example

  PERFORM UNTIL (NOT DA-OK) OR (Y00CIA-CD-RET-PGM = ZERO)
     OPEN INPUT inventory-file
  END-PERFORM.
cobol:S3581

The comparison of numeric values of different formats is inefficient. For instance, comparing a COMP-3 with a COMP-4 causes a performance drag because conversions are required under the covers before the comparison.

This rule raises an issue when variables with different USAGE clauses, or different numbers of decimal places are compared.

Noncompliant Code Example

01 SUB1 PIC 9999 BINARY
01 WS-DISPLAY-1	PIC 9(12)
01 WS-PACKED-DEC PIC 9(12)V9(2) COMP-3
01 WS-BIN PIC S9999 COMP-4
01 WS-DISPLAY-2	PIC 9(4)

PERFORM VARYING SUB1 FROM WS-DISPLAY-1
BY WS-PACKED-DEC
UNTIL WS-BIN > WS-DISPLAY-2  *> Noncompliant
* ...
END-PERFORM

Compliant Solution

01 SUB1 PIC 9999 BINARY
01 WS-DISPLAY-1	PIC 9(12)
01 WS-PACKED-DEC PIC 9(12)V9(2) COMP-4
01 WS-BIN PIC S9999 COMP-4
01 WS-DISPLAY-2	PIC 9(4)

PERFORM VARYING SUB1 FROM WS-DISPLAY-1
BY WS-PACKED-DEC
UNTIL WS-BIN > WS-DISPLAY-2
* ...
END-PERFORM
cobol:S3582

88-level variables, also known as "condition name" variables, each have a name, a value or set of values, and a "parent" variable. Those parent variables are called "conditional variables".

Each 88-level variable can be seen as a short-cut conditional for testing the value of the parent: IF MY-88 will intrinsically return true if the parent value matches MY-88's value, and false if it does not.

Thus, testing a conditional variable against a literal value is redundant and confusing. Just use the 88-levels instead.

Noncompliant Code Example

01 COLOR PIC X
  88 YELLOW VALUE 'Y'
  88 GREEN VALUE 'G'
  88 RED VALUE 'R'
...
IF COLOR = 'G' *> Noncompliant
...
END-IF

Compliant Solution

01 COLOR PIC X
  88 YELLOW VALUE 'Y'
  88 GREEN VALUE 'G'
  88 RED VALUE 'R'
...
IF GREEN
...
END-IF
cobol:S3580

Performing math on variables that are declared - explicitly or implicitly - as DISPLAY or NATIONAL is much less efficient than on COMPUTATIONAL, COMP, or BINARY variables. That's because COMP variables, for instance, are defined for binary storage, which makes math on them more efficient. That's why values that are going to be used primarily for math should be declared with a math type. When math isn't a primary use, it may not make sense to change the declared type, but MOVEing the value to a COMP variable and performing the math on it instead would.

It is important to note however, that COMPUTATIONAL, COMP, and BINARY formats should be used with caution if the variable will be passed to other systems which may not use the same storage format.

Noncompliant Code Example

01 W-AMOUNT-VALUE PIC 9(17).
01 W-AMOUNT-DECIMAL PIC 9.

COMPUTE W-CONV-AMOUNT = W-AMOUNT-VALUE * 10 ** W-AMOUNT-DECIMAL  *> Noncompliant

Compliant Solution

01 W-AMOUNT-VALUE PIC 9(17) COMP-5.
01 W-AMOUNT-DECIMAL PIC 9 COMP-5.

COMPUTE W-CONV-AMOUNT = W-AMOUNT-VALUE * 10 ** W-AMOUNT-DECIMAL
common-cobol:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-cobol:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-cobol:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-cobol:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-cobol:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-cobol:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
css:S4655

!important within keyframes declarations is completely ignored in some browsers and therefore it should not be used to be consistent among all browsers.

Noncompliant Code Example

@keyframes kf {
  from { margin-top: 50px; }
  50%  { margin-top: 150px !important; } /* Noncompliant; ignored */
  to   { margin-top: 100px; }
}

Compliant Solution

@keyframes kf {
  from { margin-top: 50px; }
  50%  { margin-top: 150px; }
  to   { margin-top: 100px; }
}

See

javascript:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

function doSomething() {
  // TODO
}

See

javascript:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

function divide(numerator, denominator) {
  return numerator / denominator;              // FIXME denominator value might be  0
}

See

javascript:S1143

Using return, break, throw, and continue from a finally block overwrites similar statements from the suspended try and catch blocks.

This rule raises an issue when a jump statement (break, continue, return and throw) would force control flow to leave a finally block.

Noncompliant Code Example

function foo() {
    try {
        return 1; // We expect 1 to be returned
    } catch(err) {
        return 2; // Or 2 in cases of error
    } finally {
        return 3; // Noncompliant: 3 is returned before 1, or 2, which we did not expect
    }
}

Compliant Solution

function foo() {
    try {
        return 1; // We expect 1 to be returned
    } catch(err) {
        return 2; // Or 2 in cases of error
    }
}

See

javascript:S1854

A dead store happens when a local variable is assigned a value that is not read by any subsequent instruction. Calculating or retrieving a value only to then overwrite it or throw it away, could indicate a serious error in the code. Even if it's not an error, it is at best a waste of resources. Therefore all calculated values should be used.

Noncompliant Code Example

i = a + b; // Noncompliant; calculation result not used before value is overwritten
i = compute();

Compliant Solution

i = a + b;
i += compute();

Exceptions

This rule ignores initializations to -1, 0, 1, null, undefined, true, false, "", [] and {}.

This rule also ignores variables declared with object destructuring using rest syntax (used to exclude some properties from object):

let {a, b, ...rest} = obj; // 'a' and 'b' are ok
doSomething(rest);

let [x1, x2, x3] = arr;    // but 'x1' is noncompliant, as omitting syntax can be used: "let [, x2, x3] = arr;"
doSomething(x2, x3);

See

javascript:S2259

When a variable is assigned an undefined or null value, it has no properties. Trying to access properties of such a variable anyway results in a TypeError, causing abrupt termination of the script if the error is not caught in a catch block. But instead of catch-ing this condition, it is best to avoid it altogether.

Noncompliant Code Example

if (x === undefined) {
  console.log(x.length); // Noncompliant; TypeError will be thrown
}

See

javascript:S2737

A catch clause that only rethrows the caught exception has the same effect as omitting the catch altogether and letting it bubble up automatically, but with more code and the additional detriment of leaving maintainers scratching their heads.

Such clauses should either be eliminated or populated with the appropriate logic.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

try {
  doSomething();
} catch (ex) {  // Noncompliant
  throw ex;
}

Compliant Solution

try {
  doSomething();
} catch (ex) {
  console.err(ex);
  throw ex;
}

or

doSomething();
javascript:S3402

Use a + with two numbers and you'll get addition. But use it with a string and anything else, and you'll get concatenation. This could be confusing, especially if it's not obvious that one of the operands is a string. It is recommended to explicitly convert the non-string component to make it easier to understand to future maintainers.

This rule raises an issue when + is used with a string and a non-string.

Noncompliant Code Example

function foo() {
  let x = 5 + 8;  // okay
  let z = "8"
  return x + z;  // Noncompliant; yields string "138"
}

Compliant Solution

function foo() {
  let x = 5 + 8;
  let z = "8"
  return x + Number(z);
}
javascript:S3523

In addition to being obtuse from a syntax perspective, function constructors are also dangerous: their execution evaluates the constructor's string arguments similar to the way eval works, which could expose your program to random, unintended code which can be both slow and a security risk.

In general it is better to avoid it altogether, particularly when used to parse JSON data. You should use ECMAScript 5's built-in JSON functions or a dedicated library.

Noncompliant Code Example

var obj =  new Function("return " + data)();  // Noncompliant

Compliant Solution

var obj = JSON.parse(data);

Exceptions

Function calls where the argument is a string literal (e.g. (Function('return this'))()) are ignored.

See

  • OWASP Top 10 2017 Category A1 - Injection

Deprecated

This rule is deprecated; use S1523 instead.

javascript:TrailingComma

Most browsers parse and discard a meaningless, trailing comma. Unfortunately, that's not the case for Internet Explorer below version 9, which throws a meaningless error. Therefore trailing commas should be eliminated.

Noncompliant Code Example

var settings = {
    'foo'  : oof,
    'bar' : rab,    // Noncompliant - trailing comma
};

Compliant Solution

var settings = {
    'foo'  : oof,
    'bar' : rab
};
javascript:S4829

Reading Standard Input is security-sensitive. It has led in the past to the following vulnerabilities:

It is common for attackers to craft inputs enabling them to exploit software vulnerabilities. Thus any data read from the standard input (stdin) can be dangerous and should be validated.

This rule flags code that reads from the standard input.

Ask Yourself Whether

  • data read from the standard input is not sanitized before being used.

You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

Sanitize all data read from the standard input before using it.

Questionable Code Example

// The process object is a global that provides information about, and control over, the current Node.js process
// All uses of process.stdin are security-sensitive and should be reviewed

process.stdin.on('readable', () => {
	const chunk = process.stdin.read(); // Questionable
	if (chunk !== null) {
		dosomething(chunk);
	}
});

const readline = require('readline');
readline.createInterface({
	input: process.stdin // Questionable
}).on('line', (input) => {
	dosomething(input);
});

See:

javascript:S3984

Creating a new Error without actually throwing it is useless and is probably due to a mistake.

Noncompliant Code Example

if (x < 0) {
  new Error("x must be nonnegative");
}

Compliant Solution

if (x < 0) {
  throw new Error("x must be nonnegative");
}
plsql:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

plsql:S1940

It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.

Noncompliant Code Example

IF NOT x <> y THEN   -- Noncompliant
  -- ...
END IF;

Compliant Solution

IF x = y THEN
  -- ...
END IF;
plsql:S1703

%TYPE and %ROWTYPE seem like an easy way to make sure that a variable's type always matches the type of the relevant column in an existing table. If the column type changes, then the variable changes with it.

However, Oracle Forms compiled against a procedure using either of these two symbols won't get the benefit of that flexibility. Instead, at compile time, the relevant type is looked up from the underlying database and used in the form. If the column type changes later or the form is running against a database with different length semantics, attempting to use the form results in an "ORA-04062: Signature of package has been changed" error on the package in question. And the form needs to be recompiled on exactly the same database environment where it will run to avoid the error.

Note that %TYPE and %ROWTYPE can be used in a package's private procedures and functions, private package variables, and local variables without issue, but not in the package specification.

Noncompliant Code Example

CREATE OR REPLACE PACKAGE PACK IS
  TYPE mytype IS RECORD (
    var1 mytable.mycolumn%TYPE -- Noncompliant
  );

  FUNCTION MY_FUNC(param1 IN mytable.mycolumn%TYPE) RETURN VARCHAR2; -- Noncompliant

  FUNCTION MY_FUNC2(param1 IN mytable%ROWTYPE) RETURN VARCHAR2; -- Noncompliant

END;

Compliant Solution

CREATE OR REPLACE PACKAGE PACK IS
  TYPE mytype IS RECORD (
    var1 VARCHAR2(100) -- Compliant
  );

  FUNCTION MY_FUNC(param1 IN VARCHAR2) RETURN VARCHAR2; -- Compliant

  TYPE myrowtype IS RECORD (
    col1 NUMBER,
    col2 VARCHAR2(30)
  );
  FUNCTION MY_FUNC2(param1 IN myrowtype) RETURN VARCHAR2; -- Compliant

END;
plsql:S1751

A loop with at most one iteration is equivalent to the use of an IF statement to conditionally execute one piece of code. No developer expects to find such usage of a loop statement. If the initial intention of the author was really to conditionally execute one piece of code, an IF statement should be used in place.

At worst that was not the initial intention of the author and so the body of the loop should be fixed to use the nested RETURN, EXIT, RAISE or GOTO statements in a more appropriate way.

Noncompliant Code Example

LOOP
  counter := counter + 1;
  dbms_output.put_line(counter);
  EXIT;   -- Noncompliant
END LOOP;

Compliant Solution

LOOP
  counter := counter + 1;
  IF counter > 10 THEN
    EXIT;
  ELSE
    dbms_output.put_line(counter);
  END IF;
END LOOP;
plsql:S1871

Having two branches in an IF/ELSIF chain 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 chain they should be combined.

Noncompliant Code Example

IF param = 1 THEN
    sort_order := 0;
    column := 'LastName';
ELSIF param = 2 THEN
    sort_order := 0;
    column := 'LastName'; -- Noncompliant
ELSE
    sort_order := 1;
    column := 'FirstName';
END IF;

Exceptions

Branches in an IF/ELSIF chain with implementation that contains a single line of code are ignored.

IF param = 1 THEN
    sort_order := 0;
ELSIF param = 2 THEN
    sort_order := 1;
ELSE
    sort_order := 0; -- No issue, usually this is done on purpose to increase the readability
END IF;

But this exception does not apply to IF chains without ELSE-s when all branches have the same single line of code. In case of IF chains with ELSE-s rule S3923 raises a bug.

IF param = 1 THEN  -- Noncompliant, this might have been done on purpose but probably not
    sort_order := 0;
ELSIF param = 2 THEN
    sort_order := 0;
END IF;
plsql:S3651

WHERE clause conditions that reinforce or contradict the definitions of their columns are useless; they are always either unconditionally true or unconditionally false. For instance, there's no point in including AND column IS NOT NULL if the column is defined as non-null.

Noteworthy

This rule raises issues only when a Data Dictionary is provided during the analysis. See https://docs.sonarqube.org/display/PLUG/Data+Dictionary

Noncompliant Code Example

CREATE TABLE product
(id INT,
  name VARCHAR(6) NOT NULL,
  mfg_name VARCHAR(6),
  mfg_id INT
  ...

SELECT name, price
FROM product
WHERE name is not null -- Noncompliant; always true. This column is NOT NULL
  AND mfg_name = 'Too long name' -- Noncompliant; always false. This column can contain only 6 characters
plsql:LiteralsNonPrintableCharactersCheck

New lines and control characters can be injected in the source code by bad manipulations. Control characters aren't visible to maintainers, so whether or not they are actually wanted should be double-checked. Note that this rule can optionally also report violations on literals containing the tabulation character.

Noncompliant Code Example

SET SERVEROUTPUT ON

BEGIN
  /* Non-Compliant */ DBMS_OUTPUT.PUT_LINE('Hello
world!');

  DBMS_OUTPUT.PUT_LINE('Hello'); -- Compliant, this is preferred
  DBMS_OUTPUT.PUT_LINE('world!');
END;
/
plsql:S5047

The TO_NUMBER function is converting the value of BINARY_FLOAT, BINARY_DOUBLE, CHAR, VARCHAR2, NCHAR, or NVARCHAR2 datatype to a value of NUMBER datatype.

Without providing the format of the input, TO_NUMBER will consider the provided value is compliant with the default format. Relying on a default configuration is a source of error because it creates a dependency between the code and the configuration of the ORACLE server where this code is deployed.

The behaviour of the TO_NUMBER function will certainly not be the expected one if the configuration of the ORACLE server is changing.

Noncompliant Code Example

The following code with return 0 on an ORACLE server running with its default US configuration with p_string = "2,540"

IF ( TO_NUMBER(p_string) >= 0 and TO_NUMBER(p_string) <= TO_NUMBER('50.00') ) THEN
  RETURN 1;
ELSE
  RETURN 0;
END IF;

Compliant Solution

The following code with return 1 on an ORACLE server running with its default FR configuration with p_string = "2,540" because the comma will be interpreted as decimal separator instead of thousand separator.

IF ( TO_NUMBER(p_string, '99.99') >= 0 and TO_NUMBER(p_string, '99.99') <= TO_NUMBER('50.00','99.99') ) THEN
  RETURN 1;
ELSE
  RETURN 0;
END IF;
plsql:S2737

An EXCEPTION WHEN ... THEN clause that only rethrows the caught exception has the same effect as omitting the EXCEPTION clause altogether and letting it bubble up automatically, but with more code and the additional detriment of leaving maintainers scratching their heads.

Such clauses should either be eliminated or populated with the appropriate logic.

Noncompliant Code Example

BEGIN
  SELECT 1/0;
EXCEPTION
  WHEN ZERO_DIVIDE THEN
    RAISE; -- Noncompliant
  WHEN OTHERS THEN
    RAISE; -- Noncompliant
END;

Compliant Solution

BEGIN
  SELECT 1/0;
EXCEPTION
  WHEN ZERO_DIVIDE THEN  -- Compliant: handles 'division by zero' error
    -- do something to manage the division by zero
    COMMIT;

  WHEN OTHERS THEN
    ROLLBACK;
END;
plsql:MaskedExceptionCheck

When exceptions occur, it is usually a bad idea to simply ignore them. Instead, it is better to handle them properly, or at least to log them.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  d VARCHAR2(1);
BEGIN
  SELECT dummy INTO d FROM DUAL WHERE dummy = 'Y'; -- Will raise NO_DATA_FOUND
  DBMS_OUTPUT.PUT_LINE('d = ' || d);
EXCEPTION
  WHEN NO_DATA_FOUND THEN -- Noncompliant, did we really want to mask this exception?
    NULL;
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  d VARCHAR2(1);
BEGIN
  SELECT dummy INTO d FROM DUAL WHERE dummy = 'Y'; -- Will raise NO_DATA_FOUND
  DBMS_OUTPUT.PUT_LINE('d = ' || d);
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE('Error: No data found');
END;
/

See

  • MITRE, CWE-391 - Unchecked Error Condition
  • OWASP Top 10 2017 Category A10 - Insufficient Logging & Monitoring
plsql:S4196

Marking a parameter for output means that callers will expect its value to be updated with a result from the execution of the procedure. Failing to update the parameter before the procedure returns is surely an error.

Noncompliant Code Example

CREATE OR REPLACE PROCEDURE greet(
  name     IN  VARCHAR2,
  greeting OUT VARCHAR2) -- Noncompliant
AS
  message VARCHAR2(45);
BEGIN
  SELECT 'Hello ' || RTRIM(name) INTO message FROM DUAL;
END;

Compliant Solution

CREATE OR REPLACE PROCEDURE greet(
  name     IN  VARCHAR2,
  greeting OUT VARCHAR2)
AS
BEGIN
  SELECT 'Hello ' || RTRIM(name) INTO greeting FROM DUAL;
END;
plsql:S1854

A dead store happens when a local variable is assigned a value that is not read by any subsequent instruction. Calculating or retrieving a value only to then overwrite it or throw it away, could indicate a serious error in the code. Even if it's not an error, it is at best a waste of resources. Therefore all calculated values should be used.

Noncompliant Code Example

declare
  my_user VARCHAR2(30);
  my_date VARCHAR2(30);
begin
  my_user := user();
  my_date := sysdate(); -- Noncompliant, the value of my_date is never read
  dbms_output.put_line('User:' || my_user || ', date: ' || my_user);
end;

Compliant Solution

declare
  my_user VARCHAR2(30);
  my_date VARCHAR2(30);
begin
  my_user := user();
  my_date := sysdate();
  dbms_output.put_line('User:' || my_user || ', date: ' || my_date);
end;

See

plsql:S1172

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

Noncompliant Code Example

CREATE PROCEDURE say_hello(name VARCHAR2) AS -- Noncompliant; name is not used
BEGIN
  DBMS_OUTPUT.PUT_LINE('Hello World');
END;
/

Compliant Solution

CREATE PROCEDURE say_hello(name VARCHAR2) AS -- Compliant
BEGIN
  DBMS_OUTPUT.PUT_LINE('Hello ' || name);
END;
/

See

  • MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions.
  • MISRA C:2012, 2.7 - There should be no unused parameters in functions
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
plsql:S3641

A WHERE clause condition that uses NOT IN with a subquery will have unexpected results if that subquery returns NULL. On the other hand NOT EXISTS subqueries work reliably under the same conditions.

This rule raises an issue when NOT IN is used with a subquery where the selected column is nullable.

Noteworthy

This rule raises issues only when a Data Dictionary is provided during the analysis. See https://docs.sonarqube.org/display/PLUG/Data+Dictionary

Noncompliant Code Example

SELECT *
FROM my_table
WHERE my_column NOT IN (SELECT nullable_column FROM another_table)  -- Noncompliant; "nullable_column" may contain 'NULL' value and the whole SELECT query will return nothing

Compliant Solution

SELECT *
FROM my_table
WHERE NOT EXISTS (SELECT 1 FROM another_table WHERE nullable_column = my_table.my_column)
SELECT *
FROM my_table
WHERE my_column NOT IN (SELECT nullable_column FROM another_table WHERE nullable_column IS NOT NULL)
plsql:S4575

The TO_DATE and TO_TIMESTAMP functions are converting char of CHAR, VARCHAR2, NCHAR, or NVARCHAR2 datatype to respectively a value of DATE or TIMESTAMP datatype.

Without providing the format of the input char, TO_DATE will consider the provided char is compliant with the default date format. Relying on a default configuration is a source of error because it creates a dependency between the code and the configuration of the ORACLE server where this code is deployed.

According to the Oracle's documentation "the default date format is determined implicitly by the NLS_TERRITORY initialization parameter or can be set explicitly by the NLS_DATE_FORMAT parameter.". It means the behaviour of the TO_DATE function will certainly not be the expected one if the configuration of the ORACLE server is changing.

Noncompliant Code Example

SELECT TO_DATE( 'January 15, 2018, 11:00 A.M.')
FROM DUAL;

Compliant Solution

SELECT TO_DATE( 'January 15, 2018, 11:00 A.M.', 'Month dd, YYYY, HH:MI A.M.')
FROM DUAL;
plsql:S5141

When a SQL query is joining n tables (with n>=2), it is expected to have join conditions defined to determine on which columns these n tables should be joined. At minimum, for n joined tables, the SQL query should contain (n-1) join conditions involving all the joined table to avoid a full cartesian product between the rows of the n tables.

Not doing so will imply that too many rows will be returned. If this is not the case and unless this has been done on purpose, the SQL query should be reviewed and missing conditions should be added or useless tables should be removed from the SQL query.

This rule is raising no issue when the SQL query is involving CROSS JOIN, NATURAL JOIN statements.

Noncompliant Code Example

SELECT c.id, c.name, o.id, o.item_id, o.item_quantity
  FROM ORDERS o, CUSTOMERS c; -- Noncompliant; no JOIN condition at all

SELECT c.id, c.name, o.id, o.item_id, o.item_quantity
  FROM ORDERS o
  JOIN CUSTOMERS c ON o.customer_id = o.id; -- Noncompliant; no condition related to CUSTOMERS

SELECT f.name, d.title, l.*
  FROM FOLDERS f, DOCUMENTS d, DOC_LINES l -- Noncompliant; missing at least one condition related to DOC_LINES
 WHERE f.id = d.folder_id;

Compliant Solution

SELECT c.id, c.name, o.id, o.item_id, o.item_quantity
  FROM ORDERS o, CUSTOMERS c
 WHERE o.customer_id = c.id; -- Compliant

SELECT c.id, c.name, o.id, o.item_id, o.item_quantity
  FROM ORDERS o
  JOIN CUSTOMERS c ON o.customer_id = c.id; -- Compliant

SELECT f.name, d.title, l.*
  FROM FOLDERS f, DOCUMENTS d, DOC_LINES l
 WHERE f.id = d.folder_id
   AND d.id = l.document_id; -- Compliant
plsql:S2761

Calling the +, - or NOT prefix operator twice does nothing: the second invocation undoes the first. Such mistakes are typically caused by accidentally double-tapping the key in question without noticing.

Either this is a bug, if the operator was actually meant to be called once, or misleading if done on purpose.

Noncompliant Code Example

IF NOT ( NOT foo = 5 ) THEN  -- Noncompliant
  value := ++1;              -- Noncompliant
END IF;

Compliant Solution

IF foo = 5 THEN  -- Compliant
  value := +1;       -- Compliant
END IF;
plsql:S131

The requirement for a final ELSE clause is defensive programming. The CASE expression should always provide a value.

Noncompliant Code Example

SELECT
  CASE category
    WHEN 'A' THEN 21
    WHEN 'B' THEN 33
END shipping_cost
FROM product

Compliant Solution

SELECT
  CASE category
    WHEN 'A' THEN 21
    WHEN 'B' THEN 33
    ELSE 42
END shipping_cost
FROM product

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
  • MITRE, CWE-478 - Missing Default Case in Switch Statement
  • CERT, MSC01-C. - Strive for logical completeness
plsql:S3618

Any insert which omits a value for a NOT NULL column in a database table will be automatically rejected by the database unless a default value has been specified for the column.

Noteworthy

This rule raises issues only when a Data Dictionary is provided during the analysis. See https://docs.sonarqube.org/display/PLUG/Data+Dictionary

Noncompliant Code Example

With the table MY_TABLE having a NOT NULL column N2 without default value and a NOT NULL column N3 with default value:

  INSERT INTO MY_TABLE  -- Noncompliant; N2 value omitted
  (
    N1
  )
  VALUES
  (
    1
  )

Compliant Solution

  INSERT INTO MY_TABLE  -- Compliant even though N3 value not supplied
  (
    N1,
    N2
  )
  VALUES
  (
    1,
    'Paul'
  )
plsql:S5245

All identifiers such as variable and table names should be written using the same case to ensure consistency in the code.

This rule checks that identifiers are all in lower case.

plsql:S3626

Jump statements, such as RETURN and CONTINUE let you change the default flow of program execution, but jump statements that direct the control flow to the original direction are just a waste of keystrokes.

Noncompliant Code Example

CREATE PROCEDURE print_numbers AS
BEGIN
  FOR i in 1..4 LOOP
    DBMS_OUTPUT.PUT_LINE(i);
    CONTINUE; -- Noncompliant
  END LOOP;
  RETURN;     -- Noncompliant
END;

Compliant Solution

CREATE PROCEDURE print_numbers AS
BEGIN
  FOR i in 1..4 LOOP
    DBMS_OUTPUT.PUT_LINE(i);
  END LOOP;
END;
c:S1760

While keywords introduced in later standards can legally be used as identifiers in code compiled to earlier standards, doing so will eventually cause problems. Such code will cause compile errors if (when) the compiler is upgraded, and fixing those errors could be difficult and painful.

Additionally, such misuse of keywords has the potential to thoroughly confuse people who are unfamiliar with the code base, possibly leading them to introduce additional errors.

For these reasons, the earlier this practice is stopped, the better.

This rule flags instances of the following keywords used as identifiers:

C99

inline, restrict, _Bool, _Complex, _Noreturn, _Static_assert, _Thread_local

C11

_Alignas, _Alignof, _Atomic, _Generic, _Imaginary

C++11

alignas, alignof, char16_t, char32_t, constexpr, decltype, noexcept, nullptr, static_assert, thread_local

C++20

concept,requires

Noncompliant Code Example

int inline = 0;

Compliant Solution

int inline_count = 0;
cpp:NamespaceName

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all namespace names match a provided regular expression.

Noncompliant Code Example

With the default regular expression [a-z][a-z_0-9]*:

namespace Foo // Noncompliant
{
}

Compliant Solution

namespace foo
{
}
cpp:S1231

The malloc, realloc, calloc and free routines are used to dynamically allocate memory in the heap. But, in contrast to the new and delete operators introduced in C++, they allocate raw memory, which is not type-safe, and they do not correctly invoke object constructors. Additionally, mixing them with new/delete results in undefined behavior.

Note that directly replacing those functions with new/delete is usually not a good idea (see S5025).

Noncompliant Code Example

string* pStringArray1 = static_cast<string*>(malloc(10 * sizeof(string))); // Noncompliant
Person *p = (Person*)malloc(sizeof(Person)); // Noncompliant

Compliant Solution

std::array<string, 10> stringArray1 ; // Compliant, use std::vector instead if the size is dynamic
auto p1 = new Person("Bjarne"); // Compliant, but don't do that, prefer the version on next line
auto p2 = std::make_unique<Person>("Bjarne"); // Compliant

See

* C++ core guidelines R.10 Avoid malloc() and free()

cpp:S1669

The C++ standard defines some identifiers as having special meaning in some contexts. These are audit, axiom, final and override. While it is technically possible to use them as normal identifiers, it's clearer for the reader of the code to consider them as if they were keywords, and only use them with their special meaning.

Noncompliant Code Example

void axiom(int final); // Noncompliant

Compliant Solution

void precept(int finalValue); // Noncompliant
cpp:S1760

While keywords introduced in later standards can legally be used as identifiers in code compiled to earlier standards, doing so will eventually cause problems. Such code will cause compile errors if (when) the compiler is upgraded, and fixing those errors could be difficult and painful.

Additionally, such misuse of keywords has the potential to thoroughly confuse people who are unfamiliar with the code base, possibly leading them to introduce additional errors.

For these reasons, the earlier this practice is stopped, the better.

This rule flags instances of the following keywords used as identifiers:

C99

inline, restrict, _Bool, _Complex, _Noreturn, _Static_assert, _Thread_local

C11

_Alignas, _Alignof, _Atomic, _Generic, _Imaginary

C++11

alignas, alignof, char16_t, char32_t, constexpr, decltype, noexcept, nullptr, static_assert, thread_local

C++20

concept,requires

Noncompliant Code Example

int inline = 0;

Compliant Solution

int inline_count = 0;
cpp:ExceptionSpecificationUsage

Exception specifications never really provided any advantages in C++. They have been deprecated since C++11, and removed since C++17 (specification with an exception) and C++20 (empty throw specification). If your code still contains some, you should replace empty throw() specifications, with noexcept and remove any other specifications.

Noncompliant Code Example

void f() throw(); // Noncompliant
void g() throw(std::exception); // Noncompliant

Compliant Solution

void f() noexcept;
void g();

Exceptions

If a derived class overrides a function with a dynamic exception specification, then the derived function is forced to add a compatible exception specification. Such exception specifications are ignored.

See

squid:S1118

Utility classes, which are collections of static members, are not meant to be instantiated. Even abstract utility classes, which can be extended, should not have public constructors.

Java adds an implicit public constructor to every class which does not define at least one explicitly. Hence, at least one non-public constructor should be defined.

Noncompliant Code Example

class StringUtils { // Noncompliant

  public static String concatenate(String s1, String s2) {
    return s1 + s2;
  }

}

Compliant Solution

class StringUtils { // Compliant

  private StringUtils() {
    throw new IllegalStateException("Utility class");
  }

  public static String concatenate(String s1, String s2) {
    return s1 + s2;
  }

}

Exceptions

When class contains public static void main(String[] args) method it is not considered as utility class and will be ignored by this rule.

squid:UselessImportCheck

The imports part of a file should be handled by the Integrated Development Environment (IDE), not manually by the developer.

Unused and useless imports should not occur if that is the case.

Leaving them in reduces the code's readability, since their presence can be confusing.

Noncompliant Code Example

package my.company;

import java.lang.String;        // Noncompliant; java.lang classes are always implicitly imported
import my.company.SomeClass;    // Noncompliant; same-package files are always implicitly imported
import java.io.File;            // Noncompliant; File is not used

import my.company2.SomeType;
import my.company2.SomeType;    // Noncompliant; 'SomeType' is already imported

class ExampleClass {

  public String someString;
  public SomeType something;

}

Exceptions

Imports for types mentioned in comments, such as Javadocs, are ignored.

squid:S1126

Return of boolean literal statements wrapped into if-then-else ones should be simplified.

Similarly, method invocations wrapped into if-then-else differing only from boolean literals should be simplified into a single invocation.

Noncompliant Code Example

boolean foo(Object param) {
  if (expression) { // Noncompliant
    bar(param, true, "qix");
  } else {
    bar(param, false, "qix");
  }

  if (expression) {  // Noncompliant
    return true;
  } else {
    return false;
  }
}

Compliant Solution

boolean foo(Object param) {
  bar(param, expression, "qix");

  return expression;
}
squid:S2699

A test case without assertions ensures only that no exceptions are thrown. Beyond basic runnability, it ensures nothing about the behavior of the code under test.

This rule raises an exception when no assertions from any of the following known frameworks are found in a test:

  • JUnit
  • Fest 1.x
  • Fest 2.x
  • Rest-assured 2.0
  • AssertJ
  • Hamcrest
  • Spring's org.springframework.test.web.servlet.ResultActions.andExpect()
  • Eclipse Vert.x
  • Truth Framework
  • Mockito
  • EasyMock
  • JMock
  • WireMock
  • RxJava 1.x
  • RxJava 2.x
  • Selenide
  • JMockit

Furthermore, as new or custom assertion frameworks may be used, the rule can be parametrized to define specific methods that will also be considered as assertions. No issue will be raised when such methods are found in test cases. The parameter value should have the following format <FullyQualifiedClassName>#<MethodName>, where MethodName can end with the wildcard character. For constructors, the pattern should be <FullyQualifiedClassName>#<init>.

Example: com.company.CompareToTester#compare*,com.company.CustomAssert#customAssertMethod,com.company.CheckVerifier#<init>.

Noncompliant Code Example

@Test
public void testDoSomething() {  // Noncompliant
  MyClass myClass = new MyClass();
  myClass.doSomething();
}

Compliant Solution

Example when com.company.CompareToTester#compare* is used as parameter to the rule.

import com.company.CompareToTester;

@Test
public void testDoSomething() {
  MyClass myClass = new MyClass();
  assertNull(myClass.doSomething());  // JUnit assertion
  assertThat(myClass.doSomething()).isNull();  // Fest assertion
}

@Test
public void testDoSomethingElse() {
  MyClass myClass = new MyClass();
  new CompareToTester().compareWith(myClass);  // Compliant - custom assertion method defined as rule parameter
  CompareToTester.compareStatic(myClass);  // Compliant
}
squid:S2129

Constructors for String, BigInteger, BigDecimal and the objects used to wrap primitives should never be used. Doing so is less clear and uses more memory than simply using the desired value in the case of strings, and using valueOf for everything else.

Noncompliant Code Example

String empty = new String(); // Noncompliant; yields essentially "", so just use that.
String nonempty = new String("Hello world"); // Noncompliant
Double myDouble = new Double(1.1); // Noncompliant; use valueOf
Integer integer = new Integer(1); // Noncompliant
Boolean bool = new Boolean(true); // Noncompliant
BigInteger bigInteger1 = new BigInteger("3"); // Noncompliant
BigInteger bigInteger2 = new BigInteger("9223372036854775807"); // Noncompliant
BigInteger bigInteger3 = new BigInteger("111222333444555666777888999"); // Compliant, greater than Long.MAX_VALUE

Compliant Solution

String empty = "";
String nonempty = "Hello world";
Double myDouble = Double.valueOf(1.1);
Integer integer = Integer.valueOf(1);
Boolean bool = Boolean.valueOf(true);
BigInteger bigInteger1 = BigInteger.valueOf(3);
BigInteger bigInteger2 = BigInteger.valueOf(9223372036854775807L);
BigInteger bigInteger3 = new BigInteger("111222333444555666777888999");

Exceptions

BigDecimal constructor with double argument is ignored as using valueOf instead might change resulting value. See S2111.

squid:S2639

Regular expressions are powerful but tricky, and even those long used to using them can make mistakes.

The following should not be used as regular expressions:

  • . - matches any single character. Used in replaceAll, it matches everything
  • | - normally used as an option delimiter. Used stand-alone, it matches the space between characters
  • File.separator - matches the platform-specific file path delimiter. On Windows, this will be taken as an escape character

Noncompliant Code Example

String str = "/File|Name.txt";

String clean = str.replaceAll(".",""); // Noncompliant; probably meant to remove only dot chars, but returns an empty string
String clean2 = str.replaceAll("|","_"); // Noncompliant; yields _/_F_i_l_e_|_N_a_m_e_._t_x_t_
String clean3 = str.replaceAll(File.separator,""); // Noncompliant; exception on Windows

String clean4 = str.replaceFirst(".",""); // Noncompliant;
String clean5 = str.replaceFirst("|","_"); // Noncompliant;
String clean6 = str.replaceFirst(File.separator,""); // Noncompliant;
squid:S2924

While some TestRule classes have the desired effect without ever being directly referenced by a test, several others do not, and there's no reason to leave them cluttering up the file if they're not in use.

This rule raises an issue when Test class fields of the following types aren't used by any of the test methods: TemporaryFolder, and TestName.

This rule also applies to the JUnit 5 equivalent classes: TempDir, and TestInfo.

Noncompliant Code Example

public class ProjectDefinitionTest {

  @Rule
  public TemporaryFolder temp = new TemporaryFolder();  // Noncompliant

  @Test
  public void shouldSetKey() {
    ProjectDefinition def = ProjectDefinition.create();
    def.setKey("mykey");
    assertThat(def.getKey(), is("mykey"));
  }
}

Compliant Solution

public class ProjectDefinitionTest {

  @Test
  public void shouldSetKey() {
    ProjectDefinition def = ProjectDefinition.create();
    def.setKey("mykey");
    assertThat(def.getKey(), is("mykey"));
  }
}
vbnet:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

Sub DoSomething()
    ' TODO
End Sub

See

vbnet:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

Function Divide(ByVal numerator As Integer, ByVal denominator As Integer) As Integer
    Return numerator / denominator  ' FIXME denominator value might be  0
End Function

See

vbnet:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the procedure is doing too many things.

Noncompliant Code Example

With a maximum number of 3 parameters:

Public Sub Foo(ByVal p1 As Integer, ByVal p2 As Integer, ByVal p3 As Integer, ByVal p4 As Integer) ' Noncompliant
  ' ...
End Sub

Public Function Bar(ByVal p1 As Integer, ByVal p2 As Integer, ByVal p3 As Integer, ByVal p4 As Integer) ' Noncompliant
  ' ...
End Function

Compliant Solution

Public Sub Foo(ByVal p1 As Integer, ByVal p2 As Integer, ByVal p3 As Integer)
  ' ...
End Sub

Public Function Bar(ByVal p1 As Integer, ByVal p2 As Integer, ByVal p3 As Integer)
  ' ...
End Function
vbnet:S108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

' Empty on purpose or missing piece of code?
For index As Integer = 1 To 42 ' NonCompliant
Next

Exceptions

When a block contains a comment, this block is not considered to be empty.

vbnet:S2234

When the names of parameters in a procedure call match the names of the procedure arguments, it contributes to a clearer, more readable code. However, when the names match but are passed in a different order than the method arguments, it indicates a mistake in the parameter order which will likely lead to unexpected results.

Noncompliant Code Example

Public Function Divide(ByVal divisor As Integer, ByVal dividend As Integer) As Double
    Return divisor / dividend
End Function

Public Sub DoTheThing()
    Dim divisor = 15
    Dim dividend = 5

    Dim result = Divide(dividend, divisor)  ' Noncompliant; operation succeeds, but result is unexpected
    '...
End Sub

Compliant Solution

Public Function Divide(ByVal divisor As Integer, ByVal dividend As Integer) As Double
    Return divisor / dividend
End Function

Public Sub DoTheThing()
    Dim divisor = 15
    Dim dividend = 5

    Dim result = Divide(divisor, dividend)
    '...
End Sub
vbnet:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

If a AndAlso ((x + y > 0)) Then ' Noncompliant
    ' ...
End If

Return ((x + 1))  ' Noncompliant

Compliant Solution

If a AndAlso x + y > 0 Then
    ' ...
End If

Return (x + 1)
vbnet:S1125

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

Noncompliant Code Example

If BooleanMethod() = True Then ' Noncompliant
  ' ...
End If
If BooleanMethod() = False Then ' Noncompliant
  ' ...
End If
If BooleanMethod() OrElse False Then ' Noncompliant
  ' ...
End If
DoSomething(Not False) ' Noncompliant
DoSomething(BooleanMethod() = True) ' Noncompliant

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

Compliant Solution

If BooleanMethod() Then
  ' ...
End If
If Not BooleanMethod() Then
  ' ...
End If
If BooleanMethod() Then
  ' ...
End If
DoSomething(True)
DoSomething(BooleanMethod())

Dim booleanVariable = BooleanMethod()
booleanVariable = BooleanMethod() OrElse exp
booleanVariable = Not BooleanMethod() AndAlso exp
booleanVariable = Not BooleanMethod() OrElse exp
booleanVariable = BooleanMethod() AndAlso exp
vbnet:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

If condition1 Then
    If condition2 Then ' Noncompliant
        ' ...
    End If
End If

Compliant Solution

If condition1 AndAlso condition2 Then
    ' ...
End If
vbnet:S1151

The Select...Case statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the case clause should be extracted into a dedicated procedure.

Noncompliant Code Example

With the default threshold of 3:

Select Case number
    Case 1 To 5 ' Noncompliant: 4 statements in the case
        MethodCall1("")
        MethodCall2("")
        MethodCall3("")
        MethodCall4("")
    Case Else
        ' ...
End Select

Compliant Solution

Select Case number
    Case 1 To 5
        DoSomething()
    Case Else
        ' ...
End Select
...
Sub DoSomething()
    MethodCall1("")
    MethodCall2("")
    MethodCall3("")
    MethodCall4("")
End Sub
vbnet:S138

A procedure that grows too large tends to aggregate too many responsibilities.

Such procedures inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller procedures which focus on well-defined tasks.

Those smaller procedures will not only be easier to understand but also probably easier to test.

php:S2001

Deprecated language features are those that have been retained temporarily for backward compatibility, but which will eventually be removed from the language. In effect, deprecation announces a grace period to allow the smooth transition from the old features to the new ones. In that period, no use of the deprecated features should be added to the code, and all existing uses should be gradually removed.

The following functions were deprecated in PHP 5:

Deprecated Use Instead
call_user_method() call_user_func()
call_user_method_array() call_user_func_array()
define_syslog_variables()
dl()
ereg() preg_match()
ereg_replace() preg_replace() (note that this is deprecated in PHP 5.5)
eregi() preg_match() with 'i' modifier
eregi_replace() preg_replace() with 'i' modifier
set_magic_quotes_runtime() and its alias, magic_quotes_runtime()
session_register() $_SESSION superglobal
session_unregister() $_SESSION superglobal
session_is_registered() $_SESSION superglobal
set_socket_blocking() stream_set_blocking()
split() preg_split()
spliti() preg_split() with 'i' modifier
sql_regcase()
mysql_db_query() mysql_select_db() and mysql_query()
mysql_escape_string() mysql_real_escape_string()
Passing locale category names as strings Use the LC_* family of constants

The following functions were deprecated in PHP 7:

Deprecated Use Instead
__autoload() spl_autoload_register()
create_function() anonymous function
parse_str() without second argument parse_str() with second argument
gmp_random() gmp_random_bits() or gmp_random_range()
each() foreach
assert() with string argument
Defining case-insensitive constants by calling define() with true as third parameter define("myconst", $value) or define("myconst", $value, false)
FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED flags FILTER_VALIDATE_URL flag
fgetss() function, "string.strip_tags" stream filter name, SplFileObject::fgetss() method and gzgetss() function
mbregex_encoding(), mbereg(), mberegi(), mbereg_replace(), mberegi_replace(), mbsplit(), mbereg_match(), mbereg_search(), mbereg_search_pos(), mbereg_search_regs(), mbereg_search_init(), mbereg_search_getregs(), mbereg_search_getpos(), mbereg_search_setpos() Use the
corresponding mb_ereg_*() variants instead
string search functions with integer needle (stristr, strrchr, strstr, strripos, stripos, strrpos, strpos, strchr) use a string needle instead
image2wbmp() imagewbmp()
Normalizer::NONE
Defining an assert() function inside a namespace use the standard assert() function

See

css:S4662

The W3C specifications define the valid at-rules. Only the official and browser-specific at-rules should be used to get the expected impact in the final rendering.

Noncompliant Code Example

@encoding "utf-8";

Compliant Solution

@charset "utf-8";
Pylint:W0143
This message is emitted when pylint detects that a comparison with a callable was made, which might suggest that some parenthesis were omitted, resulting in potential unwanted behaviour.
Pylint:I0010
Used when an inline option is either badly formatted or can't be used inside modules.
Pylint:I0011
Used when an inline option disables a message or a messages category.
Pylint:I0012
Used when an inline option enables a message or a messages category.
Pylint:I0013
Used to inform that the file will not be checked
Pylint:I1101
Used when a variable is accessed for non-existent member of C extension. Due to unavailability of source static analysis is impossible, but it may be performed by introspecting living objects in run-time.
Pylint:E0701
Used when except clauses are not in the correct order (from the more specific to the more generic). If you don't fix the order, some exceptions may not be caught by the most specific handler.
Pylint:E0703
Used when using the syntax "raise ... from ...", where the exception context is not an exception, nor None.
Pylint:E1111
Used when an assignment is done on a function call but the inferred function doesn't return anything.
Pylint:R0916
Used when an if statement contains too many boolean expressions.
Pylint:W0710
Used when a custom exception class is raised but doesn't inherit from the builtin "Exception" class. This message can't be emitted when using Python >= 3.0.
Pylint:W1001
Used when Pylint detect the use of the builtin "property" on an old style class while this is relying on new style classes features. This message can't be emitted when using Python >= 3.0.
Pylint:I0001
Used to inform that a built-in module has not been checked using the raw checkers.
Pylint:R0124
Used when something is compared against itself.
Pylint:E0712
Used when a class which doesn't inherit from Exception is used as an exception in an except clause.
Pylint:C0303
Used when there is whitespace between the end of a line and the newline.

Added in Pylint 1.0.0.

This rule is deprecated, use S1131 instead.

Pylint:C0302
Used when a module has too many lines, reducing its readability.

This rule is deprecated, use S104 instead.

Pylint:C0304
Used when the last line in a file is missing a newline.

While Python interpreters typically do not require line end character(s) on the last line, other programs processing Python source files may do, and it is simply good practice to have it.

Added in Pylint 1.0.0.

This rule is deprecated, use S113 instead.

Pylint:E1125
Used when a function call does not pass a mandatory keyword-only argument.
Pylint:E1128
Used when an assignment is done on a function call but the inferred function returns nothing but None.
Pylint:W0706
Used when an except handler uses raise as its first or only operator. This is useless because it raises back the exception immediately. Remove the raise operator or the entire try-except-raise block!
Pylint:R0801
Indicates that a set of similar lines has been detected among multiple file. This usually means that the code should be refactored to avoid this duplication.

This rule is deprecated, use DuplicatedBlocks instead.

Pylint:E0601
Used when a local variable is accessed before its assignment.
Pylint:F0401
Used when Pylint has been unable to import a module.
Pylint:E1136
Emitted when a subscripted value doesn't support subscription (i.e. doesn't define __getitem__ method).
Pylint:E1137
Emitted when an object does not support item assignment (i.e. doesn't define __setitem__ method).
Pylint:E1138
Emitted when an object does not support item deletion (i.e. doesn't define __delitem__ method).
Pylint:R0912
Used when a function or method has too many branches, making it hard to follow.

This rule is deprecated, use FunctionComplexity instead.

Pylint:R0915
Used when a function or method has too many statements. You should then split it in smaller functions / methods.
Pylint:E1135
Emitted when an instance in membership test expression doesn't implement membership protocol (__contains__/__iter__/__getitem__).
Pylint:W0716
Used when an operation is done against an exception, but the operation is not valid for the exception in question. Usually emitted when having binary operations between exceptions in except handlers.
Pylint:E1130
Emitted when a unary operand is used on an object which does not support this type of operation.
Pylint:C0325
Used when a single item in parentheses follows an if, for, or other keyword.

This rule was added in Pylint 1.1.0.

This rule is deprecated, use S1110 instead.

Pylint:E1701
Used when an async context manager is used with an object that does not implement the async context management protocol. This message can't be emitted when using Python < 3.5.
Pylint:C0204
Used when a metaclass class method has a first argument named differently than the value specified in valid-metaclass-classmethod-first-arg option (default to "mcs"), recommended to easily differentiate them from regular instance methods.
Pylint:C0326
Used when a wrong number of spaces is used around an operator, bracket or block opener.
Pylint:E0611
Used when a name cannot be found in a module.
Pylint:E1700
Used when an `yield` or `yield from` statement is found inside an async function. This message can't be emitted when using Python < 3.5.
Pylint:R0901
Used when class has too many parent classes, try to reduce this to get a simpler (and so easier to use) class.
Pylint:R0902
Used when class has too many instance attributes, try to reduce this to get a simpler (and so easier to use) class.
Pylint:C0321

Used when more than one statement are found on the same line.

This rule is deprecated, use OneStatementPerLine instead.

Pylint:R0904
Used when class has too many public methods, try to reduce this to get a simpler (and so easier to use) class.
Pylint:E1140
Emitted when a dict key is not hashable (i.e. doesn't define __hash__ method).
Pylint:W0604
Used when you use the "global" statement at the module level since it has no effect
Pylint:W0603
Used when you use the "global" statement to update a global variable. Pylint just try to discourage this usage. That doesn't mean you cannot use it !
Pylint:W0623
Used when an exception handler assigns the exception to an existing name
Pylint:R1707
In Python, a tuple is actually created by the comma symbol, not by the parentheses. Unfortunately, one can actually create a tuple by misplacing a trailing comma, which can lead to potential weird bugs in your code. You should always use parentheses explicitly for creating a tuple.
Pylint:W1602
Used when the basestring built-in function is referenced (missing from Python 3)
Pylint:W0512
Used when a source line cannot be decoded using the specified source file encoding. This message can't be emitted when using Python >= 3.0.

This rule was added in Pylint 1.0.0.

Pylint:W1603
Used when the buffer built-in function is referenced (missing from Python 3)
Pylint:W1601
Used when the apply built-in function is referenced (missing from Python 3)
Pylint:W0631
Used when a loop variable (i.e. defined by a for loop or a list comprehension or a generator expression) is used outside the loop.
Pylint:E1602
Used when parameter unpacking is specified for a function(Python 3 doesn't allow it)
Pylint:E1607
Used when the deprecated "<>" operator is used instead of "!=". This is removed in Python 3. This message can't be emitted when using Python >= 3.0.
Pylint:E1604
Used when the alternate raise syntax 'raise foo, bar' is used instead of 'raise foo(bar)'.
Pylint:E1605
Used when the deprecated "``" (backtick) operator is used instead of the str() function.
Pylint:E1601
Used when a print statement is used (`print` is a function in Python 3)
Pylint:W1613
Used when the xrange built-in function is referenced (missing from Python 3)
Pylint:W1614
Used when a __coerce__ method is defined (method is not used by Python 3)
Pylint:W0403
Used when an import relative to the package directory is detected. This message can't be emitted when using Python >= 3.0.
Pylint:W1611
Used when the StandardError built-in function is referenced (missing from Python 3)
Pylint:W1612
Used when the unicode built-in function is referenced (missing from Python 3)
Pylint:W0401
Used when `from module import *` is detected.
Pylint:W0642
Invalid assignment to self or cls in instance or class method respectively.
Pylint:F0202
Used when Pylint has been unable to check methods signature compatibility for an unexpected reason. Please report this kind if you don't make sense of it.
Pylint:W1610
Used when the reduce built-in function is referenced (missing from Python 3)
Pylint:F0321
Used when an unexpected error occurred in bad format detection. Please report the error if it occurs.
Pylint:W0641
Used when a variable is defined but might not be used. The possibility comes from the fact that locals() might be used, which could consume or not the said variable
Pylint:W1608
Used when the long built-in function is referenced (missing from Python 3)
Pylint:W1606
Used when the execfile built-in function is referenced (missing from Python 3)
Pylint:W1609
Used when the raw_input built-in function is referenced (missing from Python 3)
Pylint:W1604
Used when the cmp built-in function is referenced (missing from Python 3)
Pylint:W1607
Used when the file built-in function is referenced (missing from Python 3)
Pylint:W1605
Used when the coerce built-in function is referenced (missing from Python 3)
Pylint:W1624
Indexing exceptions will not work on Python 3. Use `exception.args[index]` instead.
Pylint:W1625
Used when a string exception is raised. This will not work on Python 3.
Pylint:W1622
Used when an object's next() method is called (Python 3 uses the next() built- in function)
Pylint:W1620
Used for calls to dict.iterkeys(), itervalues() or iteritems() (Python 3 lacks these methods)
Pylint:W1623
Used when a metaclass is specified by assigning to __metaclass__ (Python 3 specifies the metaclass as a class statement argument)
Pylint:W1621
Used for calls to dict.viewkeys(), viewvalues() or viewitems() (Python 3 lacks these methods)
Pylint:E1507
Env manipulation functions support only string type arguments. See https://docs.python.org/3/library/os.html#os.getenv.
Pylint:W1619
Used for non-floor division w/o a float literal or ``from __future__ import division`` (Python 3 returns a float for int division unconditionally)
Pylint:W1617
Used when a __setslice__ method is defined (method is not used by Python 3)
Pylint:W1618
Used when an import is not accompanied by ``from __future__ import absolute_import`` (default behaviour in Python 3)
Pylint:W1615
Used when a __delslice__ method is defined (method is not used by Python 3)
Pylint:W1616
Used when a __getslice__ method is defined (method is not used by Python 3)
Pylint:W1635
Used when the unichr built-in is referenced (Use chr in Python 3)
Pylint:W1633
Used when the round built-in is referenced (backwards-incompatible semantics in Python 3)
Pylint:W1636
Used when the map built-in is referenced in a non-iterating context (returns an iterator in Python 3)
Pylint:W0301
Used when a statement is ended by a semi-colon (";"), which isn't necessary (that's python, not C ;).
Pylint:W1634
Used when the intern built-in is referenced (Moved to sys.intern in Python 3)
Pylint:W1630
Used when a __cmp__ method is defined (method is not used by Python 3)
Pylint:W1632
Used when the input built-in is referenced (backwards-incompatible semantics in Python 3)
Pylint:E0301
Used when an __iter__ method returns something which is not an iterable (i.e. has no `__next__` method)
Pylint:F0220
Used when a Pylint as failed to find interfaces implemented by a class.
Pylint:E0303
Used when a __len__ method returns something which is not a non-negative integer
Pylint:C1001
Used when a class is defined that does not inherit from another class and does not inherit explicitly from "object". This message can't be emitted when using Python >= 3.0.

This rule was added in Pylint 1.0.0.

This rule is deprecated, use S1722 instead.

Pylint:W1509
The preexec_fn parameter is not safe to use in the presence of threads in your application. The child process could deadlock before exec is called. If you must use it, keep it trivial! Minimize the number of libraries you call into.https://docs.python.org/3/library/subprocess.html#popen-constructor
Pylint:W1628
Used when a __hex__ method is defined (method is not used by Python 3)
Pylint:W1629
Used when a __nonzero__ method is defined (method is not used by Python 3)
Pylint:W1508
Env manipulation functions return None or str values. Supplying anything different as a default may cause bugs. See https://docs.python.org/3/library/os.html#os.getenv.
Pylint:W1626
Used when the reload built-in function is referenced (missing from Python 3). You can use instead imp.reload or importlib.reload.
Pylint:W1627
Used when an __oct__ method is defined (method is not used by Python 3)
Pylint:W1646
Used when using str.encode or str.decode with a non-text encoding. Use codecs module to handle arbitrary codecs.
Pylint:W1647
Used when accessing sys.maxint. Use sys.maxsize instead.
Pylint:W1644
Used when a __rdiv__ method is defined. Using `__rtruediv__` and setting__rdiv__ = __rtruediv__ should be preferred.(method is not used by Python 3)
Pylint:W1402
Used when an escape like \u is encountered in a byte string where it has no effect.

This rule was added in Pylint 0.26.0.

Pylint:W1645
Used when the message attribute is accessed on an Exception. Use str(exception) instead.
Pylint:W1403
String literals are implicitly concatenated in a literal iterable definition : maybe a comma is missing ?
Pylint:W1642
Used when a __div__ method is defined. Using `__truediv__` and setting__div__ = __truediv__ should be preferred.(method is not used by Python 3)
Pylint:W1401
Used when a backslash is in a literal string but not as an escape.

This rule was added in Pylint 0.26.0.

This rule is deprecated, use S1717 instead.

Pylint:W1643
Used when an __idiv__ method is defined. Using `__itruediv__` and setting__idiv__ = __itruediv__ should be preferred.(method is not used by Python 3)
Pylint:W1640
Using the cmp argument for list.sort or the sorted builtin should be avoided, since it was removed in Python 3. Using either `key` or `functools.cmp_to_key` should be preferred.
Pylint:W1641
Used when a class implements __eq__ but not __hash__. In Python 2, objects get object.__hash__ as the default implementation, in Python 3 objects get None as their default __hash__ implementation if they also implement __eq__.
Pylint:W1637
Used when the zip built-in is referenced in a non-iterating context (returns an iterator in Python 3)
Pylint:W1639
Used when the filter built-in is referenced in a non-iterating context (returns an iterator in Python 3)
Pylint:W1638
Used when the range built-in is referenced in a non-iterating context (returns an iterator in Python 3)
Pylint:W1657
Used when accessing a field on operator module that has been removed in Python 3.
Pylint:W1658
Used when accessing a field on urllib module that has been removed or moved in Python 3.
Pylint:W1653
Used when a next method is defined that would be an iterator in Python 2 but is treated as a normal function in Python 3.
Pylint:W1655
Used when dict.keys is referenced in a non-iterating context (returns an iterator in Python 3)
Pylint:W1656
Used when dict.values is referenced in a non-iterating context (returns an iterator in Python 3)
Pylint:W0201
Used when an instance attribute is defined outside the __init__ method.
Pylint:W1654
Used when dict.items is referenced in a non-iterating context (returns an iterator in Python 3)
Pylint:F0004
Used to indicate that some value of an unexpected type has been inferred.
Pylint:R1719
Used when an if expression can be replaced with 'bool(test)'.
Pylint:F0003
Used to indicate that the user asked to analyze a builtin module which has been skipped.
Pylint:W1651
Used when accessing a function on itertools that has been removed in Python 3.
Pylint:F0002
Used when an unexpected error occurred while building the Astroid representation. This is usually accompanied by a traceback. Please report such errors !
Pylint:W1652
Used when accessing a field on types that has been removed in Python 3.
Pylint:F0001
Used when an error occurred preventing the analysis of a module (unable to find it for instance).
Pylint:W1650
Used when using the deprecated deletechars parameters from str.translate. Use re.sub to remove the desired characters
Pylint:R1720
Used in order to highlight an unnecessary block of code following an if containing a raise statement. As such, it will warn when it encounters an else following a chain of ifs, all of them containing a raise statement.
Pylint:E0202
Used when a class defines a method which is hidden by an instance attribute from an ancestor class or set by some client code.
Pylint:W1649
Used when accessing a string function that has been deprecated in Python 3.
Pylint:W1305
Used when a PEP 3101 format string contains both automatic field numbering (e.g. '{}') and manual field specification (e.g. '{0}').
Pylint:W1306
Used when a PEP 3101 format string uses an attribute specifier ({0.length}), but the argument passed for formatting doesn't have that attribute.
Pylint:W1303
Used when a PEP 3101 format string that uses named fields doesn't receive one or more required keywords.
Pylint:W1304
Used when a PEP 3101 format string that uses named fields is used with an argument that is not required by the format string.
Pylint:R1708
According to PEP479, the raise of StopIteration to end the loop of a generator may lead to hard to find bugs. This PEP specify that raise StopIteration has to be replaced by a simple return statement
Pylint:W1662
Emitted when using a variable, that was bound in a comprehension handler, outside of the comprehension itself. On Python 3 these variables will be deleted outside of the comprehension.
Pylint:W0211
Used when a static method has "self" or a value specified in valid- classmethod-first-arg option or valid-metaclass-classmethod-first-arg option as first argument.
Pylint:W0332
Used when a lower case "l" is used to mark a long integer. You should use a upper case "L" since the letter "l" looks too much like the digit "1" This message can't be emitted when using Python >= 3.0.
Pylint:W1660
Used when accessing a field on sys module that has been removed in Python 3.
Pylint:F0010
Used when an exception occurred while building the Astroid representation which could be handled by astroid.
Pylint:W1661
Emitted when using an exception, that was bound in an except handler, outside of the except handler. On Python 3 these exceptions will be deleted once they get out of the except handler.
Pylint:E1305
Used when a format string that uses unnamed conversion specifiers is given too many arguments.
Pylint:E1306
Used when a format string that uses unnamed conversion specifiers is given too few arguments
Pylint:E1307
Used when a type required by format string is not suitable for actual argument type
Pylint:R1715
Using the builtin dict.get for getting a value from a dictionary if a key is present or a default if not, is simpler and considered more idiomatic, although sometimes a bit slower
Pylint:R1716
This message is emitted when pylint encounters boolean operation like"a < b and b < c", suggesting instead to refactor it to "a < b < c"
Pylint:R1718
Although there is nothing syntactically wrong with this code, it is hard to read and can be simplified to a set comprehension.Also it is faster since you don't need to create another transient list
Pylint:R1717
Although there is nothing syntactically wrong with this code, it is hard to read and can be simplified to a dict comprehension.Also it is faster since you don't need to create another transient list
Pylint:E1300
Used when an unsupported format character is used in a format string.
Pylint:R1712
You do not have to use a temporary variable in order to swap variables. Using "tuple unpacking" to directly swap variables makes the intention more clear.
Pylint:R1711
Emitted when a single "return" or "return None" statement is found at the end of function or method definition. This statement can safely be removed because Python will implicitly return None
Pylint:R1714
To check if a variable is equal to one of many values, combine the values into a tuple and check if the variable is contained "in" it instead of checking for equality against each of the values.This is faster and less verbose.
Pylint:W1659
Used when accessing the xreadlines() function on a file stream, removed in Python 3.
Pylint:R1713
Using str.join(sequence) is faster, uses less memory and increases readability compared to for-loop iteration.
Pylint:W0102
Used when a mutable value as list or dictionary is detected in a default value for an argument.
Pylint:W0222
Used when a method signature is different than in the implemented interface or in an overridden method.
Pylint:E0107
Used when you attempt to use the C-style pre-increment or pre-decrement operator -- and ++, which doesn't exist in Python.

This rule is deprecated, use PreIncrementDecrement instead.

Pylint:E0106
Used when a "return" statement with an argument is found outside in a generator function or method (e.g. with some "yield" statements). This message can't be emitted when using Python >= 3.3.

This rule is deprecated, use S2712 instead.

Pylint:W1307
Used when a PEP 3101 format string uses a lookup specifier ({a[1]}), but the argument passed for formatting doesn't contain or doesn't have that key as an attribute.
Pylint:W1202
Used when a logging statement has a call form of "logging.(format_string.format(format_args...))". Such calls should use % formatting instead, but leave interpolation to the logging function by passing the parameters as arguments.
Pylint:W1308
Used when we detect that a string formatting is repeating an argument instead of using named string arguments
Pylint:W1203
Used when a logging statement has a call form of "logging.method(f"..."))". Such calls should use % formatting instead, but leave interpolation to the logging function by passing the parameters as arguments.
Pylint:W1201
Used when a logging statement has a call form of "logging.(format_string % (format_args...))". Such calls should leave string interpolation to the logging method itself and be written "logging.(format_string, format_args...)" so that the program may avoid incurring the cost of the interpolation in those cases in which no message will be logged. For more, see http://www.python.org/dev/peps/pep-0282/.
Pylint:W0110
Used when a lambda is the first argument to "map" or "filter". It could be clearer as a list comprehension or generator expression. This message can't be emitted when using Python >= 3.0.

This rule was added in Pylint 0.27.0.

Pylint:W0111
Used when assignment will become invalid in future Python release due to introducing new keyword.
Pylint:E0117
Emitted when a nonlocal variable does not have an attached name somewhere in the parent scopes
Pylint:E0119
Emitted when format function is not called on str object. e.g doing print("value: {}").format(123) instead of print("value: {}".format(123)). This might not be what the user intended to do.
Pylint:E0113
Emitted when a star expression is used as a starred assignment target.
Pylint:E0114
Emitted when a star expression is not used in an assignment target.
Pylint:E0236
Used when an invalid (non-string) object occurs in __slots__.

This rule was added in Pylint 1.2.0.

Pylint:E0115
Emitted when a name is both nonlocal and global.
Pylint:E1200
Used when an unsupported format character is used in a logging statement format string.
Pylint:E0112
Emitted when there are more than one starred expressions (`*x`) in an assignment. This is a SyntaxError.
Pylint:E1201
Used when a logging statement format string terminates before the end of a conversion specifier.
Pylint:R0205
Used when a class inherit from object, which under python3 is implicit, hence can be safely removed from bases.
Pylint:W0122
Used when you use the "exec" statement (function for Python 3), to discourage its usage. That doesn't mean you cannot use it !

This rule is deprecated, use ExecStatementUsage instead.

Pylint:W0123
Used when you use the "eval" function, to discourage its usage. Consider using `ast.literal_eval` for safely evaluating strings containing Python expressions from untrusted sources.

This rule was added in Pylint 1.2.0.

Pylint:W0120
Loops should only have an else clause if they can exit early with a break statement, otherwise the statements under else should be on the same scope as the loop itself.

This rule was added in Pylint 0.28.0.

Pylint:C0414
Used when an import alias is same as original package.e.g using import numpy as numpy instead of import numpy as np
Pylint:I0020
A message was triggered on a line, but suppressed explicitly by a disable= comment in the file. This message is not generated for messages that are ignored due to configuration settings.
Pylint:I0021
Reported when a message is explicitly disabled for a line or a block of code, but never triggered.
Pylint:I0022
Some inline pylint options have been renamed or reworked, only the most recent form should be used. NOTE:skip-all is only available with pylint >= 0.26
Pylint:I0023
Used when a message is enabled or disabled by id.
Pylint:C0402
Used when a word in docstring is not spelled correctly.
Pylint:C0401
Used when a word in comment is not spelled correctly.
Pylint:E0011
Used when an unknown inline option is encountered.

Note that options can be specified in the configuration file and can be overridden on the command line.

Pylint:E1101
Used when a variable is accessed for an unexistent member.
Pylint:E0012
Used when a bad value for an inline option is encountered.

The option exists but its value is not valid. The options can be specified in the Pylint configuration file and can be overridden in the Pylint command line.

python:S1481

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

def hello(name):
    message = "Hello " + name # Noncompliant
    print(name)
for i in range(10):
    foo()

Compliant Solution

def hello(name):
    message = "Hello " + name
    print(message)
for _ in range(10):
    foo()

Exceptions

_ as well as tuples will not raise an issue for this rule. The following examples are compliant:

for _ in range(10):
    do_something()
username, login, password = auth
do_something_else(username, login)
xml:S1778

The prolog header is the following piece of code that some XML documents start with:

<?xml version="y.x" encoding="zzzzz"?>

When the prolog exists in an XML document, it should be at the beginning of the file to enable programs to determine the encoding of non-UTF-8, non-UTF-16 files.

Noncompliant Code Example

<!-- Generated file -->  <!--  Noncompliant  -->
<?xml version="1.0" encoding="UTF-8"?>
<firstNode>
  content
</firstNode>

Compliant Solution

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated file -->
<firstNode>
  content
</firstNode>
xml:S103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

common-jsp:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-jsp:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-jsp:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-jsp:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-jsp:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-jsp:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
typescript:S2589

If an expression doesn't change the evaluation of the condition, then it is either unnecessary, and condition can be removed, or it makes some code being never executed. In any case, the code should be refactored.

Noncompliant Code Example

function checkState(state: boolean) {
  if (state) {
    console.log("Checking the state");
    if (state) { // Noncompliant, condition is always true
      doSomething();
    }
  }
}

Compliant Solution

function checkState(state: boolean) {
  if (state) {
    console.log("Checking the state");
    if (shouldDoSomething()) {
      doSomething();
    }
  }
}

See

  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
  • MITRE, CWE-571 - Expression is Always True
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
typescript:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

Noncompliant Code Example

const password = "asdasd";

let my_pwd;
my_pwd = "qwerewt";

login({ passwd: "zxvxcv"});

const url = "https://example.com?password=hl2OAIXXZ60";

Compliant Solution

const password = loadCredentials();

See

typescript:S905

Any statement (other than a null statement, which means a statement containing only a semicolon ;) which has no side effect and does not result in a change of control flow will normally indicate a programming error, and therefore should be refactored.

Noncompliant Code Example

a == 1; // Noncompliant; was assignment intended?
a < b; // Noncompliant; have we forgotten to assign the result to a variable?

See

  • MITRE, CWE-482 - Comparing instead of Assigning
  • MISRA C:2004, 14.2 - All non-null statements shall either have at least one side-effect however executed, or cause control flow to change.
typescript:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

Noncompliant Code Example

With a maximum number of 4 parameters:

function doSomething(param1: number, param2: number, param3: number, param4: number, param5: number) {
...
}

Compliant Solution

function doSomething(param1: number, param2: number, param3: number, param4: number) {
...
}

Exceptions

Parameter properties are ignored.

class A {
  constructor(public p1: number, public p2: number, public p3: number, public p4: number, public p5: number) {
  }
}
typescript:S2234

When the names of arguments in a function call match the names of the function parameters, it contributes to clearer, more readable code. However, when the names match, but are passed in a different order than the function parameters, it indicates a mistake in the parameter order which will likely lead to unexpected results.

Noncompliant Code Example

function divide(divisor: number, dividend: number) {
  return divisor/dividend;
}

function doTheThing() {
  const divisor = 15;
  const dividend = 5;

  let result = divide(dividend, divisor);  // Noncompliant; operation succeeds, but result is unexpected
  //...
}

Compliant Solution

function divide(divisor: number, dividend: number) {
  return divisor/dividend;
}

function doTheThing() {
  const divisor = 15;
  const dividend = 5;

  let result = divide(divisor, dividend);
  //...
}
typescript:S1143

Using return, break, throw, and continue from a finally block overwrites similar statements from the suspended try and catch blocks.

This rule raises an issue when a jump statement (break, continue, return and throw) would force control flow to leave a finally block.

Noncompliant Code Example

function foo() {
    try {
        return 1; // We expect 1 to be returned
    } catch(err) {
        return 2; // Or 2 in cases of error
    } finally {
        return 3; // Noncompliant: 3 is returned before 1, or 2, which we did not expect
    }
}

Compliant Solution

function foo() {
    try {
        return 1; // We expect 1 to be returned
    } catch(err) {
        return 2; // Or 2 in cases of error
    }
}

See

typescript:S2871

The default sort order is alphabetic, rather than numeric, regardless of the types in the array. Specifically, even if an array contains only numbers, all values in it will be converted to strings and sorted lexicographically, for an order like this: 1, 15, 2, 20, 5.

Fortunately the sort method allows you to pass an optional compare function to specify the sort order. When a compare function is supplied, the returned order depends on the return value of the compare function.

Noncompliant Code Example

var myarray = [80, 3, 9, 34, 23, 5, 1];

myarray.sort();
console.log(myarray); // outputs: [1, 23, 3, 34, 5, 80, 9]

Compliant Solution

var myarray = [80, 3, 9, 34, 23, 5, 1];

myarray.sort(function(a, b){
    if (a < b)
        return -1;
    if (a > b)
        return 1;
    else
        return 0;
});
console.log(myarray); // outputs: [1, 3,  5, 9, 23, 34, 80]
typescript:S1821

Nested switch structures are difficult to understand because you can easily confuse the cases of an inner switch as belonging to an outer statement. Therefore nested switch statements should be avoided.

Specifically, you should structure your code to avoid the need for nested switch statements, but if you cannot, then consider moving the inner switch to another function.

Noncompliant Code Example

function foo(n: number, m: number) {
  switch (n) {
    case 0:
      switch (m) {  // Noncompliant; nested switch
        // ...
      }
    case 1:
      // ...
    default:
      // ...
  }
}

Compliant Solution

function foo(n: number, m: number) {
  switch (n) {
    case 0:
      bar(m);
    case 1:
      // ...
    default:
      // ...
  }
}

function bar(m: number) {
  switch(m) {
    // ...
  }
}
typescript:S1874

Once deprecated, classes, and interfaces, and their members should be avoided, rather than used, inherited or extended. Deprecation is a warning that the class or interface has been superseded, and will eventually be removed. The deprecation period allows you to make a smooth transition away from the aging, soon-to-be-retired technology.

Noncompliant Code Example

export interface LanguageService {
  /**
  * @deprecated Use getEncodedSyntacticClassifications instead.
  */
  getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[];
}

const syntacticClassifications = getLanguageService().getSyntacticClassifications(file, span); // Noncompliant

See

typescript:S1751

A loop with at most one iteration is equivalent to the use of an if statement to conditionally execute one piece of code. No developer expects to find such a use of a loop statement. If the initial intention of the author was really to conditionally execute one piece of code, an if statement should be used instead.

At worst that was not the initial intention of the author and so the body of the loop should be fixed to use the nested return, break or throw statements in a more appropriate way.

Noncompliant Code Example

for (i = 0; i < 10; i++) { // noncompliant, loop only executes once
  console.log("i is " + i);
  break;
}

for (i = 0; i < 10; i++) { // noncompliant, loop only executes once
  if(i == x) {
    break;
  } else {
    console.log("i is " + i);
    return;
  }
}

Compliant Solution

for (i = 0; i < 10; i++) {
  console.log("i is " + i);
}

for (i = 0; i < 10; i++) {
  if(i == x) {
    break;
  } else {
    console.log("i is " + i);
  }
}
typescript:S2681

Curly braces can be omitted from a one-line block, such as with an if statement or for loop, but doing so can be misleading and induce bugs.

This rule raises an issue when the whitespacing of the lines after a one line block indicates an intent to include those lines in the block, but the omission of curly braces means the lines will be unconditionally executed once.

Noncompliant Code Example

if (condition)
  firstActionInBlock();
  secondAction();  // Noncompliant; executed unconditionally
thirdAction();

if (condition) firstActionInBlock(); secondAction();  // Noncompliant; secondAction executed unconditionally

if (condition) firstActionInBlock();  // Noncompliant
  secondAction();  // Executed unconditionally

if (condition); secondAction();  // Noncompliant; secondAction executed unconditionally

let str: string|null = null;
for (let i = 0; i < array.length; i++)
  str = array[i];
  doTheThing(str);  // Noncompliant; executed only on last array element

Compliant Solution

if (condition) {
  firstActionInBlock();
  secondAction();
}
thirdAction();

str: string|null = null;
for (let i = 0; i < array.length; i++) {
  str = array[i];
  doTheThing(str);
}

See

typescript:S1479

When switch statements have large sets of case clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

typescript:S1192

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.

Exceptions

To prevent generating some false-positives, literals having less than 10 characters are excluded as well as literals matching /^\w*$/. String literals inside import/export statements and JSX attributes are also ignored.

typescript:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Noncompliant Code Example

if ( a == a ) { // always true
  doZ();
}
if ( a != a ) { // always false
  doY();
}
if ( a == b && a == b ) { // if the first one is true, the second one is too
  doX();
}
if ( a == b || a == b ) { // if the first one is true, the second one is too
  doW();
}

var j = 5 / 5; //always 1
var k = 5 - 5; //always 0

Exceptions

The specific case of testing one variable against itself is a valid test for NaN and is therefore ignored.

Similarly, left-shifting 1 onto 1 is common in the construction of bit masks, and is ignored.

Moreover comma operator , and instanceof operator are ignored as there are use-cases when there usage is valid.

if(f !== f) { // test for NaN value
  console.log("f is NaN");
}

var i = 1 << 1; // Compliant
var j = a << a; // Noncompliant

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
typescript:S1121

Assignments within conditions are hard to spot and therefore make the code less readable. Moreover it often can be a typo and the comparison (==) was intended instead. Ideally, conditions should not have side-effects.

Noncompliant Code Example

if ((str = cont.substring(pos1, pos2)) != '') {  // Noncompliant
  //...
}

Compliant Solution

str = cont.substring(pos1, pos2);
if (str != '') {
  //...
}

See

  • MISRA C:2004, 13.1 - Assignment operators shall not be used in expressions that yield a Boolean value
  • MISRA C++:2008, 6-2-1 - Assignment operators shall not be used in sub-expressions
  • MISRA C:2012, 13.4 - The result of an assignment operator should not be used
  • MITRE, CWE-481 - Assigning instead of Comparing
  • CERT, EXP45-C. - Do not perform assignments in selection statements
  • CERT, EXP51-J. - Do not perform assignments in conditional expressions
typescript:S2737

A catch clause that only rethrows the caught exception has the same effect as omitting the catch altogether and letting it bubble up automatically, but with more code and the additional detriment of leaving maintainers scratching their heads.

Such clauses should either be eliminated or populated with the appropriate logic.

Noncompliant Code Example

try {
  doSomething();
} catch (ex) {  // Noncompliant
  throw ex;
}

Compliant Solution

try {
  doSomething();
} catch (ex) {
  console.err(ex);
  throw ex;
}

or

doSomething();
typescript:S1525

The debugger statement can be placed anywhere in procedures to suspend execution. Using the debugger statement is similar to setting a breakpoint in the code. By definition such statement must absolutely be removed from the source code to prevent any unexpected behavior or added vulnerability to attacks in production.

Noncompliant Code Example

for (i = 1; i<5; i++) {
  // Print i to the Output window.
  Debug.write("loop index is " + i);
  // Wait for user to resume.
  debugger;
}

Compliant Solution

for (i = 1; i<5; i++) {
  // Print i to the Output window.
  Debug.write("loop index is " + i);
}

See

  • MITRE, CWE-489 - Leftover Debug Code
  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
typescript:S1523

Executing code dynamically is security sensitive. It has led in the past to the following vulnerabilities:

The eval function is a way to run arbitrary code at run-time. Dynamically evaluating code is slow and a potential security issue when the arguments haven't been properly validated.

Any code which is dynamically evaluated in your process will have the same permissions as the rest of your code. Thus it is very dangerous to do so with code coming from an untrusted source. Injected Code can either run on the server or in the client (exemple: XSS attack).

This rule marks for review each occurence of dynamic code execution.

Noncompliant Code Example

var value = eval('obj.' + propName); // Noncompliant

Compliant Solution

var value = obj[propName];

Exceptions

Calling reflection methods with a hard-coded type name, method name or field name will not raise an issue.

See

  • MITRE CWE-95 - Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')
  • MITRE CWE-470 - Use of Externally-Controlled Input to Select Classes or Code ('Unsafe Reflection')
  • OWASP Top 10 2017 Category A1 - Injection
  • OWASP Top 10 2017 Category A7 - Cross-Site Scripting (XSS)
typescript:S4322

A common idiom in JavaScript to differentiate between two possible types is to check for the presence in the object of a member of the desired type. Usually, to simplify the code, a boolean function is created to check the type.

Typescript provides user defined type guard functions. These are just functions with a return type of argumentName is SomeType. Such functions return true if the argument is of the specified type. One of the advantages of using such a function is that in a conditional block where the condition is a type guard, the compiler automatically performs the appropriate casts, so explicit casting becomes unnecessary.

This rule raises an issue when a boolean function checking for the type of its only argument can be replaced with a user-defined type guard function.

Noncompliant Code Example

function isSomething(x: BaseType) : boolean { // Noncompliant
  return (<Something>x).foo !== undefined;
}

if (isSomething(v)) {
  (<Something>v).foo();
}

Compliant Solution

function isSomething(x: BaseType) : x is Something {
  return (<Something>x).foo !== undefined;
}

if (isSomething(v)) {
  v.foo();
}

See

TypeScript advanced types

typescript:S1854

A dead store happens when a local variable is assigned a value that is not read by any subsequent instruction. Calculating or retrieving a value only to then overwrite it or throw it away, could indicate a serious error in the code. Even if it's not an error, it is at best a waste of resources. Therefore all calculated values should be used.

Noncompliant Code Example

i = a + b; // Noncompliant; calculation result not used before value is overwritten
i = compute();

Compliant Solution

i = a + b;
i += compute();

Exceptions

This rule ignores initializations to -1, 0, 1, null, true, false, "", [] and {}.

See

typescript:S4798

Having default value for optional boolean parameters makes the logic of function when missing that parameter more evident. When providing a default value is not possible, it is better to split the function into two with a clear responsibility separation.

Noncompliant Code Example

function countPositiveNumbers(arr: number[], countZero?: boolean) { // Noncompliant, default value for 'countZero' should be defined
  // ...
}

function toggleProperty(property: string, value?: boolean) { // Noncompliant, a new function should be defined
  if (value !== undefined) {
    setProperty(property, value);
  } else {
    setProperty(property, calculateProperty());
  }
}

Compliant Solution

function countPositiveNumbers(arr: number[], countZero = false) {
  // ...
}

function toggleProperty(property: string, value: boolean) {
  setProperty(property, value);
}

function togglePropertyToCalculatedValue(property: string) {
  setProperty(property, calculateProperty());
}
typescript:S3984

Creating a new Error without actually throwing it is useless and is probably due to a mistake.

Noncompliant Code Example

if (x < 0) {
  new Error("x must be nonnegative");
}

Compliant Solution

if (x < 0) {
  throw new Error("x must be nonnegative");
}
typescript:S4158

When a collection is empty it makes no sense to access or iterate it. Doing so anyway is surely an error; either population was accidentally omitted or the developer doesn't understand the situation.

Noncompliant Code Example

let strings = [];

if (strings.includes("foo")) {}  // Noncompliant

for (str of strings) {}  // Noncompliant

strings.forEach(str => doSomething(str)); // Noncompliant

Web:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

See

Web:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

int divide(int numerator, int denominator) {
  return numerator / denominator;              // FIXME denominator value might be  0
}

See

Web:S4645

When parsing a script node, the browser treats its contents as plain text, and immediately finishes parsing when it finds the first closing </script> character sequence.

As a consequence, nested script nodes are not possible, because all opening <script> tags found along the way are ignored.

Web browsers doesn't support nested <script>...</script> elements. But there is no error in such case and browers just close the first encountered <script> tag as soon as a closing </script> tag is found along the way. So there is a big chance to display something totally unexpected to the end-users.

Noncompliant Code Example

<script type="text/template">
  <div>
    Hello!
  </div>
  <script type="text/javascript">  <!-- Noncompliant -->
    alert("Hi!");
  </script>
</script>

Compliant Solution

<script type="text/javascript">
  alert("Hi!");
</script>

<script type="text/template">
  <div>
    Hello!
  </div>
</script>
Web:FileLengthCheck

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

Web:HeaderCheck

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
Web:InlineStyleCheck

The goal of this rule is to ban the usage of HTML "style" property to make sure that all CSS styles are defined in CSS classes. Consolidating all styling into classes makes it easier to read, understand and maintain.

Noncompliant Code Example

<body>
  <h1 style="color: blue;">Hello World!</h1>  <!-- Noncompliant -->

Compliant Solution

<head>
  <style>
    h1 {
      color: blue;
    }
  </style>
</head>
<body>
<h1>Hello World!</h1>
Web:ComplexityCheck

Most of the time, a very complex file breaks the Single Responsibility Principle and should be re-factored into several different files.

Deprecated

This rule is deprecated, and will eventually be removed.

Web:ImgWithoutWidthOrHeightCheck

If the width and height attributes are set, the space required for the image is reserved immediately by the browser, even before it actually starts to load the image.

Without those attributes, the page layout constantly changes as images are loaded until they are all loaded, which can disorient users.

Noncompliant Code Example

<img src="logo.png" alt="My Company" />                           <!-- Non-Compliant -->

Compliant Solution

<img src="logo.png" alt="My Company" width="100" height="50" />   <!-- Compliant -->
squid:S3551

When @Overrides of synchronized methods are not themselves synchronized, the result can be improper synchronization as callers rely on the thread-safety promised by the parent class.

Noncompliant Code Example

public class Parent {

  synchronized void foo() {
    //...
  }
}

public class Child extends Parent {

 @Override
  public foo () {  // Noncompliant
    // ...
    super.foo();
  }
}

Compliant Solution

public class Parent {

  synchronized void foo() {
    //...
  }
}

public class Child extends Parent {

  @Override
  synchronized foo () {
    // ...
    super.foo();
  }
}

See

  • CERT, TSM00-J - Do not override thread-safe methods with methods that are not thread-safe
squid:S1143

Using return, break, throw, and so on from a finally block suppresses the propagation of any unhandled Throwable which was thrown in the try or catch block.

This rule raises an issue when a jump statement (break, continue, return, throw, and goto) would force control flow to leave a finally block.

Noncompliant Code Example

public static void main(String[] args) {
  try {
    doSomethingWhichThrowsException();
    System.out.println("OK");   // incorrect "OK" message is printed
  } catch (RuntimeException e) {
    System.out.println("ERROR");  // this message is not shown
  }
}

public static void doSomethingWhichThrowsException() {
  try {
    throw new RuntimeException();
  } finally {
    for (int i = 0; i < 10; i ++) {
      //...
      if (q == i) {
        break; // ignored
      }
    }

    /* ... */
    return;      // Noncompliant - prevents the RuntimeException from being propagated
  }
}

Compliant Solution

public static void main(String[] args) {
  try {
    doSomethingWhichThrowsException();
    System.out.println("OK");
  } catch (RuntimeException e) {
    System.out.println("ERROR");  // "ERROR" is printed as expected
  }
}

public static void doSomethingWhichThrowsException() {
  try {
    throw new RuntimeException();
  } finally {
    for (int i = 0; i < 10; i ++) {
      //...
      if (q == i) {
        break; // ignored
      }
    }

    /* ... */
  }
}

See

squid:UndocumentedApi

Try to imagine using the standard Java API (Collections, JDBC, IO, ...) without Javadoc. It would be a nightmare, because Javadoc is the only way to understand of the contract of the API. Documenting an API with Javadoc increases the productivity of the developers consuming it.

On top of a main description for each member of a public API, the following Javadoc elements are required to be described:

  • Parameters, using @param parameterName.
  • Thrown exceptions, using @throws exceptionName.
  • Method return values, using @return.
  • Generic types, using @param <T>.

Furthermore the following guidelines should be followed:

  • At least 1 line of description.
  • All parameters documented with @param, and names should match.
  • All checked exceptions documented with @throws
  • @return present and documented when not void.
  • Placeholders like "TODO", "FIXME", "..." should be avoided.

The following public methods and constructors are not taken into account by this rule:

  • Getters and setters.
  • Methods overriding another method (usually decorated with @Override).
  • Empty constructors.
  • Static constants.

Noncompliant Code Example

/**
  * This is a Javadoc comment
  */
public class MyClass<T> implements Runnable {    // Noncompliant - missing '@param <T>'

  public static final DEFAULT_STATUS = 0;    // Compliant - static constant
  private int status;                           // Compliant - not public

  public String message;                  // Noncompliant

  public MyClass() {                         // Noncompliant - missing documentation
    this.status = DEFAULT_STATUS;
  }

  public void setStatus(int status) {  // Compliant - setter
    this.status = status;
  }

  @Override
  public void run() {                          // Compliant - has @Override annotation
  }

  protected void doSomething() {    // Compliant - not public
  }

  public void doSomething2(int value) {  // Noncompliant
  }

  public int doSomething3(int value) {  // Noncompliant
    return value;
  }
}

Compliant Solution

/**
  * This is a Javadoc comment
  * @param <T> the parameter of the class
  */
public class MyClass<T> implements Runnable {

  public static final DEFAULT_STATUS = 0;
  private int status;

  /**
    * This is a Javadoc comment
    */
  public String message;

  /**
   * Class comment...
   */
  public MyClass() {
    this.status = DEFAULT_STATUS;
  }

  public void setStatus(int status) {
    this.status = status;
  }

  @Override
  public void run() {
  }

  protected void doSomething() {
  }

  /**
    * Will do something.
    * @param value the value to be used
    */
  public void doSomething(int value) {

  /**
    *  {@inheritDoc}
    */
  public int doSomething(int value) {
    return value;
  }
}
squid:S4926

Providing a serialVersionUID field on Serializable classes is strongly recommended by the Serializable documentation but blindly following that recommendation can be harmful.

serialVersionUID value is stored with the serialized data and this field is verified when deserializing the data to ensure that the code reading the data is compatible with the serialized data. In case of failure, it means the serialized data and the code are not in sync and this fine because you know what's wrong.

When the serialVersionUID is generated by an IDE or blindly hard-coded, there is a high probability that one will forget to update the serialVersionUID value when the Serializable class is later enriched with additional fields. As a consequence, old serialized data will incorrectly be considered compatible with the newer version of the code creating situations which are hard to debug.

Therefore, defining serialVersionUID should be done with care. This rule raises an issue on each serialVersionUID field declared on classes implementing Serializable to be sure the presence and the value of the serialVersionUID field is challenged and validated by the team.

Noncompliant Code Example

public class Foo implements Serializable {
  private static final long serialVersionUID = 1;
}

public class BarException extends RuntimeException {
  private static final long serialVersionUID = 8582433437601788991L;
}

See

squid:S1698

It is equivalent to use the equality == operator and the equals method to compare two objects if the equals method inherited from Object has not been overridden. In this case both checks compare the object references.

But as soon as equals is overridden, two objects not having the same reference but having the same value can be equal. This rule spots suspicious uses of == and != operators on objects whose equals methods are overridden.

Noncompliant Code Example

String firstName = getFirstName(); // String overrides equals
String lastName = getLastName();

if (firstName == lastName) { ... }; // Non-compliant; false even if the strings have the same value

Compliant Solution

String firstName = getFirstName();
String lastName = getLastName();

if (firstName != null && firstName.equals(lastName)) { ... };

Exceptions

Comparing two instances of the Class object will not raise an issue:

Class c;
if(c == Integer.class) { // No issue raised
}

Comparing Enum will not raise an issue:

public enum Fruit {
   APPLE, BANANA, GRAPE
}
public boolean isFruitGrape(Fruit candidateFruit) {
  return candidateFruit == Fruit.GRAPE; // it's recommended to activate S4551 to enforce comparison of Enums using ==
}

Comparing with final reference will not raise an issue:

private static final Type DEFAULT = new Type();

void foo(Type other) {
  if (other == DEFAULT) { // Compliant
  //...
  }
}

Comparing with this will not raise an issue:

  public boolean equals(Object other) {
    if (this == other) {  // Compliant
      return false;
    }
 }

Comparing with java.lang.String and boxed types java.lang.Integer, ... will not raise an issue.

See

  • S4973 - Strings and Boxed types should be compared using "equals()"
  • MITRE, CWE-595 - Comparison of Object References Instead of Object Contents
  • MITRE, CWE-597 - Use of Wrong Operator in String Comparison
  • CERT, EXP03-J. - Do not use the equality operators when comparing values of boxed primitives
  • CERT, EXP50-J. - Do not confuse abstract object equality with reference equality
squid:S1217

The purpose of the Thread.run() method is to execute code in a separate, dedicated thread. Calling this method directly doesn't make sense because it causes its code to be executed in the current thread.

To get the expected behavior, call the Thread.start() method instead.

Noncompliant Code Example

Thread myThread = new Thread(runnable);
myThread.run(); // Noncompliant

Compliant Solution

Thread myThread = new Thread(runnable);
myThread.start(); // Compliant

See

squid:S4973

It's almost always a mistake to compare two instances of java.lang.String or boxed types like java.lang.Integer using reference equality == or !=, because it is not comparing actual value but locations in memory.

Noncompliant Code Example

String firstName = getFirstName(); // String overrides equals
String lastName = getLastName();

if (firstName == lastName) { ... }; // Non-compliant; false even if the strings have the same value

Compliant Solution

String firstName = getFirstName();
String lastName = getLastName();

if (firstName != null && firstName.equals(lastName)) { ... };

See

  • MITRE, CWE-595 - Comparison of Object References Instead of Object Contents
  • MITRE, CWE-597 - Use of Wrong Operator in String Comparison
  • CERT, EXP03-J. - Do not use the equality operators when comparing values of boxed primitives
  • CERT, EXP50-J. - Do not confuse abstract object equality with reference equality
squid:S2183

Since an int is a 32-bit variable, shifting by more than +/-31 is confusing at best and an error at worst. When the runtime shifts 32-bit integers, it uses the lowest 5 bits of the shift count operand. In other words, shifting an int by 32 is the same as shifting it by 0, and shifting it by 33 is the same as shifting it by 1.

Similarly, when shifting 64-bit integers, the runtime uses the lowest 6 bits of the shift count operand and shifting long by 64 is the same as shifting it by 0, and shifting it by 65 is the same as shifting it by 1.

Noncompliant Code Example

public int shift(int a) {
  int x = a >> 32; // Noncompliant
  return a << 48;  // Noncompliant
}

Compliant Solution

public int shift(int a) {
  int x = a >> 31;
  return a << 16;
}

Exceptions

This rule doesn't raise an issue when the shift by zero is obviously for cosmetic reasons:

  • When the value shifted is a literal.
  • When there is a similar shift at the same position on line before or after. E.g.:
bytes[loc+0] = (byte)(value >> 8);
bytes[loc+1] = (byte)(value >> 0);
xml:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

<!-- TODO Drop this dependency -->
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.8.1</version>
</dependency>

See

xml:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

<!-- FIXME we should update version to 3.8.1 -->
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.6</version>
</dependency>

See

xml:S125

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
php:S2737

A catch clause that only rethrows the caught exception has the same effect as omitting the catch altogether and letting it bubble up automatically, but with more code and the additional detriment of leaving maintainers scratching their heads.

Such clauses should either be eliminated or populated with the appropriate logic.

Noncompliant Code Example

$s = "";
try {
  $s = readMyFile($fileName);
} catch (Exception $e)  {
  throw $e;  // Noncompliant
}

Compliant Solution

$s = "";
try {
  $s = readMyFile($fileName);
} catch (Exception $e) {
  error_log($e->getMessage());
  throw $e;  // Compliant
}

or

$s = "";
try {
  $s = readMyFile($fileName);
} catch (Exception $e) {
  error_log($e->getMessage());
  throw new MyException("an exception occurred", 2, $e);  // Compliant
}

or

$s = readMyFile($fileName);
php:S4829

Reading Standard Input is security-sensitive. It has led in the past to the following vulnerabilities:

It is common for attackers to craft inputs enabling them to exploit software vulnerabilities. Thus any data read from the standard input (stdin) can be dangerous and should be validated.

This rule flags code that reads from the standard input.

Ask Yourself Whether

  • data read from the standard input is not sanitized before being used.

You are at risk if you answered yes to this question.

Recommended Secure Coding Practices

Sanitize all data read from the standard input before using it.

Questionable Code Example

// Any reference to STDIN is Questionable
$varstdin = STDIN; // Questionable
stream_get_line(STDIN, 40); // Questionable
stream_copy_to_stream(STDIN, STDOUT); // Questionable
// ...


// Except those references as they can't create an injection vulnerability.
ftruncate(STDIN, 5); // OK
ftell(STDIN); // OK
feof(STDIN); // OK
fseek(STDIN, 5); // OK
fclose(STDIN); // OK


// STDIN can also be referenced like this
$mystdin = 'php://stdin'; // Questionable

file_get_contents('php://stdin'); // Questionable
readfile('php://stdin'); // Questionable

$input = fopen('php://stdin', 'r'); // Questionable
fclose($input); // OK

See:

php:S3984

Creating a new Exception without actually throwing it is useless and is probably due to a mistake.

Noncompliant Code Example

if ($x < 0)
  new Exception('$x must be nonnegative');

Compliant Solution

if ($x < 0)
  throw new Exception('$x must be nonnegative');
vbnet:S1751

A loop with at most one iteration is equivalent to the use of an if statement to conditionally execute one piece of code. No developer expects to find such a use of a loop statement. If the initial intention of the author was really to conditionally execute one piece of code, an if statement should be used instead.

At worst that was not the initial intention of the author and so the body of the loop should be fixed to use the nested return, break or throw statements in a more appropriate way.

Noncompliant Code Example

For i As Integer = 0 To 10   'noncompliant, loop only executes once
  foo(i)
  Exit For
Next
...
For i As Integer = 0 To 10   'noncompliant, loop only executes once
  If i = Something
    Exit For
  Else
    foo(i)
    Return
  End If
Next

Compliant Solution

For i As Integer = 0 To 10
  foo(i)
Next
...
For i As Integer = 0 To 10
  If i = Something
    Exit For
  Else
    foo(i)
  End If
Next
vbnet:S4586

Returning Nothing from a non-async Task/Task(Of T) method will cause a NullReferenceException at runtime. This problem can be avoided by returning Task.FromResult(Of T)(Nothing) instead.

Noncompliant Code Example

Public Function GetFooAsync() As Task(Of Object)
    Return Nothing
End Function

Compliant Solution

Public Function GetFooAsync() As Task(Of Object)
    Return Task.FromResult(Of Object)(Nothing)
End Function
vbnet:S2737

A Catch clause that only rethrows the caught exception has the same effect as omitting the Catch altogether and letting it bubble up automatically, but with more code and the additional detriment of leaving maintainers scratching their heads.

Such clauses should either be eliminated or populated with the appropriate logic.

Noncompliant Code Example

Dim s As String = ""
Try
    s = File.ReadAllText(fileName)
Catch e As Exception
    Throw
End Try

Compliant Solution

Dim s As String = ""
Try
    s = File.ReadAllText(fileName)
Catch e As Exception
    logger.LogError(e)
    Throw
End Try

or

Dim s As String = File.ReadAllText(fileName)

Exceptions

This rule will not generate issues for Catch blocks with just Throw inside if they are followed by a Catch block for a more general exception type that does more than just rethrowing the exception.

Dim s As String = ""
Try
    s = File.ReadAllText(fileName)
Catch e As IOException 'Compliant, if removed will change the logic
    Throw
Catch e As Exception 'Compliant, does more than just rethrow
    logger.LogError(e)
    Throw
End Try
swift:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

Noncompliant Code Example

var post:NSString = "username=Steve&password=123456"  // Noncompliant
var postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!
//...
var request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPBody = postData
//...
var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)

Compliant Solution

var post:NSString = "username=\(getEncryptedUser())&password=\(getEncryptedPass())"
var postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!
//...
var request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPBody = postData
//...
var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)

See

swift:S1659

Declaring multiple variables on one line is difficult to read.

Noncompliant Code Example

var i = 1, j = 2

Compliant Solution

var i = 1
var j = 2

See

  • MISRA C++:2008, 8-0-1 - An init-declarator-list or a member-declarator-list shall consist of a single init-declarator or member-declarator respectively
  • CERT, DCL52-J. - Do not declare more than one variable per declaration
  • CERT, DCL04-C. - Do not declare more than one variable per declaration
swift:S2070

The MD5 algorithm and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them. That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160.

Consider using safer alternatives, such as SHA-256, or SHA-3.

Noncompliant Code Example

  var hash = MD5() // Noncompliant
  "123".sha1() // Noncompliant

Compliant Solution

  "123".sha512()

See

  • MITRE, CWE-328 - Reversible One-Way Hash
  • MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
  • OWASP Top 10 2017 Category A6 - Security Misconfiguration
  • SANS Top 25 - Porous Defenses
  • SHAttered - The first concrete collision attack against SHA-1.
swift:S2737

A catch clause that only rethrows the caught exception has the same effect as omitting the catch altogether and letting it bubble up automatically, but with more code and the additional detriment of leaving maintainers scratching their heads.

Such clauses should either be eliminated or populated with the appropriate logic.

Noncompliant Code Example

do {
    try loadImage(imagePath)
} catch { // Noncompliant
    throw error
}

Compliant Solution

do {
    try loadImage(imagePath)
} catch {
    handleImageError(error)
    throw error
}

or

try loadImage(imagePath)
csharpsquid:S4069

Operator overloading is convenient but unfortunately not portable across languages. To be able to access the same functionality from another language you need to provide an alternate named method following the convention:

Operator Method Name
+ (binary) Add
& BitwiseAnd
| BitwiseOr
/ Divide
== Equals
^ Xor
> Compare
>= Compare
!= Equals
< Compare
<= Compare
! LogicalNot
% Mod
* (binary) Multiply
~ OnesComplement
- (binary) Subtract
- (unary) Negate
+ (unary) Plus

This rule raises an issue when there is an operator overload without the expected named alternative method.

Exceptions

This rule does not raise an issue when the class implementing the comparison operators >, <, >= and <= contains a method named CompareTo.

csharpsquid:S3927

Serialization event handlers that don't have the correct signature will simply not be called, thus bypassing any attempts to augment the automated de/serialization.

This rule raises issue when a method marked with one of the following attributes is not private, does not return void, has type parameters, or does not have a single parameter of type System.Runtime.Serialization.StreamingContext:

  • System.Runtime.Serialization.OnSerializingAttribute
  • System.Runtime.Serialization.OnSerializedAttribute
  • System.Runtime.Serialization.OnDeserializingAttribute
  • System.Runtime.Serialization.OnDeserializedAttribute

Noncompliant Code Example

[Serializable]
public class Foo
{
    [OnSerializing]
    public void OnSerializing(StreamingContext context) {} // Noncompliant should be private

    [OnSerialized]
    int OnSerialized(StreamingContext context) {} // Noncompliant should return void

    [OnDeserializing]
    void OnDeserializing() {} // Noncompliant should have a single parameter of type StreamingContext

    [OnSerializing]
    public void OnSerializing2<T>(StreamingContext context) {} // Noncompliant should have no type parameters

    [OnDeserialized]
    void OnDeserialized(StreamingContext context, string str) {} // Noncompliant should have a single parameter of type StreamingContext
}

Compliant Solution

[Serializable]
public class Foo
{
    [OnSerializing]
    private void OnSerializing(StreamingContext context) {}

    [OnSerialized]
    private void OnSerialized(StreamingContext context) {}

    [OnDeserializing]
    private void OnDeserializing(StreamingContext context) {}

    [OnDeserialized]
    private void OnDeserialized(StreamingContext context) {}
}
csharpsquid:S2365

Most developers expect property access to be as efficient as field access. However, if a property returns a copy of an array or collection, it will be much slower than simple field access, contrary to the caller's likely expectations. Therefore, such properties should be refactored into methods so that callers are not surprised by the unexpectedly poor performance.

This rule detects calls to ToList, ToArray and array Clone.

Noncompliant Code Example

private List<string> _foo = new List<string> { "a", "b", "c" };
public IEnumerable<string> Foo  // Noncompliant
{
    get
    {
        return _foo.ToList();
    }
}

private string[] _bar = new string[] { "a", "b", "c" };
public IEnumerable<string> Bar // Noncompliant
{
    get
    {
        return (string[])_bar.Clone();
    }
}

Compliant Solution

private List<string> _foo = new List<string> { "a", "b", "c" };
private string[] _bar = new string[] { "a", "b", "c" };

public IEnumerable<string> GetFoo()
{
    return _foo.ToList();
}

public IEnumerable<string> GetBar()
{
    return (string[])_bar.Clone();
}
csharpsquid:S3902

Using Type.Assembly to get the current assembly is nearly free in terms of performance; it's a simple property access. On the other hand, Assembly.GetExecutingAssembly() can take up to 30 times as long because it walks up the call stack to find the assembly.

Note that Assembly.GetExecutingAssembly() is different than Type.Assembly because it dynamically returns the assembly that contains the startup object of the currently executed application. For example, if executed from an application it will return the application assembly, but if executed from a unit test project it could return the unit test assembly. Type.Assembly always returns the assembly that contains the specified type.

Noncompliant Code Example

public class Example
{
   public static void Main()
   {
      Assembly assem = Assembly.GetExecutingAssembly(); // Noncompliant
      Console.WriteLine("Assembly name: {0}", assem.FullName);
   }
}

Compliant Solution

public class Example
{
   public static void Main()
   {
      Assembly assem = typeof(Example).Assembly; // Here we use the type of the current class
      Console.WriteLine("Assembly name: {0}", assem.FullName);
   }
}
csharpsquid:S2931

An IDisposable object should be disposed (there are some rare exceptions where not disposing is fine, most notably Task). If a class has an IDisposable field, there can be two situations:

- The class observes a field that it under the responsibility of another class.

- The class owns the field, and is therefore responsible for calling Dispose on it.

In the second case, the safest way for the class to ensure Dispose is called is to call it in its own Dispose function, and therefore to be itself IDisposable. A class is considered to own an IDisposable field resource if it created the object referenced by the field.

Noncompliant Code Example

public class ResourceHolder   // Noncompliant; doesn't implement IDisposable
{
  private FileStream fs;  // This member is never Disposed
  public void OpenResource(string path)
  {
    this.fs = new FileStream(path, FileMode.Open); // I create the FileStream, I'm owning it
  }
  public void CloseResource()
  {
    this.fs.Close();
  }
}

Compliant Solution

public class ResourceHolder : IDisposable
{
  private FileStream fs;
  public void OpenResource(string path)
  {
    this.fs = new FileStream(path, FileMode.Open); // I create the FileStream, I'm owning it
  }
  public void CloseResource()
  {
    this.fs.Close();
  }

  public void Dispose()
  {
    this.fs.Dispose();
  }
}

See

csharpsquid:S2183

Shifting an integral number by 0 is equivalent to doing nothing but makes the code confusing for maintainers.

If the first operand is an int or uint (32-bit quantity), the shift count is given by the low-order five bits of the second operand. That is, the actual shift count is 0 to 31 bits.

Note that integral number with a less than 32-bit quantity (e.g. short, ushort...) are implicitly converted to int before the shifting operation and so the rule for int/uint applies.

If the first operand is a long or ulong (64-bit quantity), the shift count is given by the low-order six bits of the second operand. That is, the actual shift count is 0 to 63 bits.

Noncompliant Code Example

public void Main()
{
    short s = 1;
    short shortShift1 = (short)(s << 0); // Noncompliant
    short shortShift1 = (short)(s << 16); // Compliant as short will be cast to int (16 is between 0 and 31)
    short shortShift3 = (short)(s << 32); // Noncompliant, this is equivalent to shifting by 1

    int i = 1;
    int intShift1 = i << 0; // Noncompliant
    int intShift2 = i << 32; // Noncompliant, this is equivalent to shifting by 1

    long lg = 1;
    long longShift1 = lg << 0; // Noncompliant
    long longShift2 = lg << 64; // Noncompliant, this is equivalent to shifting by 1
}

Compliant Solution

public void Main()
{
    short s = 1;
    short shortShift1 = s;
    short shortShift1 = (short)(s << 16);
    short shortShift3 = (short)(s << 1);

    int i = 1;
    var intShift1 = i;
    var intShift2 = i << 1;

    long lg = 1;
    var longShift1 = lg;
    var longShift2 = lg << 1;
}

Exceptions

This rule doesn't raise an issue when the shift by zero is obviously for cosmetic reasons:

  • When the value shifted is a literal.
  • When there is a similar shift at the same position on line before or after. E.g.:
bytes[loc+0] = (byte)(value >> 8);
bytes[loc+1] = (byte)(value >> 0);

See

csharpsquid:S4226

It makes little sense to create an extension method when it is possible to just add that method to the class itself.

This rule raises an issue when an extension is declared in the same namespace as the class it is extending.

Noncompliant Code Example

namespace MyLibrary
{
    public class Foo
    {
        // ...
    }

    public static class MyExtensions
    {
        public static void Bar(this Foo a) // Noncompliant
        {
            // ...
        }
    }
}

Compliant Solution

Using separate namespace:

namespace MyLibrary
{
    public class Foo
    {
        // ...
    }
}

namespace Helpers
{
    public static class MyExtensions
    {
        public void Bar()
        {
            // ...
        }
    }
}

Merging the method in the class:

namespace MyLibrary
{
    public class Foo
    {
        // ...
        public void Bar()
        {
            // ...
        }
    }
}
csharpsquid:S1751

A loop with at most one iteration is equivalent to the use of an if statement to conditionally execute one piece of code. If the initial intention of the author was really to conditionally execute one piece of code, an if statement should be used instead. If that was not the initial intention of the author, the body of the loop should be fixed to use the nested return, break or throw statements in a more appropriate way.

Noncompliant Code Example

for (int i = 0; i < 10; i++)
{
    Console.WriteLine(i);
    break;  // Noncompliant, loop only executes once
}
...
foreach (var item in items)
{
    return item;  // Noncompliant, loop only executes once
}
...

Compliant Solution

for (int i = 0; i < 10; i++)
{
    Console.WriteLine(i);
}
...
var item = items.FirstOrDefault();
if (item != null)
{
    return item;
}
...
csharpsquid:S2737

A catch clause that only rethrows the caught exception has the same effect as omitting the catch altogether and letting it bubble up automatically, but with more code and the additional detriment of leaving maintainers scratching their heads.

Such clauses should either be eliminated or populated with the appropriate logic.

Noncompliant Code Example

string s = "";
try
{
  s = File.ReadAllText(fileName);
}
catch (Exception e)  // Noncompliant
{
  throw;
}

Compliant Solution

string s = "";
try
{
  s = File.ReadAllText(fileName);
}
catch (Exception e) // Compliant
{
  logger.LogError(e);
  throw;
}

or

string s = File.ReadAllText(fileName);

Exceptions

This rule will not generate issues for catch blocks with just throw inside if they are followed by a catch block for a more general exception type that does more than just rethrowing the exception.

var s = ""
try
{
    s = File.ReadAllText(fileName);
}
catch (IOException) // Compliant, if removed will change the logic
{
    throw;
}
catch (Exception)  // Compliant, does more than just rethrow
{
    logger.LogError(e);
    throw;
}
csharpsquid:S2436

A method or class with too many type parameters has likely aggregated too many responsibilities and should be split.

Noncompliant Code Example

With the default parameter value of 2:

<S, T, U, V> void foo() {} // Noncompliant; not really readable
<String, Integer, Object, String>foo(); // especially on invocations
csharpsquid:S4039

When a base type explicitly implements a public interface method, that method is only accessible in derived types through a reference to the current instance (namely this). If the derived type explicitly overrides that interface method, the base implementation becomes inaccessible.

This rule raises an issue when an unsealed, externally visible type provides an explicit method implementation of a public interface and does not provide an alternate, externally visible method with the same name.

Noncompliant Code Example

public interface IMyInterface
{
    void MyMethod();
}

public class Foo : IMyInterface
{
    void IMyInterface.MyMethod() // Noncompliant
    {
        MyMethod();
    }

    void MyMethod()
    {
        // Do something ...
    }
}

public class Bar : Foo, IMyInterface
{
    public void MyMethod()
    {
        // Can't access base.MyMethod()
        // ((IMyInterface)this).MyMethod() would be a recursive call
    }
}

Compliant Solution

public interface IMyInterface
{
    void MyMethod();
}

public class Foo : IMyInterface
{
    void IMyInterface.MyMethod()
    {
        MyMethod();
    }

    protected void MyMethod() // or public
    {
        // Do something ...
    }
}

public class Bar : Foo, IMyInterface
{
    public void MyMethod()
    {
        // Do something
        base.MyMethod();
    }
}

Exceptions

This rule does not report a violation for an explicit implementation of IDisposable.Dispose when an externally visible Close() or System.IDisposable.Dispose(Boolean) method is provided.

csharpsquid:S3984

Creating a new Exception without actually throwing it is useless and is probably due to a mistake.

Noncompliant Code Example

if (x < 0)
{
  new ArgumentException("x must be nonnegative");
}

Compliant Solution

if (x < 0)
{
  throw new ArgumentException("x must be nonnegative");
}
objc:S1141

Nesting try/catch or @try/@catch blocks severely impacts the readability of source code because it makes it too difficult to understand which block will catch which exception.

This C++ example also applies to Objective-C.

Noncompliant Code Example

try {
  try {                                     // Noncompliant
    doSomething();
  } catch (RuntimeException e) {
    /* Ignore */
  }

  doSomethingElse();
} catch (Exception e) {
  /* ... */
}

Compliant Solution

try {
  dedicatedMethod();                        // Compliant
  doSomethingElse();
} catch (Exception e) {
  /* ... */
}

/* ... */

private void dedicatedMethod() {
  try {                                     // Compliant
    doSomething();
  } catch (RuntimeException e) {
    /* Ignore */
  }
}
objc:S1706

While exceptions are a common feature of modern languages, there are several reasons to potentially avoid them:

  • They make the control flow of a program difficult to understand, because they introduce additional exit points.
  • The use of exceptions in new code can make that code difficult to integrate with existing, non-exception-safe code.
  • They add to the size of each binary produced, thereby increasing both compile time and final executable size.
  • They may incur a small performance penalty.
  • The time required to handle an exception is not easy to assess, which makes them difficult to use for hard real-time applications.

This rule raises an issue when:

  • an exception is thrown
  • a try-catch block is used
  • an exception specification (throw(xxx)) is present.

Noncompliant Code Example

This C++ code example also applies to Objective-C.

double myfunction(char param) throw (int); // Noncompliant
void f {
  try // Noncompliant
  {
    do_something();
    throw 1; // Noncompliant
  }
  catch (...)
  {
    // handle exception
  }
}

Compliant Solution

double myfunction(char param) noexcept;
bool f {
  if (!do_something()); {
    // Handle the situation
    return false;
  }
  // Rest of the code
  return true;
}

Exceptions

noexcept specifications are ignored, because even if you choose not to use exceptions in your code, it's important to decorate as noexcept certain functions (for instance, move constructors that do not throw). This decoration can be detected by type traits, and some meta-programming techniques rely on this information.

objc:S1854

A dead store happens when a local variable is assigned a value that is not read by any subsequent instruction. Calculating or retrieving a value only to then overwrite it or throw it away, could indicate a serious error in the code. Even if it's not an error, it is at best a waste of resources. Therefore all calculated values should be used.

Noncompliant Code Example

i = a + b; // Noncompliant; calculation result not used before value is overwritten
i = compute();

Compliant Solution

i = a + b;
i += compute();

Exceptions

This rule ignores:

  • variable declarations initializers
  • prefix and postfix increments and decrements x++;
  • null pointer assignments x = NULL;
  • self assignments (i.e. x = x;)

See

objc:S1749

Shared coding conventions allow teams to collaborate efficiently. This rule checks that type specifiers always appear in the following order:

  1. typedef
  2. type name, spelling of built-in types with more than one type-specifier:
    1. signedness - signed or unsigned
    2. last single type-specifier or
      • short int
      • long int
      • long long int
      • long double

Since the positioning of the const keyword is controversial, this rule does not check it.

Noncompliant Code Example

int typedef T;

double long d;
char unsigned ch;
long signed int i;

Compliant Solution

typedef int T;

long double d;
unsigned char ch;
signed long int i;

objc:S3923

Having all branches in a switch or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a switch/if chain at all.

Noncompliant Code Example

if (b == 0) {  // Noncompliant
  doOneMoreThing();
} else {
  doOneMoreThing();
}

int b = a > 12 ? 4 : 4;  // Noncompliant

switch (i) {  // Noncompliant
  case 1:
    doSomething();
    break;
  case 2:
    doSomething();
    break;
  case 3:
    doSomething();
    break;
  default:
    doSomething();
}

Exceptions

This rule does not apply to if chains without else-s, or to switch-es without default clauses.

if(b == 0) {    //no issue, this could have been done on purpose to make the code more readable
  doSomething();
} else if(b == 1) {
  doSomething();
}
objc:S1751

A loop with at most one iteration is equivalent to the use of an if statement to conditionally execute one piece of code. No developer expects to find such a use of a loop statement. If the initial intention of the author was really to conditionally execute one piece of code, an if statement should be used instead.

At worst that was not the initial intention of the author and so the body of the loop should be fixed to use the nested return, break or throw statements in a more appropriate way.

Noncompliant Code Example

for (int i = 0; i < 10; i++) { // noncompliant, loop only executes once
  printf("i is %d", i);
  break;
}
...
for (int i = 0; i < 10; i++) { // noncompliant, loop only executes once
  if(i == x) {
    break;
  } else {
    printf("i is %d", i);
    return;
  }
}

Compliant Solution

for (int i = 0; i < 10; i++) {
  printf("i is %d", i);
}
...
for (int i = 0; i < 10; i++) {
  if(i == x) {
    break;
  } else {
    printf("i is %d", i);
  }
}
objc:S1079

The %s placeholder is used to read a word into a string.

By default, there is no restriction on the length of that word, and the developer is required to pass a sufficiently large buffer for storing it.

No matter how large the buffer is, there will always be a longer word.

Therefore, programs relying on %s are vulnerable to buffer overflows.

A field width specifier can be used together with the %s placeholder to limit the number of bytes which will by written to the buffer.

Note that an additional byte is required to store the null terminator.

Noncompliant Code Example

char buffer[10];
scanf("%s", buffer);      // Noncompliant - will overflow when a word longer than 9 characters is entered

Compliant Solution

char buffer[10];
scanf("%9s", buffer);     // Compliant - will not overflow

See

objc:S1871

Having two cases in a switch statement or two branches in an if chain 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 chain they should be combined, or for a switch, one should fall through to the other.

Noncompliant Code Example

switch (i) {
  case 1:
    doFirstThing();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  case 3:  // Noncompliant; duplicates case 1's implementation
    doFirstThing();
    doSomething();
    break;
  default:
    doTheRest();
}

if (a >= 0 && a < 10) {
  doFirstThing();
  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else if (a >= 20 && a < 50) {
  doFirstThing();
  doTheThing();  // Noncompliant; duplicates first condition
}
else {
  doTheRest();
}

Exceptions

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a switch statement that contain a single line of code with or without a following break.

if(a == 1) {
  doSomething();  //no issue, usually this is done on purpose to increase the readability
} else if (a == 2) {
  doSomethingElse();
} else {
  doSomething();
}

But this exception does not apply to if chains without else-s, or to switch-es without default clauses when all branches have the same single line of code. In case of if chains with else-s, or of switch-es with default clauses, rule S3923 raises a bug.

if(a == 1) {
  doSomething();  //Noncompliant, this might have been done on purpose but probably not
} else if (a == 2) {
  doSomething();
}
objc:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Noncompliant Code Example

if ( a == a ) { // always true
  do_z();
}
if ( a != a ) { // always false
  do_y();
}
if ( a == b && a == b ) { // if the first one is true, the second one is too
  do_x();
}
if (a == b || a == b ) { // if the first one is true, the second one is too
  do_w();
}

if (5 / 5) { // always 1
  do_v();
}
if (5 - 5) { // always 0
  do_u();
}

Exceptions

The following are ignored:

  • The expression 1 << 1
  • When an increment or decrement operator is used, ex: *p++ == *p++
  • Bitwise operators |, &, ^

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
objc:S2737

A catch clause that only rethrows the caught exception has the same effect as omitting the catch altogether and letting it bubble up automatically, but with more code and the additional detriment of leaving maintainers scratching their heads.

Such clauses should either be eliminated or populated with the appropriate logic.

Noncompliant Code Example

try {
  saveDocument();
} catch (const std::exception& e) { // Noncompliant
  throw;
}

Compliant Solution

try {
  saveDocument();
} catch (const std::exception& e) { // Compliant
  log << e.what();
  throw;
}

or

saveDocument();
objc:S3973

In the absence of enclosing curly braces, the line immediately after a conditional is the one that is conditionally executed. By both convention and good practice, such lines are indented. In the absence of both curly braces and indentation the intent of the original programmer is entirely unclear and perhaps not actually what is executed. Additionally, such code is highly likely to be confusing to maintainers.

Noncompliant Code Example

if (condition)  // Noncompliant
doTheThing();

doTheOtherThing();
somethingElseEntirely();

foo();

Compliant Solution

if (condition)
  doTheThing();

doTheOtherThing();
somethingElseEntirely();

foo();
c:S1854

A dead store happens when a local variable is assigned a value that is not read by any subsequent instruction. Calculating or retrieving a value only to then overwrite it or throw it away, could indicate a serious error in the code. Even if it's not an error, it is at best a waste of resources. Therefore all calculated values should be used.

Noncompliant Code Example

i = a + b; // Noncompliant; calculation result not used before value is overwritten
i = compute();

Compliant Solution

i = a + b;
i += compute();

Exceptions

This rule ignores:

  • variable declarations initializers
  • prefix and postfix increments and decrements x++;
  • null pointer assignments x = NULL;
  • self assignments (i.e. x = x;)

See

c:S1749

Shared coding conventions allow teams to collaborate efficiently. This rule checks that type specifiers always appear in the following order:

  1. typedef
  2. type name, spelling of built-in types with more than one type-specifier:
    1. signedness - signed or unsigned
    2. last single type-specifier or
      • short int
      • long int
      • long long int
      • long double

Since the positioning of the const keyword is controversial, this rule does not check it.

Noncompliant Code Example

int typedef T;

double long d;
char unsigned ch;
long signed int i;

Compliant Solution

typedef int T;

long double d;
unsigned char ch;
signed long int i;

c:S3923

Having all branches in a switch or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a switch/if chain at all.

Noncompliant Code Example

if (b == 0) {  // Noncompliant
  doOneMoreThing();
} else {
  doOneMoreThing();
}

int b = a > 12 ? 4 : 4;  // Noncompliant

switch (i) {  // Noncompliant
  case 1:
    doSomething();
    break;
  case 2:
    doSomething();
    break;
  case 3:
    doSomething();
    break;
  default:
    doSomething();
}

Exceptions

This rule does not apply to if chains without else-s, or to switch-es without default clauses.

if(b == 0) {    //no issue, this could have been done on purpose to make the code more readable
  doSomething();
} else if(b == 1) {
  doSomething();
}
c:S1751

A loop with at most one iteration is equivalent to the use of an if statement to conditionally execute one piece of code. No developer expects to find such a use of a loop statement. If the initial intention of the author was really to conditionally execute one piece of code, an if statement should be used instead.

At worst that was not the initial intention of the author and so the body of the loop should be fixed to use the nested return, break or throw statements in a more appropriate way.

Noncompliant Code Example

for (int i = 0; i < 10; i++) { // noncompliant, loop only executes once
  printf("i is %d", i);
  break;
}
...
for (int i = 0; i < 10; i++) { // noncompliant, loop only executes once
  if(i == x) {
    break;
  } else {
    printf("i is %d", i);
    return;
  }
}

Compliant Solution

for (int i = 0; i < 10; i++) {
  printf("i is %d", i);
}
...
for (int i = 0; i < 10; i++) {
  if(i == x) {
    break;
  } else {
    printf("i is %d", i);
  }
}
c:S1871

Having two cases in a switch statement or two branches in an if chain 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 chain they should be combined, or for a switch, one should fall through to the other.

Noncompliant Code Example

switch (i) {
  case 1:
    doFirstThing();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  case 3:  // Noncompliant; duplicates case 1's implementation
    doFirstThing();
    doSomething();
    break;
  default:
    doTheRest();
}

if (a >= 0 && a < 10) {
  doFirstThing();
  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else if (a >= 20 && a < 50) {
  doFirstThing();
  doTheThing();  // Noncompliant; duplicates first condition
}
else {
  doTheRest();
}

Exceptions

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a switch statement that contain a single line of code with or without a following break.

if(a == 1) {
  doSomething();  //no issue, usually this is done on purpose to increase the readability
} else if (a == 2) {
  doSomethingElse();
} else {
  doSomething();
}

But this exception does not apply to if chains without else-s, or to switch-es without default clauses when all branches have the same single line of code. In case of if chains with else-s, or of switch-es with default clauses, rule S3923 raises a bug.

if(a == 1) {
  doSomething();  //Noncompliant, this might have been done on purpose but probably not
} else if (a == 2) {
  doSomething();
}
c:S1079

The %s placeholder is used to read a word into a string.

By default, there is no restriction on the length of that word, and the developer is required to pass a sufficiently large buffer for storing it.

No matter how large the buffer is, there will always be a longer word.

Therefore, programs relying on %s are vulnerable to buffer overflows.

A field width specifier can be used together with the %s placeholder to limit the number of bytes which will by written to the buffer.

Note that an additional byte is required to store the null terminator.

Noncompliant Code Example

char buffer[10];
scanf("%s", buffer);      // Noncompliant - will overflow when a word longer than 9 characters is entered

Compliant Solution

char buffer[10];
scanf("%9s", buffer);     // Compliant - will not overflow

See

c:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Noncompliant Code Example

if ( a == a ) { // always true
  do_z();
}
if ( a != a ) { // always false
  do_y();
}
if ( a == b && a == b ) { // if the first one is true, the second one is too
  do_x();
}
if (a == b || a == b ) { // if the first one is true, the second one is too
  do_w();
}

if (5 / 5) { // always 1
  do_v();
}
if (5 - 5) { // always 0
  do_u();
}

Exceptions

The following are ignored:

  • The expression 1 << 1
  • When an increment or decrement operator is used, ex: *p++ == *p++
  • Bitwise operators |, &, ^

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
c:S3973

In the absence of enclosing curly braces, the line immediately after a conditional is the one that is conditionally executed. By both convention and good practice, such lines are indented. In the absence of both curly braces and indentation the intent of the original programmer is entirely unclear and perhaps not actually what is executed. Additionally, such code is highly likely to be confusing to maintainers.

Noncompliant Code Example

if (condition)  // Noncompliant
doTheThing();

doTheOtherThing();
somethingElseEntirely();

foo();

Compliant Solution

if (condition)
  doTheThing();

doTheOtherThing();
somethingElseEntirely();

foo();
cpp:S1141

Nesting try/catch or @try/@catch blocks severely impacts the readability of source code because it makes it too difficult to understand which block will catch which exception.

This C++ example also applies to Objective-C.

Noncompliant Code Example

try {
  try {                                     // Noncompliant
    doSomething();
  } catch (RuntimeException e) {
    /* Ignore */
  }

  doSomethingElse();
} catch (Exception e) {
  /* ... */
}

Compliant Solution

try {
  dedicatedMethod();                        // Compliant
  doSomethingElse();
} catch (Exception e) {
  /* ... */
}

/* ... */

private void dedicatedMethod() {
  try {                                     // Compliant
    doSomething();
  } catch (RuntimeException e) {
    /* Ignore */
  }
}
cpp:S1706

While exceptions are a common feature of modern languages, there are several reasons to potentially avoid them:

  • They make the control flow of a program difficult to understand, because they introduce additional exit points.
  • The use of exceptions in new code can make that code difficult to integrate with existing, non-exception-safe code.
  • They add to the size of each binary produced, thereby increasing both compile time and final executable size.
  • They may incur a small performance penalty.
  • The time required to handle an exception is not easy to assess, which makes them difficult to use for hard real-time applications.

This rule raises an issue when:

  • an exception is thrown
  • a try-catch block is used
  • an exception specification (throw(xxx)) is present.

Noncompliant Code Example

This C++ code example also applies to Objective-C.

double myfunction(char param) throw (int); // Noncompliant
void f {
  try // Noncompliant
  {
    do_something();
    throw 1; // Noncompliant
  }
  catch (...)
  {
    // handle exception
  }
}

Compliant Solution

double myfunction(char param) noexcept;
bool f {
  if (!do_something()); {
    // Handle the situation
    return false;
  }
  // Rest of the code
  return true;
}

Exceptions

noexcept specifications are ignored, because even if you choose not to use exceptions in your code, it's important to decorate as noexcept certain functions (for instance, move constructors that do not throw). This decoration can be detected by type traits, and some meta-programming techniques rely on this information.

cpp:S3654

Throwing an exception from a destructor results in undefined behavior, meaning that your program could be terminated abruptly without neatly destroying others objects.

Thus destructors should never throw exceptions. Instead, they should catch and handle those thrown by the functions they call, and be noexcept.

This rule raises an issue when a destructor is not noexcept. By default, destructors are noexcept, therefore most of the time, nothing needs to be written in the source code. A destructor is not noexcept if:

- the base class or a data member has a non noexcept destructor,

- the destructor is decorated with the noexcept keyword followed by something that evaluates to false.

Noncompliant Code Example

struct A {
  ~A() noexcept(false) {} // Noncompliant
};

struct C {
  /* ... */
  A a; // This member data prevents automatic declaration of the destructor as noexcept
  ~C() { // Noncompliant
    /* ... */
  }
};

Compliant Solution

struct A {
  ~A() noexcept(true) {}
};

struct C {
  /* ... */
  A a;
  ~C() { // Compliant, noexcept by default
    /* ... */
  }
};
cpp:S4999

The functions memcpy, memmove, and memset can only be used for objects of trivially copyable types. This includes scalar types, arrays, and trivially copyable classes.

A class type is trivially copyable if:

  • One or more of the following methods is trivial and the rest are deleted: copy constructor, move constructor, copy assignment operator, and move assignment operator,
  • It has a trivial, non-deleted destructor.

A consequence of those rules is that a trivially copyable class type can only have trivially copyable members or base classes.

Noncompliant Code Example

class Shape {
public:
  int x;
  int y;
  virtual ~Shape(); // This makes the class non trivially copyable
};

void f(Shape *dest, Shape *source)
{
    memcpy(dest, source, sizeof Shape); // Noncompliant
}

Compliant Solution

class Shape {
public:
  int x;
  int y;
  virtual ~Shape(); // This makes the class non trivially copyable
};

void f(Shape *dest, Shape *source)
{
    (*dest) = (*source);
}
cpp:S1854

A dead store happens when a local variable is assigned a value that is not read by any subsequent instruction. Calculating or retrieving a value only to then overwrite it or throw it away, could indicate a serious error in the code. Even if it's not an error, it is at best a waste of resources. Therefore all calculated values should be used.

Noncompliant Code Example

i = a + b; // Noncompliant; calculation result not used before value is overwritten
i = compute();

Compliant Solution

i = a + b;
i += compute();

Exceptions

This rule ignores:

  • variable declarations initializers
  • prefix and postfix increments and decrements x++;
  • null pointer assignments x = NULL;
  • self assignments (i.e. x = x;)

See

cpp:S3470

It may seem tidy to add your new declarations to the std or posix namespaces, but doing so results in undefined behavior. The C++14 Standard, [namespace.std] (ISO/IEC 14882-2014 §17.6.4.2.1), paragraphs 1 and 2 states:

  1. The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.
  2. The behavior of a C++ program is undefined if it declares:
    • an explicit specialization of any member function of a standard library class template, or
    • an explicit specialization of any member function template of a standard library class or class template, or
    • an explicit or partial specialization of any member class template of a standard library class or class template.

In addition to restricting extensions to the the std namespace, the C++14 Standard goes on in §17.6.4.2.2 to say:

  1. The behavior of a C++ program is undefined if it adds declarations or definitions to namespace posix or to a namespace within namespace posix unless otherwise specified. The namespace posix is reserved for use by ISO/IEC 9945 and other POSIX standards.

This rule raises an issue for any modification of the standard std and posix namespaces.

Noncompliant Code Example

namespace std {  // Noncompliant
  int x;
}

Compliant Solution

namespace expanded_std {
  int x;
}

Exceptions

A namespace fragment that only contains template specializations or explicit instantiations is ignored by this rule.

See

cpp:S2156

The difference between private and protected visibility is that child classes can see and use protected members, but they cannot see private ones. Since a final class will have no children, marking the members of a final class protected is confusingly pointless.

Noncompliant Code Example

class C final {
protected:  // Noncompliant
  void fun();
};

Compliant Solution

class C final {
private:
  void fun();
};

Exceptions

When overriding a base class function, it is common practice to keep the same visibility as for the base class. This rule ignores protected functions in a final class that are overrides of a base class protected function.

cpp:S1749

Shared coding conventions allow teams to collaborate efficiently. This rule checks that type specifiers always appear in the following order:

  1. typedef
  2. type name, spelling of built-in types with more than one type-specifier:
    1. signedness - signed or unsigned
    2. last single type-specifier or
      • short int
      • long int
      • long long int
      • long double

Since the positioning of the const keyword is controversial, this rule does not check it.

Noncompliant Code Example

int typedef T;

double long d;
char unsigned ch;
long signed int i;

Compliant Solution

typedef int T;

long double d;
unsigned char ch;
signed long int i;

cpp:S3923

Having all branches in a switch or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a switch/if chain at all.

Noncompliant Code Example

if (b == 0) {  // Noncompliant
  doOneMoreThing();
} else {
  doOneMoreThing();
}

int b = a > 12 ? 4 : 4;  // Noncompliant

switch (i) {  // Noncompliant
  case 1:
    doSomething();
    break;
  case 2:
    doSomething();
    break;
  case 3:
    doSomething();
    break;
  default:
    doSomething();
}

Exceptions

This rule does not apply to if chains without else-s, or to switch-es without default clauses.

if(b == 0) {    //no issue, this could have been done on purpose to make the code more readable
  doSomething();
} else if(b == 1) {
  doSomething();
}
cpp:S3468

Like a clever insect posing as a leaf, there are constructs in C++ which look like variable declarations, but which are actually interpreted by the compiler as function or function pointer declarations. Beyond the problem of confusing maintainers, it's highly likely in such cases that what the coder intended is not what the compiler will do.

Noncompliant Code Example

void doWork(Status status) {
  Lock lock();  // Noncompliant; declares function named "lock"
  ...
  Form form(ProgressBar(status)); // Noncompliant; declares function named "form" with "status" parameter
  ...
}

Compliant Solution

void doWork(Status status) {
  Lock lock;  // remove the parentheses to declare a variable
  ...
  Form form((ProgressBar(status))); // add a pair of parentheses to declare a variable
  ...
}

Since C++11 you can also use direct initialization to declare a variable:

void doWork(Status status) {
  Lock lock{};
  ...
  Form form{ProgressBar{status}};
  ...
}

See

cpp:S1771

While it is possible to define a struct with member functions in C++, the general expectation is that structs only aggregate data, while classes are used for fully encapsulated abstractions, containing data and methods. Thus, including a member function in a struct is likely to lead to confusion at best and should be avoided.

Noncompliant Code Example

struct S
{
  S(int x, int y) : x(x), y(y) {}
  int x;
  int y;
  public:
    int fun(); // Noncompliant
};

Compliant Solution

struct S
{
  S(int x, int y) : x(x), y(y) {}
  int x;
  int y;
};

Exceptions

Constructors are ignored for this rule, because they are the only way that a struct designer can enforce that all fields of a struct are correctly initialized.

cpp:S1751

A loop with at most one iteration is equivalent to the use of an if statement to conditionally execute one piece of code. No developer expects to find such a use of a loop statement. If the initial intention of the author was really to conditionally execute one piece of code, an if statement should be used instead.

At worst that was not the initial intention of the author and so the body of the loop should be fixed to use the nested return, break or throw statements in a more appropriate way.

Noncompliant Code Example

for (int i = 0; i < 10; i++) { // noncompliant, loop only executes once
  printf("i is %d", i);
  break;
}
...
for (int i = 0; i < 10; i++) { // noncompliant, loop only executes once
  if(i == x) {
    break;
  } else {
    printf("i is %d", i);
    return;
  }
}

Compliant Solution

for (int i = 0; i < 10; i++) {
  printf("i is %d", i);
}
...
for (int i = 0; i < 10; i++) {
  if(i == x) {
    break;
  } else {
    printf("i is %d", i);
  }
}
cpp:S1871

Having two cases in a switch statement or two branches in an if chain 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 chain they should be combined, or for a switch, one should fall through to the other.

Noncompliant Code Example

switch (i) {
  case 1:
    doFirstThing();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  case 3:  // Noncompliant; duplicates case 1's implementation
    doFirstThing();
    doSomething();
    break;
  default:
    doTheRest();
}

if (a >= 0 && a < 10) {
  doFirstThing();
  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else if (a >= 20 && a < 50) {
  doFirstThing();
  doTheThing();  // Noncompliant; duplicates first condition
}
else {
  doTheRest();
}

Exceptions

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a switch statement that contain a single line of code with or without a following break.

if(a == 1) {
  doSomething();  //no issue, usually this is done on purpose to increase the readability
} else if (a == 2) {
  doSomethingElse();
} else {
  doSomething();
}

But this exception does not apply to if chains without else-s, or to switch-es without default clauses when all branches have the same single line of code. In case of if chains with else-s, or of switch-es with default clauses, rule S3923 raises a bug.

if(a == 1) {
  doSomething();  //Noncompliant, this might have been done on purpose but probably not
} else if (a == 2) {
  doSomething();
}
cpp:S1079

The %s placeholder is used to read a word into a string.

By default, there is no restriction on the length of that word, and the developer is required to pass a sufficiently large buffer for storing it.

No matter how large the buffer is, there will always be a longer word.

Therefore, programs relying on %s are vulnerable to buffer overflows.

A field width specifier can be used together with the %s placeholder to limit the number of bytes which will by written to the buffer.

Note that an additional byte is required to store the null terminator.

Noncompliant Code Example

char buffer[10];
scanf("%s", buffer);      // Noncompliant - will overflow when a word longer than 9 characters is entered

Compliant Solution

char buffer[10];
scanf("%9s", buffer);     // Compliant - will not overflow

See

cpp:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Noncompliant Code Example

if ( a == a ) { // always true
  do_z();
}
if ( a != a ) { // always false
  do_y();
}
if ( a == b && a == b ) { // if the first one is true, the second one is too
  do_x();
}
if (a == b || a == b ) { // if the first one is true, the second one is too
  do_w();
}

if (5 / 5) { // always 1
  do_v();
}
if (5 - 5) { // always 0
  do_u();
}

Exceptions

The following are ignored:

  • The expression 1 << 1
  • When an increment or decrement operator is used, ex: *p++ == *p++
  • Bitwise operators |, &, ^

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
cpp:S2737

A catch clause that only rethrows the caught exception has the same effect as omitting the catch altogether and letting it bubble up automatically, but with more code and the additional detriment of leaving maintainers scratching their heads.

Such clauses should either be eliminated or populated with the appropriate logic.

Noncompliant Code Example

try {
  saveDocument();
} catch (const std::exception& e) { // Noncompliant
  throw;
}

Compliant Solution

try {
  saveDocument();
} catch (const std::exception& e) { // Compliant
  log << e.what();
  throw;
}

or

saveDocument();
cpp:S4963

Most classes should not directly handle resources, but instead use members that perform resource handling for them:

- For memory, it can be std::unique_ptr, std::shared_ptr, std::vector...

- For files, it can be std::ofstream, std::ifstream...

- ...

Classes that avoid directly handling resources don't need to define any of the special member functions required to properly handle resources: destructor, copy constructor, move constructor, copy-assignment operator, move-assignment operator. That's because the versions of those functions provided by the compiler do the right thing automatically, which is especially useful because writing these functions correctly is typically tricky and error-prone.

Omitting all of these functions from a class is known as the Rule of Zero because no special function should be defined.

In some cases, this rule take a slightly different shape, while respecting the fact that no definition of those functions will be provided:

- For the base class of a polymorphic hierarchy, the destructor should be declared as public and virtual, and defaulted (=default). The copy-constructor and copy-assignment operator should be deleted. (If you want to copy classes in a polymorphic hierarchy, use the clone idiom.) The move operation will be automatically deleted by the compiler.

- For other kinds of base classes, the destructor should be protected and non-virtual, and defaulted (=default).

Noncompliant Code Example

class FooPointer { // Non compliant. The code is correct (it follows the rule of 5), but unnecessarily complex
  Foo* pFoo;
public:
  FooPointer(int initValue) {
    pFoo = new Foo(initValue);
  }
  ~FooPointer() {
    delete pFoo;
  }
  FooPointer(FooPointer const &fp) = delete;
  FooPointer const & operator=(FooPointer const &fp) = delete;
  FooPointer(FooPointer &&fp) noexcept {
    pFoo = fp.pFoo;
    fp.pFoo = nullptr;
  }
  FooPointer const & operator=(FooPointer &&fp) {
    FooPointer temp(std::move(fp));
    std::swap(temp.pFoo, pFoo);
    return *this;
  }
};

Compliant Solution

class FooPointer { // Compliant, std::unique_ptr is use to handle memory management
  unique_ptr<Foo> pFoo;
public:
  FooPointer(int initValue) : pFoo(std::make_unique<Foo>(initValue) {}
};

A polymorphic base class can look like this:

class Base { // Compliant, the virtual destructor is defaulted
public:
  virtual ~Base() = default;
  Base(Base const &) = delete;
  Base &operator=(Base const &) = delete;
};

Exceptions

Empty destructors are treated as though they were defaulted.

See

cpp:S5019

A lambda can only capture local variables. When a lambda is defined within a member function, you may believe that you are capturing a member variable of the current class, but in fact, what you are capturing is this. This may be very surprising, and lead to bugs if the lambda is then used after the current object has been destroyed.

Therefore, it's better to be explicit about exactly what is captured as soon as this is captured.

Noncompliant Code Example

class A {
  int i;
  void f(int j) {
    auto l = [=](int k) { return i+j+k;}; // Noncompliant, someone reading the code might believe that i is captured by copy
  }
};

Compliant Solution

class A {
  int i;
  void f(int j) {
    auto l = [this, j](int k) { return i+j+k;}; // It is now clearer that i is not directly captured
    // auto l = [i, j](int k) { return i+j+k;}; // Would not compile
  }
};

See

* C++ core guidelines F.54 If you capture this, capture all variables explicitly (no default capture)

cpp:S5020

The use of srand together with rand to seed the random number generator and then generate numbers usually produces low-quality randomness. Further, rand can only provide a number between 0 and RAND_MAX, and it is left to the caller to transform the result into what is actually required (E.G. a float between 0 and 1 for a random percentage, an int between 1 and 6 for a dice game, ...), and that transformation might introduce additional biases.

C++11 introduced the <random> library, which contains several high quality random value generators as well as statistical distributions you can use to put the results in the form you need. Those mechanisms should be used instead of rand and srand.

Additionally, std::random_shuffle, which is deprecated in C++14 and removed in C++17, uses rand and should be replaced by std::shuffle, which uses the random number generators provided by <random>.

Noncompliant Code Example

#include <stdlib.h>
#include <algorithm>
// ...

void f() {
  srand(time(nullptr)); // Noncompliant
  vector<int> v;
  int size = rand() % 1000 + 1000; // Noncompliant, note that this way of coercing the result introduces extra bias
  for (auto i = 0; i < size; ++i) {
    v.push_back(i);
  }
  random_shuffle(v.begin(), v.end()); // Noncompliant
  for (auto i : v) { cout << i << " "; }
}

Compliant Solution

#include <algorithm>
#include <random>
// ...

void f() {
  random_device rd;  // Will be used to obtain a seed for the random number engine
  mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
  uniform_int_distribution<> dis(1000, 1999); // Same distribution as before, but explicit and without bias
  vector<int> v;
  for (auto i = 0; i < dis(gen); ++i) {
    v.push_back(i);
  }
  shuffle(v.begin(), v.end(), gen);
  for (auto i : v) { cout << i << " "; }
}
cpp:S3973

In the absence of enclosing curly braces, the line immediately after a conditional is the one that is conditionally executed. By both convention and good practice, such lines are indented. In the absence of both curly braces and indentation the intent of the original programmer is entirely unclear and perhaps not actually what is executed. Additionally, such code is highly likely to be confusing to maintainers.

Noncompliant Code Example

if (condition)  // Noncompliant
doTheThing();

doTheOtherThing();
somethingElseEntirely();

foo();

Compliant Solution

if (condition)
  doTheThing();

doTheOtherThing();
somethingElseEntirely();

foo();
objc:S2479

Control characters aren't visible to maintainers, so they should be escaped.

Noncompliant Code Example

const char* foo = "A	B";  // Noncompliant, contains a tabulation

Compliant Solution

const char* foo = "A\tB";  // Compliant, use escaped value

Exceptions

Raw string literals has no escape character mechanism.

objc:S1143

Returning from a finally block suppresses the propagation of any unhandled exception which was thrown in the try or catch block.

Noncompliant Code Example

void openResource() {
  @throw [NSException exceptionWithName:@"FileNotFoundException" reason:@"File Not Found on System" userInfo:nil];
}

void fun() {
  @try {
    openResource();
  }
  @finally {
    closeResource();
    return; // Noncompliant - prevents the exception from being propagated
  }
}

Compliant Solution

void openResource() {
  @throw [NSException exceptionWithName:@"FileNotFoundException" reason:@"File Not Found on System" userInfo:nil];
}

void fun() {
  @try {
    openResource();
  }
  @finally {
    closeResource();
  }
}

See

objc:S1448

A class that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor the class into smaller ones which focus on well defined topics.

objc:S5000

The function memcmp can only be used for objects of trivially copyable types. This includes scalar types, arrays, and trivially copyable classes.

A class type is trivially copyable if:

  • One or more of the following methods is trivial and the rest are deleted: copy constructor, move constructor, copy assignment operator, and move assignment operator,
  • It has a trivial, non-deleted destructor.

Additionally, if the type contains padding, some of its bits might be non-representative, and a strict comparison of raw memory contents might lead to the mistaken belief that two identical objects are actually different.

Noncompliant Code Example

class Shape { // Trivially copyable, but will contain padding after the bool on most architectures
public:
  bool visible;
  int x;
  int y;
};

bool isSame(Shape *s1, Shape *s2)
{
    return memcmp(s1, s2, sizeof Shape) == 0; // Noncompliant
}

Compliant Solution

class Shape {
public:
  bool visible;
  int x;
  int y;
};

bool operator==(Shape const &s1, Shape const &s2) {
  return s1.visible == s2.visible && s1.x == s2.x && s1.y == s2.y;
}

bool isSame(Shape *s1, Shape *s2)
{
    return (*s1) == (*s2);
}
tsql:S3650

If a WHERE clause contains a condition which is redundant in the context of the the rest of the clause, then it can be removed. If it is redundant because it does not match the programmer's intent, then it's a bug and the sub-condition should be fixed.

Noncompliant Code Example

SELECT name, price
FROM product
WHERE price > 15  -- Noncompliant
  AND price < 100  -- Noncompliant
  AND price = 50

Compliant Solution

SELECT name, price
FROM product
WHERE price = 50
tsql:S2737

A CATCH clause that only rethrows the caught exception has the same effect as omitting the CATCH altogether and letting it bubble up automatically, but with more code and the additional detriment of leaving maintainers scratching their heads.

Such clauses should either be eliminated or populated with the appropriate logic.

Noncompliant Code Example

BEGIN TRY
    SELECT 1/0;
END TRY
BEGIN CATCH -- Noncompliant
    THROW;
END CATCH;

Compliant Solution

BEGIN TRY
    SELECT 1/0;
END TRY
BEGIN CATCH
    EXECUTE usp_GetErrorInfo;
    THROW;
END CATCH;

or

SELECT 1/0;
c:S2479

Control characters aren't visible to maintainers, so they should be escaped.

Noncompliant Code Example

const char* foo = "A	B";  // Noncompliant, contains a tabulation

Compliant Solution

const char* foo = "A\tB";  // Compliant, use escaped value

Exceptions

Raw string literals has no escape character mechanism.

c:S5000

The function memcmp can only be used for objects of trivially copyable types. This includes scalar types, arrays, and trivially copyable classes.

A class type is trivially copyable if:

  • One or more of the following methods is trivial and the rest are deleted: copy constructor, move constructor, copy assignment operator, and move assignment operator,
  • It has a trivial, non-deleted destructor.

Additionally, if the type contains padding, some of its bits might be non-representative, and a strict comparison of raw memory contents might lead to the mistaken belief that two identical objects are actually different.

Noncompliant Code Example

class Shape { // Trivially copyable, but will contain padding after the bool on most architectures
public:
  bool visible;
  int x;
  int y;
};

bool isSame(Shape *s1, Shape *s2)
{
    return memcmp(s1, s2, sizeof Shape) == 0; // Noncompliant
}

Compliant Solution

class Shape {
public:
  bool visible;
  int x;
  int y;
};

bool operator==(Shape const &s1, Shape const &s2) {
  return s1.visible == s2.visible && s1.x == s2.x && s1.y == s2.y;
}

bool isSame(Shape *s1, Shape *s2)
{
    return (*s1) == (*s2);
}
common-apex:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-apex:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-apex:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-apex:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-apex:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-apex:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
cpp:S2479

Control characters aren't visible to maintainers, so they should be escaped.

Noncompliant Code Example

const char* foo = "A	B";  // Noncompliant, contains a tabulation

Compliant Solution

const char* foo = "A\tB";  // Compliant, use escaped value

Exceptions

Raw string literals has no escape character mechanism.

cpp:S4998

If you use std::unique_ptr<T> const & for a function parameter type, it means that the function will not be able to alter the ownership of the pointed-to object by the unique_ptr:

  • It cannot acquire ownership of the pointed-to object (this would require a parameter of type std::unique_ptr<T>)
  • It cannot transfer the object ownership to someone else (this would require a std::unique_ptr<T> &).

That means the function can only observe the pointed-to object, and in this case passing a T* (if the unique_ptr can be null) or a T& (if it cannot) provides the same features, while also allowing the function to work with objects that are not handled by a unique_ptr (E.G. objects on the stack, in a vector, or in another kind of smart pointer), thus making the function more general-purpose.

Noncompliant Code Example

using namespace std;
void draw(unique_ptr<Shape> const &shape); // Noncompliant

void drawAll(vector<unique_ptr<Shape>> v)
{
  for (auto &shape : v) {
      if (shape) {
        draw(shape);
      }
  }
}

Compliant Solution

using namespace std;
void draw(Shape const &shape); // Compliant

void drawAll(vector<unique_ptr<Shape>> v)
{
  for (auto &shape : v) {
      if (shape) {
        draw(*shape);
      }
  }
}
cpp:S4997

std::auto_ptr was a pre-C++11 attempt to do what std::unique_ptr now does. Unfortunately, the move semantics needed to make it work properly weren't in place, so copying a std::auto_ptr has the very surprising behavior of invalidating the source of the copy.

That problem has been fixed with std::unique_ptr, so std::auto_ptr has been deprecated in C++11 and removed in C++17.

If your compiler allows it, you should replace all use of std::auto_ptr with std::unique_ptr. Otherwise, define your own (non-copyable) smart pointer.

Noncompliant Code Example

using namespace std;

void draw(auto_ptr<Shape> p) { cout << s->x() << ", " << s.y() << endl;} // Noncompliant

void f()
{
    std::auto_ptr<Shape> s = createShape(); // Noncompliant
    draw(s); // This call invalidates s
    draw(s); // This call will crash, because s is null
}

Compliant Solution

using namespace std;

void draw(unique_ptr<Shape> p) { cout << s->x() << ", " << s.y() << endl;} // Compliant

void f()
{
    std::unique_ptr<Shape> s = createShape();
    // draw(s); // Would not compile
    draw(move(s)); // Will compile, and the user knows s has been invalidated
}
cpp:S3252

In the interest of code clarity, static member variables of a base class should never be accessed using a derived type's name. Doing so is confusing and could create the illusion that two different static variables exist. If the variable is const, there is no risk of confusion.

Noncompliant Code Example

class Parent {
  public:
    static int count;
    static Color const defaultColor = green;
};

class Child : public Parent {
  public:
    Child() : myColor(Child::defaultColor) // Compliant, this is a constant
    {
      Child::count++;  // Noncompliant
    }
};

Compliant Solution

class Parent {
  public:
    static int count;
    static Color const defaultColor = green;
};

class Child : public Parent {
  public:
    Child() : myColor(Child::defaultColor) // Compliant, this is a constant
    {
      Parent::count++;
    }
};
cpp:S5018

Move operations (move constructor, move assignment operator) are all about efficient resource stealing. When stealing resources from the source, you don't have to allocate any memory or perform any other operation that might fail. This is why most people will expect move operation to be non-throwing.

Additionally, if a move operation fails, the source object can have been partially altered by the move, making recovery very tricky, or just impossible. Therefore, to ensure robustness, some functions (for instance, std::move_if_noexcept, used by std::vector) will decide to copy your object if its move operations are not decorated with noexcept. This can significantly slow down your program.

If you can not implement your move operations so that they never throw, you may as well only provide copy operations that will be safer to use.

Note that for most classes, you should not write your own move operations, but rely on the "Rule-of-Zero" (S4963).

Noncompliant Code Example

struct A {
  A (A const &a);
  A (A && a); // Noncompliant
  ~A();
  A &operator=(A const &a);
  A &operator=(A &&a); // Noncompliant
};

Compliant Solution

struct A {
  A (A const &a);
  A (A && a) noexcept;
  ~A();
  A &operator=(A const &a);
  A &operator=(A &&a) noexcept;
};

See

cpp:S4962

Before C+11, the only way to refer to a null pointer was by using the integer literal 0, which created ambiguity with regard to whether a pointer or integers was intended. Even when the NULL macro is used, the underlying value is still 0.

C++11 introduced the keyword nullptr, which is unambiguous and should be used systematically.

Noncompliant Code Example

void f(char *c);
void g(int i);
void h()
{
    f(0); // Noncompliant
    f(NULL); // Noncompliant
    g(0); // Compliant, a real integer
    g(NULL); // Noncompliant, NULL should not be used for a real integer
}

Compliant Solution

void f(char *c);
void g(int i);
void h()
{
    f(nullptr); // Compliant
    g(0);  // Compliant, a real integer
}

See

* C++ core guidelines ES.47 Use nullptr rather than 0 or NULL

cpp:S3624

In C++, you should not directly manipulate resources (a database transaction, a network connection, a mutex lock), but encapsulate them in RAII wrapper classes that will allow to manipulate them safely. When defining one of those wrapper classes, you cannot rely on the compiler-generated special member functions to manage the class' resources for you (see the Rule-of-Zero, S4963). You must define those functions yourself to make sure the class' resources are properly copied, moved, and destroyed.

In that case, make sure you consider what should be done for all five special functions (all three of them if your compiler is pre-C++11):

- The destructor, to release the resource when the wrapper is destroyed

- The copy constructor and the copy-assignment operator, to handle what should happen to the resource when the wrapper is copied (a valid option is to disable those operations with =delete)

- The move constructor and the move-assignment operator, to handle what should happen to the resource when the wrapper is moved (since C++11). If you cannot find a way to implement them more efficiently than the copy operations, as an exception to this rule, you can just leave out these operations: the compiler will not generate them and will use the copy operations as a fallback.

Those operations work together, and letting the compiler automatically generate some of them, but not all, means that when one of those functions is called, the integrity of the resource will probably be compromised (for instance, it might lead to double release of a resource when the wrapper is copied).

Noncompliant Code Example

class FooPointer { // Noncompliant, missing copy constructor and copy-assignment operator
  Foo* pFoo;
public:
  FooPointer(int initValue) {
    pFoo = new Foo(initValue);
  }
  ~FooPointer() {
    delete pFoo;
  }
};

int main() {
  FooPointer a(5);
  FooPointer b = a; // implicit copy constructor gives rise to double free memory error
  return 0;
}

Compliant Solution

class FooPointer { // Compliant, although it's usually better to reuse an existing wrapper for memory
  Foo* pFoo;
public:
  FooPointer(int initValue) {
    pFoo = new Foo(initValue);
  }
  FooPointer(FooPointer& other) {
    pFoo = new Foo(other.pFoo->value);
  }
  FooPointer& operator=(const FooPointer& other) {
    int val = other.pFoo->value;
    delete pFoo;
    pFoo = new Foo(val);
    return *this;
  }
  FooPointer(FooPointer &&fp) noexcept {
    pFoo = fp.pFoo;
    fp.pFoo = nullptr;
  }
  FooPointer const & operator=(FooPointer &&fp) {
    FooPointer temp(std::move(fp));
    std::swap(temp.pFoo, pFoo);
    return *this;
  }
  ~FooPointer() {
    delete pFoo;
  }
};

int main() {
  FooPointer a(5);
  FooPointer b = a; // no error
  return 0;
}

See

  • CERT, OOP-06-CPP. - Create a private copy constructor and assignment operator for non copyable objects
cpp:S5000

The function memcmp can only be used for objects of trivially copyable types. This includes scalar types, arrays, and trivially copyable classes.

A class type is trivially copyable if:

  • One or more of the following methods is trivial and the rest are deleted: copy constructor, move constructor, copy assignment operator, and move assignment operator,
  • It has a trivial, non-deleted destructor.

Additionally, if the type contains padding, some of its bits might be non-representative, and a strict comparison of raw memory contents might lead to the mistaken belief that two identical objects are actually different.

Noncompliant Code Example

class Shape { // Trivially copyable, but will contain padding after the bool on most architectures
public:
  bool visible;
  int x;
  int y;
};

bool isSame(Shape *s1, Shape *s2)
{
    return memcmp(s1, s2, sizeof Shape) == 0; // Noncompliant
}

Compliant Solution

class Shape {
public:
  bool visible;
  int x;
  int y;
};

bool operator==(Shape const &s1, Shape const &s2) {
  return s1.visible == s2.visible && s1.x == s2.x && s1.y == s2.y;
}

bool isSame(Shape *s1, Shape *s2)
{
    return (*s1) == (*s2);
}
apex:S1313

Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:

Today's services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery and deployment:

  • The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
  • It forces the same address to be used in every environment (dev, sys, qa, prod).

Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service at this address or spoof the IP address. Such an attack is always possible, but in the case of a hardcoded IP address the fix will be much slower, which will increase an attack's impact.

Recommended Secure Coding Practices

  • make the IP address configurable.

Noncompliant Code Example

String ip = '192.168.12.42'; // Noncompliant
String clientIp = ApexPages.currentPage().getHeaders().get(ā€˜True-Client-IP’);
Boolean isKnown = ip.equals(clientIp);

Exceptions

No issue is reported for the following cases because they are not considered sensitive:

  • Loopback addresses 127.0.0.0/8 in CIDR notation (from 127.0.0.0 to 127.255.255.255)
  • Broadcast address 255.255.255.255
  • Non routable address 0.0.0.0
  • Strings of the form 2.5.<number>.<number> as they often match Object Identifiers (OID).

See

  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
  • CERT, MSC03-J. - Never hard code sensitive information
apex:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

See

apex:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

apex:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

Integer divide(Integer numerator, Integer denominator) {
  return numerator / denominator;              // FIXME denominator value might be  0
}

See

apex:S1871

Having two whens in a switch statement or two branches in an if chain 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 chain they should be combined, or for a switch, one should fall through to the other.

Noncompliant Code Example

switch on i {
  when 1 {
    doFirstThing();
    doSomething();
  }
  when 2 {
    doSomethingDifferent();
  }
  when 3 {  // Noncompliant; duplicates when 1's implementation
    doFirstThing();
    doSomething();
  }
  when else {
    doTheRest();
  }
}

if (a >= 0 && a < 10) {
  doFirstThing();
  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else if (a >= 20 && a < 50) {
  doFirstThing();
  doTheThing();  // Noncompliant; duplicates first condition
}
else {
  doTheRest();
}

Exceptions

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a switch statement that contain a single line of code with or without a following break.

if(a == 1) {
  doSomething();  //no issue, usually this is done on purpose to increase the readability
} else if (a == 2) {
  doSomethingElse();
} else {
  doSomething();
}

But this exception does not apply to if chains without else-s, or to switch-es without default clauses when all branches have the same single line of code. In case of if chains with else-s, or of switch-es with default clauses, rule S3923 raises a bug.

if(a == 1) {
  doSomething();  //Noncompliant, this might have been done on purpose but probably not
} else if (a == 2) {
  doSomething();
}
apex:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

Integer x = (y / 2 + 1);   //Compliant even if the parenthesis are ignored by the compiler

if (a && ((x+y > 0))) {  // Noncompliant
  //...
}

return ((x + 1));  // Noncompliant

Compliant Solution

Integer x = (y / 2 + 1);

if (a && (x+y > 0)) {
  //...
}

return (x + 1);
apex:S131

The requirement for a final when else clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken.

Noncompliant Code Example

switch on i { // missing 'when else'
  when 2 {
    System.debug('when block 2');
  }
  when -3 {
    System.debug('when block -3');
  }
}

Compliant Solution

switch on i {
  when 2 {
    System.debug('when block 2');
  }
  when -3 {
    System.debug('when block -3');
  }
  when else {
    System.debug('default');
  }
}

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
  • MITRE, CWE-478 - Missing Default Case in Switch Statement
  • CERT, MSC01-C. - Strive for logical completeness
apex:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

Noncompliant Code Example

String password = "xxxx"; // Noncompliant

Compliant Solution

String password = retrievePassword();

See

apex:S4144

When two methods have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, one implementation should invoke the other. Numerical and string literals are not taken into account.

Noncompliant Code Example

private String code = 'bounteous';

public String calculateCode() {
  doTheThing();
  return code;
}

public String getName() {  // Noncompliant
  doTheThing();
  return code;
}

Compliant Solution

private String code = 'bounteous';

public String getCode() {
  doTheThing();
  return code;
}

public String getName() {
  return getCode();
}

Exceptions

Methods that are not accessors (getters and setters), with fewer than 2 statements are ignored.

apex:S134

Nested if, for, while, switch, 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:

switch on i { // Compliant - depth = 1
  when 1 {
    /* ... */
    for (Integer i = 0, j = 0; i < 10; i++) { // Compliant - depth = 2
      /* ... */
      Integer j = i + 1;
      if(j == 0){// Compliant - depth = 3, not exceeding the limit
        /* ... */
        while(j < 10){ // Noncompliant - depth = 4
          /* ... */
          if(j == 1){ // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
            /* ... */
          }
        }
      }
    }
  }
}
apex:S4663

An empty multi-line comment is likely to be a mistake and doesn't help to improve the readability of the code. For these reasons, it should be removed.

Noncompliant Code Example

/* */

/*

 */
apex:ParsingError

When the parser fails, it is possible to record the failure as an issue on the file. This way, not only is it possible to track the number of files that do not parse but also to easily find out why they do not parse.

apex:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

public void setName(String name) {
  name = name;
}

Compliant Solution

public void setName(String name) {
  this.name = name;
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
apex:S1479

When switch statements have large sets of case clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

apex:S125

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
apex:S103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

apex:S1151

The switch statement should be used only to clearly define some new branches in the control flow. As soon as a when clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the when clause should be extracted into a dedicated function.

Noncompliant Code Example

With the threshold set at 5:

public void foo(Integer value) {
  switch on value {
    when 1 {
      methodCall1('');
      methodCall2('');
      methodCall3('');
      methodCall4('');
      methodCall5('');
    }
    when 2 { /* ... */ }
  }
}

Compliant Solution

public void foo(Integer value) {
  switch on value {
    when 1 { doSomething(); }
    when 2 { /* ... */ }
    }
  }
}

private void doSomething() {
  methodCall1('');
  methodCall2('');
  methodCall3('');
  methodCall4('');
  methodCall5('');
}
apex:S1172

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

Noncompliant Code Example

void doSomething(Integer a, Integer b) {     // "b" is unused
  compute(a);
}

Compliant Solution

void doSomething(Integer a) {
  compute(a);
}

See

  • MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions.
  • MISRA C:2012, 2.7 - There should be no unused parameters in functions
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
apex:S105

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

apex:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

apex:S1192

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

class A {
    void doSomething(String msg) {
        System.debug('string literal'); // Noncompliant - 'string literal' is duplicated 3 times
        System.assertEquals(msg, 'string literal');
        msg = 'string literal';
    }

    void doSomethingElse(String msg) {
        System.debug('a'); // Compliant - literal 'a' has less than 5 characters and is excluded
        System.assertEquals(msg, 'a');
        msg = 'a';
    }
}

Compliant Solution

class A {
    static final String STRING_CONST = 'string literal';

    void doSomething(String msg) {
        System.debug(STRING_CONST); // Compliant
        System.assertEquals(msg, STRING_CONST);
        msg = STRING_CONST;
    }
}

Exceptions

To prevent generating some false-positives, literals having less than 5 characters are excluded.

apex:S126

This rule applies whenever an if statement is followed by one or more else if statements; the final else if should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch statement.

Noncompliant Code Example

if (x == 0) {
  doSomething();
} else if (x == 1) {
  doSomethingElse();
}

Compliant Solution

if (x == 0) {
  doSomething();
} else if (x == 1) {
  doSomethingElse();
} else {
  throw new MyException('Illegal state');
}

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
apex:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

Noncompliant Code Example

With a maximum number of 4 parameters:

public void doSomething(String param1, String param2, String param3, String param4, String param5) {
...
}

Compliant Solution

public void doSomething(String param1, String param2, String param3, String param4) {
...
}
apex:S108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

if (i < 10) {} // Empty on purpose or missing piece of code ?

Exceptions

When a block contains a comment, this block is not considered to be empty.

apex:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Noncompliant Code Example

if ( a == a ) { // always true
  foo();
}
if ( a != a ) { // always false
  foo();
}
if ( a == b && a == b ) { // if the first one is true, the second one is too
  foo();
}
if ( a != b || a <> b ) { // if the first one is true, the second one is too
  foo();
}

Integer i = 5 / 5; // always 1
Integer j = 5 - 5; // always 0

Exceptions

  • This rule ignores *, +, ^, &, |, =, <<, >> and >>>.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
apex:S1940

It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.

Noncompliant Code Example

if ( !(a == 2)) { ...}  // Noncompliant
Boolean b = !(i < 10);  // Noncompliant

Compliant Solution

if (a != 2) { ...}
Boolean b = (i >= 10);
apex:S1862

A switch and a chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

For a switch, the second when will never be executed, rendering it dead code. Worse there is the risk in this situation that future maintenance will be done on the dead case, rather than on the one that's actually used.

Noncompliant Code Example

if (param == 1) {
  openWindow();
} else if (param == 2) {
  closeWindow();
} else if (param == 1) { // Noncompliant
  moveWindowToTheBackground();
}

switch on i {
  when 1 {
    // ...
  }
  when 2 {
    // ...
  }
  when 1 { // Noncompliant
    // ...
  }
  when else {
    // ...
  }
}

Compliant Solution

if (param == 1) {
  openWindow();
} else if (param == 2) {
  closeWindow();
} else if (param == 3) {
  moveWindowToTheBackground();
}

switch on i {
  when 1 {
    // ...
  }
  when 2 {
    // ...
  }
  when else {
    // ...
  }
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
apex:S1763

Jump statements (return, break, continue) and throw expressions move control flow out of the current code block. So any statements that come after a jump are dead code.

Noncompliant Code Example

Integer foo(Integer a) {
    Integer i = 10;
    return i + a; // Noncompliant
    i++; // dead code
}

Compliant Solution

Integer foo(Integer a) {
    Integer i = 10;
    return i + a; // Noncompliant
}

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code
  • MISRA C++:2008, 0-1-9 - There shall be no dead code
  • MISRA C:2012, 2.1 - A project shall not contain unreachable code
  • MISRA C:2012, 2.2 - There shall be no dead code
  • MITRE, CWE-561 - Dead Code
  • CERT, MSC56-J. - Detect and remove superfluous code and values
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
apex:S1125

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

Noncompliant Code Example

if (booleanMethod() == true) { /* ... */ }
if (booleanMethod() == false) { /* ... */ }
if (booleanMethod() || false) { /* ... */ }
doSomething(!false);
doSomething(booleanMethod() == true);

Compliant Solution

if (booleanMethod()) { /* ... */ }
if (!booleanMethod()) { /* ... */ }
if (booleanMethod()) { /* ... */ }
doSomething(true);
doSomething(booleanMethod());
apex:S1145

if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.

There are three possible causes for the presence of such code:

  • An if statement was changed during debugging and that debug code has been committed.
  • Some value was left unset.
  • Some logic is not doing what the programmer thought it did.

In any of these cases, unconditional if statements should be removed.

Noncompliant Code Example

  if (true) {
    doSomething();
  }
  // ...
  if (false) {
    doSomethingElse();
  }

Compliant Solution

  doSomething();
  // ...

See

  • MITRE, CWE-489 - Leftover Debug Code
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
apex:S1144

private methods that are never executed are dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.

apex:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if (condition1)
{
  if (condition2)
  {
    ...
  }
}

Compliant Solution

if (condition1 && condition2)
{
  ...
}
apex:S1067

The complexity of an expression is defined by the number of && and || operators it contains.

A single expression's complexity should not become too high to keep the code readable.

Noncompliant Code Example

With the default threshold value of 3:

if (((condition1 && condition2) || (condition3 && condition4)) && condition5) { ... }

Compliant Solution

if ((myFirstCondition || mySecondCondition) && myLastCondition) { ... }
apex:S1186

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

  • 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.

Noncompliant Code Example

public void doSomething() {
}

Compliant Solution

public void doSomething() {
  // Do nothing because of X and Y.
}
apex:S101

Shared coding conventions allow teams to collaborate effectively. This rule allows to check that all class names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression ^[A-Z][a-zA-Z0-9_]*$:

class myClass {}

Compliant Solution

class MyClass {}
apex:S122

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

a = true;return 0;

Compliant Solution

a = true;
return 0;
apex:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

With provided regular expression ^[a-z][a-zA-Z0-9_]*$:

public void DoSomething(){...}

Compliant Solution

public void doSomething(){...}
apex:S2757

The use of operators pairs ( =+, =- or =! ) where the reversed, single operator was meant (+=, -= or !=) will compile and run, but not produce the expected results.

This rule raises an issue when =+, =-, or =! is used without any spacing between the two operators and when there is at least one whitespace character after.

Noncompliant Code Example

Integer target = -5;
Integer num = 3;

target =- num;  // Noncompliant; target = -3. Is that really what's meant?
target =+ num; // Noncompliant; target = 3

Compliant Solution

Integer target = -5;
Integer num = 3;

target = -num;  // Compliant; intent to assign inverse value of num is clear
target += num;
apex:S3923

Having all branches in a switch or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a switch/if chain at all.

Noncompliant Code Example

if (b == 0) {  // Noncompliant
  doOneMoreThing();
} else {
  doOneMoreThing();
}

switch on i {  // Noncompliant
  when 1 {
    doSomething();
  }
  when 2 {
    doSomething();
  }
  when 3 {
    doSomething();
  }
  when else {
    doSomething();
  }
}

Exceptions

This rule does not apply to if chains without else-s, or to switch-es without default clauses.

if(b == 0) {    //no issue, this could have been done on purpose to make the code more readable
  doSomething();
} else if(b == 1) {
  doSomething();
}
apex:S1821

Nested switch structures are difficult to understand because you can easily confuse the when blocks of an inner switch as belonging to an outer statement. Therefore nested switch statements should be avoided.

Specifically, you should structure your code to avoid the need for nested switch statements, but if you cannot, then consider moving the inner switch to another function.

Noncompliant Code Example

public void foo(Integer i, Integer j) {
  switch on i {
    when 1 {System.debug(' 1'); }
    when 2 { System.debug(' 2'); }
    when -3 {
      switch on j {  // Noncompliant
        when 1 {System.debug(' 3');}
        when else {System.debug(' 4');}
      }
    }
  }
}

Compliant Solution

public void foo(Integer i, Integer j) {
  switch on i {
    when 1 {System.debug(' 1'); }
    when 2 { System.debug(' 2'); }
    when -3 {bar(j);}
  }
}

public void bar(Integer j) {
  switch on j {
    when 1 {System.debug(' 3');}
    when else {System.debug(' 4');}
  }
}
apex:S1481

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

public Integer numberOfMinutes(Integer hours) {
  Integer seconds = 0;   // seconds is never used
  return hours * 60;
}

Compliant Solution

public Integer numberOfMinutes(Integer hours) {
  return hours * 60;
}
apex:S138

A function that grows too large tends to aggregate too many responsibilities.

Such functions inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions which focus on well-defined tasks.

Those smaller functions will not only be easier to understand, but also probably easier to test.

apex:S117

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a local variable or function parameter name does not match the provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9_]*$:

public void doSomething(Integer PARAM) { // Noncompliant
  Integer LOCAL; // Noncompliant
  ...
}

Compliant Solution

public void doSomething(Integer param) {
  Integer local;
  ...
}
cpp:S2806

The real need for bit fields is narrow and highly specialized. Previously, they were used to save memory, but that's less a concern in modern systems than are the extra instructions required to interact with them. Today, they may be needed in direct hardware interaction, but since their behavior is platform-dependent, getting them right can be tricky, and since their use is increasingly rare these days, they're likely to confuse maintainers. For these reasons, it's simpler and more performant to use another field type instead of bit fields.

Noncompliant Code Example

unsigned int b1 : 3;  // Noncompliant
unsigned char b2 : 3;  // Noncompliant

Compliant Solution

unsigned int b1;
unsigned char b2;
scala:S1313

Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:

Today's services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery and deployment:

  • The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
  • It forces the same address to be used in every environment (dev, sys, qa, prod).

Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service at this address or spoof the IP address. Such an attack is always possible, but in the case of a hardcoded IP address the fix will be much slower, which will increase an attack's impact.

Recommended Secure Coding Practices

  • make the IP address configurable.

Noncompliant Code Example

val ip = "192.168.12.42" // Noncompliant
val socket = new Socket(ip, 6667)

Exceptions

No issue is reported for the following cases because they are not considered sensitive:

  • Loopback addresses 127.0.0.0/8 in CIDR notation (from 127.0.0.0 to 127.255.255.255)
  • Broadcast address 255.255.255.255
  • Non routable address 0.0.0.0
  • Strings of the form 2.5.<number>.<number> as they often match Object Identifiers (OID).

See

  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
  • CERT, MSC03-J. - Never hard code sensitive information
scala:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

See

scala:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

scala:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

var result = numerator / denominator  // FIXME denominator value might be  0

See

scala:S1871

Having two cases in a match statement or two branches in an if chain 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 chain they should be combined, or for a match, one should fall through to the other.

Noncompliant Code Example

value match {
  case 1 =>
    doFirstThing
    doSomething
  case 2 =>
    doSomethingDifferent
  case 3 => // Noncompliant; duplicates case 1's implementation
    doFirstThing
    doSomething
  case _ =>
    doTheRest
}

if (a >= 0 && a < 10) {
  doFirstThing
  doTheThing
}
else if (a >= 10 && a < 20) {
  doTheOtherThing
}
else if (a >= 20 && a < 50) {
  doFirstThing
  doTheThing  // Noncompliant; duplicates first condition
}
else {
  doTheRest
}

Exceptions

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a match statement that contain a single line of code.

if(a == 1) {
  doSomething  //no issue, usually this is done on purpose to increase the readability
} else if (a == 2) {
  doSomethingElse
} else {
  doSomething
}

But this exception does not apply to if chains without else-s, or to match-es without default clauses when all branches have the same single line of code. In case of if chains with else-s, or of match-es with default clauses, rule S3923 raises a bug.

if(a == 1) {
  doSomething  //Noncompliant, this might have been done on purpose but probably not
} else if (a == 2) {
  doSomething
}
scala:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
scala:S4144

When two methods have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, one implementation should invoke the other.

Noncompliant Code Example

class Box(length: Int, width: Int, height: Int) {
  def volume: Int = {
    val s = length * width
    s * height
  }

  def area: Int = {
    val s = length * width
    s * height
  }
}

Compliant Solution

class Box(length: Int, width: Int, height: Int) {
  def volume: Int = {
    val s = length * width
    s * height
  }

  def area: Int = {
    length * width
  }
}

Exceptions

Methods with fewer than 2 statements are ignored.

scala:S134

Nested if, for, while, match, and try statements are key ingredients for making what's known as "Spaghetti code".

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

scala:S4663

An empty multi-line comment is likely to be a mistake and doesn't help to improve the readability of the code. For these reasons, it should be removed.

Noncompliant Code Example

/* */

/*

 */
scala:ParsingError

When the parser fails, it is possible to record the failure as an issue on the file. This way, not only is it possible to track the number of files that do not parse but also to easily find out why they do not parse.

scala:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

def doSomething() = {
    var name = ""
    // ...
    name = name
}

Compliant Solution

def doSomething() = {
    var name = ""
    // ...
    this.name = name
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
scala:S125

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
scala:S1479

When match expressions have a large number of clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

scala:S103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

scala:S1151

The match statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the case clause should be extracted into a dedicated method.

Noncompliant Code Example

With the default threshold of 5:

myVariable match {
  case 0 => // Noncompliant: 6 lines till next case
    methodCall1()
    methodCall2()
    methodCall3()
    methodCall4()
    methodCall5()
  case 1 =>
  // ...
}

Compliant Solution

myVariable match {
  case 0 => doSomething()
  case 1 =>
  // ...
}
// ...
def doSomething(): Unit = {
  methodCall1()
  methodCall2()
  methodCall3()
  methodCall4()
  methodCall5()
}
scala:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

scala:S105

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

scala:S1172

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

See

  • MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions.
  • MISRA C:2012, 2.7 - There should be no unused parameters in functions
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
scala:S1192

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.

Exceptions

To prevent generating some false-positives, literals having less than 5 characters are excluded.

scala:S126

This rule applies whenever an if statement is followed by one or more else if statements; the final else if should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final case _ clause in a match.

Noncompliant Code Example

if (x == 0) {
  doSomething
} else if (x == 1) {
  doSomethingElse
}

Compliant Solution

if (x == 0) {
  doSomething
} else if (x == 1) {
  doSomethingElse
} else {
  throw new IllegalStateException
}

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
scala:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

scala:S108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

if (i < 10) {}  // Empty on purpose or missing piece of code ?

Exceptions

When a block contains a comment, this block is not considered to be empty.

scala:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Exceptions

This rule ignores *, +, and =.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
scala:S1940

It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.

Noncompliant Code Example

if (!(a == 2)) { ...}  // Noncompliant
val b = !(i < 10)  // Noncompliant

Compliant Solution

if (a != 2) { ...}
val b = (i >= 10)
scala:S1763

Jump statements (return) move control flow out of the current code block. So any statements that come after a jump are dead code.

Noncompliant Code Example

def foo(a: Int) {
  val i = 10;
  return a + i;       // Noncompliant
  bar;                // dead code
}

Compliant Solution

def foo(a: Int): Int {
  val i = 10;
  return a + i;
}

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code
  • MISRA C++:2008, 0-1-9 - There shall be no dead code
  • MISRA C:2012, 2.1 - A project shall not contain unreachable code
  • MISRA C:2012, 2.2 - There shall be no dead code
  • MITRE, CWE-561 - Dead Code
  • CERT, MSC56-J. - Detect and remove superfluous code and values
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
scala:S1862

A match and a chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

For a match, the second case will never be executed, rendering it dead code. Worse there is the risk in this situation that future maintenance will be done on the dead case, rather than on the one that's actually used.

Noncompliant Code Example

if (param == 1) {
  openWindow
} else if (param == 2) {
  closeWindow
} else if (param == 1) { // Noncompliant
  moveWindowToTheBackground
}

param match {
  case 1 =>
  // ...
  case 3 =>
  // ...
  case 1 => // Noncompliant
  // ...
  case _ =>
  //...
}

Compliant Solution

if (param == 1) {
  openWindow
} else if (param == 2) {
  closeWindow
} else if (param == 3) {
  moveWindowToTheBackground
}

param match {
  case 1 =>
  // ...
  case 3 =>
  // ...
  case _ =>
  //...
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
scala:S1125

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

Noncompliant Code Example

if (booleanMethod() || false) { /* ... */ }
doSomething(!false)

booleanVariable = if (booleanMethod()) true else false
booleanVariable = if (booleanMethod()) true else exp
booleanVariable = if (booleanMethod()) false else exp
booleanVariable = if (booleanMethod()) exp else true
booleanVariable = if (booleanMethod()) exp else false

Compliant Solution

if (booleanMethod()) { /* ... */ }
doSomething(true)

booleanVariable = booleanMethod()
booleanVariable = booleanMethod() || exp
booleanVariable = !booleanMethod() && exp
booleanVariable = !booleanMethod() || exp
booleanVariable = booleanMethod() && exp
scala:S1145

if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.

There are three possible causes for the presence of such code:

  • An if statement was changed during debugging and that debug code has been committed.
  • Some value was left unset.
  • Some logic is not doing what the programmer thought it did.

In any of these cases, unconditional if statements should be removed.

Noncompliant Code Example

  if (true) {
    doSomething
  }
  // ...
  if (false) {
    doSomethingElse
  }

Compliant Solution

  doSomething
  // ...

See

  • MITRE, CWE-489 - Leftover Debug Code
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
scala:S1067

The complexity of an expression is defined by the number of && and || operators it contains.

A single expression's complexity should not become too high to keep the code readable.

Noncompliant Code Example

With the default threshold value of 3:

if (((condition1 && condition2) || (condition3 && condition4)) && condition5) { ... }

Compliant Solution

if ((myFirstCondition || mySecondCondition) && myLastCondition) { ... }
scala:S1144

private methods that are never executed are dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.

scala:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if (file != null) {
  if (file.isFile || file.isDirectory) {
    /* ... */
  }
}

Compliant Solution

if (file != null && isFileOrDirectory(file)) {
  /* ... */
}

def isFileOrDirectory(file: File): Boolean = file.isFile || file.isDirectory
scala:S1186

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

  • 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.
scala:S101

Shared coding conventions allow teams to collaborate effectively. This rule allows to check that all class names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression ^[A-Z][a-zA-Z0-9]*$:

class my_class {...}

Compliant Solution

class MyClass {...}
scala:S122

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

println("Hello"); println("world!")

Compliant Solution

println("Hello")
println("world!")
scala:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression:

def DoSomething( ) : Unit = { // Noncompliant
   // ...
}

Compliant Solution

def doSomething( ) : Unit = {
   // ...
}
scala:S1821

Nested match structures are difficult to understand because you can easily confuse the cases of an inner match as belonging to an outer statement. Therefore nested match statements should be avoided.

Specifically, you should structure your code to avoid the need for nested match statements, but if you cannot, then consider moving the inner match to another function.

Noncompliant Code Example

def foo(n: Int, m: Int): Unit = {
  n match {
    case 0 => m match {
        case 0 =>
        // ...
      }
    case 1 =>
    // ...
  }
}

Compliant Solution

def foo(n: Int, m: Int): Unit = {
  n match {
    case 0 => bar(m)
    case 1 =>
    // ...
  }
}

def bar(m: Int): Unit = {
  m match {
    case 0 =>
    // ...
  }
}
scala:S3923

Having all branches in a match or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a match/if chain at all.

Noncompliant Code Example

if (b == 0) { // Noncompliant
  doSomething
} else {
  doSomething
}

i match { // Noncompliant
  case 1 => doSomething
  case 2 => doSomething
  case 3 => doSomething
  case _ => doSomething
}

Exceptions

This rule does not apply to if chains without else-s, or to match-es without case _ alternatives.

if (b == 0) {
  doSomething
} else if (b == 1) {
  doSomething
}
scala:S138

A method that grows too large tends to aggregate too many responsibilities. Such method inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller methods which focus on well-defined tasks. Those smaller methods will not only be easier to understand, but also probably easier to test.

scala:S1481

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.

scala:S117

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a local variable or function parameter name does not match the provided regular expression.

Web:InternationalizationCheck

Web applications can be made available in multiple languages through the use of internationalization. This allows the server to plug in the correct version of a piece of text based on the language chosen, but it requires that internationalization messages be used instead of hard-coded text.

Noncompliant Code Example

  <form method="post">
    <label for="username">Username:</label>  <!-- Noncompliant -->
    <input type="text" id="username" name="username">
    <br>
    <label for="password">Password:</label>  <!-- Noncompliant -->
    <input type="password" id="password" name="password">
    <br>
    <input type="submit" name="submit" value="${buttonValue}">
  </form>

Compliant Solution

  <form method="post">
    <label for="username"><fmt:message key="login.label.username" />:</label>
    <input type="text" id="username" name="username">
    <br>
    <label for="password"><fmt:message key="login.label.password" />:</label>
    <input type="password" id="password" name="password">
    <br>
    <input type="submit" name="submit" value="${buttonValue}">
  </form>
squid:S3878

There's no point in creating an array solely for the purpose of passing it as a varargs (...) argument; varargs is an array. Simply pass the elements directly. They will be consolidated into an array automatically. Incidentally passing an array where Object ... is expected makes the intent ambiguous: Is the array supposed to be one object or a collection of objects?

Noncompliant Code Example

public void callTheThing() {
  //...
  doTheThing(new String[] { "s1", "s2"});  // Noncompliant: unnecessary
  doTheThing(new String[12]);  // Compliant
  doTheOtherThing(new String[8]);  // Noncompliant: ambiguous
  // ...
}

public void doTheThing (String ... args) {
  // ...
}

public void doTheOtherThing(Object ... args) {
  // ...
}

Compliant Solution

public void callTheThing() {
  //...
  doTheThing("s1", "s2");
  doTheThing(new String[12]);
  doTheOtherThing((Object[]) new String[8]);
   // ...
}

public void doTheThing (String ... args) {
  // ...
}

public void doTheOtherThing(Object ... args) {
  // ...
}
csharpsquid:S2327

When multiple, adjacent try statements have duplicate catch and/or finally blocks, they should be merged to consolidate the catch/finally logic for cleaner, more readable code. Note that this applies even when there is intervening code outside any try block.

Noncompliant Code Example

try
{
  DoTheFirstThing(a, b);
}
catch (InvalidOperationException ex)
{
  HandleException(ex);
}

DoSomeOtherStuff();

try  // Noncompliant; catch is identical to previous
{
  DoTheSecondThing();
}
catch (InvalidOperationException ex)
{
  HandleException(ex);
}

try  // Compliant; catch handles exception differently
{
  DoTheThirdThing(a);
}
catch (InvalidOperationException ex)
{
  LogAndDie(ex);
}

Compliant Solution

try
{
  DoTheFirstThing(a, b);
  DoSomeOtherStuff();
  DoTheSecondThing();
}
catch (InvalidOperationException ex)
{
  HandleException(ex);
}

try  // Compliant; catch handles exception differently
{
  DoTheThirdThing(a);
}
catch (InvalidOperationException ex)
{
  LogAndDie(ex);
}
python:S117

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a local variable or function parameter name does not match the provided regular expression.

Exceptions

Loop counters are ignored by this rule.

for i in range(limit):  # Compliant
    print(i)
python:S116

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that field names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[_a-z][_a-z0-9]*$:

class MyClass:
  myField = 1

Compliant Solution

class MyClass:
  my_field = 1
plsql:SelectListSizeCheck

SELECT queries that return too many columns may be complex or difficult to maintain.

This rule identifies queries that SELECT more than the specified number of columns.

Noncompliant Code Example

With a threshold of 6:

BEGIN
  SELECT id, name, firstname, gender, height, weight, age -- Noncompliant
    INTO peopleArray
    FROM people
    WHERE age > 60;
END;
/
plsql:WeakRefCursorCheck

Weak REF CURSOR types are harder to work with than ones with a return type. Indeed, the compiler's type-checker is unable to make some verifications, which are then delayed till runtime.

When the use of weak REF CURSOR is required, it is best to use the SYS_REFCURSOR built-in type instead of defining a new one.

This rule's sysRefCursorAllowed parameter can be used to control whether or not the usage of SYS_REFCURSOR is allowed.

Noncompliant Code Example

DECLARE
  TYPE dualCursorType IS REF CURSOR;                      -- Noncompliant
  dualCursor dualCursorType;

  otherCursor SYS_REFCURSOR;                              -- Compliant or non-compliant, depending on the "sysRefCursorAllowed" parameter
BEGIN
  otherCursor := dualCursor;                              -- Works
END;
/

Compliant Solution

DECLARE
  TYPE dualCursorType IS REF CURSOR RETURN DUAL%ROWTYPE;
  dualCursor dualCursorType;

  TYPE otherCursorType IS REF CURSOR RETURN a%ROWTYPE;
  otherCursor otherCursorType;
BEGIN
  otherCursor := dualCursor;                              -- raises PLS-00382: expression is of wrong type, which makes debugging easier
END;
/
plsql:NoSonarCheck

Any issue to quality rule can be deactivated with the NOSONAR marker. This marker is pretty useful to exclude false-positive results but it can also be used abusively to hide real quality flaws.

This rule raises an issue when NOSONAR is used.

plsql:PlSql.ParsingError

When the PL/SQL parser fails, it is possible to record the failure as an issue on the file. This way, not only it is possible to track the number of files that do not parse but also to easily find out why they do not parse.

plsql:TablesShouldBeAliasedCheck

When multiple tables are involved in a query, using table aliases helps to make it more understandable and keeps it short.

Noncompliant Code Example

BEGIN
  SELECT
    name,
    firstname,
    location
  INTO employeesArray
  FROM employee -- Noncompliant - should be aliased
  INNER JOIN department -- Noncompliant - should be aliased
  ON employee.DepartmentID = department.ID;
END;
/

Compliant Solution

BEGIN
  SELECT
    empl.name,
    empl.firstname,
    dpt.location
  INTO employeesArray
  FROM employee empl
  INNER JOIN department dpt
  ON empl.DepartmentID = dpt.ID;
END;
/
plsql:S1192

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

With the default threshold of 3:

BEGIN
  prepare('action1');
  execute('action1');
  release('action1');
END;
/

Compliant Solution

DECLARE
  action CONSTANT VARCHAR2(7) := 'action1';
BEGIN
  prepare(action);
  execute(action);
  release(action);
END;
/

Exceptions

To prevent generating some false-positives, literals having less than 5 characters are excluded.

plsql:OneStatementPerLineCheck

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

SET SERVEROUTPUT ON

BEGIN
  DBMS_OUTPUT.PUT_LINE('Hello!'); DBMS_OUTPUT.PUT_LINE('This is unreadable!'); -- Noncompliant
END;
/

Compliant Solution

SET SERVEROUTPUT ON

BEGIN
  DBMS_OUTPUT.PUT_LINE('Hello!');
  DBMS_OUTPUT.PUT_LINE('This is much better!');
END;
/
plsql:UseAnsiJoinsCheck

Since ANSI SQL-92, explicit joins using the JOIN keyword have been possible, and are preferred. Therefore table joins should be done with help of the one of the following clauses: JOIN, INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, and FULL OUTER JOIN. The old way to join tables is deprecated and should not be used anymore.

Noncompliant Code Example

SELECT *
FROM PARTS, PRODUCTS
WHERE PARTS.PROD = PRODUCTS.PROD

Compliant Solution

SELECT *
FROM PARTS
INNER JOIN PRODUCTS ON PARTS.PROD = PRODUCTS.PROD
plsql:JoinConditionNumberCheck

When you need access to data from multiple tables, it is more efficient, effective, and understandable to use pre-built views than to select the data from a large number of tables - effectively creating in-memory views - at runtime.

Noncompliant Code Example

With a maximum number of 3 joined tables:

SELECT PERSONS.NAME, COUNTRIES.NAME, GENRES.NAME, PROFESSIONS.NAME
FROM PERSONS
  INNER JOIN COUNTRIES ON COUNTRIES.ID = PERSON.COUNTRY_ID
  INNER JOIN GENRES ON GENRES.ID = PERSONS.GENRE_ID
  INNER JOIN PROFESSIONS ON PROFESSIONS.ID = PERSONS.PROFESSIONS_ID  -- Noncompliant; this is table #4
WHERE COUNTRIES.CODE = 'US'

SELECT PERSONS.NAME, COUNTRIES.NAME, GENRES.NAME, PROFESSIONS.NAME
FROM PERSONS, COUNTRIES, GENRES, PROFESSIONS -- Noncompliant
WHERE COUNTRIES.CODE = 'US' AND COUNTRIES.ID = PERSON.COUNTRY_ID AND GENRES.ID = PERSONS.GENRE_ID AND PROFESSIONS.ID = PERSONS.PROFESSIONS_ID
plsql:S1138

SQL queries that use EXISTS subqueries are inefficient because the subquery is re-run for every row in the outer query's table. There are more efficient ways to write most queries, ways that do not use the EXISTS condition.

Noncompliant Code Example

SELECT e.name
FROM employee e
WHERE EXISTS (SELECT * FROM department d WHERE e.department_id = d.id AND d.name = 'Marketing');

Compliant Solution

SELECT e.name
FROM employee e INNER JOIN department d
  ON e.department_id = d.id AND d.name = 'Marketing';
common-plsql:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-plsql:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-plsql:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
plsql:S2070

The MD5 algorithm and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them. That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160.

Consider using safer alternatives, such as SHA-256, or SHA-3.

Noncompliant Code Example

DBMS_CRYPTO.Hash(str, HASH_MD4);

DBMS_CRYPTO.Hash(str, HASH_MD5);

DBMS_CRYPTO.Hash(str, HASH_SH1);

See

  • MITRE, CWE-328 - Reversible One-Way Hash
  • MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
  • OWASP Top 10 2017 Category A6 - Security Misconfiguration
  • SANS Top 25 - Porous Defenses
  • SHAttered - The first concrete collision attack against SHA-1.
plsql:SysOwnedFunctions

Some Oracle packages contain powerful SYS-owned functions that can be used to perform malicious operations. For instance, DBMS_SYS_SQL.PARSE_AS_USER can be used to execute a statement as another user.

Most programs do not need those functions and this rule helps identify them in order to prevent security risks.

Noncompliant Code Example

DECLARE
  c INTEGER;
  sqltext VARCHAR2(100) := 'ALTER USER system IDENTIFIED BY hacker'; -- Might be injected by the user
BEGIN
  c := SYS.DBMS_SYS_SQL.OPEN_CURSOR();                               -- Noncompliant

   -- Will change 'system' user's password to 'hacker'
  SYS.DBMS_SYS_SQL.PARSE_AS_USER(c, sqltext, DBMS_SQL.NATIVE, UID);  -- Non-Compliant

  SYS.DBMS_SYS_SQL.CLOSE_CURSOR(c);                                  -- Noncompliant
END;
/

See

plsql:S125

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
plsql:UpperCaseReservedWordsCheck

Shared coding conventions allow teams to collaborate efficiently. This rule checks that reserved words are written in upper case.

Noncompliant Code Example

BEGIN
  null; -- Noncompliant
END;
/

Compliant Solution

BEGIN
  NULL;
END;
/
plsql:LowerCaseReservedWordsCheck

All reserved words should be written using the same case to ensure consistency in the code.

This rule checks that reserved words are all in lower case.

Noncompliant Code Example

begin
  null;
  NULL; -- Noncompliant
end;
/
plsql:ProcedureWithoutParametersCheck

Procedures which don't accept parameters are likely to either not be reused that often or to depend on global variables instead. Refactoring those procedures to take parameters will make them both more flexible and reusable.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  name VARCHAR2(42) := 'John';

  PROCEDURE print_name; -- Noncompliant

  PROCEDURE print_name AS -- Noncompliant
  BEGIN
    DBMS_OUTPUT.PUT_LINE('Name: ' || name);
  END;

BEGIN
  print_name;
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  PROCEDURE print_name(name VARCHAR2) AS -- Compliant
  BEGIN
    DBMS_OUTPUT.PUT_LINE('Name: ' || name);
  END;
BEGIN
  print_name('John');
END;
/
plsql:StandaloneProcAndFuncCheck

Having a bunch of standalone functions or procedures reduces maintainability because it becomes harder to find them and to see how they are related. Instead, they should be logically grouped into meaningful packages.

Noncompliant Code Example

CREATE PROCEDURE show_name(name VARCHAR2) AS -- Non-Compliant
BEGIN
  DBMS_OUTPUT.PUT_LINE('Name: ' || name);
END;
/

DROP PROCEDURE show_name;

Compliant Solution

CREATE PACKAGE employee AS
  PROCEDURE show_name;
END;
/

CREATE PACKAGE BODY employee AS
  name VARCHAR2(42);

  PROCEDURE show_name AS  -- Compliant
  BEGIN
    DBMS_OUTPUT.PUT_LINE('Name: ' || name);
  END;
END;
/

DROP PACKAGE employee;
plsql:ParameterExplicitInCheck

By default, the parameter mode is IN. However, specifying it explicitly makes the code easier to read.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  PROCEDURE printName(name VARCHAR2) AS -- Noncompliant; relies on default mode
  BEGIN
    DBMS_OUTPUT.PUT_LINE('name: ' || name);
  END;

BEGIN
  printName('Foo');
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  PROCEDURE printName(name IN VARCHAR2) AS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('name: ' || name);
  END;
BEGIN
  printName('Foo');
END;
/
plsql:OracleJoinOperatorUsageCheck

Developers should use the FROM ... OUTER JOIN syntax rather than the Oracle join operator (+). The reason is that outer join queries that use + are subject to several restrictions which do not apply to the FROM ... OUTER JOIN syntax. For instance, a WHERE condition containing the + operator cannot be combined with another condition using the OR logical operator.

Noncompliant Code Example

BEGIN
  -- Noncompliant
  SELECT *
    INTO employeesArray
    FROM employee, department
    WHERE employee.DepartmentID = department.ID(+);
END;
/

Compliant Solution

BEGIN
  -- Compliant
  SELECT *
    INTO employeesArray
    FROM employee LEFT OUTER JOIN department
    ON employee.DepartmentID = department.ID;
END;
/
plsql:NestedSubqueriesCheck

Subqueries are nested when they appear in the WHERE clause of the parent statement. When an Oracle database evaluates a statement with a nested subquery, it must evaluate the subquery portion multiple times and may overlook some efficient access paths or joins.

Subquery unnesting unnests and merges the body of the subquery into the body of the statement that contains it, allowing the optimizer to consider the queries together when evaluating access paths and joins. The optimizer can unnest most subqueries, with some exceptions. Those exceptions include:

  • hierarchical subqueries
  • subqueries that contain a ROWNUM pseudocolumn
  • subqueries that contain one of the set operators
  • subqueries that contain a nested aggregate function
  • subqueries that contain a correlated reference to a query block that is not the immediate outer query block of the subquery.

Assuming no restrictions exist, the optimizer automatically unnests some (but not all) of the following nested subqueries:

  • Uncorrelated IN subqueries
  • IN and EXISTS correlated subqueries, as long as they do not contain aggregate functions or a GROUP BY clause

You can enable extended subquery unnesting by instructing the optimizer to unnest additional types of subqueries:

  • You can unnest an uncorrelated NOT IN subqueries by specifying the HASH_AJ or MERGE_AJ hint in the subquery.
  • You can unnest other subqueries by specifying the UNNEST hint in the subquery.

Because these optimizations are dependant on the version of Oracle used, it is best to avoid using nested subqueries in the first place when possible.

Noncompliant Code Example

BEGIN
  SELECT col1
  BULK COLLECT INTO result
  FROM table1
  WHERE col2 IN (SELECT col3 FROM table2); -- Noncompliant
END;
/

Compliant Solution

BEGIN
  SELECT col1                              -- Compliant
  BULK COLLECT INTO result
  FROM table1
  JOIN table2 ON col2 = col3;
END;
/
plsql:LabeledNestedLoopsCheck

Labeled loops are useful, especially when the code is badly indented, to match the begin and end of each loop. When loops are nested, labeling them can improve the code's readability. This rule detects nested loops which do not have a start label.

Noncompliant Code Example

BEGIN
  LOOP
    LOOP -- Noncompliant, this nested loop is not labeled
      EXIT;
    END LOOP;

    EXIT;
  END LOOP;

  FOR i IN 1..10  LOOP
    WHILE true LOOP -- Noncompliant, this nested loop has no start label
      EXIT;
    END LOOP nestedLoopLabel1;

    EXIT;
  END LOOP;

  WHILE true LOOP
    <<nestedLoopLabel2>>
    LOOP -- Compliant, but better with an end label
      EXIT;
    END LOOP;

    EXIT;
  END LOOP;
END;
/

Compliant Solution

BEGIN
  LOOP
    <<nestedLoopLabel0>>
    LOOP
      EXIT;
    END LOOP nestedLoopLabel0;

    EXIT;
  END LOOP;

  FOR i IN 1..10  LOOP
    <<nestedLoopLabel1>>
    WHILE true LOOP
      EXIT;
    END LOOP nestedLoopLabel1;

    EXIT;
  END LOOP;

  WHILE true LOOP
    <<nestedLoopLabel2>>
    LOOP
      EXIT;
    END LOOP nestedLoopLabel2;

    EXIT;
  END LOOP;
END;
/
plsql:LabelSubBlock

Labeled blocks are useful, especially when the code is badly indented, to help maintainers match the beginning and ending of each block. When blocks are nested, labeling them can improve the code's readability. This rule detects nested block which do not have a start label.

Noncompliant Code Example

BEGIN -- Compliant, this is not a nested block
  NULL;
END;
/

BEGIN
  BEGIN -- Noncompliant; this nested block has no label
    NULL;
  END;
END;
/

BEGIN
  BEGIN -- Noncompliant; this nested block has only an end label
    NULL;
  END myBlockLabel1;

  <<myBlockLabel2>> -- Compliant
  BEGIN
    NULL;
  END;
END;
/

Compliant Solution

BEGIN
  NULL;
END;
/

BEGIN
  BEGIN myBlockLabel0
    NULL;
  END myBlockLabel0;
END;
/

BEGIN
  BEGIN myBlockLabel1
    NULL;
  END myBlockLabel1;

  <<myBlockLabel2>>
  BEGIN
    NULL;
  END;
END;
/
plsql:MagicNumber

A magic number is a number that comes out of nowhere, and is directly used in a statement. Magic numbers are often used, for instance to limit the number of iterations of a loops, to test the value of a property, etc.

Using magic numbers may seem obvious and straightforward when you're writing a piece of code, but they are much less obvious and straightforward at debugging time.

That is why magic numbers must be demystified by first being assigned to clearly named variables before being used.

By default, -1, 0 and 1 are not considered magic numbers.

plsql:MagicLiteral

Literals should not be hard-coded, but externalized instead. Exceptions can be parameterized using the below parameters.

plsql:S1131

Trailing whitespaces are simply useless and should not stay in code. They may generate noise when comparing different versions of the same file.

If you encounter issues from this rule, this probably means that you are not using an automated code formatter - which you should if you have the opportunity to do so.

Noncompliant Code Example

DECLARE
  -- The following line has many trailing whitespaces
  foo VARCHAR2(42) := 'a
b';
BEGIN
  -- Will misleadingly show 3, counting only the characters 'a', 'b', and the line terminator, but none of the trailing whitespaces
  DBMS_OUTPUT.PUT_LINE(LENGTH(foo));
END;
/
plsql:LineLength

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

common-plsql:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
plsql:MultiLineCommentFormatCheck

Multi-line comments are more readable when each line is aligned using the "*" character. At most one violation is created for each comment

Noncompliant Code Example

/*
this line is not aligned and ugly Non-Compliant
no violation is created on this line, even though is it also bad
 */

/* this is Compliant */

Compliant Solution

/*
 * this is much better Compliant
 */

/* this is Compliant */
plsql:VariableInPackageSpecificationCheck

When data structures (scalar variables, collections, cursors) are declared in the package specification (not within any specific program), they can be referenced directly by any program running in a session with EXECUTE rights to the package.

Instead, declare all package-level data in the package body and provide getter and setter functions in the package specification. Developers can then access the data using these methods and will automatically follow all rules you set upon data modification.

By doing so you can guarantee data integrity, change your data structure implementation, and also track access to those data structures.

Noncompliant Code Example

-- Package specification
CREATE PACKAGE employee AS
   name VARCHAR2(42); -- Non-Compliant
END employee;
/

DROP PACKAGE employee;

Compliant Solution

-- Package specification
CREATE PACKAGE employee AS
   PROCEDURE setName (newName VARCHAR2);
   FUNCTION getName RETURN VARCHAR2;
END employee;
/

-- Package body
CREATE PACKAGE BODY employee AS
   name VARCHAR2(42);

   PROCEDURE setName (newName VARCHAR2) IS
   BEGIN
     name := newName;
   END;

   FUNCTION getName RETURN VARCHAR2 IS
   BEGIN
     RETURN name;
   END;
END employee;
/

DROP PACKAGE BODY employee;

DROP PACKAGE employee;
plsql:PlSql.FunctionAndProcedureExcessiveParameters

Having functions and procedures which take too many parameters decreases the code's readability and usability. It is likely that such a function/procedure is not modular enough, and should be split into several smaller ones.

Noncompliant Code Example

With the default threshold of 10:

SET SERVEROUTPUT ON

CREATE FUNCTION sumWithTooManyParameters( -- Noncompliant, too many parameters
  a1 PLS_INTEGER,
  a2 PLS_INTEGER,
  a3 PLS_INTEGER,
  a4 PLS_INTEGER,
  a5 PLS_INTEGER,
  a6 PLS_INTEGER,
  a7 PLS_INTEGER,
  a8 PLS_INTEGER,
  a9 PLS_INTEGER,
  a10 PLS_INTEGER,
  a11 PLS_INTEGER
  )
  RETURN PLS_INTEGER AS
BEGIN
  RETURN a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11;
END;
/

BEGIN
  DBMS_OUTPUT.PUT_LINE('Sum is ' || sumWithTooManyParameters(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));
END;
/

DROP FUNCTION sumWithTooManyParameters;

Compliant Solution

SET SERVEROUTPUT ON

CREATE FUNCTION sumCorrected(n PLS_INTEGER) RETURN PLS_INTEGER AS -- Compliant
BEGIN
  RETURN (1 + n)*(n / 2);
END;
/

BEGIN
  DBMS_OUTPUT.PUT_LINE('Sum is ' || sumCorrected(11));
END;
/

DROP FUNCTION sumCorrected;

						
plsql:PlSql.FunctionAndProcedureComplexity

The cyclomatic complexity of functions and procedures should not exceed a defined threshold.

Complex code can perform poorly and will in any case be difficult to understand and therefore to maintain.

plsql:S4421

Deprecated language features are those that have been retained temporarily for backward compatibility, but which will eventually be removed from the language. In effect, deprecation announces a grace period to allow the smooth transition from the old features to the new ones. In that period, no use of the deprecated features should be added to the code, and all existing uses should be gradually removed.

The following features are deprecated in Oracle 12:

Deprecated Replacement
DBMS_DDL.ALTER_COMPILE Native Dynamic SQL
ALL_SCHEDULER_CREDENTIALS ALL_CREDENTIALS
DBA_NETWORK_ACL_PRIVILEGES DBA_HOST_ACES
DBA_NETWORK_ACLS DBA_HOST_ACLS
DBA_SCHEDULER_CREDENTIALS DBA_CREDENTIALS
USER_NETWORK_ACL_PRIVILEGES USER_HOST_ACES
USER_SCHEDULER_CREDENTIALS DBA_HOST_ACES
V$OBJECT_USAGE USER_OBJECT_USAGE
common-plsql:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
plsql:S1573

If you do not explicitly close a cursor, it will be closed at the end of the task. But if you try to re-open this cursor to process it, you will get an error. That is why a cursor should be explicitly closed after it has been processed.

See

plsql:S1615

Sharing some naming conventions is a key factory in efficient team collaboration. This rule checks that all constraint names match a provided regular expression.

Noncompliant Code Example

With format_primary_key set to "pk_[a-z]++ " and format_foreign_key to "fk_[a-z]++ ".

CREATE TABLE employee(
  first_name VARCHAR2(42),
  last_name VARCHAR2(42)
  department_id INTEGER CONSTRAINT department_fk REFERENCES department,
  CONSTRAINT fullname_pk PRIMARY KEY (first_name, last_name);
);

Compliant Solution

CREATE TABLE employee(
  first_name VARCHAR2(42),
  last_name VARCHAR2(42)
  department_id INTEGER CONSTRAINT fk_department REFERENCES department,
  CONSTRAINT pk_fullname PRIMARY KEY (first_name, last_name);
);
plsql:S139

This rule verifies that single-line comments are not located at the ends of lines of code. The main idea behind this rule is that in order to be really readable, trailing comments would have to be properly written and formatted (correct alignment, no interference with the visual structure of the code, not too long to be visible) but most often, automatic code formatters would not handle this correctly: the code would end up less readable. Comments are far better placed on the previous empty line of code, where they will always be visible and properly formatted.

Noncompliant Code Example

a := b + c; -- This is a trailing comment that can be very very long

Compliant Solution

-- This very long comment is better placed before the line of code
a := b + c;
plsql:SelectStarCheck

SELECT * should be avoided because it releases control of the returned columns and could therefore lead to errors and potentially to performance issues.

Noncompliant Code Example

DECLARE
  myvar CHAR;
BEGIN
  SELECT * INTO myvar FROM DUAL; -- Noncompliant
 END;
/

Compliant Solution

DECLARE
  myvar CHAR;
BEGIN
  SELECT dummy INTO myvar FROM DUAL;
END;
/

Exceptions

Wrapper queries using ROWNUM are ignored.

SELECT *
FROM ( SELECT fname, lname, deptId
    FROM employee
    ORDERBY salary
  )
WHERE rownum <= 10
plsql:ComplexIfShouldBeReplacedByCase

When a single primitive is tested against three or more values in an IF, ELSIF chain, it should be converted to a CASE instead for greater readability.

Noncompliant Code Example

DECLARE
  x PLS_INTEGER := 0;
BEGIN
  IF x = 0 THEN                     -- Noncompliant
    DBMS_OUTPUT.PUT_LINE('x = 0');
  ELSIF x = 1 THEN
    DBMS_OUTPUT.PUT_LINE('x = 1');
  ELSE
    DBMS_OUTPUT.PUT_LINE('x > 1');
  END IF;
END;
/

Compliant Solution

DECLARE
  x PLS_INTEGER := 0;
BEGIN
  CASE x
    WHEN 0 THEN
      DBMS_OUTPUT.PUT_LINE('x = 0');
    WHEN 1 THEN
      DBMS_OUTPUT.PUT_LINE('x = 1');
    ELSE
      DBMS_OUTPUT.PUT_LINE('x > 1');
  END CASE;
END;
/
plsql:S1151

The CASE statement should be used only to clearly define some new branches in the control flow. As soon as a WHEN clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of WHEN clause should be extracted in a dedicated function.

Noncompliant Code Example

CASE my_variable
  WHEN 0 THEN -- 6 lines till next WHEN
    procedure1;
    procedure2;
    procedure3;
    procedure4;
    procedure5;
  WHEN 1 THEN
-- ...
END CASE;

Compliant Solution

DECLARE
  PROCEDURE do_something AS
  BEGIN
    procedure1;
    procedure2;
    procedure3;
    procedure4;
    procedure5;
  END;
BEGIN
  CASE my_variable
    WHEN 0 THEN
      do_something;
    WHEN 1 THEN
-- ...
  END CASE;
END;
/
plsql:WhenOthersAsOnlyExceptionHandlerCheck

Before trapping all possible exceptions, it is best to try to trap the specific ones and try to recover from those.

Noncompliant Code Example

SET SERVEROUTPUT ON

CREATE TABLE hitCounter
(
  page VARCHAR2(42),
  hits NUMBER,
  CONSTRAINT pk PRIMARY KEY (page)
);

CREATE PROCEDURE hitPage(pageIn VARCHAR2) AS
BEGIN
  INSERT INTO hitCounter VALUES (pageIn, 1);
EXCEPTION -- Noncompliant, the only exception handler is WHEN OTHERS
  WHEN OTHERS THEN
    IF SQLCODE = -1 THEN
      UPDATE hitCounter SET hits = hits + 1 WHERE page = pageIn;
    ELSE
      DBMS_OUTPUT.PUT_LINE('An unknown error occured!');
    END IF;
END;
/

BEGIN
  hitPage('index.html');
  hitPage('index.html');
END;
/

SELECT * FROM hitCounter;

DROP PROCEDURE hitPage;
DROP TABLE hitCounter;

Compliant Solution

SET SERVEROUTPUT ON

CREATE TABLE hitCounter
(
  page VARCHAR2(42),
  hits NUMBER,
  CONSTRAINT pk PRIMARY KEY (page)
);

CREATE PROCEDURE hitPage(pageIn VARCHAR2) AS
BEGIN
  INSERT INTO hitCounter VALUES (pageIn, 1);
EXCEPTION
  WHEN DUP_VAL_ON_INDEX THEN
    UPDATE hitCounter SET hits = hits + 1 WHERE page = pageIn;
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('An unknown error occured!');
END;
/

BEGIN
  hitPage('index.html');
  hitPage('index.html');
END;
/

SELECT * FROM hitCounter;

DROP PROCEDURE hitPage;
DROP TABLE hitCounter;

See

plsql:PlSql.UseWhenOthers

Ensure that every possible exception is caught by using a WHEN OTHERS clause.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  result PLS_INTEGER;
  custom_exception EXCEPTION;
BEGIN
  result := 42 / 0;                            -- "Unexpected" division by 0

  RAISE custom_exception;
EXCEPTION                                      -- Non-Compliant
  WHEN custom_exception THEN
    DBMS_OUTPUT.PUT_LINE ('custom_exception: ' || DBMS_UTILITY.FORMAT_ERROR_STACK);
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  result PLS_INTEGER;
  custom_exception EXCEPTION;
BEGIN
  result := 42 / 0;                            -- "Unexpected" division by 0

  RAISE custom_exception;
EXCEPTION                                      -- Compliant
  WHEN custom_exception THEN
    DBMS_OUTPUT.PUT_LINE ('custom_exception: ' || DBMS_UTILITY.FORMAT_ERROR_STACK);
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE ('other: ' || DBMS_UTILITY.FORMAT_ERROR_STACK);
END;
/

See

plsql:UnionUsageCheck

UNION is a convenient syntax to combine the results of two or more SQL statements because it helps you cut a complex problem into multiple simple SQL statements. But when it comes to execution, using UNION is debatable.

First, it may be possible to fuse two simple SQL statements into a bigger one that will run faster. Second, UNION is significantly less performant compared to UNION ALL because it removes duplicated entries and runS an internal DISTINCT to achieve this.

UNION ALL does not remove duplicates and returns all the results from the queries. It performs faster in most cases compared to UNION. Nevertheless, the quantity of data returned by UNION ALL can be significantly larger than with UNION. On a slow network, the performance gain of using UNION ALL instead of UNION can be negated by the time lost in the larger data transfer.

This rule raises an issue on each UNION. It's up to the developer to challenge its use and see if there is a better way to rewrite without UNION.

Noncompliant Code Example

-- case #1
SELECT EMAIL FROM EMPLOYEES WHERE COUNTRY = 'FR'
UNION                           -- Noncompliant
SELECT EMAIL FROM EMPLOYEES WHERE COUNTRY = 'CH'

-- case #2
-- if you care about not having duplicated entries, then UNION is the good choice
SELECT EMAIL FROM EMPLOYEES
UNION                           -- Noncompliant
SELECT EMAIL FROM CUSTOMERS

Compliant Solution

-- case #1
SELECT EMAIL FROM EMPLOYEES WHERE COUNTRY = 'FR' OR COUNTRY = 'CH'

-- case #2
-- if you don't care about duplicated entries in the results of this UNION, then UNION ALL should be preferred
SELECT EMAIL FROM EMPLOYEES
UNION ALL
SELECT EMAIL FROM CUSTOMERS
plsql:SimpleIntegerPlsIntegerCheck

ORACLE 11g introduced the SIMPLE_INTEGER data type, which is a sub-type of PLS_INTEGER, and covers the same range. There are three main differences between the two types:

  • SIMPLE_INTEGER is always NOT NULL. So when the value of the declared variable is never going to be null, you can declare it as SIMPLE_INTEGER.
  • You will never face a numeric overflow using SIMPLE_INTEGER because this data type wraps around without giving any error.
  • The SIMPLE_INTEGER data type gives a major performance boost over PLS_INTEGER when the code is compiled in "NATIVE" mode, because arithmetic operations on SIMPLE_INTEGER type are performed directly at the hardware level.

Noncompliant Code Example

DECLARE
  v1 PLS_INTEGER; -- Noncompliant
  v2 VARCHAR2(10);
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  v1 SIMPLE_INTEGER := 42;
  v2 VARCHAR2(10);
BEGIN
  NULL;
END;
/
plsql:RowidAndUrowidCheck

Be careful about your use of Oracle-specific data types like ROWID and UROWID. They might offer a slight improvement in performance over other means of identifying a single row (primary key or unique index value), but that is by no means guaranteed.

On the other hand, the use of ROWID or UROWID means that your SQL statement will not be portable to other SQL databases. Further, many developers are not familiar with these data types, which can make the code harder to maintain.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  id rowid; -- Non-Compliant
  universeId urowid; -- Non-Compliant
BEGIN
  SELECT rowid INTO id FROM DUAL;
  SELECT rowid INTO universeId FROM DUAL;

  DBMS_OUTPUT.PUT_LINE('id = ' || id);
  DBMS_OUTPUT.PUT_LINE('universe id = ' || universeId);
END;
/
plsql:FunctionResultCacheCheck

Because RESULT_CACHE-enabled functions increase memory consumption, one should double-check that the gain in performances is significant, and avoid over-using this feature in general.

Noncompliant Code Example

CREATE FUNCTION myFastFunction RETURN PLS_INTEGER RESULT_CACHE AS -- Noncompliant
BEGIN
  RETURN 42;
END;
/

DROP FUNCTION myFastFunction;
plsql:S4081

Using a NUMBER to store an integer is less performant than using a PLS_INTEGER. PLS_INTEGERs require less storage than NUMBERs, and benefit from the use of hardware math, as opposed to the library math required for NUMBERs. Even more performant is the SIMPLE_INTEGER subtype of PLS_INTEGER. However, changing to either of these types is only appropriate under certain circumstances.

PLS_INTEGER is only a candidate for NUMBER with a scale of up to 9.

SIMPLE_INTEGER has the same size limitation, in addition to it's NOT NULL constraint and lack of overflow checking.

This rule raises an issue when a NUMBER is declared with a scale of 9 or less.

Noncompliant Code Example

DECLARE
    son NUMBER(1);      -- Noncompliant
    rumbo NUMBER(9);  -- Noncompliant
    conga Number(10);   -- Ignored; falls outside the PLS_INTEGER range
    compalsa PLS_INTEGER;

Compliant Solution

DECLARE
    son SIMPLE_INTEGER;
    rumbo PLS_INTEGER;
    conga Number(10);   -- Ignored; falls outside the PLS_INTEGER range
    compalsa PLS_INTEGER;
plsql:NumberWithoutPrecisionCheck

Declaring a NUMBER variable without any precision wastes memory because Oracle supports up to 38 decimal digits by default (or the maximum supported by your system, whichever is less). If you don't need that large a value, you should specify whatever matches your needs. This will save memory and provide extra integrity checking on input.

This rule also applies to some NUMBER subtypes as well: NUMERIC, DEC, and DECIMAL.

Noncompliant Code Example

DECLARE
  var1 NUMBER; -- Noncompliant
  var2 NUMERIC; -- Noncompliant
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  var1 NUMBER(9,2);
  var2 NUMERIC(4,0);
BEGIN
  NULL;
END;
/
plsql:S1739

When the value of a LIKE clause starts with '%' or '_', indexes on the searched column are ignored, and a full table scan is performed instead.

Noncompliant Code Example

SELECT FIRST_NAME, LAST_NAME FROM PERSONS
WHERE LAST_NAME LIKE '%PONT'
plsql:NestedIf

Nested IF statements are a key ingredient for making what's known as "Spaghetti code".

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

plsql:FunctionOutParametersCheck

Functions with OUT parameters are complex to understand. Indeed, it is impossible to tell, just by looking at the function call, whether an argument is a input or output. Moreover, functions with OUT parameters cannot be called from SQL. It is better to either break such functions up into smaller ones, which each return a single value, or to return several values at once, by combining them in a collection, record, type, or table row.

Noncompliant Code Example

SET SERVEROUTPUT ON

CREATE TABLE employee(
  firstName VARCHAR2(42),
  name VARCHAR2(42),
  phone VARCHAR2(42)
);

INSERT INTO employee VALUES ('John', 'Smith', '+1');

DECLARE
  firstName VARCHAR2(42);
  name VARCHAR2(42);
  phone VARCHAR2(42);

  -- This DOES NOT return the employee name
  FUNCTION getEmployeeInfos(firstName OUT VARCHAR2, phone OUT VARCHAR2) RETURN VARCHAR2 AS -- Non-Compliant, confusing
    name VARCHAR2(42);
  BEGIN
    SELECT firstName, name, phone INTO firstName, name, phone FROM employee;
    RETURN name;
  END;
BEGIN
  name := getEmployeeInfos(firstName, phone);

  DBMS_OUTPUT.PUT_LINE('firstName: ' || firstName);
  DBMS_OUTPUT.PUT_LINE('name: ' || name);
  DBMS_OUTPUT.PUT_LINE('phone: ' || phone);
END;
/

Compliant Solution

SET SERVEROUTPUT ON

CREATE TABLE employee(
  firstName VARCHAR2(42),
  name VARCHAR2(42),
  phone VARCHAR2(42)
);

INSERT INTO employee VALUES ('John', 'Smith', '+1');

DECLARE
  emp employee%ROWTYPE;

  FUNCTION getEmployeeInfos RETURN employee%ROWTYPE AS -- Compliant
    emp employee%ROWTYPE;
  BEGIN
    SELECT * INTO emp FROM employee;
    RETURN emp;
  END;
BEGIN
  emp := getEmployeeInfos;

  DBMS_OUTPUT.PUT_LINE('firstName: ' || emp.firstName);
  DBMS_OUTPUT.PUT_LINE('name: ' || emp.name);
  DBMS_OUTPUT.PUT_LINE('phone: ' || emp.phone);
END;
/

DROP TABLE employee;
plsql:PreferExecuteImmediateToDbmsSqlCheck

EXECUTE IMMEDIATE is easier to use and understand than the DBMS_SQL package's procedures. It should therefore be preferred, when possible.

Noncompliant Code Example

SET SERVEROUTPUT ON

CREATE TABLE myTable(
  foo VARCHAR2(42)
);

CREATE PROCEDURE drop_table(tableName VARCHAR2) AS
  cursorIdentifier INTEGER;
BEGIN
  cursorIdentifier := DBMS_SQL.OPEN_CURSOR; -- Compliant; this is not a procedure call
  DBMS_SQL.PARSE(cursorIdentifier, 'DROP TABLE ' || tableName, DBMS_SQL.NATIVE); -- Noncompliant
  DBMS_SQL.CLOSE_CURSOR(cursorIdentifier); -- Noncompliant

  DBMS_OUTPUT.PUT_LINE('Table ' || tableName || ' dropped.');
EXCEPTION
  WHEN OTHERS THEN
    DBMS_SQL.CLOSE_CURSOR(cursorIdentifier); -- Noncompliant
END;
/

BEGIN
  drop_table('myTable');
END;
/

DROP PROCEDURE drop_table;

Compliant Solution

SET SERVEROUTPUT ON

CREATE TABLE myTable(
  foo VARCHAR2(42)
);

CREATE PROCEDURE drop_table(tableName VARCHAR2) AS
  cursorIdentifier INTEGER;
BEGIN
  EXECUTE IMMEDIATE 'DROP TABLE ' || tableName;
  DBMS_OUTPUT.PUT_LINE('Table ' || tableName || ' dropped.');
END;
/

BEGIN
  drop_table('myTable');
END;
/

DROP PROCEDURE drop_table;
plsql:DeleteOrUpdateWithoutWhereCheck

UPDATE and DELETE statements should contain WHERE clauses to keep the modification of records under control. Otherwise unexpected data loss could result.

Noncompliant Code Example

DECLARE
  maxAge PLS_INTEGER := 60;
BEGIN
  UPDATE employee SET status = 'retired'; -- Noncompliant - the WHERE was forgotten
END;
/

Compliant Solution

DECLARE
  maxAge PLS_INTEGER := 60;
BEGIN
  UPDATE employee SET status = 'retired' WHERE age > maxAge;
END;
/
plsql:DbmsOutputPutLineCallCheck

The output of DBMS_OUTPUT.PUT_LINE is not always visible, for example when SERVEROUTPUT is set to OFF. Moreover, there is no standardized way to specify the importance of the message. It is better to use a logging mechanism instead.

Noncompliant Code Example

SET SERVEROUTPUT ON

BEGIN
  DBMS_OUTPUT.PUT_LINE('An error occured'); -- Noncompliant
END;
/
plsql:PlSql.FunctionAndProcedureNaming

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

CREATE FUNCTION my_function_ RETURN PLS_INTEGER AS -- Noncompliant
BEGIN
  RETURN 42;
END;
/

Compliant Solution

CREATE FUNCTION my_function RETURN PLS_INTEGER AS
BEGIN
  RETURN 42;
END;
/
plsql:NamingVariablesCheck

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all variable names match the provided regular expression.

Noncompliant Code Example

With the default regular expression [a-zA-Z]([a-zA-Z0-9_]*[a-zA-Z0-9])?:

DECLARE
  goodVariable PLS_INTEGER; -- Compliant
  badVariable_ PLS_INTEGER; -- Non-Compliant
BEGIN
  NULL;
END;
/
plsql:NamingTypesCheck

Shared coding conventions allow teams to collaborate efficiently. This rule checks that type names match the provided regular expression.

Noncompliant Code Example

With the default regular expression [a-zA-Z]([a-zA-Z0-9_]*[a-zA-Z0-9])?:

DECLARE
  TYPE Collection-type_ IS VARRAY(42) OF PLS_INTEGER; -- Noncompliant
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  TYPE collectionType IS VARRAY(42) OF PLS_INTEGER;
BEGIN
  NULL;
END;
/ {code}
plsql:NamingRecordField

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all record field names match the provided regular rexpression.

Noncompliant Code Example

With the default regular expression [a-zA-Z](_?+[a-zA-Z0-9])*+:

DECLARE
  TYPE my_type IS RECORD(
    foo__bar PLS_INTEGER   -- Non-Compliant
  );
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  TYPE my_type IS RECORD(
    foo_bar PLS_INTEGER    -- Compliant
  );
BEGIN
  NULL;
END;
/
plsql:PlSql.PackageNaming

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all package names match a provided regular expression.

plsql:NamingObjectAttribute

Shared coding conventions allow teams to collaborate efficiently. This rule checks that object attribute names match the provided regular expression.

Noncompliant Code Example

With the default regular expression [a-zA-Z](_?+[a-zA-Z0-9])*+ :

CREATE TYPE my_type AS OBJECT(
  foo__bar INTEGER             -- Non-Compliant
);
/

DROP TYPE my_type;

Compliant Solution

CREATE TYPE my_type AS OBJECT(
  foo_bar INTEGER              -- Compliant
);
/

DROP TYPE my_type;
plsql:NamingFunctionAndProcedureParametersCheck

Each function and procedure parameter name must match a given regular expression.

Noncompliant Code Example

DECLARE
  FUNCTION myfunction2(parameter_ PLS_INTEGER) RETURN PLS_INTEGER; -- Noncompliant

  PROCEDURE myprocedure2(parameter_ PLS_INTEGER); -- Noncompliant

  FUNCTION myfunction2(parameter_ PLS_INTEGER) RETURN PLS_INTEGER AS -- Noncompliant
  BEGIN
    RETURN 42;
  END;

  PROCEDURE myprocedure2(parameter_ PLS_INTEGER) AS -- Noncompliant
  BEGIN
    NULL;
  END;
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  FUNCTION myfunction1(parameter PLS_INTEGER) RETURN PLS_INTEGER; -- Compliant

  PROCEDURE myprocedure1(parameter PLS_INTEGER); -- Compliant

  FUNCTION myfunction1(parameter PLS_INTEGER) RETURN PLS_INTEGER AS -- Compliant
  BEGIN
    RETURN 42;
  END;

  PROCEDURE myprocedure1(parameter PLS_INTEGER) AS -- Compliant
  BEGIN
    NULL;
  END;

BEGIN
  NULL;
END;
/
plsql:NamingExceptionsCheck

Naming conventions allow teams to collaborate effectively. This rule checks that exception names match a given regular expression.

Noncompliant Code Example

With the default regular expression [a-zA-Z]([a-zA-Z0-9_]*[a-zA-Z0-9])?:

DECLARE
  my-Exception_ EXCEPTION; -- Noncompliant
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  myException EXCEPTION;
BEGIN
  NULL;
END;
/
plsql:NamingCursorsCheck

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all cursor names match the provided regular expression.

Noncompliant Code Example

With the default regular expression, [a-zA-Z]([a-zA-Z0-9_]*[a-zA-Z0-9])?:

CREATE TABLE employee(
  name VARCHAR2(42)
);

DECLARE
  CURSOR myCursor_ RETURN employee%ROWTYPE; -- Noncompliant

  CURSOR myCursor_ RETURN employee%ROWTYPE IS SELECT * FROM employee; -- Noncompliant
BEGIN
  NULL;
END;
/

DROP TABLE employee;

Compliant Solution

CREATE TABLE employee(
  name VARCHAR2(42)
);

DECLARE
  CURSOR myCursor RETURN employee%ROWTYPE;

  CURSOR myCursor RETURN employee%ROWTYPE IS SELECT * FROM employee;
BEGIN
  NULL;
END;
/

DROP TABLE employee;
plsql:NamingCursorParametersCheck

Shared coding conventions allow teams to collaborate efficiently. This rule checks that cursor parameters match the provided regular expression.

Noncompliant Code Example

With the default regular expression [a-zA-Z]([a-zA-Z0-9_]*[a-zA-Z0-9])?:

CREATE TABLE employee(
  name VARCHAR2(42)
);

DECLARE
  CURSOR mycursor2(Employee-name-parameter_ VARCHAR2) RETURN employee%ROWTYPE; -- Noncompliant

  CURSOR mycursor2(Employee-name-parameter_ VARCHAR2) RETURN employee%ROWTYPE IS SELECT * FROM employee WHERE name = Employee-name-parameter_; -- Noncompliant
BEGIN
  NULL;
END;
/

DROP TABLE employee;

Compliant Solution

CREATE TABLE employee(
  name VARCHAR2(42)
);

DECLARE
  CURSOR mycursor2(employeeNameParameter VARCHAR2) RETURN employee%ROWTYPE;

  CURSOR mycursor2(employeeNameParameter VARCHAR2) RETURN employee%ROWTYPE IS SELECT * FROM employee WHERE name = employeeNameParameter;
BEGIN
  NULL;
END;
/

DROP TABLE employee;
plsql:NamingConstantsCheck

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all constant names match a provided regular expression.

Noncompliant Code Example

With the default regular expression [a-zA-Z]([a-zA-Z0-9_]*[a-zA-Z0-9])?:

DECLARE
  constant_ CONSTANT PLS_INTEGER := 42; -- Noncompliant
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  constant CONSTANT PLS_INTEGER := 42; -- Compliant
BEGIN
  NULL;
END;
/
common-xml:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
objc:S2342

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all enum names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression [A-Z][a-zA-Z0-9]+:

enum someEnumeration { // Noncompliant
};

Compliant Solution

enum SomeEnumeration {
};
objc:S3222

Shared coding conventions allow teams to collaborate effectively. This rule checks that labels match a provided regular expression.

Noncompliant Code Example

With default provided regular expression [A-Z][A-Z0-9_]+:

exit:  // Noncompliant
  doCleanup();

Compliant Solution

EXIT:  // Compliant
  doCleanup();
objc:ClassName

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate.

This rule allows to check that all class names (along with Objective-C interface, protocol and implementation names) match a provided regular expression.

Noncompliant Code Example

With default provided regular expression [A-Z][a-zA-Z0-9]+:

// C++
class foo // Noncompliant
{
};

// Objective-C
@interface nonCompliant : NSObject
@end

Compliant Solution

// C++
class Foo // Compliant
{
};

// Objective-C
@interface Compliant : NSObject
@end
objc:S1878

Sharing some naming conventions enables teams to collaborate more efficiently. This rule checks that all union names match a provided regular expression.

Noncompliant Code Example

Using the default regular expression [A-Z][a-zA-Z0-9]*:

union my_union {
    int one;
    int two;
};

Compliant Solution

union MyUnion {
    int one;
    int two;
};
objc:S1642

Sharing some naming conventions enables teams to collaborate more efficiently. This rule checks that all struct names match a provided regular expression.

Noncompliant Code Example

Using the default regular expression [A-Z][a-zA-Z0-9]*:

struct myStruct {
  int one;
  int two;
};

Compliant Solution

struct MyStruct {
  int one;
  int two;
};
c:S2342

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all enum names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression [A-Z][a-zA-Z0-9]+:

enum someEnumeration { // Noncompliant
};

Compliant Solution

enum SomeEnumeration {
};
c:S3222

Shared coding conventions allow teams to collaborate effectively. This rule checks that labels match a provided regular expression.

Noncompliant Code Example

With default provided regular expression [A-Z][A-Z0-9_]+:

exit:  // Noncompliant
  doCleanup();

Compliant Solution

EXIT:  // Compliant
  doCleanup();
c:S1878

Sharing some naming conventions enables teams to collaborate more efficiently. This rule checks that all union names match a provided regular expression.

Noncompliant Code Example

Using the default regular expression [A-Z][a-zA-Z0-9]*:

union my_union {
    int one;
    int two;
};

Compliant Solution

union MyUnion {
    int one;
    int two;
};
c:S1642

Sharing some naming conventions enables teams to collaborate more efficiently. This rule checks that all struct names match a provided regular expression.

Noncompliant Code Example

Using the default regular expression [A-Z][a-zA-Z0-9]*:

struct myStruct {
  int one;
  int two;
};

Compliant Solution

struct MyStruct {
  int one;
  int two;
};
squid:S2235

According to Oracle Javadoc:

IllegalMonitorStateException is thrown when a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.

In other words, this exception can be thrown only in case of bad design because Object.wait(...), Object.notify() and Object.notifyAll() methods should never be called on an object whose monitor is not held.

Noncompliant Code Example

public void doSomething(){
  ...
  try {
    ...
    anObject.notify();
    ...
  } catch(IllegalMonitorStateException e) {
    ...
  }
}

Compliant Solution

public void doSomething(){
  ...
  synchronized(anObject) {
    ...
    anObject.notify();
    ...
  }
}
squid:S1141

Nesting try/catch blocks severely impacts the readability of source code because it makes it too difficult to understand which block will catch which exception.

squid:S2689

ObjectOutputStreams are used with serialization, and the first thing an ObjectOutputStream writes is the serialization stream header. This header should appear once per file, at the beginning. Pass a file opened in append mode into an ObjectOutputStream constructor and the serialization stream header will be added to the end of the file before your object is then also appended.

When you're trying to read your object(s) back from the file, only the first one will be read successfully, and a StreamCorruptedException will be thrown after that.

Noncompliant Code Example

FileOutputStream fos = new FileOutputStream (fileName , true);  // fos opened in append mode
ObjectOutputStream out = new ObjectOutputStream(fos);  // Noncompliant

Compliant Solution

FileOutputStream fos = new FileOutputStream (fileName);
ObjectOutputStream out = new ObjectOutputStream(fos);
squid:S3658

When the code under test in a unit test throws an exception, the test itself fails. Therefore, there is no need to surround the tested code with a try-catch structure to detect failure. Instead, you can simply move the exception type to the method signature.

This rule raises an issue when there is a fail assertion inside a catch block.

Noncompliant Code Example

@Test
public void testMethod() {
  try {
            // Some code
  } catch (MyException e) {
    Assert.fail(e.getMessage());  // Noncompliant
  }
}

Compliant Solution

@Test
public void testMethod() throws MyException {
    // Some code
}
squid:S4517

According to the Java documentation, any implementation of the InputSteam.read() method is supposed to read the next byte of data from the input stream. The value byte must be an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned.

But in Java, the byte primitive data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127. So by contract, the implementation of an InputSteam.read() method should never directly return a byte primitive data type. A conversion into an unsigned byte must be done before by applying a bitmask.

Noncompliant Code Example

@Override
public int read() throws IOException {
  if (pos == buffer.length()) {
    return -1;
  }
  return buffer.getByte(pos++); // Noncompliant, a signed byte value is returned
}

Compliant Solution

@Override
public int read() throws IOException {
  if (pos == buffer.length()) {
    return -1;
  }
  return buffer.getByte(pos++) & 0xFF; // The 0xFF bitmask is applied
}
squid:S2142

InterruptedExceptions should never be ignored in the code, and simply logging the exception counts in this case as "ignoring". The throwing of the InterruptedException clears the interrupted state of the Thread, so if the exception is not handled properly the fact that the thread was interrupted will be lost. Instead, InterruptedExceptions should either be rethrown - immediately or after cleaning up the method's state - or the thread should be re-interrupted by calling Thread.interrupt() even if this is supposed to be a single-threaded application. Any other course of action risks delaying thread shutdown and loses the information that the thread was interrupted - probably without finishing its task.

Similarly, the ThreadDeath exception should also be propagated. According to its JavaDoc:

If ThreadDeath is caught by a method, it is important that it be rethrown so that the thread actually dies.

Noncompliant Code Example

public void run () {
  try {
    while (true) {
      // do stuff
    }
  }catch (InterruptedException e) { // Noncompliant; logging is not enough
    LOGGER.log(Level.WARN, "Interrupted!", e);
  }
}

Compliant Solution

public void run () {
  try {
    while (true) {
      // do stuff
    }
  }catch (InterruptedException e) {
    LOGGER.log(Level.WARN, "Interrupted!", e);
    // Restore interrupted state...
    Thread.currentThread().interrupt();
  }
}

See

squid:S4682

By definition, primitive types are not Objects and so they can't be null. Adding @CheckForNull or @Nullable on primitive types adds confusion and is useless.

This rule raises an issue when @CheckForNull or @Nullable is set on a method returning a primitive type: byte, short, int, long, float, double, boolean, char.

Noncompliant Code Example

@CheckForNull
boolean isFoo() {
 ...
}

Compliant Solution

boolean isFoo() {
 ...
}
squid:S2272

By contract, any implementation of the java.util.Iterator.next() method should throw a NoSuchElementException exception when the iteration has no more elements. Any other behavior when the iteration is done could lead to unexpected behavior for users of this Iterator.

Noncompliant Code Example

public class MyIterator implements Iterator<String>{
  ...
  public String next(){
    if(!hasNext()){
      return null;
    }
    ...
  }
}

Compliant Solution

public class MyIterator implements Iterator<String>{
  ...
  public String next(){
    if(!hasNext()){
      throw new NoSuchElementException();
    }
    ...
  }
}
squid:S2139

In applications where the accepted practice is to log an Exception and then rethrow it, you end up with miles-long logs that contain multiple instances of the same exception. In multi-threaded applications debugging this type of log can be particularly hellish because messages from other threads will be interwoven with the repetitions of the logged-and-thrown Exception. Instead, exceptions should be either logged or rethrown, not both.

Noncompliant Code Example

catch (SQLException e) {
  ...
  LOGGER.log(Level.ERROR,  contextInfo, e);
  throw new MySQLException(contextInfo, e);
}

Compliant Solution

catch (SQLException e) {
  ...
  throw new MySQLException(contextInfo, e);
}

or

catch (SQLException e) {
  ...
  LOGGER.log(Level.ERROR,  contextInfo, e);
  // handle exception...
}
squid:S2629

Passing message arguments that require further evaluation into a Guava com.google.common.base.Preconditions check can result in a performance penalty. That's because whether or not they're needed, each argument must be resolved before the method is actually called.

Similarly, passing concatenated strings into a logging method can also incur a needless performance hit because the concatenation will be performed every time the method is called, whether or not the log level is low enough to show the message.

Instead, you should structure your code to pass static or pre-computed values into Preconditions conditions check and logging calls.

Specifically, the built-in string formatting should be used instead of string concatenation, and if the message is the result of a method call, then Preconditions should be skipped altoghether, and the relevant exception should be conditionally thrown instead.

Noncompliant Code Example

logger.log(Level.DEBUG, "Something went wrong: " + message);  // Noncompliant; string concatenation performed even when log level too high to show DEBUG messages

logger.fine("An exception occurred with message: " + message); // Noncompliant

LOG.error("Unable to open file " + csvPath, e);  // Noncompliant

Preconditions.checkState(a > 0, "Arg must be positive, but got " + a);  // Noncompliant. String concatenation performed even when a > 0

Preconditions.checkState(condition, formatMessage());  // Noncompliant. formatMessage() invoked regardless of condition

Preconditions.checkState(condition, "message: %s", formatMessage());  // Noncompliant

Compliant Solution

logger.log(Level.SEVERE, "Something went wrong: {0} ", message);  // String formatting only applied if needed

logger.fine("An exception occurred with message: {}", message);  // SLF4J, Log4j

logger.log(Level.SEVERE, () -> "Something went wrong: " + message); // since Java 8, we can use Supplier , which will be evaluated lazily

LOG.error("Unable to open file {0}", csvPath, e);

if (LOG.isDebugEnabled() {
  LOG.debug("Unable to open file " + csvPath, e);  // this is compliant, because it will not evaluate if log level is above debug.
}

Preconditions.checkState(arg > 0, "Arg must be positive, but got %d", a);  // String formatting only applied if needed

if (!condition) {
  throw new IllegalStateException(formatMessage());  // formatMessage() only invoked conditionally
}

if (!condition) {
  throw new IllegalStateException("message: " + formatMessage());
}

Exceptions

catch blocks are ignored, because the performance penalty is unimportant on exceptional paths (catch block should not be a part of standard program flow). Getters are ignored as well as methods called on annotations which can be considered as getters. This rule accounts for explicit test-level testing with SLF4J methods isXXXEnabled and ignores the bodies of such if statements.

squid:S4929

When directly subclassing java.io.InputStream or java.io.FilterInputStream, the only requirement is that you implement the method read(). However most uses for such streams don't read a single byte at a time and the default implementation for read(byte[],int,int) will call read(int) for every single byte in the array which can create a lot of overhead and is utterly inefficient. It is therefore strongly recommended that subclasses provide an efficient implementation of read(byte[],int,int).

This rule raises an issue when a direct subclass of java.io.InputStream or java.io.FilterInputStream doesn't provide an override of read(byte[],int,int).

Noncompliant Code Example

public class MyInputStream extends java.io.InputStream {
  private FileInputStream fin;

  public MyInputStream(File file) throws IOException {
    fin = new FileInputStream(file);
  }

  @Override
  public int read() throws IOException {
    return fin.read();
  }
}

Compliant Solution

public class MyInputStream extends java.io.InputStream {
  private FileInputStream fin;

  public MyInputStream(File file) throws IOException {
    fin = new FileInputStream(file);
  }

  @Override
  public int read() throws IOException {
    return fin.read();
  }

  @Override
  public int read(byte[] b, int off, int len) throws IOException {
    return fin.read(b, off, len);
  }
}

Exceptions

This rule doesn't raise an issue when the class is declared abstract.

squid:S1751

A loop with at most one iteration is equivalent to the use of an if statement to conditionally execute one piece of code. No developer expects to find such a use of a loop statement. If the initial intention of the author was really to conditionally execute one piece of code, an if statement should be used instead.

At worst that was not the initial intention of the author and so the body of the loop should be fixed to use the nested return, break or throw statements in a more appropriate way.

Noncompliant Code Example

for (int i = 0; i < 10; i++) { // noncompliant, loop only executes once
  printf("i is %d", i);
  break;
}
...
for (int i = 0; i < 10; i++) { // noncompliant, loop only executes once
  if(i == x) {
    break;
  } else {
    printf("i is %d", i);
    return;
  }
}

Compliant Solution

for (int i = 0; i < 10; i++) {
  printf("i is %d", i);
}
...
for (int i = 0; i < 10; i++) {
  if(i == x) {
    break;
  } else {
    printf("i is %d", i);
  }
}
squid:S2737

A catch clause that only rethrows the caught exception has the same effect as omitting the catch altogether and letting it bubble up automatically, but with more code and the additional detriment of leaving maintainers scratching their heads.

Such clauses should either be eliminated or populated with the appropriate logic.

Noncompliant Code Example

public String readFile(File f) {
  StringBuilder sb = new StringBuilder();
  try {
    FileReader fileReader = new FileReader(fileName);
    BufferedReader bufferedReader = new BufferedReader(fileReader);

    while((line = bufferedReader.readLine()) != null) {
      //...
  }
  catch (IOException e) {  // Noncompliant
    throw e;
  }
  return sb.toString();
}

Compliant Solution

public String readFile(File f) {
  StringBuilder sb = new StringBuilder();
  try {
    FileReader fileReader = new FileReader(fileName);
    BufferedReader bufferedReader = new BufferedReader(fileReader);

    while((line = bufferedReader.readLine()) != null) {
      //...
  }
  catch (IOException e) {
    logger.LogError(e);
    throw e;
  }
  return sb.toString();
}

or

public String readFile(File f) throws IOException {
  StringBuilder sb = new StringBuilder();
  FileReader fileReader = new FileReader(fileName);
  BufferedReader bufferedReader = new BufferedReader(fileReader);

  while((line = bufferedReader.readLine()) != null) {
    //...

  return sb.toString();
}
squid:S3822

The use of any value but "validate" for hibernate.hbm2ddl.auto may cause the database schema used by your application to be changed, dropped, or cleaned of all data. In short, the use of this property is risky, and should only be used in production with the "validate" option, if it is used at all.

Noncompliant Code Example

<session-factory>
  <property name="hibernate.hbm2ddl.auto">update</property>  <!-- Noncompliant -->
</session-factory>

Compliant Solution

<session-factory>
  <property name="hibernate.hbm2ddl.auto">validate</property>  <!-- Compliant -->
</session-factory>

or

<session-factory>
  <!-- Property deleted -->
</session-factory>
squid:S1695

A NullPointerException should indicate that a null value was unexpectedly encountered. Good programming practice dictates that code is structured to avoid NPE's.

Explicitly throwing NullPointerException forces a method's callers to explicitly catch it, rather than coding to avoid it. Further, it makes it difficult to distinguish between the unexpectedly-encountered null value and the condition which causes the method to purposely throw an NPE.

If an NPE is being thrown to indicate that a parameter to the method should not have been null, use the @NotNull annotation instead.

Noncompliant Code Example

public void doSomething (String aString) throws NullPointerException {
     throw new NullPointerException();
}

Compliant Solution

public void doSomething (@NotNull String aString) {
}
squid:S4738

Some Guava features were really useful for Java 7 application because Guava was bringing APIs missing in the JDK. Java 8 fixed these limitations. When migrating an application to Java 8 or even when starting a new one, it's recommended to prefer Java 8 APIs over Guava ones to ease its maintenance: developers don't need to learn how to use two APIs and can stick to the standard one.

This rule raises an issue when the following Guava APIs are used:

Guava API Java 8 API
com.google.common.io.BaseEncoding#base64() java.util.Base64
com.google.common.io.BaseEncoding#base64Url() java.util.Base64
com.google.common.base.Joiner.on() java.lang.String#join() or java.util.stream.Collectors#joining()
com.google.common.base.Optional#of() java.util.Optional#of()
com.google.common.base.Optional#absent() java.util.Optional#empty()
com.google.common.base.Optional#fromNullable() java.util.Optional#ofNullable()
com.google.common.base.Optional java.util.Optional
com.google.common.base.Predicate java.util.function.Predicate
com.google.common.base.Function java.util.function.Function
com.google.common.base.Supplier java.util.function.Supplier
squid:S3984

Creating a new Throwable without actually throwing it is useless and is probably due to a mistake.

Noncompliant Code Example

if (x < 0)
  new IllegalArgumentException("x must be nonnegative");

Compliant Solution

if (x < 0)
  throw new IllegalArgumentException("x must be nonnegative");
squid:S4838

This rule raises an issue when an iteration over the items of a Collection is performed on a super-type of the type handled by the Collection.

Relying on Object or any classes between Object and the real class handled by the Collection is not recommended. While it's accepted by the language, this practice reduces readability of the code and forces to down-cast the item of the Collection to be able to call a method on it while simply using the correct type in the iteration makes things more clear and simple.

Noncompliant Code Example

public Collection<Person> getPersons() { ... }

for (Object item : getPersons()) { // Noncompliant
  Person person = (Person) item; // Noncompliant; it's required to down-cast to the to correct type to use "item"
  person.getAdress();
}

Compliant Solution

for (Person person : getPersons()) { // Compliant
  person.getAddress() ;
}
squid:S4719

JDK7 introduced the class java.nio.charset.StandardCharsets. It provides constants for all charsets that are guaranteed to be available on every implementation of the Java platform.

  • ISO_8859_1
  • US_ASCII
  • UTF_16
  • UTF_16BE
  • UTF_16LE
  • UTF_8

These constants should be preferred to:

- the use of a String such as "UTF-8" which has the drawback of requiring the catch/throw of an UnsupportedEncodingException that will never actually happen

- the use of Guava’s Charsets class, which has been obsolete since JDK7

Noncompliant Code Example

try {
  byte[] bytes = string.getBytes("UTF-8"); // Noncompliant; use a String instead of StandardCharsets.UTF_8
} catch (UnsupportedEncodingException e) {
  throw new AssertionError(e);
}
// ...
byte[] bytes = string.getBytes(Charsets.UTF_8); // Noncompliant; Guava way obsolete since JDK7

Compliant Solution

byte[] bytes = string.getBytes(StandardCharsets.UTF_8)
squid:S2166

Clear, communicative naming is important in code. It helps maintainers and API users understand the intentions for and uses of a unit of code. Using "exception" in the name of a class that does not extend Exception or one of its subclasses is a clear violation of the expectation that a class' name will indicate what it is and/or does.

Noncompliant Code Example

public class FruitException {  // Noncompliant; this has nothing to do with Exception
  private Fruit expected;
  private String unusualCharacteristics;
  private boolean appropriateForCommercialExploitation;
  // ...
}

public class CarException {  // Noncompliant; the extends clause was forgotten?
  public CarException(String message, Throwable cause) {
  // ...

Compliant Solution

public class FruitSport {
  private Fruit expected;
  private String unusualCharacteristics;
  private boolean appropriateForCommercialExploitation;
  // ...
}

public class CarException extends Exception {
  public CarException(String message, Throwable cause) {
  // ...
squid:S3014

There is little valid reason to use the methods of the ThreadGroup class. Some are deprecated (allowThreadSuspension(), resume(), stop(), and suspend()), some are obsolete, others aren't thread-safe, and still others are insecure (activeCount(), enumerate()) . For these reasons, any use of ThreadGroup is suspicious and should be avoided.

Compliant Solution

ThreadFactory threadFactory = Executors.defaultThreadFactory();
ThreadPoolExecutor executorPool = new ThreadPoolExecutor(3, 10, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2), threadFactory);

for (int i = 0; i < 10; i++) {
  executorPool.execute(new JobThread("Job: " + i));
}

System.out.println(executorPool.getActiveCount()); // Compliant
executorPool.shutdown();

See

squid:RedundantThrowsDeclarationCheck

An exception in a throws declaration in Java is superfluous if it is:

  • listed multiple times
  • a subclass of another listed exception
  • a RuntimeException, or one of its descendants
  • completely unnecessary because the declared exception type cannot actually be thrown

Noncompliant Code Example

void foo() throws MyException, MyException {}  // Noncompliant; should be listed once
void bar() throws Throwable, Exception {}  // Noncompliant; Exception is a subclass of Throwable
void baz() throws RuntimeException {}  // Noncompliant; RuntimeException can always be thrown

Compliant Solution

void foo() throws MyException {}
void bar() throws Throwable {}
void baz() {}

Exceptions

The rule will not raise any issue for exceptions that cannot be thrown from the method body:

  • in overriding and implementation methods
  • in interface default methods
  • in non-private methods that only throw, have empty bodies, or a single return statement .
  • in overridable methods (non-final, or not member of a final class, non-static, non-private), if the exception is documented with a proper javadoc.
class A extends B {
  @Override
  void doSomething() throws IOException {
    compute(a);
  }

  public void foo() throws IOException {}

  protected void bar() throws IOException {
    throw new UnsupportedOperationException("This method should be implemented in subclasses");
  }

  Object foobar(String s) throws IOException {
    return null;
  }

  /**
   * @throws IOException Overriding classes may throw this exception if they print values into a file
   */
  protected void print() throws IOException { // no issue, method is overridable and the exception has proper javadoc
    System.out.println("foo");
  }
}
squid:S3077

Marking an array volatile means that the array itself will always be read fresh and never thread cached, but the items in the array will not be. Similarly, marking a mutable object field volatile means the object reference is volatile but the object itself is not, and other threads may not see updates to the object state.

This can be salvaged with arrays by using the relevant AtomicArray class, such as AtomicIntegerArray, instead. For mutable objects, the volatile should be removed, and some other method should be used to ensure thread-safety, such as synchronization, or ThreadLocal storage.

Noncompliant Code Example

private volatile int [] vInts;  // Noncompliant
private volatile MyObj myObj;  // Noncompliant

Compliant Solution

private AtomicIntegerArray vInts;
private MyObj myObj;

See

  • CERT, CON50-J. - Do not assume that declaring a reference volatile guarantees safe publication of the members of the referenced object
squid:S3078

Using compound operators as well as increments and decrements (and toggling, in the case of booleans) on primitive fields are not atomic operations. That is, they don't happen in a single step. For instance, when a volatile primitive field is incremented or decremented you run the risk of data loss if threads interleave in the steps of the update. Instead, use a guaranteed-atomic class such as AtomicInteger, or synchronize the access.

Noncompliant Code Example

private volatile int count = 0;
private volatile boolean boo = false;

public void incrementCount() {
  count++;  // Noncompliant
}

public void toggleBoo(){
  boo = !boo;  // Noncompliant
}

Compliant Solution

private AtomicInteger count = 0;
private boolean boo = false;

public void incrementCount() {
  count.incrementAndGet();
}

public synchronized void toggleBoo() {
  boo = !boo;
}

See

  • CERT, VNA02-J. - Ensure that compound operations on shared variables are atomic
squid:S3065

When using Math.min() and Math.max() together for bounds checking, it's important to feed the right operands to each method. Math.min() should be used with the upper end of the range being checked, and Math.max() should be used with the lower end of the range. Get it backwards, and the result will always be the same end of the range.

Noncompliant Code Example

  private static final int UPPER = 20;
  private static final int LOWER = 0;

  public int doRangeCheck(int num) {    // Let's say num = 12
    int result = Math.min(LOWER, num);  // result = 0
    return Math.max(UPPER, result);     // Noncompliant; result is now 20: even though 12 was in the range
  }

Compliant Solution

Swapping method min() and max() invocations without changing parameters.

  private static final int UPPER = 20;
  private static final int LOWER = 0;

  public int doRangeCheck(int num) {    // Let's say num = 12
    int result = Math.max(LOWER, num);  // result = 12
    return Math.min(UPPER, result);     // Compliant; result is still 12
  }

or swapping bounds UPPER and LOWER used as parameters without changing the invoked methods.

  private static final int UPPER = 20;
  private static final int LOWER = 0;

  public int doRangeCheck(int num) {    // Let's say num = 12
    int result = Math.min(UPPER, num);  // result = 12
    return Math.max(LOWER, result);     // Compliant; result is still 12
  }
cpp:S2342

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all enum names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression [A-Z][a-zA-Z0-9]+:

enum someEnumeration { // Noncompliant
};

Compliant Solution

enum SomeEnumeration {
};
cpp:S3222

Shared coding conventions allow teams to collaborate effectively. This rule checks that labels match a provided regular expression.

Noncompliant Code Example

With default provided regular expression [A-Z][A-Z0-9_]+:

exit:  // Noncompliant
  doCleanup();

Compliant Solution

EXIT:  // Compliant
  doCleanup();
cpp:ClassName

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate.

This rule allows to check that all class names (along with Objective-C interface, protocol and implementation names) match a provided regular expression.

Noncompliant Code Example

With default provided regular expression [A-Z][a-zA-Z0-9]+:

// C++
class foo // Noncompliant
{
};

// Objective-C
@interface nonCompliant : NSObject
@end

Compliant Solution

// C++
class Foo // Compliant
{
};

// Objective-C
@interface Compliant : NSObject
@end
cpp:S1878

Sharing some naming conventions enables teams to collaborate more efficiently. This rule checks that all union names match a provided regular expression.

Noncompliant Code Example

Using the default regular expression [A-Z][a-zA-Z0-9]*:

union my_union {
    int one;
    int two;
};

Compliant Solution

union MyUnion {
    int one;
    int two;
};
cpp:S1642

Sharing some naming conventions enables teams to collaborate more efficiently. This rule checks that all struct names match a provided regular expression.

Noncompliant Code Example

Using the default regular expression [A-Z][a-zA-Z0-9]*:

struct myStruct {
  int one;
  int two;
};

Compliant Solution

struct MyStruct {
  int one;
  int two;
};
php:S1751

A loop with at most one iteration is equivalent to the use of an if statement to conditionally execute one piece of code. No developer expects to find such a use of a loop statement. If the initial intention of the author was really to conditionally execute one piece of code, an if statement should be used instead.

At worst that was not the initial intention of the author and so the body of the loop should be fixed to use the nested return, break or throw statements in a more appropriate way.

Noncompliant Code Example

for ($i = 0; $i < 10; $i++) { // Noncompliant
  echo "i is $i";
  break;
}
...
for ($i = 0; $i < 10; $i++) { // Noncompliant
  if ($i == $x) {
    break;
  } else {
    echo "i is $i";
    return;
  }
}

Compliant Solution

for ($i = 0; $i < 10; $i++) {
  echo "i is $i";
}
...
for ($i = 0; $i < 10; $i++) {
  if ($i == $x) {
    break;
  } else {
    echo "i is $i";
  }
}
php:S4833

PHP 5.3 introduces namespaces to the language. Use of this mechanism should be preferred to include or include_once or require or require_once because it solves two common problems:

  • it avoids name collisions
  • it provides the ability to create alias which improve readability of the code

Starting from its version 8, Drupal is relying on namespaces to be compliant with PSR-4 standard. Drupal's modules should be compliant with PSR-4 standard and therefore should no longer rely on include or include_once or require or require_once functions.

Noncompliant Code Example

require_once('./modules/vegetable/src/Entity/Tomato.php');

Compliant Solution

use Drupal\vegetable\Entity\Tomato

Exceptions

This rule doesn't raise issues on autoload.php or ScriptHandler.php files.

vbnet:S1940

It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.

Noncompliant Code Example

If Not (a = 2) Then  // Noncompliant
Dim b as Boolean = Not (i < 10)  // Noncompliant

Compliant Solution

If a <> 2 Then
Dim b as Boolean = i >= 10
vbnet:S2757

The use of operators pairs ( =+ or =-) where the reversed, single operator was meant (+= or -=) will compile and run, but not produce the expected results.

This rule raises an issue when =+ or =- is used without any spacing between the two operators and when there is at least one whitespace character after.

Noncompliant Code Example

Dim target As Integer = -5
Dim num As Integer = 3

target =- num ' Noncompliant; target = -3. Is that really what's meant?
target =+ num ' Noncompliant; target = 3

Compliant Solution

Dim target As Integer = -5
Dim num As Integer = 3

target = -num ' Compliant; intent to assign inverse value of num is clear
target += num
vbnet:S1821

Nested switch structures are difficult to understand because you can easily confuse the cases of an inner switch as belonging to an outer statement. Therefore nested switch statements should be avoided.

Specifically, you should structure your code to avoid the need for nested switch statements, but if you cannot, then consider moving the inner switch to another function.

vbnet:S3449

Numbers can be shifted with the << and >> operators, but the right operand of the operation needs to be an int or a type that has an implicit conversion to int. However, with dynamic, the compiler's type checking is turned off, so you can pass anything to a shift operator and have it compile. And if the argument can't be converted to int at runtime, then a RuntimeBinderException will be raised.

Noncompliant Code Example

Dim o As Object = 5
Dim x As Integer = 5

x = o >> 5 ' Noncompliant
x = x >> o ' Noncompliant

Exceptions

This rule does not raise when the left or the right expression is Nothing.

x = Nothing >> 5
x = 5 >> Nothing
vbnet:S3603

Marking a method with the Pure attribute specifies that the method doesn't make any visible changes; thus, the method should return a result, otherwise the call to the method should be equal to no-operation. So Pure on a void method is either a mistake, or the method doesn't do any meaningful task.

Noncompliant Code Example

Class Person
    Private age As Integer

    <Pure> ' Noncompliant. In this case the method makes a possibly visible state change
    Private Sub ConfigureAge(ByVal age As Integer)
        ...
        Me.age = age
    End Sub
End Class

Compliant Solution

Class Person
    Private age As Integer

    Private Sub ConfigureAge(ByVal age As Integer)
        Me.age = age
    End Sub
End Class
vbnet:S1479

When switch statements have large sets of case clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

Exceptions

This rule ignores Switch Cases over Enums and empty, fall-through cases.

vbnet:S1481

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

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

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
vbnet:S3358

Just because you can do something, doesn't mean you should, and that's the case with nested ternary operations. Nesting ternary operators results in the kind of code that may seem clear as day when you write it, but six months later will leave maintainers (or worse - future you) scratching their heads and cursing.

Instead, err on the side of clarity, and use another line to express the nested operation as a separate statement.

Noncompliant Code Example

Public Function GetTitle(ByVal p As Person) As String
    Return If(p.Gender = Gender.MALE, "Mr. ", If(p.IsMarried, "Mrs. ", "Miss ")) ' Noncompliant
End Function

Compliant Solution

Public Function GetTitle(ByVal p As Person) As String
    If p.Gender = Gender.MALE Then
        Return "Mr. "
    End If

    Return If(p.IsMarried, "Mrs. ", "Miss ")
End Function
vbnet:S3598

When declaring a Windows Communication Foundation (WCF) OperationContract method one-way, that service method won't return any result, not even an underlying empty confirmation message. These are fire-and-forget methods that are useful in event-like communication. Specifying a return type therefore does not make sense.

Noncompliant Code Example

<ServiceContract>
Interface IMyService
    <OperationContract(IsOneWay:=True)>
    Function SomethingHappened(ByVal parameter As Integer) As Integer ' Noncompliant
End Interface

Compliant Solution

<ServiceContract>
Interface IMyService
    <OperationContract(IsOneWay:=True)>
    Sub SomethingHappened(ByVal parameter As Integer)
End Interface

Exceptions

The rule doesn't report if OperationContractAttribute.AsyncPattern is set to true.

vbnet:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

The headerFormat must end with an empty line if you want to have an empty line between the file header and the first line for your source file (using, namespace...).

For example, if you want the source file to look like this

' Copyright (c) SonarSource. All Rights Reserved. Licensed under the LGPL License.  See License.txt in the project root for license information.

namespace Foo
{
}

then the headerFormat parameter should end with an empty line like this

' Copyright (c) SonarSource. All Rights Reserved. Licensed under the LGPL License.  See License.txt in the project root for license information.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
vbnet:S4210

When an assembly uses Windows Forms (classes and interfaces from the System.Windows.Forms namespace) its entry point should be marked with the STAThreadAttribute to indicate that the threading model should be "Single-Threaded Apartment" (STA) which is the only one supported by Windows Forms.

This rule raises an issue when the entry point (Shared Sub Main method) of an assembly using Windows Forms is not marked as STA.

Noncompliant Code Example

Imports System.Windows.Forms

Public Class Foo
  Shared Sub Main()
    Dim winForm As Form = New Form
    Application.Run(winForm)
  End Sub
End Class

Compliant Solution

Imports System.Windows.Forms

Public Class Foo
  <STAThread()> Shared Sub Main()
    Dim winForm As Form = New Form
    Application.Run(winForm)
  End Sub
End Class
vbnet:S1186

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

  • It is an unintentional omission, and should be fixed.
  • It is not yet, or never will be, supported. In this case a NotSupportedException should be thrown.
  • The method is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.

Noncompliant Code Example

Sub DoSomething()
End Sub

Function DoSomething()
End Function

Compliant Solution

Sub DoSomething()
    ' Not implemented because of reason
End Sub

Function DoSomething()
    Throw New NotSupportedException
End Function

Exceptions

The following methods are ignored:

  • empty Overridable or MustOverride methods,
  • empty methods that override an MustOverride method,
  • empty overrides in test assemblies.
vbnet:S3927

Serialization event handlers that don't have the correct signature will simply not be called, thus bypassing any attempts to augment the automated de/serialization.

This rule raises issue when a method marked with one of the following attributes is not private, does not return void, has type parameters, or does not have a single parameter of type System.Runtime.Serialization.StreamingContext:

  • System.Runtime.Serialization.OnSerializingAttribute
  • System.Runtime.Serialization.OnSerializedAttribute
  • System.Runtime.Serialization.OnDeserializingAttribute
  • System.Runtime.Serialization.OnDeserializedAttribute

Noncompliant Code Example

<Serializable>
Public Class Foo
    <OnSerializing>
    Public Sub OnSerializing(ByVal context As StreamingContext) ' Noncompliant should be private
    End Sub

    <OnSerialized>
    Private Function OnSerialized(ByVal context As StreamingContext) As Integer '  Noncompliant should return void
    End Function

    <OnDeserializing>
    Private Sub OnDeserializing() ' Noncompliant should have a single parameter of type StreamingContext
    End Sub

    <OnSerializing>
    Public Sub OnSerializing2(Of T)(ByVal context As StreamingContext) ' Noncompliant should have no type parameters
    End Sub

    <OnDeserialized>
    Private Sub OnDeserialized(ByVal context As StreamingContext, ByVal str As String) ' Noncompliant should have a single parameter of type StreamingContext
    End Sub
End Class

Compliant Solution

<Serializable>
Public Class Foo
    <OnSerializing>
    Private Sub OnSerializing(ByVal context As StreamingContext)
    End Sub

    <OnSerialized>
    Private Sub OnSerialized(ByVal context As StreamingContext)
    End Sub

    <OnDeserializing>
    Private Sub OnDeserializing(ByVal context As StreamingContext)
    End Sub

    <OnDeserialized>
    Private Sub OnDeserialized(ByVal context As StreamingContext)
    End Sub
End Class
vbnet:S3926

Fields marked with System.Runtime.Serialization.OptionalFieldAttribute are serialized just like any other field. But such fields are ignored on deserialization, and retain the default values associated with their types. Therefore, deserialization event handlers should be declared to set such fields during the deserialization process.

This rule raises when at least one field with the System.Runtime.Serialization.OptionalFieldAttribute attribute is declared but one (or both) of the following event handlers System.Runtime.Serialization.OnDeserializingAttribute or System.Runtime.Serialization.OnDeserializedAttribute are not present.

Noncompliant Code Example

<Serializable>
Public Class Foo ' Noncompliant
    <OptionalField(VersionAdded:=2)>
    Private optionalField As Integer = 5
End Class

Compliant Solution

<Serializable>
Public Class Foo
    <OptionalField(VersionAdded:=2)>
    Private optionalField As Integer = 5

    <OnDeserializing>
    Private Sub OnDeserializing(ByVal context As StreamingContext)
        optionalField = 5
    End Sub

    <OnDeserialized>
    Private Sub OnDeserialized(ByVal context As StreamingContext)
    End Sub
End Class
vbnet:S3923

Having all branches in a Select Case or If chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a Select Case / If chain at all.

Noncompliant Code Example

Dim b As Integer = If(a > 12, 4, 4)

If b = 0 Then
    DoTheThing()
Else
    DoTheThing()
End If

Select Case i
    Case 1
        DoSomething()
    Case 2
        DoSomething()
    Case 3
        DoSomething()
    Case Else
        DoSomething()
End Select

Exceptions

This rule does not apply to If chains without Else-s, or to Select Case-es without Case Else clauses.

If b = 0 Then ' No issue, this could have been done on purpose to make the code more readable
    DoTheThing()
ElseIf
    DoTheThing()
End If
vbnet:S3889

Thread.Suspend and Thread.Resume can give unpredictable results, and both methods have been deprecated. Indeed, if Thread.Suspend is not used very carefully, a thread can be suspended while holding a lock, thus leading to a deadlock. Other safer synchronization mechanisms should be used, such as Monitor, Mutex, and Semaphore.

Noncompliant Code Example

Public Sub Foo()
    Thread.CurrentThread.Suspend() ' Noncompliant
    Thread.[Resume]() ' Noncompliant
End Sub

See

vbnet:S3453

A class with only private constructors can't be instantiated, thus, it seems to be pointless code.

Noncompliant Code Example

Public Class [MyClass]
    Private Sub New() // Noncompliant
        ' ...
    End Sub
End Class

Compliant Solution

Public Class [MyClass]
    Private Sub New()
        ' ...
    End Sub
End Class

Exceptions

Classes that themselves access their private constructors (singletons or smart enums) are ignored. Classes with only static members are also ignored because they are covered by Rule S1118.

vbnet:S2761

Calling the Not operator twice does nothing: the second invocation undoes the first. Either this is a bug, if the operator was actually meant to be called once, or misleading if done on purpose.

Noncompliant Code Example

Dim b As Boolean = False
Dim c As Boolean = Not Not b 'Noncompliant

Compliant Solution

Dim b As Boolean = False
Dim c As Boolean = b 'Compliant
vbnet:S3693

It may be a good idea to raise an exception in a constructor if you're unable to fully flesh the object in question, but not in an exception constructor. If you do, you'll interfere with the exception that was originally being thrown. Further, it is highly unlikely that an exception raised in the creation of an exception will be properly handled in the calling code, and the unexpected, unhandled exception will lead to program termination.

Noncompliant Code Example

Class MyException
    Inherits Exception

    Public Sub MyException()
        If bad_thing Then
            Throw New Exception("A bad thing happened")
        End If
    End Sub
End Class
vbnet:S4428

The PartCreationPolicyAttribute attribute, which is part of the Managed Extensibility Framework (MEF), is used to specify how the exported object will be created. Therefore it doesn't make sense not to export this a class with this attribute using the ExportAttribute attribute.

This rule raises an issue when a class is marked as shared with a PartCreationPolicyAttribute but lacks a ExportAttribute.

Noncompliant Code Example

<PartCreationPolicy(CreationPolicy.Any)> ' Noncompliant
Public Class FooBar
    Inherits IFooBar
End Class

Compliant Solution

<Export(GetType(IFooBar))>
<PartCreationPolicy(CreationPolicy.Any)>
Public Class FooBar
    Inherits IFooBar
End Class
vbnet:S2360

The overloading mechanism should be used in place of optional parameters for several reasons:

  • Optional parameter values are baked into the method call site code, thus, if a default value has been changed, all referencing assemblies need to be rebuilt, otherwise the original values will be used.
  • The Common Language Specification (CLS) allows compilers to ignore default parameter values, and thus require the caller to explicitly specify the values. For example, if you want to consume a method with default argument from another .NET compatible language (for instance C++/CLI), you will have to provide all arguments. When using method overloads, you could achieve similar behavior as default arguments.
  • Optional parameters prevent muddying the definition of the function contract. Here is a simple example: if there are two optional parameters, when one is defined, is the second one still optional or mandatory?

Noncompliant Code Example

Sub Notify(ByVal Company As String, Optional ByVal Office As String = "QJZ") ' Noncompliant

End Sub

Compliant Solution

Sub Notify(ByVal Company As String)
  Notify(Company, "QJZ")
End Sub

Sub Notify(ByVal Company As String, ByVal Office As String)

End Sub

Exceptions

The rule ignores non externally visible methods.

vbnet:S4143

It is highly suspicious when a value is saved for a key or index and then unconditionally overwritten. Such replacements are likely in error.

Noncompliant Code Example

towns.Item(x) = "London"
towns.Item(x) = "Chicago";  // Noncompliant
vbnet:S4260

When creating a custom Markup Extension that accepts parameters in WPF, the ConstructorArgument markup must be used to identify the discrete properties that match these parameters. However since this is done via a string, the compiler will not notice if there are typos.

This rule raises an issue when the string argument to ConstructorArgumentAttribute doesn't match any parameter of any constructor.

Noncompliant Code Example

Imports System

Namespace myLibrary
    Public Class MyExtension
        Inherits MarkupExtension

        Public Sub New()
        End Sub

        Public Sub New(ByVal value1 As Object)
            Value1 = value1
        End Sub

        <ConstructorArgument("value2")> ' Noncompliant
        Public Property Value1 As Object
    End Class
End Namespace

Compliant Solution

Imports System

Namespace MyLibrary
    Public Class MyExtension
        Inherits MarkupExtension

        Public Sub New()
        End Sub

        Public Sub New(ByVal value1 As Object)
            Value1 = value1
        End Sub

        <ConstructorArgument("value1")>
        Public Property Value1 As Object
    End Class
End Namespace
vbnet:S4159

In the Attributed Programming Model, the ExportAttribute declares that a part "exports", or provides to the composition container, an object that fulfills a particular contract. During composition, parts with imports that have matching contracts will have those dependencies filled by the exported object.

If the type doesn't implement the interface it is exporting there will be an issue at runtime (either a cast exception or just a container not filled with the exported type) leading to unexpected behaviors/crashes.

The rule raises an issue when a class doesn't implement or inherit the type declared in the ExportAttribute.

Noncompliant Code Example

<Export(GetType(ISomeType))>
Public Class SomeType  // Noncompliant; doesn't implement 'ISomeType'.
End Class

Compliant Solution

<Export(GetType(ISomeType))>
Public Class SomeType
    Inherits ISomeType
End Class
vbnet:S3466

Generally, writing the least code that will readably do the job is a good thing, so omitting default parameter values seems to make sense. Unfortunately, when you omit them from the base call in an override, you're not actually getting the job done thoroughly, because you're ignoring the value the caller passed in. The result will likely not be what the caller expected.

Noncompliant Code Example

Public Class BaseClass
    Public Overridable Sub MyMethod(ByVal Optional i As Integer = 1)
        Console.WriteLine(i)
    End Sub
End Class

Public Class DerivedClass
    Inherits BaseClass

    Public Overrides Sub MyMethod(ByVal Optional i As Integer = 1)
        ' ...
        MyBase.MyMethod() ' Noncompliant; caller's value is ignored
    End Sub

    Private Shared Function Main(ByVal args As String()) As Integer
        Dim dc As DerivedClass = New DerivedClass()
        dc.MyMethod(12) ' prints 1
    End Function
End Class

Compliant Solution

Public Class BaseClass
    Public Overridable Sub MyMethod(ByVal Optional i As Integer = 1)
        Console.WriteLine(i)
    End Sub
End Class

Public Class DerivedClass
    Inherits BaseClass

    Public Overrides Sub MyMethod(ByVal Optional i As Integer = 1)
        ' ...
        MyBase.MyMethod(i)
    End Sub

    Private Shared Function Main(ByVal args As String()) As Integer
        Dim dc As DerivedClass = New DerivedClass()
        dc.MyMethod(12) ' prints 12
    End Function
End Class

vbnet:S3464

Recursion is acceptable in methods, where you can break out of it. But with class types, you end up with code that will compile but not run if you try to instantiate the class.

Noncompliant Code Example

Class C1(Of T)
End Class
Class C2(Of T)
    Inherits C1(Of C2 (Of T))
End Class
' ...
Dim c2 = New C2(Of Integer)
vbnet:S4277

Marking a class with PartCreationPolicy(CreationPolicy.Shared), which is part of Managed Extensibility Framework (MEF), means that a single, shared instance of the exported object will be created. Therefore it doesn't make sense to create new instances using the constructor and it will most likely result in unexpected behaviours.

This rule raises an issue when a constructor of a class marked shared with a PartCreationPolicyAttribute is invoked.

Noncompliant Code Example

<Export(GetType(IFooBar))>
<PartCreationPolicy(CreationPolicy.[Shared])>
Public Class FooBar
    Inherits IFooBar
End Class

Public Class Program
    Public Shared Sub Main()
        Dim fooBar = New FooBar() ' Noncompliant
    End Sub
End Class

Compliant Solution

<Export(GetType(IFooBar))>
<PartCreationPolicy(CreationPolicy.[Shared])>
Public Class FooBar
    Inherits IFooBar
End Class

Public Class Program
    Public Shared Sub Main()
        Dim fooBar = serviceProvider.GetService(Of IFooBar)()
    End Sub
End Class
vbnet:S3903

Types are declared in namespaces in order to prevent name collisions and as a way to organize them into the object hierarchy. Types that are defined outside any named namespace are in a global namespace that cannot be referenced in code.

Noncompliant Code Example

Public Class Foo
End Class

Public Structure Bar
End Structure

Compliant Solution

Namespace SomeSpace
    Public Class Foo
    End Class

    Public Structure Bar
    End Structure
End Namespace
vbnet:S3869

Not surprisingly, the SafeHandle.DangerousGetHandle method is dangerous. That's because it may not return a valid handle. Using it can lead to leaks and vulnerabilities. While it is possible to use the method successfully, it's extremely difficult to do correctly, so the method should simply be avoided altogether.

Noncompliant Code Example

Sub Dangerous(fieldInfo As System.Reflection.FieldInfo)
  Dim handle As SafeHandle = CType(fieldInfo.GetValue(fieldInfo), SafeHandle)
  Dim dangerousHandle As IntPtr = handle.DangerousGetHandle ' Noncompliant
End Sub
vbnet:S4275

Properties provide a way to enforce encapsulation by providing public, protected or internal methods that give controlled access to private fields. However in classes with multiple fields it is not unusual that cut and paste is used to quickly create the needed properties, which can result in the wrong field being accessed by a getter or setter.

This rule raises an issue in any of these cases:

  • A setter does not update the field with the corresponding name.
  • A getter does not access the field with the corresponding name.

For simple properties it is better to use auto-implemented properties (C# 3.0 or later).

Noncompliant Code Example

Class A
    Private x As Integer
    Private y As Integer

    Public Property X As Integer
        Get
            Return x
        End Get
        Set(ByVal value As Integer)
            x = value
        End Set
    End Property

    Public Property Y As Integer
        Get  ' Noncompliant: field 'y' is not used in the return value
            Return x
        End Get
        Set(ByVal value As Integer) ' Noncompliant: field 'y' is not updated
            x = value
        End Set
    End Property
End Class

Compliant Solution

Class A
    Private x As Integer
    Private y As Integer

    Public Property X As Integer
        Get
            Return x
        End Get
        Set(ByVal value As Integer)
            x = value
        End Set
    End Property

    Public Property Y As Integer
        Get
            Return y
        End Get
        Set(ByVal value As Integer)
            y = value
        End Set
    End Property
End Class
csharpsquid:S4143

It is highly suspicious when a value is saved for a key or index and then unconditionally overwritten. Such replacements are likely in error.

Noncompliant Code Example

list[index] = "value 1";
list[index] = "value 2";  // Noncompliant

dictionary.Add(key, "value 1");
dictionary[key] = "value 2"; // Noncompliant
plsql:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

See

plsql:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

CREATE TABLE mytable(col1 INTEGER NOT NULL);
INSERT INTO mytable VALUES (value) -- FIXME ensure value is not null

See

plsql:S4801

An "EXISTS" statement is generally used to select/update/delete some rows of a table based on the content of columns of other tables.

If the "SELECT" statement used as argument of the "EXISTS" statement is always returning "true" for all rows of the main SELECT statement, the EXISTS statement is useless and has the same effect as if it was not there. Still, this is probably not the original intend of the developer to have an EXISTS statement that is always true.

As a consequence, the SELECT statement of an EXISTS statement should always contain a WHERE clause.

What is true for EXISTS is also true for NOT EXISTS.

Noncompliant Code Example

SELECT  *
FROM    sys.[databases] AS [sd]
WHERE EXISTS (SELECT  1
              FROM    [sys].[master_files] AS [mf])

Compliant Solution

SELECT  *
FROM    sys.[databases] AS [sd]
WHERE EXISTS (SELECT  1
              FROM    [sys].[master_files] AS [mf]
              WHERE [mf].[database_id] = [sd].[database_id])

Exceptions

This rule doesn't raise an issue when EXISTS is used in the context of a WHILE or a IF statement.

plsql:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

UPDATE person
SET name = name;

Compliant Solution

UPDATE person
SET name = UPPER(name);

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
plsql:S1145

IF statements with conditions that are always false have the effect of making blocks of code non-functional. This can be useful during debugging, but should not be checked in. IF statements with conditions that are always true are completely redundant, and make the code less readable. In either case, unconditional IF statements should be removed.

Noncompliant Code Example

IF TRUE THEN
  do_something;
END IF;

IF FALSE THEN
  do_something_else;
END IF;

Compliant Solution

do_something;

See

  • MITRE, CWE-489 - Leftover Debug Code
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
plsql:S4584

CREATE_TIMER is generating network traffic each time the timer is fired. It's probably totally fine for a timer being executed every hour but generally, this is used to provide clocks components that are going to generate network traffic every second or more.

It is recommended by Oracle to examine timers and replace them with JavaBeans.

Noncompliant Code Example

BEGIN
  timer := CREATE_TIMER('foo', 1000, REPEAR)
ENDl

See

plsql:NestedCommentsCheck

PL/SQL does not support nested C-style (/* ... */) comments.

Noncompliant Code Example

/*
  This is a comment block, for which the ending tag was omitted
  It may be difficult to figure out that the following line of code is actually commented


variable = function_call();
/* variable contains the result, this is not allowed, as it is an attempt to create an inner comment */

See

  • CERT, MSC04-C. - Use comments consistently and in a readable fashion
  • MISRA C:2004, 2.3 - The character sequence /* shall not be used within a comment.
  • MISRA C++:2008, 2-7-1 - The character sequence /* shall not be used within a C-style comment.
  • MISRA C:2012, 3.1 - The character sequences /* and // shall not be used within a comment
plsql:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified.

This rule ignores operators +, * and ||, and expressions: 1=1, 1<>1, 1!=1, 1~=1 and 1^=1.

Noncompliant Code Example

SELECT code
  FROM Person
  WHERE first_name IS NULL OR first_name IS NULL; -- Noncompliant

SELECT * FROM Users
  INNER JOIN Clients ON Clients.id = Clients.id; -- Noncompliant

Compliant Solution

SELECT code
  FROM Person
  WHERE first_name IS NULL OR last_name IS NULL;

SELECT * FROM Users
  INNER JOIN Clients ON Clients.id = Users.id;

Exceptions

This rule ignores *, +, and =.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
plsql:S1523

Executing code dynamically is security sensitive. It has led in the past to the following vulnerabilities:

Any code which is dynamically evaluated in your process will have the same permissions as the rest of your code. Thus it is very dangerous to do so with code coming from an untrusted source. Injected Code can either run on the server or in the client (exemple: XSS attack).

EXECUTE IMMEDIATE executes as a dynamic SQL statement or anonymous PL/SQL block the string passed as an argument. It's safe only if the argument is composed of constant character string expressions. But if the command string is dynamically built using external parameters, then it is considered very dangerous because executing a random string allows the execution of arbitrary code.

This rule marks for review each occurence of dynamic code execution.

Ask Yourself Whether

  • the executed code may come from a untrusted source and hasn't been sanitized.
  • the code to run is dynamically chosen via reflection, and an untrusted source can use it to choose which code to run. For example a class could be retrieved by its name and this name comes from a user input.

You are at risk if you answered yes to any of these questions.

Recommended Secure Coding Practices

The best solution is to not run code provided by an untrusted source. If you really need to build a command string using external parameters, you should use EXECUTE IMMEDIATE with bind variables instead.

Do not try to create a blacklist of dangerous code. It is impossible to cover all attacks that way.

Noncompliant Code Example

CREATE OR REPLACE PROCEDURE ckpwd (p_user IN VARCHAR2, p_pass IN VARCHAR2)
IS
 v_query  VARCHAR2(100);
 v_output NUMBER;
BEGIN
 v_query :=    q'{SELECT COUNT(*) FROM user_pwd }'
         ||    q'{WHERE username = '}'
         ||    p_user
         ||    q'{' AND password = '}'
         ||    p_pass
         ||    q'{'}';
 EXECUTE IMMEDIATE v_query
  INTO v_output;
END;

Compliant Solution

CREATE OR REPLACE PROCEDURE ckpwd_bind (p_user IN VARCHAR2, p_pass IN VARCHAR2)
IS
 v_query  VARCHAR2(100);
 v_output NUMBER;
BEGIN
 v_query :=
   q'{SELECT COUNT(*) FROM user_pwd WHERE username = :1 AND password = :2}';
 EXECUTE IMMEDIATE v_query
  INTO v_output
  USING p_user, p_pass;
END;

Exceptions

Calling reflection methods with a hard-coded type name, method name or field name will not raise an issue.

See

  • MITRE CWE-95 - Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')
  • MITRE CWE-470 - Use of Externally-Controlled Input to Select Classes or Code ('Unsafe Reflection')
  • OWASP Top 10 2017 Category A1 - Injection
  • OWASP Top 10 2017 Category A7 - Cross-Site Scripting (XSS)
plsql:VariableHiding

Overriding a variable declared in an outer scope can strongly impact the readability, and therefore the maintainability, of a piece of code. Further, it could lead maintainers to introduce bugs because they think they're using one variable but are really using another.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  foo VARCHAR2(42) := 'foo';
BEGIN
  DECLARE
    foo VARCHAR2(42) := 'bar'; -- Noncompliant - this variable hides the one above and should be renamed
  BEGIN
    DBMS_OUTPUT.PUT_LINE(foo); -- Displays "bar", which is confusing
  END;

  DBMS_OUTPUT.PUT_LINE(foo); -- Displays "foo"
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  foo VARCHAR2(42) := 'foo';
BEGIN
  DECLARE
    bar VARCHAR2(42) := 'bar'; -- Compliant
  BEGIN
    DBMS_OUTPUT.PUT_LINE(bar); -- Displays "bar"
  END;

  DBMS_OUTPUT.PUT_LINE(foo); -- Displays "foo"
END;
/

See

  • MISRA C:2004, 5.2 - Identifiers in an inner scope shall not use the same name as an identifier in an outer scope, and therefore hide that identifier
  • MISRA C++:2008, 2-10-2 - Identifiers declared in an inner scope shall not hide an identifier declared in an outer scope
  • MISRA C:2012, 5.3 - An identifier declared in an inner scope shall not hide an identifier declared in an outer scope
  • CERT, DCL01-C. - Do not reuse variable names in subscopes
plsql:S4577

SYNCHRONIZE was introduced by Oracle as a recovery mechanism in case there is a loss of synchronization between what is in memory and what is displayed. It works but it comes with a price; each call to SYNCHRONIZE generates a network round-trip between the server and the Forms client. Most of the time it should be avoided or used with caution as explicitly stated in the Oracle Forms documentation.

Noncompliant Code Example

SYNCHRONIZE;
plsql:S1862

A CASE and a chain of IF/ELSIF statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

Noncompliant Code Example

IF param == 1 THEN
  x := 'A';
ELSIF param == 2 THEN
  x := 'B';
ELSIF param == 1 THEN -- Noncompliant, for sure this is a bug
  x := 'C';
END IF;

result := CASE param
   WHEN 1 THEN 'A'
   WHEN 2 THEN 'B'
   WHEN 1 THEN 'C'  -- Noncompliant
   ELSE 'D'
END;

Compliant Solution

IF param == 1 THEN
  result := 'A';
ELSIF param == 2 THEN
  result := 'B';
ELSIF param == 3 THEN
  result := 'C';
END IF;

result := CASE param
   WHEN 1 THEN 'A'
   WHEN 2 THEN 'B'
   WHEN 3 THEN 'C'
   ELSE 'D'
END;

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
plsql:S2278

According to the US National Institute of Standards and Technology (NIST), the Data Encryption Standard (DES) is no longer considered secure:

Adopted in 1977 for federal agencies to use in protecting sensitive, unclassified information, the DES is being withdrawn because it no longer provides the security that is needed to protect federal government information.

Federal agencies are encouraged to use the Advanced Encryption Standard, a faster and stronger algorithm approved as FIPS 197 in 2001.

For similar reasons, RC2 should also be avoided.

Noncompliant Code Example

PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_DES
                           + DBMS_CRYPTO.CHAIN_CBC
                           + DBMS_CRYPTO.PAD_PKCS5;

Compliant Solution

PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_AES256
                           + DBMS_CRYPTO.CHAIN_CBC
                           + DBMS_CRYPTO.PAD_PKCS5;

See

plsql:UnusedLabel

If a label is declared but not used in the program, it can be considered as dead code and should therefore be removed.

This will improve maintainability as developers will not wonder what this label is used for.

Noncompliant Code Example

<<foo>> -- Noncompliant
BEGIN
  DBMS_OUTPUT.PUT_LINE('Hello, world!');
END;

Compliant Solution

-- Compliant
BEGIN
  DBMS_OUTPUT.PUT_LINE('Hello, world!');
END;

See

  • MISRA C:2012, 2.6 - A function should not contain unused label declarations
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
plsql:S3643

The use of LIKE in a SQL query without one or more wildcards in the sought value is suspicious. A maintainer can suppose that either = was meant instead, or that the wildcard was unintentionally omitted.

Note that in some cases using LIKE without a wildcard may return different results than the use of =. Thus, the use of LIKE without a wildcard may be intentional. However, it is highly likely to confuse maintainers who either are unaware of this fact, or don't understand that such circumstances apply to the query in question.

Noncompliant Code Example

SELECT name
FROM product
WHERE name LIKE 'choc'

Compliant Solution

SELECT name
FROM product
WHERE name LIKE 'choc%'

or

SELECT name
FROM product
WHERE name = 'choc'
plsql:S4576

FORMS_DDL command, like every DDL statements, is performing an implicit COMMIT. It should be used only if there is no pending transaction otherwise this transaction is automatically committed without updating the Form statuses. Also, the potentially acquired locks are lost in case of this implicit COMMIT.

"FORMS_DDL('COMMIT')" and "FORMS_DDL('ROLLBACK')" should be used with care and most of the time, "COMMIT_FORM" or "ROLLBACK_FORM" should be preferred.

Check the Oracle Forms documentation for more details.

Noncompliant Code Example

FORMS_DDL('COMMIT');

Compliant Solution

COMMIT_FORM;
plsql:S3923

Having all branches in a CASE or IF/ELSIF chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a CASE/IF/ELSIF chain at all.

Noncompliant Code Example

IF param = 1 THEN
  result := 'A';
ELSIF param = 2 THEN
  result := 'A';
ELSE
  result := 'A';
END IF;

result := CASE param
   WHEN 1 THEN 'A'
   WHEN 2 THEN 'A'
   ELSE 'A'
END;

Compliant Solution

IF param = 1 THEN
  result := 'A';
ELSIF param = 2 THEN
  result := 'B';
ELSE
  result := 'C';
END IF;

result := CASE param
   WHEN 1 THEN 'A'
   WHEN 2 THEN 'B'
   ELSE 'C'
END;

Exceptions

This rule does not apply to IF/CASE chains without ELSE clauses.

IF param = 1 THEN   -- no issue, this could have been done on purpose to make the code more readable
  result := 'A';
ELSIF param = 2 THEN
  result := 'A';
END IF;
plsql:S1745

An INSERT statement that does not explicitly list the columns being inserted into, as well as the values being inserted, is dependent for correct functioning on the structure of the table not changing. Additionally, not having the explicit column list degrades the readability and understandability of the code. Therefore, INSERT statements should always contain an explicit column list.

Noncompliant Code Example

INSERT INTO PERSONS VALUES (1, 'DUPONT', 'Marcel')

Compliant Solution

INSERT INTO PERSONS (ID, LAST_NAME, FIRST_NAME)
VALUES (1, 'DUPONT', 'Marcel')
plsql:S3921

Trying to assign a large character value to a smaller variable or column will raise an error.

Noncompliant Code Example

create table persons (id number, name varchar2(4));

insert into persons (id, name) values (1, 'Alice'); -- Noncompliant, raises ORA-12899

create or replace procedure sp1
is
  foo varchar2(2);
begin
  select name into foo from persons where id = 1; -- Noncompliant, may raise ORA-06502
end;

Compliant Solution

create table persons (id number, name varchar2(8));

insert into persons (id, name) values (1, 'Alice');

create or replace procedure sp1
is
  foo varchar2(8);
begin
  select name into foo from persons where id = 1;
end;

See

plsql:S126

This rule applies whenever an IF statement is followed by one or

more ELSEIF statements; the final ELSEIF should be followed by an ELSE statement.

The requirement for a final ELSE statement is defensive programming.

The ELSE statement should either take appropriate action or contain

a suitable comment as to why no action is taken. This is consistent with the

requirement to have a final ELSE clause in a CASE

statement.

Noncompliant Code Example

IF my_variable = 0 THEN
  do_something;
ELSIF my_variable = 1 THEN
  do_something_else;
END IF;

Compliant Solution

IF my_variable = 0 THEN
  do_something;
ELSIF my_variable = 1 THEN
  do_something_else;
ELSE
  -- Nothing has to be done.
  NULL;
END IF;

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
plsql:DeadCodeCheck

Jump statements (EXIT, CONTINUE, RETURN, RAISE, and RAISE_APPLICATION_ERROR), move control flow out of the current code block. So any statements that come after a jump are dead code.

This rule detects for statements that follow:

  • EXIT without a WHEN
  • CONTINUE without a WHEN
  • RETURN
  • RAISE
  • RAISE_APPLICATION_ERROR

Noncompliant Code Example

SET SERVEROUTPUT ON

BEGIN
  LOOP
    DBMS_OUTPUT.PUT_LINE('This will be printed out');
    EXIT;

    DBMS_OUTPUT.PUT_LINE('This will NEVER be printed out'); -- Non-Compliant
  END LOOP;
END;
/

Compliant Solution

SET SERVEROUTPUT ON

BEGIN
  LOOP
    DBMS_OUTPUT.PUT_LINE('This will be printed out');
    EXIT;
  END LOOP;
END;
/

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code
  • MISRA C++:2008, 0-1-9 - There shall be no dead code
  • MISRA C:2012, 2.1 - A project shall not contain unreachable code
  • MISRA C:2012, 2.2 - There shall be no dead code
  • MITRE, CWE-561 - Dead Code
  • CERT, MSC56-J. - Detect and remove superfluous code and values
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
c:EmptyCompoundStatement

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

void foo()
{
  int x;
  if (x == 42)
  {                     /* Noncompliant */
    /* do nothing */
  }
  else
  {
    printf("x != 42");
  }
}

void bar()
{                       /* Compliant - functions are not nested blocks */
}

Compliant Solution

void foo()
{
  int x;
  if (x != 42)
  {                     /* Compliant */
    printf("x != 42");
  }
}

/* ... */

Exceptions

When a block contains a comment, this block is not considered to be empty.

ruby:S1313

Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:

Today's services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery and deployment:

  • The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
  • It forces the same address to be used in every environment (dev, sys, qa, prod).

Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service at this address or spoof the IP address. Such an attack is always possible, but in the case of a hardcoded IP address the fix will be much slower, which will increase an attack's impact.

Recommended Secure Coding Practices

  • make the IP address configurable.

Noncompliant Code Example

ip = "192.168.12.42"; // Noncompliant

Exceptions

No issue is reported for the following cases because they are not considered sensitive:

  • Loopback addresses 127.0.0.0/8 in CIDR notation (from 127.0.0.0 to 127.255.255.255)
  • Broadcast address 255.255.255.255
  • Non routable address 0.0.0.0
  • Strings of the form 2.5.<number>.<number> as they often match Object Identifiers (OID).

See

  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
  • CERT, MSC03-J. - Never hard code sensitive information
kotlin:S1313

Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:

Today's services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery and deployment:

  • The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
  • It forces the same address to be used in every environment (dev, sys, qa, prod).

Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service at this address or spoof the IP address. Such an attack is always possible, but in the case of a hardcoded IP address the fix will be much slower, which will increase an attack's impact.

Recommended Secure Coding Practices

  • make the IP address configurable.

Noncompliant Code Example

val ip = "192.168.12.42"
val socket = ServerSocket(ip, 6667)

Compliant Solution

val ip = System.getenv("myapplication.ip")
val socket = ServerSocket(ip, 6667)

Exceptions

No issue is reported for the following cases because they are not considered sensitive:

  • Loopback addresses 127.0.0.0/8 in CIDR notation (from 127.0.0.0 to 127.255.255.255)
  • Broadcast address 255.255.255.255
  • Non routable address 0.0.0.0
  • Strings of the form 2.5.<number>.<number> as they often match Object Identifiers (OID).

See

  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
  • CERT, MSC03-J. - Never hard code sensitive information
common-scala:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-scala:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-scala:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-scala:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-scala:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-scala:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
squid:S00107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

Noncompliant Code Example

With a maximum number of 4 parameters:

public void doSomething(int param1, int param2, int param3, String param4, long param5) {
...
}

Compliant Solution

public void doSomething(int param1, int param2, int param3, String param4) {
...
}

Exceptions

Methods annotated with Spring's @RequestMapping (and related shortcut annotations, like @GetRequest) or @JsonCreator may have a lot of parameters, encapsulation being possible. Such methods are therefore ignored.

squid:S1640

When all the keys of a Map are values from the same enum, the Map can be replaced with an EnumMap, which can be much more efficient than other sets because the underlying data structure is a simple array.

Noncompliant Code Example

public class MyClass {

  public enum COLOR {
    RED, GREEN, BLUE, ORANGE;
  }

  public void mapMood() {
    Map<COLOR, String> moodMap = new HashMap<COLOR, String> ();
  }
}

Compliant Solution

public class MyClass {

  public enum COLOR {
    RED, GREEN, BLUE, ORANGE;
  }

  public void mapMood() {
    EnumMap<COLOR, String> moodMap = new EnumMap<> (COLOR.class);
  }
}
squid:S1450

When the value of a private field is always assigned to in a class' methods before being read, then it is not being used to store class information. Therefore, it should become a local variable in the relevant methods to prevent any misunderstanding.

Noncompliant Code Example

public class Foo {
  private int a;
  private int b;

  public void doSomething(int y) {
    a = y + 5;
    ...
    if(a == 0) {
      ...
    }
    ...
  }

  public void doSomethingElse(int y) {
    b = y + 3;
    ...
  }
}

Compliant Solution

public class Foo {

  public void doSomething(int y) {
    int a = y + 5;
    ...
    if(a == 0) {
      ...
    }
  }

  public void doSomethingElse(int y) {
    int b = y + 3;
    ...
  }
}

Exceptions

This rule doesn't raise any issue on annotated field.

squid:S2057

A serialVersionUID field is strongly recommended in all Serializable classes. If you do not provide one, one will be calculated for you by the compiler. The danger in not explicitly choosing the value is that when the class changes, the compiler will generate an entirely new id, and you will be suddenly unable to deserialize (read from file) objects that were serialized with the previous version of the class.

serialVersionUID's should be declared with all of these modifiers: static final long.

Noncompliant Code Example

public class Raspberry extends Fruit  // Noncompliant; no serialVersionUID.
        implements Serializable {
  private String variety;

  public Raspberry(Season ripe, String variety) { ...}
  public void setVariety(String variety) {...}
  public String getVarity() {...}
}

public class Raspberry extends Fruit
        implements Serializable {
  private final int serialVersionUID = 1; // Noncompliant; not static & int rather than long

Compliant Solution

public class Raspberry extends Fruit
        implements Serializable {
  private static final long serialVersionUID = 1;
  private String variety;

  public Raspberry(Season ripe, String variety) { ...}
  public void setVariety(String variety) {...}
  public String getVarity() {...}
}

Exceptions

Swing and AWT classes, abstract classes, Throwable and its subclasses (Exceptions and Errors), and classes marked with @SuppressWarnings("serial") are ignored.

See

  • CERT, SER00-J. - Enable serialization compatibility during class evolution
squid:S4266

When using the Stream API, call chains should be simplified as much as possible to improve readability and maintainability.

This rule raises an issue when one of the following substitution can be made:

Original Preferred
stream.collect(counting()) stream.count()
stream.collect(maxBy(comparator)) stream.max(comparator)
stream.collect(minBy(comparator)) stream.min(comparator)
stream.collect(mapping(mapper)) stream.map(mapper).collect()
stream.collect(reducing(...)) stream.reduce(...)
stream.collect(summingInt(mapper)) stream.mapToInt(mapper).sum()
stream.collect(summingLong(mapper)) stream.mapToLong(mapper).sum()
stream.collect(summingDouble(mapper)) stream.mapToDouble(mapper).sum()

Noncompliant Code Example

int count = stream.collect(counting());  // Noncompliant

Compliant Solution

int count = stream.count();
squid:S4034

When using the Stream API, call chains should be simplified as much as possible. Not only does it make the code easier to read, it also avoid creating unnecessary temporary objects.

This rule raises an issue when one of the following substitution is possible:

Original Preferred
stream.filter(predicate).findFirst().isPresent() stream.anyMatch(predicate)
stream.filter(predicate).findAny().isPresent() stream.anyMatch(predicate)
!stream.anyMatch(predicate) stream.noneMatch(predicate)
!stream.anyMatch(x -> !(...)) stream.allMatch(...)
stream.map(mapper).anyMatch(Boolean::booleanValue) stream.anyMatch(predicate)

Noncompliant Code Example

boolean hasRed = widgets.stream().filter(w -> w.getColor() == RED).findFirst().isPresent(); // Noncompliant

Compliant Solution

boolean hasRed = widgets.stream().anyMatch(w -> w.getColor() == RED);
javascript:S1940

It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

if (!(a === 2)) { ... }  // Noncompliant

Compliant Solution

if (a !== 2) { ... }
javascript:S1264

When only the condition expression is defined in a for loop, and the initialization and increment expressions are missing, a while loop should be used instead to increase readability.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

for (;condition;) { /*...*/ }

Compliant Solution

while (condition) { /*...*/ }
javascript:S1479

When switch statements have large sets of case clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

Note that this rule requires Node.js to be available during analysis.

javascript:S1126

Return of boolean literal statements wrapped into if-then-else ones should be simplified.

Note that if the result of the expression is not a boolean but for instance an integer, then double negation should be used for proper conversion.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

if (expression) {
  return true;
} else {
  return false;
}

Compliant Solution

return expression;

or

return !!expression;
javascript:S1488

Declaring a variable only to immediately return or throw it is a bad practice.

Some developers argue that the practice improves code readability, because it enables them to explicitly name what is being returned. However, this variable is an internal implementation detail that is not exposed to the callers of the method. The method name should be sufficient for callers to know exactly what will be returned.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

function computeDurationInMilliseconds() {
  var duration = (((hours * 60) + minutes) * 60 + seconds ) * 1000 ;
  return duration;
}

Compliant Solution

function computeDurationInMilliseconds() {
  return (((hours * 60) + minutes) * 60 + seconds ) * 1000 ;
}
javascript:S1125

Boolean literals should be avoided in comparison expressions == and != to improve code readability.

This rule also reports on redundant boolean operations.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

let someValue = "0";
// ...

if (someValue == true) { /* ... */ }
if (someBooleanValue != true) { /* ... */ }
doSomething(!false);

Compliant Solution

if (someValue && someValue != "0") { /* ... */ }
if (!someBooleanValue) { /* ... */ }
doSomething(true);
javascript:S3358

Just because you can do something, doesn't mean you should, and that's the case with nested ternary operations. Nesting ternary operators results in the kind of code that may seem clear as day when you write it, but six months later will leave maintainers (or worse - future you) scratching their heads and cursing.

Instead, err on the side of clarity, and use another line to express the nested operation as a separate statement.

Noncompliant Code Example

function getTitle(p) {
  return p.gender == "male" ? "Mr. " : p.isMarried() ? "Mrs. " : "Miss ";  // Noncompliant
}

Compliant Solution

function getTitle(p) {
  if (p.gender == "male") {
    return "Mr. ";
  }
  return p.isMarried() ? "Mrs. " : "Miss ";
}
javascript:S1862

A switch and a chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

For a switch, if the first case ends with a break, the second case will never be executed, rendering it dead code. Worse there is the risk in this situation that future maintenance will be done on the dead case, rather than on the one that's actually used.

On the other hand, if the first case does not end with a break, both cases will be executed, but future maintainers may not notice that.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

if (param == 1)
  openWindow();
else if (param == 2)
  closeWindow();
else if (param == 1)  // Noncompliant
  moveWindowToTheBackground();


switch(i) {
  case 1:
    //...
    break;
  case 3:
    //...
    break;
  case 1:  // Noncompliant
    //...
    break;
  default:
    // ...
    break;
}

Compliant Solution

if (param == 1)
  openWindow();
else if (param == 2)
  closeWindow();
else if (param == 3)
  moveWindowToTheBackground();


switch(i) {
  case 1:
    //...
    break;
  case 3:
    //...
    break;
  default:
    // ...
    break;
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
javascript:S3699

If a function does not return anything, it makes no sense to use its output. Specifically, passing it to another function, or assigning its "result" to a variable is probably a bug because such functions return undefined, which is probably not what was intended.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

function foo() {
  console.log("Hello, World!");
}

a = foo();

Compliant Solution

function foo() {
  console.log("Hello, World!");
}

foo();
javascript:NestedIfDepth

Nested if, for, while, switch, 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:

  if (condition1) {                  // Compliant - depth = 1
    /* ... */
    if (condition2) {                // Compliant - depth = 2
      /* ... */
      for(let i = 0; i < 10; i++) {  // Compliant - depth = 3, not exceeding the limit
        /* ... */
        if (condition4) {            // Non-Compliant - depth = 4
          if (condition5) {          // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
            /* ... */
          }
          return;
        }
      }
    }
  }
javascript:CollapsibleIfStatements

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if (x != undefined) {
  if (y === 2) {
    // ...
  }
}

Compliant Solution

if (x != undefined && y === 2) {
  // ...
}
javascript:S3812

Mixing up the order of operations will almost always yield unexpected results.

Similarly, mis-applied negation will also yield bad results. For instance consider the difference between !key in dict and !(key in dict). The first looks for a boolean value (!key) in dict, and the other looks for a string and inverts the result. !obj instanceof SomeClass has the same problem.

This rule raises an issue when the left operand of an in or instanceof operator is negated.

Noncompliant Code Example

if (!"prop" in myObj) {  // Noncompliant;  "in" operator is checking property "false"
  doTheThing();  // this block will be never executed
}

if (!foo instanceof MyClass) {  // Noncompliant; "!foo" returns a boolean, which is not an instance of anything
  doTheOtherThing();  // this block is never executed
}

Compliant Solution

if (!("prop" in myObj)) {
  doTheThing();
}

if (!(foo instanceof MyClass)) {
  doTheOtherThing();
}
javascript:S1192

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.

Note that this rule requires Node.js to be available during analysis.

Exceptions

To prevent generating some false-positives, literals having less than 10 characters are excluded as well as literals matching /^\w*$/. String literals inside import/export statements and JSX attributes are also ignored.

javascript:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

if (a == b && a == b) { // if the first one is true, the second one is too
  doX();
}
if (a > a) { // always false
  doW();
}

var j = 5 / 5; //always 1
var k = 5 - 5; //always 0

Exceptions

The specific case of testing one variable against itself is a valid test for NaN and is therefore ignored.

Similarly, left-shifting 1 onto 1 is common in the construction of bit masks, and is ignored.

Moreover comma operator , and instanceof operator are ignored as there are use-cases when there usage is valid.

if (f !== f) { // test for NaN value
  console.log("f is NaN");
}

var i = 1 << 1; // Compliant
var j = a << a; // Noncompliant

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
javascript:S2428

Object literal syntax, which initializes an object's properties inside the object declaration is cleaner and clearer than the alternative: creating an empty object, and then giving it properties one by one.

An issue is raised when the following pattern is met:

  • An empty object is created.
  • A consecutive single-line statement adds a property to the created object.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

let person = {};  // Noncompliant
person.firstName = "John";
person.middleInitial = "Q";
person.lastName = "Public";

Compliant Solution

let person = {
  firstName: "John",
  middleInitial: "Q",
  lastName: "Public",
}
javascript:S4144

When two functions have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, the code should be refactored.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

function calculateCode() {
  doTheThing();
  doOtherThing();
  return code;
}

function getName() {  // Noncompliant
  doTheThing();
  doOtherThing();
  return code;
}

Compliant Solution

function calculateCode() {
  doTheThing();
  doOtherThing();
  return code;
}

function getName() {
  return calculateCode();
}

Exceptions

Functions with fewer than 3 lines are ignored.

javascript:S4143

It is highly suspicious when a value is saved for a key or index and then unconditionally overwritten. Such replacements are likely in error.

Note that this rule requires Node.js to be available during analysis.

Noncompliant Code Example

 fruits[1] = "banana";
 fruits[1] = "apple";  // Noncompliant - value on index 1 is overwritten

 myMap.set("key", 1);
 myMap.set("key", 2); // Noncompliant - value for key "key" is replaced

 mySet.add(1);
 mySet.add(1); // Noncompliant - element is already in the set
csharpsquid:S3433

A method is detected as test method if marked with one of the following attributes [TestMethod] or [DataTestMethod] (for mstest), [Fact] or [Theory] (for xunit) or [Test], [TestCase], [TestCaseSource] or [Theory] (for nunit). However, whether or not they have a test attribute, non-public methods are not recognized as tests, and therefore not executed. Neither are async void methods, or methods with generics anywhere in their signatures.

Noncompliant Code Example

[TestMethod]
void TestNullArg()  // Noncompliant; method is not public
{  /* ... */  }

[TestMethod]
public async void MyIgnoredTestMethod()  // Noncompliant; this is an 'async void' method
{ /* ... */ }

[TestMethod]
public void MyIgnoredGenericTestMethod<T>(T foo)  // Noncompliant; method has generics in its signature
{ /* ... */ }

Compliant Solution

[TestMethod]
public void TestNullArg()
{  /* ... */  }

Exceptions

Accessibility is ignored for xUnit Fact test methods, since they do not need to be public.

[Theory] test methods in xUnit and [TestCase] and [TestCaseSource] test methods in nunit can be generic.

csharpsquid:S2148

Beginning with C# 7, it is possible to add underscores ('_') to numeric literals to enhance readability. The addition of underscores in this manner has no semantic meaning, but makes it easier for maintainers to understand the code.

The number of digits to the left of a decimal point needed to trigger this rule varies by base.

Base Minimum digits
binary 9
decimal 6
hexadecimal 9

It is only the presence of underscores, not their spacing that is scrutinized by this rule.

Note that this rule is automatically disabled when the project's C# version is lower than 7.

Noncompliant Code Example

int i = 10000000;  // Noncompliant; is this 10 million or 100 million?
int  j = 0b01101001010011011110010101011110;  // Noncompliant
long l = 0x7fffffffffffffffL;  // Noncompliant

Compliant Solution

int i = 10_000_000;
int  j = 0b01101001_01001101_11100101_01011110;
long l = 0x7fff_ffff_ffff_ffffL;
csharpsquid:S2187

There's no point in having a test class without any test methods.This could lead a maintainer to assume a class is covered by tests even though it is not.

Supported test frameworks are NUnit and MSTest (not applicable to xUnit).

This rule will raise an issue when any of these conditions are met:

  • For NUnit, a class is marked with TestFixture but does not contain any method marked with Test, TestCase, TestCaseSource or Theory.
  • For MSTest, a class is marked with TestClass but does not contain any method marked with TestMethod or DataTestMethod.

Noncompliant Code Example

[TestFixture]
public class SomeClassTest { } // Noncompliant - no test

[TestClass]
public class SomeOtherClassTest { } // Noncompliant - no test

Compliant Solution

[TestFixture]
public class SomeClassTest
{
    [Test]
    public void SomeMethodShouldReturnTrue() { }
}

[TestClass]
public class SomeOtherClassTest
{
    [TestMethod]
    public void SomeMethodShouldReturnTrue() { }
}

Exceptions

  • abstract classes
  • derived classes that inherit from a base class that does have test methods
  • in MSTest, classes that contain methods marked with either AssemblyInitialize or AssemblyCleanup.
csharpsquid:S3603

Marking a method with the Pure attribute specifies that the method doesn't make any visible changes; thus, the method should return a result, otherwise the call to the method should be equal to no-operation. So Pure on a void method is either a mistake, or the method doesn't do any meaningful task.

Noncompliant Code Example

class Person
{
  private int age;
  [Pure] // Noncompliant. In this case the method makes a possibly visible state change
  void ConfigureAge(int age)
  {
    ...
    this.age = age;
  }
  ...
}

Compliant Solution

class Person
{
  private int age;

  void ConfigureAge(int age)
  {
    ...
    this.age = age;
  }
  ...
}
csharpsquid:S4260

When creating a custom Markup Extension that accepts parameters in WPF, the ConstructorArgument markup must be used to identify the discrete properties that match these parameters. However since this is done via a string, the compiler will not notice if there are typos.

This rule raises an issue when the string argument to ConstructorArgumentAttribute doesn't match any parameter of any constructor.

Noncompliant Code Example

using System;

namespace myLibrary
{
  public class MyExtension : MarkupExtension
  {
    public MyExtension() { }

    public MyExtension(object value1)
    {
      Value1 = value1;
    }

    [ConstructorArgument("value2")]
    public object Value1 { get; set; }
  }
}

Compliant Solution

using System;

namespace myLibrary
{
  public class MyExtension : MarkupExtension
  {
    public MyExtension() { }

    public MyExtension(object value1)
    {
      Value1 = value1;
    }

    [ConstructorArgument("value1")]
    public object Value1 { get; set; }
  }
}
squid:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
common-cs:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-web:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-ruby:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-tsql:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-objc:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-go:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-flex:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-abap:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-ts:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-cpp:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-py:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-vbnet:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-xml:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-css:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-php:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-c:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-swift:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-plsql:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-kotlin:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
common-js:InsufficientBranchCoverage
An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. It gives the number of branches to be covered in order to reach the required threshold.
kotlin:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

// FIXME denominator value might be  0
fun divide(numerator: Int, denominator: Int): Int = numerator / denominator

See

kotlin:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

fun doSomething() {
  // TODO
}

See

kotlin:S1871

Having two clauses in a when statement or two branches in an if chain 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 chain they should be combined, or for a when, duplicates should be refactored.

Noncompliant Code Example

fun s1871(x: Int) {
    when (x) {
        1 -> {
            val y = x / 2
            print(y)
        }
        2 -> {
            val y = x / 2
            print(y)
        }
    }
}

Exceptions

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a when statement that contain a single line of code with or without a following break.

if (a == 1) {
    doSomething()  //no issue, usually this is done on purpose to increase the readability
} else if (a == 2) {
    doSomethingElse()
} else {
    doSomething()
}

But this exception does not apply to if chains without else-s, or to when-es without else clauses when all branches have the same single line of code. In case of if chains with else-s, or of when-es with default clauses, rule S3923 raises a bug.

if (a == 1) {
  doSomething()  //Noncompliant, this might have been done on purpose but probably not
} else if (a == 2) {
  doSomething()
}
kotlin:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

Noncompliant Code Example

val params = "password=xxxx" // Noncompliant
val writer = OutputStreamWriter(getOutputStream())
writer.write(params)
writer.flush()
...
val password = "xxxx" // Noncompliant
...

Compliant Solution

val params = "password=${retrievePassword()}"
val writer = OutputStreamWriter(getOutputStream())
writer.write(params)
writer.flush()
...
val password = retrievePassword()
...

See

kotlin:S4144

When two functions have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, the code should be refactored.

Noncompliant Code Example

class MyClass {
  fun calculateCode(): String {
    doTheThing()
    doOtherThing()
    return "done"
  }

  fun getStatus(): String {  // Noncompliant
    doTheThing()
    doOtherThing()
    return "done"
  }
}

Compliant Solution

class MyClass {
  fun calculateCode(): String {
    doTheThing()
    doOtherThing()
    return "done"
  }

  fun getStatus(): String = calculateCode()
}

Exceptions

Methods with fewer than 2 statements are ignored.

kotlin:S4663

An empty multi-line comment is likely to be a mistake and doesn't help to improve the readability of the code. For these reasons, it should be removed.

Noncompliant Code Example

/* */

/*

 */
kotlin:ParsingError

When the parser fails, it is possible to record the failure as an issue on the file. This way, not only is it possible to track the number of files that do not parse but also to easily find out why they do not parse.

kotlin:S1151

The when statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the case clause should be extracted into a dedicated function.

Noncompliant Code Example

With the threshold set at 5:

when (myVariable) {
  0 -> {// Noncompliant: 6 lines till next case
    methodCall1("");
    methodCall2("");
    methodCall3("");
    methodCall4("");
    }
  1 -> {
    ...
  }
}

Compliant Solution

when (myVariable) {
  0 -> doSomething()
  1 -> {
    ...
  }
}
...
fun doSomething() {
    methodCall1("");
    methodCall2("");
    methodCall3("");
    methodCall4("");
}
kotlin:S108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

for (int i = 0; i < 42; i++){}  // Empty on purpose or missing piece of code ?

Exceptions

When a block contains a comment, this block is not considered to be empty.

while and unless loops are also exception to the rule.

while (order.processNext());  // Compliant
kotlin:S1763

Jump statements (return, break and continue) move control flow out of the current code block. So any statements that come after a jump are dead code.

Noncompliant Code Example

fun foo(a: Int): Int {
  var i = 10;
  return a + i;       // Noncompliant
  i++;                // dead code
}

Compliant Solution

fun foo(a: Int): Int {
  var i = 10;
  return a + i;
}

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code
  • MISRA C++:2008, 0-1-9 - There shall be no dead code
  • MISRA C:2012, 2.1 - A project shall not contain unreachable code
  • MISRA C:2012, 2.2 - There shall be no dead code
  • MITRE, CWE-561 - Dead Code
  • CERT, MSC56-J. - Detect and remove superfluous code and values
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
kotlin:S1125

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

Noncompliant Code Example

if (booleanMethod() || false) { /* ... */ }
doSomething(!false);

booleanVariable = if (booleanMethod()) true else false;
booleanVariable = if (booleanMethod()) true else exp;
booleanVariable = if (booleanMethod()) false else exp;
booleanVariable = if (booleanMethod()) exp else true;
booleanVariable = if (booleanMethod()) exp else false;

Compliant Solution

if (booleanMethod()) { /* ... */ }
doSomething(true);

booleanVariable = booleanMethod();
booleanVariable = booleanMethod() || exp;
booleanVariable = !booleanMethod() && exp;
booleanVariable = !booleanMethod() || exp;
booleanVariable = booleanMethod() && exp;
kotlin:S1145

if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.

There are three possible causes for the presence of such code:

  • An if statement was changed during debugging and that debug code has been committed.
  • Some value was left unset.
  • Some logic is not doing what the programmer thought it did.

In any of these cases, unconditional if statements should be removed.

Noncompliant Code Example

if (true) {
  doSomething()
}
...
if (false) {
  doSomethingElse()
}

Compliant Solution

doSomething()
...

See

  • MITRE, CWE-489 - Leftover Debug Code
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
kotlin:S2757

The use of operators pairs ( =+, =- or =! ) where the reversed, single operator was meant (+=, -= or !=) will compile and run, but not produce the expected results.

This rule raises an issue when =+, =-, or =! is used without any spacing between the two operators and when there is at least one whitespace character after.

Noncompliant Code Example

var target = -5
val num = 3

target =- num // Noncompliant; target = -3. Is that really what's meant?
target =+ num // Noncompliant; target = 3

Compliant Solution

var target = -5
val num = 3

target = -num // Compliant; intent to assign inverse value of num is clear
target += num
kotlin:S3923

Having all branches in a when or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a when/if chain at all.

Noncompliant Code Example

if (b == 0) {  // Noncompliant
     doOneMoreThing()
} else {
     doOneMoreThing()
}

when (i) {  // Noncompliant
    1 -> doSomething()
    2 -> doSomething()
    3 -> doSomething()
    else -> doSomething()
}

Exceptions

This rule does not apply to if chains without else-s, or to when-es without else clauses.

if (b == 0) {
    doOneMoreThing()
} else if (b == 1) {
    doOneMoreThing()
}

tsql:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

CREATE PROCEDURE doSomething
	AS
BEGIN
  ...
  -- TODO something
  ...
END
GO

See

tsql:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

CREATE TABLE notnull(col1 INTEGER NOT NULL)
INSERT notnull VALUES (@value) -- FIXME ensure @value is not null

See

tsql:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

--
-- SonarQube, open source software quality management tool.
-- Copyright (C) 2008-2018 SonarSource
-- mailto:contact AT sonarsource DOT com
--
-- SonarQube is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 3 of the License, or (at your option) any later version.
--
-- SonarQube is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public License
-- along with this program; if not, write to the Free Software Foundation,
-- Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
--
tsql:S1614

Tables without primary keys are largely unusable in a relational database because they cannot be joined to. A primary key should be specified at table creation to guarantee that all its records have primary key values.

Noncompliant Code Example

CREATE TABLE employee
(
  employee_id INTEGER NOT NULL,
  first_name VARCHAR(42) NOT NULL,
  last_name VARCHAR(42) NOT NULL
);

Compliant Solution

CREATE TABLE employee
(
  employee_id INTEGER NOT NULL PRIMARY KEY,
  first_name VARCHAR(42) NOT NULL,
  last_name VARCHAR(42) NOT NULL
);
CREATE TABLE employee
(
  employee_id INTEGER NOT NULL,
  first_name VARCHAR(42) NOT NULL,
  last_name VARCHAR(42) NOT NULL,
  CONSTRAINT PK_Employee PRIMARY KEY (employee_id)
);

Exceptions

No issue is reported on temporary tables as they are often used to manipulate data and do not always require a primary key.

Example:

CREATE TABLE #EmployeeName (last_name VARCHAR(42) NOT NULL); -- Compliant
tsql:S4801

An "EXISTS" statement is generally used to select/update/delete some rows of a table based on the content of columns of other tables.

If the "SELECT" statement used as argument of the "EXISTS" statement is always returning "true" for all rows of the main SELECT statement, the EXISTS statement is useless and has the same effect as if it was not there. Still, this is probably not the original intend of the developer to have an EXISTS statement that is always true.

As a consequence, the SELECT statement of an EXISTS statement should always contain a WHERE clause.

What is true for EXISTS is also true for NOT EXISTS.

Noncompliant Code Example

SELECT  *
FROM    sys.[databases] AS [sd]
WHERE EXISTS (SELECT  1
              FROM    [sys].[master_files] AS [mf])

Compliant Solution

SELECT  *
FROM    sys.[databases] AS [sd]
WHERE EXISTS (SELECT  1
              FROM    [sys].[master_files] AS [mf]
              WHERE [mf].[database_id] = [sd].[database_id])

Exceptions

This rule doesn't raise an issue when EXISTS is used in the context of a WHILE or a IF statement.

tsql:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

tsql:S1940

It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.

Noncompliant Code Example

IF NOT (@a = 2) -- Noncompliant
BEGIN
  ...
END

IF NOT (@b < 10) -- Noncompliant
BEGIN
  ...
END

Compliant Solution

IF @a <> 2
BEGIN
  ...
END

IF @b >= 10
BEGIN
  ...
END
tsql:S1067

The complexity of an expression is defined by the number of AND and OR operators it contains.

A single expression's complexity should not become too high to keep the code readable.

Noncompliant Code Example

With the default threshold value of 3

IF ((@a = 1 AND @b > 2) OR (@c <> 3 AND @d <= 4)) AND @e IS NULL
  ...
tsql:S4819

NOCOUNT is by default deactivated (OFF) at server level. It means by default, the server will send to the client the number of rows affected by the SQL query executed which is, in most cases, useless because no one will read this information.

Deactivating this feature will save some network traffic and improve the execution performance of stored procedures and triggers that's why it is recommended to define SET NOCOUNT ON at the beginning of the definition of PROCEDUREs and TRIGGERs, before any query is processed.

This rule raises an issue when NOCOUNT is not set or is set to OFF between the beginning of the PROCEDURE (or TRIGGER) definition and the first statement that is not a SET, IF or DECLARE.

Noncompliant Code Example

CREATE PROCEDURE dbo.MyProc
AS
BEGIN
  DECLARE @var INT;
  SET NOCOUNT OFF; -- Noncompliant; deactivate NOCOUNT
  SELECT COUNT(*) FROM MY_TABLE
END;
CREATE PROCEDURE dbo.MyProc
AS
BEGIN
  -- Noncompliant; SET NOCOUNT is not specified so behaviour of the procedure execution is based on server configuration (OFF by default)
  SELECT COUNT(*) FROM MY_TABLE
END;
CREATE PROCEDURE dbo.MyProc
AS
BEGIN
  SELECT COUNT(*) FROM MY_TABLE
  SET NOCOUNT ON -- Noncompliant; SET NOCOUNT is set after select statement
END;

Compliant Solution

CREATE PROCEDURE dbo.MyProc(@debug  INT)
AS
BEGIN
  DECLARE @var INT;
  IF @debug = 0
    BEGIN
      SET NOCOUNT ON;
    END
  SELECT COUNT(*) FROM MY_TABLE
END;
CREATE TRIGGER MyTrigger ON MyTable
AFTER INSERT
AS
BEGIN
  SET NOCOUNT ON;
  [...]
END;
tsql:S3923

Having all branches in a CASE, IF or IIF chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a CASE/IF/IIF chain at all.

Noncompliant Code Example

IF @x < 25 -- Noncompliant
  PRINT 'A'
ELSE IF @x < 10
  PRINT 'A'
ELSE
  PRINT 'A'

SELECT
  CASE col1 -- Noncompliant
    WHEN 1 THEN 'A'
    WHEN 2 THEN 'A'
    ELSE        'A'
  END,
  IIF(col1 < 25, 'A', 'A') -- Noncompliant
 FROM table1

Exceptions

This rule does not apply to IF/CASE chains without ELSE clauses.

IF @x < 25 -- no issue, this could have been done on purpose to make the code more readable
  PRINT 'A'
ELSE IF @x > 10
  PRINT 'A'
tsql:S4104

COALESCE and IIF (which evaluate to CASE expressions under the covers), as well as CASE input expressions should not be used with subqueries because the subquery will be evaluated once for each option in the expression, and each evaluation could return different results depending on the isolation level. To ensure consistent results, use the SNAPSHOT ISOLATION isolation level. To ensure consistent results and better performance, move the subquery out of the expression.

Note it is also an option to replace COALESCE with ISNULL.

Noncompliant Code Example

...
COALESCE((SELECT a FROM b WHERE c) , 1)  -- Noncompliant
...
...
CASE
WHEN (SELECT COUNT(*) FROM A) > 0 THEN (SELECT COUNT(*) FROM A) + 42
...
ELSE otherExpression
END
...

Compliant Solution

SET @a = SELECT a FROM b WHERE c
...
COALESCE(@a, 1)
...

or

SET TRANSACTION ISOLATION LEVEL SNAPSHOT
BEGIN TRANSACTION
...
COALESCE((SELECT a FROM b WHERE c) , 1)
...
...

SET @a = SELECT COUNT(*) FROM A

CASE
WHEN @a > 0 THEN @a + 42
...
ELSE otherExpression
END
...
tsql:S1751

A WHILE loop with at most one iteration is equivalent to the use of an IF statement to conditionally execute one piece of code. No developer expects to find such usage of a loop statement. If the initial intention of the author was really to conditionally execute one piece of code, an IF statement should be used in place.

At worst that was not the initial intention of the author and so the body of the loop should be fixed to use the nested RETURN, BREAK or THROW statements in a more appropriate way.

Noncompliant Code Example

WHILE @cond -- noncompliant, loop only executes once
BEGIN
  EXEC something;
  BREAK;
END;
...
WHILE @cond1 -- noncompliant, loop only executes once
BEGIN
  IF @cond2
  BEGIN
    EXEC something;
    BREAK;
  END ELSE
  BEGIN
    RETURN @value;
  END;
END;

Compliant Solution

IF @cond
BEGIN
  EXEC something;
  BREAK;
END;
...
WHILE @cond
BEGIN
  IF @cond2
  BEGIN
    EXEC something;
  END ELSE
  BEGIN
    RETURN @value;
  END;
END;
tsql:S1871

Having two branches in an IF/ELSE IF chain 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 chain they should be combined.

Noncompliant Code Example

IF @SortOrder = 1
  BEGIN
    SET @SortOrder = 0
    SELECT LastName FROM Employees ORDER BY LastName
  END
ELSE IF @SortOrder = 2
  BEGIN
    SET @SortOrder = 0
    SELECT LastName FROM Employees ORDER BY LastName -- Noncompliant
  END
ELSE
  BEGIN
    SET @SortOrder = -1
    SELECT LastName FROM Employees
  END
GO

Exceptions

Branches in an IF/ELSE IF chain with implementation that contains a single line of code are ignored.

IF @SortOrder = 1
  BEGIN
    SELECT LastName FROM Employees ORDER BY LastName
  END
ELSE IF @SortOrder = 2
  BEGIN
    SELECT LastName FROM Employees
  END
ELSE
  BEGIN
    SELECT LastName FROM Employees ORDER BY LastName -- No issue, usually this is done on purpose to increase the readability
  END
GO

But this exception does not apply to IF chains without ELSE-s when all branches have the same single line of code. In case of IF chains with ELSE-s rule S3923 raises a bug.

IF @SortOrder = 1    -- Noncompliant, this might have been done on purpose but probably not
  BEGIN
    SELECT LastName FROM Employees ORDER BY LastName
  END
ELSE IF @SortOrder = 2
  BEGIN
    SELECT LastName FROM Employees ORDER BY LastName
  END
GO
tsql:S2681

BEGIN...END can be omitted from a one-line block, such as with an IF statement or WHILE loop, but doing so can be misleading and induce bugs.

This rule raises an issue when the indentation of the lines after a one-line block indicates an intent to include those lines in the block, but the omission of BEGIN...END means the lines will be unconditionally executed once.

Noncompliant Code Example

IF (0=1)
  EXEC firstActionInBlock;
  EXEC secondAction;  -- Noncompliant; executed unconditionally
EXEC thirdAction;

IF (0=1) EXEC firstActionInBlock; EXEC secondAction;  -- Noncompliant; secondAction executed unconditionally

IF (0=1) EXEC firstActionInBlock;  -- Noncompliant
  EXEC secondAction;  -- Executed unconditionally

Compliant Solution

IF (0=1) BEGIN
  EXEC firstActionInBlock;
  EXEC secondAction;
END
EXEC thirdAction;

See

tsql:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

This rule ignores operators + and *, and expressions: 1=1, 1<>1 and 1!=1.

Exceptions

This rule ignores *, +, and =.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
tsql:S3626

Jump statements, such as RETURN and CONTINUE let you change the default flow of program execution, but jump statements that direct the control flow to the original direction are just a waste of keystrokes.

Noncompliant Code Example

CREATE PROCEDURE MyProc
AS
  DECLARE @return_status int = 0;
  WHILE @return_status = 0
  BEGIN
    EXEC @return_status = something;
    CONTINUE; -- Noncompliant
  END;
  RETURN; -- Noncompliant
GO

Compliant Solution

CREATE PROCEDURE MyProc
AS
  DECLARE @return_status int = 0;
  WHILE @return_status = 0
  BEGIN
    EXEC @return_status = something;
  END;
GO
abap:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression ^([A-Z0-9_]*|[a-z0-9_]*)$:

METHOD MyMethod
...
ENDMETHOD.

Compliant Solution

METHOD MY_METHOD
...
ENDMETHOD.
abap:S101

Shared coding conventions allow teams to collaborate effectively. This rule allows to check that all class names match a provided regular expression.

Noncompliant Code Example

With the default provided regular expression ^([A-Z0-9_]*|[a-z0-9_]*)$:

CLASS MyClass DEFINITION.
...
ENDCLASS.

Compliant Solution

CLASS MY_CLASS DEFINITION.
...
ENDCLASS.
abap:S103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

abap:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

abap:S105

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

abap:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

IF something.
  IF somethingElse.
    WRITE / 'hello'.
  ENDIF.
ENDIF.

Compliant Solution

IF something and somethingElse.
  WRITE / 'hello'.
ENDIF.
abap:S1067

The complexity of an expression is defined by the number of AND, OR, XOR and EQUIV operators it contains.

A single expression's complexity should not become too high to keep the code readable.

Noncompliant Code Example

With the default threshold value of 3

IF ((condition1 AND condition2) OR (condition3 AND condition4)) AND condition5.
  ...
ENDIF.
abap:S109

A magic number is a number that comes out of nowhere, and is directly used in a statement. Magic numbers are often used, for instance to limit the number of iterations of a loops, to test the value of a property, etc.

Using magic numbers may seem obvious and straightforward when you're writing a piece of code, but they are much less obvious and straightforward at debugging time.

That is why magic numbers must be demystified by first being assigned to clearly named variables before being used.

-1, 0 and 1 are not considered magic numbers.

Noncompliant Code Example

IF sy-subrc EQ 42.
  screen-request = 45.
ENDIF.

Compliant Solution

answer = 42.
IF sy-subrc EQ answer.
  screen-request = 45.
ENDIF.
abap:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

 CHECK (SY-SUBRC NE 0). "compliant even if ignored by compiler
 IF ((SY-SUBRC EQ 0)). "Noncompliant

Compliant Solution

 CHECK (SY-SUBRC NE 0).
 IF (SY-SUBRC EQ 0).
abap:S1138

SQL queries that use EXISTS subqueries are inefficient because the subquery is re-run for every row in the outer query's table. There are more efficient ways to write most queries, ways that do not use the EXISTS condition.

Noncompliant Code Example

SELECT name
FROM employee
WHERE EXISTS (SELECT * FROM department WHERE department_id = id AND name = 'Marketing');

Compliant Solution

SELECT name
FROM employee INNER JOIN department AS d
  ON department_id = d.id AND d.name = 'Marketing';
abap:S1139

DELETE FROM dbtab without a WHERE condition deletes all the entries of the table. Check whether dataset to be deleted can be limited by a suitable WHERE condition.

Noncompliant Code Example

DELETE FROM COUNTRIES.

Compliant Solution

DELETE FROM COUNTRIES WHERE CODE = country_code.
abap:S114

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all interface names match a provided regular expression.

Noncompliant Code Example

With the default regular expression YIF_[A-Za-z]+:

INTERFACE MyInterface. "Noncompliant
...
ENDINTERFACE.

Compliant Solution

INTERFACE YIF_myinterface.
...
ENDINTERFACE.
abap:S1192

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

With the default threshold of 3:

WRITE: / 'Firstname'.
*...
WRITE: / 'Firstname'.
*...
WRITE: / 'Firstname'.

Compliant Solution

CONSTANTS: fname    TYPE c LENGTH 9 VALUE 'Firstname',

WRITE: / fname.
*...
WRITE: / fname.
*...
WRITE: / fname.

Exceptions

To prevent generating some false-positives, literals having less than 5 characters are excluded.

abap:S122

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

WRITE 'Hello World'. WRITE 'You can use multiple statements on a line'.

Compliant Solution

WRITE 'Hello World'.
WRITE 'You can use multiple statements on a line'.
WRITE 'But you shouldn't.'.
abap:S1311

The Cyclomatic Complexity is measured by summing the number of and, or and xor operators, the number of control flow statement like IF, WHILE, DO, RETURN ... in the body of a class plus one for each method. Even when the Cyclomatic Complexity of a class is very high, this complexity might be well distributed among all methods. Nevertheless, most of the time, a very complex class is a class which breaks the Single Responsibility Principle and which should be re-factored to be split in several classes.

Deprecated

This rule is deprecated, and will eventually be removed.

abap:S133

The Cyclomatic Complexity of methods should not exceed a defined threshold. Complex code may perform poorly and can be difficult to test thoroughly.

Deprecated

This rule is deprecated; use S1541 instead.

abap:S134

Nested IF, CASE, DO, LOOP, SELECT, WHILE and PROVIDE statements is a key ingredient 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:

IF param1 = 2.
  IF param2 = 4.
    DO 3 TIMES.    "Compliant - depth = 3, not exceeding the limit
      IF sy-index = 2.   "Noncompliant - depth = 4
        CONTINUE.
      ENDIF.
      WRITE sy-index.
    ENDDO.
  ENDIF.
ENDIF.
abap:S135

Restricting the number of CONTINUE, EXIT and CHECK statements in a loop is done in the interest of good structured programming.

One CONTINUE, EXIT and CHECK statement is acceptable in a loop, since it facilitates optimal coding. If there is more than one, the code should be refactored to increase readability.

Noncompliant Code Example

DO counter TIMES.
  IF sy-index = 2.
    CONTINUE.
  ENDIF.
  IF sy-index = 10.
    EXIT.
  ENDIF.
  WRITE sy-index.
ENDDO.
abap:S1481

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

FUNCTION f.
  DATA: LOCAL_1 LIKE BAR.
  DATA: LOCAL_2 LIKE BAR. "Noncompliant

  SELECT * FROM LOCAL_1.

ENDFUNCTION.

Compliant Solution

FUNCTION f.
  DATA: LOCAL_1 LIKE BAR.

  SELECT * FROM LOCAL_1.

ENDFUNCTION.
abap:S1485

DATA BEGIN OF ... OCCURS has been deprecated and will eventually be removed. All usages should be replaced.

Noncompliant Code Example

DATA BEGIN OF itab OCCURS n. "Noncompliant
  ...
DATA END OF itab [VALID BETWEEN intlim1 AND intlim2].

Compliant Solution

DATA BEGIN OF wa.
       ...
DATA END OF wa.
DATA itab LIKE TABLE OF wa.
abap:S1487

The ABAP documentation is pretty clear on this subject :

This statement is only for

!!! Internal use in SAP Basis development !!!

Even within SAP Basis, it may only be used in programs within the ABAP+GUI development group.

Its use is subject to various restrictions, not all of which may be listed in the documentation. This documentation is intended for internal SAP use within the Basis development group ABAP+GUI.

Changes and further development, which may be incompatible, may occur at any time, without warning or notice!

Noncompliant Code Example

SYSTEM-CALL CREATE CLASS c.
abap:S1491

This statement deletes all rows of an internal table itab. This REFRESH statement is deprecated and usage should be avoided.

Noncompliant Code Example

REFRESH itab.

Compliant Solution

CLEAR itab.
abap:S1492

Although the WHERE condition is optional in a SELECT statement, for performance and security reasons, a WHERE clause should always be specified to prevent reading the whole table.

Noncompliant Code Example

SELECT * FROM db_persons INTO us_persons.

Compliant Solution

SELECT * FROM db_persons INTO us_persons WHERE country IS 'US'.

Exceptions

SELECT SINGLE and UP TO 1 ROWS result in only one record being read, so such SELECTs are ignored by this rule.

SELECT SINGLE * FROM db_persons INTO us_persons.

SELECT * FROM db_persons UP TO 1 ROWS INTO us_persons.
abap:S1494

JOIN bypasses the SAP table buffer. Buffered tables should be accessed with the simplest SELECT statements possible so as not to risk bypassing the buffer.

If one of the tables in a JOIN is buffered, it would be an advantage to first import the required entries using a SELECT into an internal table itab, and then for example, using the statement SELECT ... FOR ALL ENTRIES IN itab to access further tables.

Noncompliant Code Examples

For JOIN clauses:

SELECT s~carrid s~carrname p~connid
       INTO CORRESPONDING FIELDS OF TABLE itab
       FROM scarr AS s
       LEFT OUTER JOIN spfli AS p ON s~carrid   =  p~carrid
            AND p~cityfrom = p_cityfr.

For subqueries

SELECT  carrname
  INTO  TABLE name_tab
  FROM  scarr
  WHERE EXISTS ( select  *
                   FROM  spfli
                   WHERE carrid   =  scarr~carrid AND
                         cityfrom = 'NEW YORK'        ).
abap:S1496

UPDATE dbtab SET ... without a WHERE condition changes all the entries of the table. Check whether dataset to be changed can be limited by a suitable WHERE condition.

Noncompliant Code Example

UPDATE COUNTRIES SET NAME=country_name.

Compliant Solution

UPDATE COUNTRIES SET NAME=country_name WHERE CODE=country_code.
abap:S1498

Using the LIKE operator in SQL WHERE conditions can highly impact the performance of the request. The use of this operator should be strongly indicated.

Noncompliant Code Example

SELECT *
       FROM doktl
       INTO TABLE text_tab
       WHERE doktext LIKE srch_str.
abap:S1499

SELECT * should be avoided because it releases control of the returned columns and could therefore lead to errors and potentially to performance issues.

Noncompliant Code Example

SELECT *
       FROM persons
       INTO newyorkers
       WHERE city = 'NEW YORK'.

Compliant Solution

SELECT firstname, lastname
       FROM persons
       INTO newyorkers
       WHERE city = 'NEW YORK'.
abap:S1500

DISTINCT operator causes the SELECT statement to avoid the SAP buffering and to read directly from the database and not from the buffer on the application server.

Noncompliant Code Example

SELECT DISTINCT carrid
       FROM spfli
       INTO count
       WHERE cityto = 'NEW YORK'.
abap:S1501

Whenever more than one line needs to be read, inserted or deleted from a database table, it is more efficient to work with an internal table than to read, insert or delete the lines one by one inside a loop.

Noncompliant Code Example

LOOP AT TAB INTO TAB_WA.
  INSERT INTO CUSTOMERS VALUES TAB_WA.
ENDLOOP.

Compliant Solution

INSERT CUSTOMERS FROM TABLE TAB.
abap:S1502

SQL COUNT(..), MIN(..), MAX(..), SUM(..), AVG(..) aggregate functions cause the SAP table buffer to be bypassed, so the use of these functions can lead to performance issues.

Noncompliant Code Example

SELECT COUNT(*)
       FROM persons
       INTO count
       WHERE city = 'NEW YORK'.
abap:S1505

This BYPASSING BUFFER clause explicitly switches off SAP table buffering, so the SELECT reads data directly from the database.

By definition, using this clause can lead to performance issues, which is why its use must be strongly indicated.

Noncompliant Code Example

SELECT *
INTO US_PERSONS
FROM PERSONS
BYPASSING BUFFER
WHERE CITY EQ 'US'
abap:S1506

The EXEC SQL ... END-EXEC statement can be used to embed Native SQL statically in ABAP programs.

According to the SAP documentation:

Alongside ADBC, it is also possible to embed Native SQL statically between EXEC SQL and ENDEXEC in ABAP programs. The recommendation, however, is to use ADBC. While the static embedding of Native SQL offers exclusively static access to the Native SQL interface, ADBC makes modern object-orientated and dynamic access possible. New developments and improvements, such as optimized performance using bulk access across internal tables, are now made only for ADBC.

The existing static embedding of Native SQL statements is still supported but should no longer be used in new programs.

Noncompliant Code Example

EXEC SQL.
      CREATE TABLE abap_docu_demo_mytab (
               val1 char(10) NOT NULL,
               val2 char(10) NOT NULL,
               PRIMARY KEY (val1)      )
ENDEXEC.

Compliant Solution

NEW cl_sql_statement( )->execute_ddl(
      `CREATE TABLE ` && dbname   &&
      `( val1 char(10) NOT NULL,` &&
      `  val2 char(10) NOT NULL,` &&
      `  PRIMARY KEY (val1) )` ).
abap:S1507

According to the SAP documentation:

System functions are only intended for internal usage. Incompatible changes and further development is possible at any time and without warning or notice.

So calling system C functions using a CALL statement should be avoided.

Noncompliant Code Example

CALL 'MULTIPLY' ID 'P1'  FIELD '9999'
                ID 'P2'  FIELD '9999'
                ID 'RES' FIELD RESULT.
abap:S1508

ABAP provides the ability to manipulate programs dynamically during execution for instance with statements like INSERT REPORT and GENERATE SUBROUTINE POOL. Most of those statements are for internal use within SAP Technology Development and incompatible changes are possible at any time without prior warning or notice.

This rule raises an issue when any of the following source code processing statements is used: INSERT REPORT, READ REPORT, DELETE REPORT, EDITOR-CALL FOR REPORT, SYNTAX-CHECK FOR itab, GENERATE REPORT/SUBROUTINE POOL, LOAD REPORT, SCAN, INSERT TEXTPOOL, READ TEXTPOOL, DELETE TEXTPOOL, EXPORT DYNPRO, IMPORT DYNPRO, DELETE DYNPRO, SYNTAX-CHECK FOR DYNPRO, and GENERATE DYNPRO.

Noncompliant Code Example

GENERATE REPORT MY_PROG.
abap:S1510

Naming conventions are an important tool in efficient team collaboration. This rule checks that all form names match a regular expression naming convention.

Noncompliant Code Example

With the default regular expression:

FORM MyForm.
...
ENDFORM.

Compliant Solution

FORM MY_FORM.
...
ENDFORM.
abap:S1512

ABAP hints can be used to override the default behavior of the SAP Cost Based Optimizer (CBO). When the execution plan provided by the CBO is not optimal, it is possible to "drive" the CBO by providing the main index to be used to filter rows.

Such optimizations are not portable from one database to another, such as when migrating from Oracle to DB2. Therefore hard coding an optimization should be done only when it is strongly indicated.

Noncompliant Code Example

select MY_COLUMN
into it_data
from MY_TABLE
WHERE FILTERING_COLUMN = '0'
%_HINTS ORACLE 'INDEX("MY_TABLE" "MY_INDEX")'.
abap:S1540

This variant of the REFRESH statement is deprecated and should be avoided.

This REFRESH statement initializes the internal table itab, reads several rows from the database table dbtab, and adds their contents to the internal table itab. A SELECT statement should be used instead.

Noncompliant Code Example

TABLES t100.
DATA itab TYPE STANDARD TABLE OF t100.

t100-sprsl = 'E'.
t100-arbgb = 'BC'.

REFRESH itab FROM TABLE t100.

Compliant Solution

DATA itab TYPE STANDARD TABLE OF t100.

SELECT *
       FROM t100
       INTO TABLE itab
       WHERE sprsl = 'E' AND
             arbgb LIKE 'BC%'.
abap:S1541

The Cyclomatic Complexity of functions should not exceed a defined threshold. Complex code may perform poorly and can be difficult to test thoroughly.

abap:S1542

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression: ^([A-Z0-9_]*|[a-z0-9_]*)$

FUNCTION MyFunction.
...
ENDFUNCTION.

Compliant Solution

FUNCTION MY_FUNCTION.
...
ENDFUNCTION.
abap:S1543

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all macro names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression: ^([A-Z0-9_]*|[a-z0-9_]*)$

DEFINE MyMacro.
  ...
END-OF-DEFINITION.

Compliant Solution

DEFINE my_macro.
  ...
END-OF-DEFINITION.
abap:S1544

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all [report/]program names match a provided regular expression.

Noncompliant Code Example

With the regular expression ^([A-Z0-9_]*|[a-z0-9_]*)$:

    IDENTIFICATION DIVISION.
       PROGRAM-ID. MY-PROGRAM.      *> Noncompliant

Compliant Solution

    IDENTIFICATION DIVISION.
       PROGRAM-ID. MY_PROGRAM.
abap:S1545

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all variable names match a provided regular expression.

Noncompliant Code Example

DATA: MyText TYPE string.

Compliant Solution

DATA: my_text TYPE string.
abap:S1546

Every class definition should be commented to explain its goal and how it works. This comment must be located before [or after] the class definition.

Noncompliant Code Example

CLASS my_class DEFINITION.
  ...
ENDCLASS

Compliant Solution

* here is
* my comment
CLASS my_class DEFINITION.
  ...
ENDCLASS

Exceptions

CLASS my_class IMPLEMENTATION.  //Only class DEFINITIONs are checked by this rule
  ...
ENDCLASS
abap:S1547

Every subroutine(FORM) should be commented to explain its goal and how it works. This comment can be located just before or after the form definition.

Noncompliant Code Example

FORM my_form.
  ...
ENDFORM

Compliant Solution

* here is
* my comment
FORM my_form.
  ...
ENDFORM

or

FORM my_form.
* here is
* my comment
  ...
ENDFORM
abap:S1548

Every function should be commented to explain its goal and how it works. This non-empty comment must be located before the function definition.

Noncompliant Code Example

FUNCTION my_function.
  ...
ENDFUNCTION.

Compliant Solution

* here is
* my comment
FUNCTION my_function.
  ...
ENDFUNCTION.
abap:S1549

Every macro should be commented to explain its goal and how it works. This comment can be located just before or after the macro definition.

Noncompliant Code Example

DEFINE my_macro.
  ...
END-OF-DEFINITION.

Compliant Solution

* here is
* my comment
DEFINE my_macro.
  ...
END-OF-DEFINITION.

or

DEFINE my_macro.
* here is
* my comment
  ...
END-OF-DEFINITION.
abap:S1597

Having too many tables in a SELECT makes the code difficult to maintain and can lead to poor performance. Rewrite the logic or use views instead.

abap:S1639

While NOT IN can be far more efficient than NOT EXISTS in a query, it may return misleading results if the column in question contains null values.

Noncompliant Code Example

SELECT COUNT(*) FROM emp
  WHERE empno NOT IN ( SELECT mgr FROM emp );

Compliant Solution

SELECT COUNT(*) FROM emp T1
   WHERE NOT EXISTS ( SELECT NULL FROM emp T2 WHERE t2.mgr = t1.empno );
abap:S1655

Procedural development in general, and FORM... ENDFORM, and PERFORM specifically, have been been classified as obsolete by SAP and should be avoided. Classes and methods should be used for all new development.

Noncompliant Code Example

FORM fill_table USING    wa   TYPE any
                CHANGING ptab TYPE INDEX TABLE.
  APPEND wa TO ptab.
ENDFORM.
* ...
PERFORM fill_table IN PROGRAM my_prog.
abap:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

public void setName(String name) {
  name = name;
}

Compliant Solution

public void setName(String name) {
  this.name = name;
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
abap:S1668

The main reason for using chained statements is to increase readability, but when used with operational statements, chaining can have the opposite effect. Even worse, it can lead to unexpected program behavior.

Noncompliant Code Example

TRY.
     ...
  CATCH: cx_1, cx_2, cx_3.  " only cx_3 gets the following CATCH block
     "exception handling
      ...
ENDTRY.

Compliant Solution

TRY.
     ...
  CATCH cx_1.
     "exception handling
  CATCH cx_2.
     "exception handling
  CATCH cx_3.
     "exception handling
      ...
ENDTRY.
abap:S1669

Using keywords as variable names may yield incomprehensible code, and should be avoided.

Noncompliant Code Example

DATA:  wa_struct TYPE struct,
       name       TYPE string,
       dob          TYPE string,
       aliases     TYPE string,    " ALIASES is a keyword

Compliant Solution

DATA:  wa_struct TYPE struct,
       name         TYPE string,
       dob            TYPE string,
       alt_names  TYPE string,
abap:S1670

Internal tables can quickly become a source of performance problems if not accessed correctly, SORTED and HASHED tables should always be accessed with the appropriate key or partial key.

Noncompliant Code Example

READ TABLE it INTO work_area INDEX 1.

Compliant Solution

READ TABLE it INTO work_area WITH KEY color = 'RED'.
abap:S1671

When several lines must be inserted/updated into an internal table, instead of doing those changes line by line, mass operations should be used because they offer better performance by design.

This rule raises an issue when a single line operation like APPEND, CONCATENATE, and INSERT is performed on an internal table in a loop.

Noncompliant Code Example

LOOP AT ITAB1 INTO WA.
  APPEND WA TO ITAB2.
ENDLOOP.

Compliant Solution

APPEND LINES OF ITAB1 TO ITAB2.
abap:S1672

Internal tables can be sorted without specifying the specific fields on which to sort. However, doing so is inefficient because when a sort key is not specified, the entire row is used in the sort, which can be markedly inefficient.

Noncompliant Code Example

SORT ITAB.

Compliant Solution

SORT ITAB BY LAND WEIGHT.
abap:S1673

Calling DELETE ADJACENT DUPLICATES won't reliably do any good if the table hasn't first been sorted to put duplicates side by side, since the ADJACENT part of the command looks for multiple rows side-by-side with the same content.

Noncompliant Code Example

DELETE ADJACENT DUPLICATES FROM ITAB COMPARING LAND.

Compliant Solution

SORT ITAB BY LAND.
DELETE ADJACENT DUPLICATES FROM ITAB COMPARING LAND.
abap:S1674

Leaving a CATCH block empty means that the exception in question is neither handled nor passed forward to callers for handling at a higher level. Suppressing errors rather than handling them could lead to unpredictable system behavior and should be avoided.

Noncompliant Code Example

  try.
    if ABS( NUMBER ) > 100.
      write / 'Number is large'.
    endif.
    catch CX_SY_ARITHMETIC_ERROR into OREF.
  endtry.

Compliant Solution

  try.
    if ABS( NUMBER ) > 100.
      write / 'Number is large'.
    endif.
  catch CX_SY_ARITHMETIC_ERROR into OREF.
    write / OREF->GET_TEXT( ).
  endtry.

Exceptions

When a block contains a comment, it is not considered to be empty.

See

  • MITRE, CWE-391 - Unchecked Error Condition
  • OWASP Top 10 2017 Category A10 - Insufficient Logging & Monitoring
abap:S1675

Because CX_ROOT is the base exception type, catching it directly probably casts a wider net than you intended. Catching CX_ROOT could mask far more serious system errors that your CATCH logic was intended to deal with.

Some smaller, more specific exception type should be caught instead.

Noncompliant Code Example

  try.
    if ABS( NUMBER ) > 100.
      write / 'Number is large'.
    endif.
  catch CX_ROOT into OREF.
    write / OREF->GET_TEXT( ).
  endtry.

Compliant Solution

  try.
    if ABS( NUMBER ) > 100.
      write / 'Number is large'.
    endif.
  catch CX_SY_ARITHMETIC_ERROR into OREF.
    write / OREF->GET_TEXT( ).
  endtry.
abap:S1676

For readability, SAP recommends that asterisks (*) only be used to comment out header lines and code. Commentary should be commented using a double quote (")

Noncompliant Code Example

* GAC -  13 June 13 - output user data
* WRITE: / 'Firstname'.

Compliant Solution

" GAC -  13 June 13 - output user data
* WRITE: / 'Firstname'.

Exceptions

This rule ignores code that is included in a commentary block and commented as commentary.

" This is a commentary block. It could go on for a number of lines.
" As we see in the code sample below...
" WRITE: / 'Firstname'.
" It would have been better to comment the line above as code (i.e. with an asterisk)
" but not doing so is accepted.
abap:S1715

When there is only one statement in a chain, the chain syntax can be omitted, which simplifies the code.

Noncompliant Code Example

CLEAR: w_alvvr.

Compliant Solution

CLEAR w_alvvr.
abap:S1739

When the value of a LIKE clause starts with '%' or '_', indexes on the searched column are ignored, and a full table scan is performed instead.

Noncompliant Code Example

SELECT FIRST_NAME, LAST_NAME FROM PERSONS
WHERE LAST_NAME LIKE '%PONT'
abap:S1751

A loop with at most one iteration is equivalent to the use of an IF statement to conditionally execute one piece of code. No developer expects to find such usage of a loop statement. If the initial intention of the author was really to conditionally execute one piece of code, an IF statement should be used in place.

At worst that was not the initial intention of the author and so the body of the loop should be fixed to use the nested STOP, RETURN or EXIT statements in a more appropriate way.

Noncompliant Code Example

DATA remainder TYPE i.
DO 20 TIMES.
  remainder = sy-index MOD 2.
  cl_demo_output=>write_text().
  EXIT.  " noncompliant, loop only executes once
ENDDO.

Compliant Solution

DATA remainder TYPE i.
DO 20 TIMES.
  remainder = sy-index MOD 2.
  cl_demo_output=>write_text().
ENDDO.
abap:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Exceptions

This rule ignores *, +, and =.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
abap:S1862

A chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

Noncompliant Code Example

if param = 1.
  Statement.
elseif param = 2.
  Statement.
elseif param = 1.  // Noncompliant
 Statement.
endif.

Compliant Solution

if param = 1.
  Statement.
elseif param = 2.
  Statement.
elseif param = 3.
 Statement.
endif.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
abap:S1871

Having two WHEN in a CASE statement or two branches in an IF chain with the same implementation is at best duplicate code, and at worst a coding error. If the same logic is truly needed for both cases, they should be combined.

Noncompliant Code Example

CASE i.
  WHEN 1.
    doFirst.
    doSomething.
  WHEN 2.
    doSomethingDifferent.
  WHEN 3.  // Noncompliant; duplicates case 1's implementation
    doFirst.
    doSomething.
  WHEN OTHERS.
    doTheRest.
ENDCASE.

IF a >= 0 AND a < 10.
  doFirst.
  doTheThing.
ELSEIF a >= 10 AND a < 20.
  doTheOtherThing.
ELSEIF a >= 20 AND a < 50.
  doFirst.       // Noncompliant; duplicates first condition
  doTheThing.
ENDIF.

Exceptions

Blocks in an IF chain or in CASE statement that contain a single line of code are ignored.

IF a >= 0 AND a < 10.
  doTheThing.
ELSEIF a >= 10 AND a < 20.
  doTheOtherThing.
ELSEIF a >= 20 AND a < 50.
  doTheThing.  // no issue, usually this is done on purpose to increase the readability
ENDIF.

But this exception does not apply to IF chains without final ELSE-s, or to CASE-s without WHEN OTHERS clauses when all branches have the same single line of code. In case of IF chains with ELSE-s, or of CASE-s with WHEN OTHERS clauses, rule S3923 raises a bug.

if a >= 0 AND a < 10. //Noncompliant, this might have been done on purpose but probably not
  doTheThing.
elseif a >= 10 AND a < 20.
  doTheThing.
endif.
abap:S2237

Using an empty driver table in a SELECT/FOR ALL ENTRIES table has a very important side effect: the complete WHERE clause is not taken into account because a NO WHERE condition is generated. Thus a full table scan is unexpectedly executed.

Noncompliant Code Example

SELECT carrid , connid , seatsocc FROM flights
INTO TABLE seatsocc_tab                  		
FOR ALL ENTRIES IN conn_tab  " Noncompliant; conn_tab may be empty.
WHERE carrid = conn_tab-carrid
AND connid = conn_tab-connid.

Compliant Solution

IF conn_tab is not initial. 		
  ...	
  SELECT carrid , connid , seatsocc FROM flights
  INTO TABLE seatsocc_tab
  FOR ALL ENTRIES IN conn_tab
  WHERE carrid = conn_tab-carrid
  AND connid = conn_tab-connid
  ...
ENDIF.
abap:S2239

Removing duplicate entries from driver tables enables OPEN SQL to generate fewer queries for getting the same data, giving a performance boost.

Noncompliant Code Example

SELECT carrid , connid , seatsocc FROM flights
INTO TABLE seatsocc_tab                  		
FOR ALL ENTRIES IN conn_tab
WHERE carrid = conn_tab-carrid
AND connid = conn_tab-connid.

Compliant Solution

SORT conn_tab BY carrid.
DELETE ADJACENT DUPLICATES FROM conn_tab COMPARING carrid.
...
SELECT carrid , connid , seatsocc FROM flights
INTO TABLE seatsocc_tab                  		
FOR ALL ENTRIES IN conn_tab
WHERE carrid = conn_tab-carrid
AND connid = conn_tab-connid.
abap:S2240

Using EXIT and CHECK in SELECT statements to stop the execution of SELECT loop is an expensive and ineffective way to filter data. Filtering should be part of the SELECT loop themselves. Most of the time conditions located in a CHECK statement should be moved to the WHERE clause, and the EXIT statement should typically be replaced by an UP TO 1 ROW clause.

Noncompliant Code Example

SELECT * FROM SBOOK INTO SBOOK_WA.
  CHECK: SBOOK_WAS-CARRID = 'LH' AND SBOOK_WAS-CONNID = '0400'. "Noncompliant
ENDSELECT.

Compliant Solution

SELECT * FROM SBOOK INTO SBOOK_WA WHERE CARRID = 'LH' AND CONNID = '0400'.
ENDSELECT.
abap:S2241

An Open SQL SELECT statement without an explicit ORDER BY clause will retrieve rows in an unpredictable order. On pool/cluster tables, the current implementation of Open SQL SELECT returns the result set in the primary key order, but that's not the case for transparent tables. That's why it's safer to always use an ORDER BY clause.

Noncompliant Code Example

OPEN CURSOR C FOR SELECT * FROM SBOOK WHERE CARRID = 'LH '. "NonCompliant
SELECT * FROM FLIGHTS WHERE FLIGHT_NUMBER = 'LH '."NonCompliant

Compliant Solution

OPEN CURSOR C FOR SELECT * FROM SBOOK WHERE CARRID = 'LH '
  ORDER BY PRIMARY KEY.
SELECT * FROM FLIGHTS WHERE FLIGHT_NUMBER = 'LH ' ORDER BY PRIMARY KEY.
abap:S2242

SELECT INTO TABLE is much more efficient than SELECT ... ENDSELECT. SELECT INTO TABLE needs more memory to hold the result set, but in normal situations, this is not a concern. When memory is a concern, the result set can be divided into smaller sets.

Noncompliant Code Example

SELECT * FROM T006 INTO X006_WA.
  ...
ENDSELECT.

Compliant Solution

SELECT * FROM T006 INTO TABLE X006.
LOOP AT X006 INTO X006_WA.
  ...
ENDLOOP.
abap:S2243

SELECT with JOIN always performs better than nested selects.

Noncompliant Code Example

SELECT * FROM SPFL INTO SPFLI_WA.
  SELECT * FROM SFLOGHT INTO SFLIGHT_WA
    WHERE CARRID = SPFLI_WA-CARRID
    AND CONNID = SPFLIGHT_WA_CONNID.
  ENDSELECT.
ENDSELECT.

Compliant Solution

SELECT * INTO WA
  FROM SPFLI AS P INNER JOIN SFLIGHT AS F
    ON P~CARRID = F~CARRID AND
        P~CONNID = F~CONNID.
END-SELECT.
abap:S3626

Jump statements, such as CHECK and CONTINUE let you change the default flow of program execution, but jump statements that direct the control flow to the original direction are just a waste of keystrokes.

Noncompliant Code Example

  LOOP AT myTable.
    PERFORM form_open USING ...
    CHECK retcode = 0.
    ...
    perform form_close.
    CHECK retcode = 0. "Noncompliant; whatever the result of the check, the loop will continue to the next iteration
  ENDLOOP.

Compliant Solution

  LOOP AT myTable.
    PERFORM form_open USING ...
    CHECK retcode = 0.
    ...
    PERFORM form_close.
  ENDLOOP.
abap:S3633

Queries with contradictory WHERE clauses will always return empty result sets. This is clearly a bug.

Noncompliant Code Example

SELECT *
FROM fruit
WHERE type='apple' AND type='orange'  -- Noncompliant
abap:S3643

The use of LIKE in a SQL query without one or more wildcards in the sought value is suspicious. A maintainer can suppose that either = was meant instead, or that the wildcard was unintentionally omitted.

Note that in some cases using LIKE without a wildcard may return different results than the use of =. Thus, the use of LIKE without a wildcard may be intentional. However, it is highly likely to confuse maintainers who either are unaware of this fact, or don't understand that such circumstances apply to the query in question.

Noncompliant Code Example

SELECT name
FROM product
WHERE name LIKE 'choc'

Compliant Solution

SELECT name
FROM product
WHERE name LIKE 'choc%'

or

SELECT name
FROM product
WHERE name = 'choc'
abap:S3923

Having all branches in a CASE or IF chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a CASE/IF chain at all.

Noncompliant Code Example

IF a >0.
    doSomething.
ELSE IF b> 0.
    doSomething.
ELSE.
    doSomething.
ENDIF.

CASE i.
  WHEN 1 OR 3.
    doSomething.
  WHEN 2.
    doSomething.
  WHEN OTHERS.
        doSomething.
ENDCASE.

Exceptions

Note that this rule does not apply to IF chains without final ELSE-s, or to CASE-s without WHEN OTHERS clauses.

IF a >0.   "no issue, this could have been done on purpose to make the code more readable
    doSomething.
ELSEIF b> 0.
    doSomething.
ENDIF.
c:CommentMixedStyles

Use either the // ... or /* ... */ comment syntax, but be consistent and do not mix them within the same file.

Noncompliant Code Example

/* Noncompliant; both comment syntaxes are used in the same file */
// Foo
/* Bar */

Compliant Solution

// Compliant; uniform comment syntax
// Foo
// Bar

See

  • CERT, MSC55-J. - Use comments consistently and in a readable fashion
c:FileComplexity

Most of the time, a very complex file breaks the Single Responsibility Principle and should be re-factored into several different files.

Deprecated

This rule is deprecated, and will eventually be removed.

c:FileLoc

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

c:FunctionComplexity

The Cyclomatic Complexity of functions should not exceed a defined threshold. Complex code may perform poorly and can be difficult to test thoroughly.

c:LineLength

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

c:NonReentrantFunction

A function is called reentrant if it can be interrupted in the middle of its execution and then safely called again ("re-entered") before its previous invocations complete execution.

It is especially important that multi-threaded applications do not call the same non-reentrant function from different threads.

This rule will trigger an issue each time a function in the configurable list is invoked.

Noncompliant Code Example

Given a function that includes localtime:

#include <stdio.h>
#include <time.h>

void print_date_and_time(struct tm *time_ptr)
{
  printf(
    "Current date and time: %d/%02d/%02d %02d:%02d:%02d\n",
    time_ptr->tm_year + 1900,
    time_ptr->tm_mon,
    time_ptr->tm_mday,
    time_ptr->tm_hour,
    time_ptr->tm_min,
    time_ptr->tm_sec);
}

void print_unix_epoch_date_and_time()
{
  time_t unix_epoch_time = (time_t)0;
  struct tm *local_time_ptr = localtime(&unix_epoch_time); // Noncompliant, call to the non-reentrant localtime() function
  print_date_and_time(local_time_ptr);
}

int main(int argc, char* argv[])
{
  time_t current_time;
  struct tm *local_time_ptr;

  time(&current_time);

  local_time_ptr = localtime(&current_time); // Noncompliant, call to the non-reentrant localtime() function

  // As expected, this will print: Current date and time: 1970/00/01 01:00:00
  print_unix_epoch_date_and_time();

  // This will actually also print Current date and time: 1970/00/01 01:00:00
  // Indeed, localtime() is non-reentrant, and always returns the same pointer
  print_date_and_time(local_time_ptr);

  return 0;
}

Compliant Solution

#include <stdio.h>
#include <time.h>

void print_date_and_time(struct tm *time_ptr)
{
  printf(
    "Current date and time: %d/%02d/%02d %02d:%02d:%02d\n",
    time_ptr->tm_year + 1900,
    time_ptr->tm_mon,
    time_ptr->tm_mday,
    time_ptr->tm_hour,
    time_ptr->tm_min,
    time_ptr->tm_sec);
}

void print_unix_epoch_date_and_time()
{
  time_t unix_epoch_time = (time_t)0;
  struct tm local_time;
  localtime_r(&unix_epoch_time, &local_time); // Compliant
  print_date_and_time(&local_time);
}

int main(int argc, char* argv[])
{
  time_t current_time;
  struct tm local_time;

  time(&current_time);

  localtime_r(&current_time, &local_time); // Compliant

  // As expected, this will print: Current date and time: 1970/00/01 01:00:00
  print_unix_epoch_date_and_time();

  // As expected, this will print the current date and time, as expected
  print_date_and_time(&local_time);

  return 0;
}
c:OneStatementPerLine

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

foo(); bar(); // Noncompliant

Compliant Solution

foo();
bar();

Exceptions

Control flow statements with a single nested statement are ignored.

if (condition) doSomething();       // Compliant
while (condition) doSomething();    // Compliant

case or default statements containing a single statement and followed by break are ignored.

switch (foo) {
  case  0: doSomething(); break;    // Compliant
  default: doSomething(); break;    // Compliant
}

Statements enclosed in curly braces on the same line are ignored.

auto lambda = [](int x) { doSomething(x); return x; }; // Compliant
c:ParsingError

When the parser fails, it is possible to record the failure as an issue on the file. This way, not only is it possible to track the number of files that do not parse but also to easily find out why they do not parse.

c:PPBackslashNotLastCharacter

The standard mentions that the line continuation character (\) should be immediately followed by a newline or be the very last character of the file in order for the lines to be joined.

Several compilers relax this requirement by allowing whitespace after the \ character, but this is not portable because other compilers may not do the same.

Compliant Solution

// There should be no whitespace after the '\'
#define FOO BAR \
            BAZ
c:PPDirectiveIndentation

Indenting preprocessor directives reduces the code readability, because it make preprocessor directives harder to spot.

Noncompliant Code Example

void optimal()
{
  #if INTEL             /* Noncompliant - hard to spot */
  specificIntelStuff();
  #endif                /* Noncompliant - hard to spot */
}

Compliant Solution

void optimal()
{
#if INTEL               /* Compliant */
  specificIntelStuff();
#endif                  /* Compliant */
}
c:PPErrorDirectiveReached

This rule creates a issue whenever an #error preprocessor directive is reached during the project's analysis. In most cases, this indicates that the preprocessor was badly configured. Some predefined macros or library include paths might be required to fix the configuration.

Noncompliant Code Example

#error This is an error
c:PPMacroName

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all macro names match a provided regular expression.

Noncompliant Code Example

#define foo // Noncompliant

Compliant Solution

#define FOO
c:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression: [a-z][a-zA-Z0-9]*:

void DoSomething (void);

Compliant Solution

void doSomething (void);
c:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if (condition1) {
  if (condition2) {             // NonCompliant
    /* ... */
  }
}

Compliant Solution

if (condition1 && condition2) { // Compliant
  /* ... */
}
c:S1067

The complexity of an expression is defined by the number of &&, || and condition ? ifTrue : ifFalse operators it contains.

A single expression's complexity should not become too high to keep the code readable.

Noncompliant Code Example

With the default threshold value 3.

if (((condition1 && condition2) || (condition3 && condition4)) && condition5) { ... }

Compliant Solution

if ((myFirstCondition() || mySecondCondition()) && myLastCondition()) { ... }
c:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

Noncompliant Code Example

With a maximum number of 4 parameters:

void doSomething(int param1, int param2, int param3, int param4, int param5) {
  ...
}

Compliant Solution

void doSomething(int param1, int param2, int param3, int param4) {
  ...
}
c:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

int x = (y / 2 + 1);   //Compliant even if the parenthesis are ignored by the compiler

if (a && ((x+y > 0))) {  // Noncompliant
  //...
}

return ((x + 1));  // Noncompliant

Compliant Solution

int x = (y / 2 + 1);

if (a && (x+y > 0)) {
  //...
}

return (x + 1);

Exceptions

When the result of an assignment is used as a condition, clang raises a warning to make sure the purpose was not to use == in place of =. Adding some parentheses around the assignment is a common way to silence this clang warning. So, no issue is raised in such case.

if ((x = 7)) {} // Compliant
c:S1123

The deprecated attribute can be applied with or without explanations, but marking something deprecated without including advice as to why it's deprecated or on what to use instead will lead maintainers to waste time trying to figure those things out - every single time the warning is encountered.

Noncompliant Code Example

[[deprecated]] // Noncompliant
void foo1();

__attribute__((deprecated)) // Noncompliant
void foo2();

__declspec(deprecated) // Noncompliant
void foo3();

Compliant Solution

[[deprecated("use 'bar' instead")]]
void foo1();

__attribute__((deprecated("use 'bar' instead")))
void foo2();

__declspec(deprecated("use 'bar' instead"))
void foo3();
c:S113

Some tools work better when files end with an empty line.

This rule simply generates an issue if it is missing.

For example, a Git diff looks like this if the empty line is missing at the end of the file:

+class Test {
+}
\ No newline at end of file
c:S1131

Trailing whitespaces are simply useless and should not stay in code. They may generate noise when comparing different versions of the same file.

If you encounter issues from this rule, this probably means that you are not using an automated code formatter - which you should if you have the opportunity to do so.

c:S1133

This rule is meant to be used as a way to track code which is marked as being deprecated. Deprecated code should eventually be removed.

Noncompliant Code Example

// C++14 attribute
[[deprecated]] // Noncompliant
void fun();

// GNU attribute
__attribute__((deprecated)) // Noncompliant
void fun();

// Microsoft attribute
__declspec(deprecated) // Noncompliant
void fun();
c:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

int divide(int numerator, int denominator) {
  return numerator / denominator;              // FIXME denominator value might be  0
}

See

c:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

void foo() {
  // TODO
}

See

c:S1142

Having too many return statements in a function increases the function's essential complexity because the flow of execution is broken each time a return statement is encountered. This makes it harder to read and understand the logic of the function.

Noncompliant Code Example

With the default threshold of 3:

int fun() {
  if (condition1) {
    return 1;
  } else {
    if (condition2) {
      return 0;
    } else {
      return 1;
    }
  }
  return 0;
}
c:S1151

The switch statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of case clause should be extracted in a dedicated function.

Noncompliant Code Example

With the default threshold of 5:

switch (myVariable) {
  case 0: // 6 lines till next case
    methodCall1("");
    methodCall2("");
    methodCall3("");
    methodCall4("");
    break;
  case 1:
  // ...
}

Compliant Solution

switch (myVariable) {
  case 0:
    doSomething();
    break;
  case 1:
  // ...
}
// ...
void doSomething(){
    methodCall1("");
    methodCall2("");
    methodCall3("");
    methodCall4("");
}
c:S1186

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

  • 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 in languages where that mechanism is available.
  • The method is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.

Noncompliant Code Example

void fun(int p1) {
}

Compliant Solution

void fun(int p1) {
  int a = doSomething(p1);
  int threshold = 42;
  if (a > threshold) {
    // ...
  }
}

or

void fun(int p1) {
  // Intentionally unimplemented...
}

Exceptions

This rule doesn't raise an issue for empty class constructors or destructors. For instance this is the only way to define user-defined default constructors.

c:S1198

In 1978, Brian Kernighan and Dennis Ritchie published the first edition of The C Programming Language. This book, known to C programmers as "K&R", served for many years as an informal specification of the language. The version of C that it describes is commonly referred to as K&R C.

The K&R function definition syntax introduced in the book was later deprecated in the ANSI C and ISO C standards. Even though the K&R syntax is still supported in the ISO C11 standard, it's not in ISO C++ standard versions and is not considered readable by most C/C++ developers today.

Noncompliant Code Example

int foo(a, b)   // Noncompliant K&R C syntax
  int a;
  char* b;
{
}

Compliant Solution

int foo(int a, char* b) { // Compliant
}
c:S1199

Nested code blocks can be used to create a new scope and restrict the visibility of the variables defined inside it. Using this feature in a method typically indicates that the method has too many responsibilities, and should be refactored into smaller methods.

Noncompliant Code Example

public void evaluate(int operator) {
  switch (operator) {
    /* ... */
    case ADD: {                                // Noncompliant - nested code block '{' ... '}'
        int a = stack.pop();
        int b = stack.pop();
        int result = a + b;
        stack.push(result);
        break;
      }
    /* ... */
  }
}

Compliant Solution

public void evaluate(int operator) {
  switch (operator) {
    /* ... */
    case ADD:                                  // Compliant
      evaluateAdd();
      break;
    /* ... */
  }
}

private void evaluateAdd() {
  int a = stack.pop();
  int b = stack.pop();
  int result = a + b;
  stack.push(result);
}
c:S1227

break; is an unstructured control flow statement which makes code harder to read.

Ideally, every loop should have a single termination condition.

Noncompliant Code Example

for (element = list.first; element != null; element = element->next) { // First termination condition
  if (!matches(element->value)) {                                      // Second termination condition
    break; // Noncompliant
  }

  /* ... */
}

Compliant Solution

// Compliant
for (element = list.first; element != null && matches(element->value); element = element->next) {
  /* ... */
}
c:S1259

Function pointer syntax can be hard on the eyes, particularly when one function is used as a parameter to another. Providing and using a typedef instead can make code easier to read, and should be preferred.

Noncompliant Code Example

extern void (*signal(int, void(*)(int)))(int);

Compliant Solution

typedef void (*SignalHandler)(int signum);
extern SignalHandler signal(int signum, SignalHandler handler);
c:S1264

When only the condition expression is defined in a for loop, and the initialization and increment expressions are missing, a while loop should be used instead to increase readability.

Noncompliant Code Example

for (;condition;) { /*...*/ }

Compliant Solution

while (condition) { /*...*/ }
c:S1291

Any issue to quality rule can be deactivated with the NOSONAR marker. This marker is pretty useful to exclude false-positive results but it can also be used abusively to hide real quality flaws.

This rule raises an issue when NOSONAR is used.

c:S134

Nested if, for, do, while, switch and try statements is a key ingredient 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:

  if (condition1) {                  // Compliant; depth = 1
    /* ... */
    if (condition2) {                // Compliant; depth = 2
      /* ... */
      for(int i = 0; i < 10; i++) {  // Compliant; depth = 3, not exceeding the limit
        /* ... */
        if (condition4) {            // Noncompliant; depth = 4
          if (condition5) {          // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
            /* ... */
          }
          return;
        }
      }
    }
  }

Exceptions

Each use of a macro containing control flow statements is counted as one nesting level, even if the macro contains more than one control flow statement.

  #define FOREACH(V,ARR) if(ARR!=nullptr) for(int V=0; V<(sizeof(ARR)/sizeof(ARR[0])); V++)

  if (condition1) {       // Compliant; depth = 1
    if (condition2) {     // Compliant; depth = 2
      FOREACH(i, arr) {     // Compliant; depth = 3 (not 4)
        if (condition3) {   // Noncompliant; depth = 4
          /* ... */
        }
      }
    }
  }
c:S138

A function that grows too large tends to aggregate too many responsibilities.

Such functions inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions which focus on well-defined tasks.

Those smaller functions will not only be easier to understand, but also probably easier to test.

c:S139

This rule verifies that single-line comments are not located at the ends of lines of code. The main idea behind this rule is that in order to be really readable, trailing comments would have to be properly written and formatted (correct alignment, no interference with the visual structure of the code, not too long to be visible) but most often, automatic code formatters would not handle this correctly: the code would end up less readable. Comments are far better placed on the previous empty line of code, where they will always be visible and properly formatted.

Noncompliant Code Example

a = b + c;   // This is a trailing comment that could be very very long

Compliant Solution

// This very long comment is better placed before the line of code
a = b + c;
c:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
c:S1479

When switch statements have large sets of case clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

c:S1578

Shared coding conventions allow teams to collaborate effectively. For that reason, file names should conform to a defined standard. This rule raises an issue when the names of analyzed files don't match the provided regular expression.

See

c:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

void setValue(int value) {
  value = value;
}

Compliant Solution

void setValue(int value) {
  this->value = value;
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
c:S1705

Postfix increment and decrement typically involves making a copy of the object being incremented or decremented, whereas its prefix form does not. Therefore the prefix form is usually the more efficient form, and should be preferred.

Noncompliant Code Example

void myFunc(int lim)
{
  int i;
  for (i = 0; i < lim; i++)
  {
    // do something
  }
}

Compliant Solution

void myFunc(int lim)
{
  int i;
  for (i = 0; i < lim; ++i)
  {
    // do something
  }
}
c:S1707

TODO and FIXME comments are typically intended to be short-lived; they are placeholders and reminders that programmers leave for themselves. Unfortunately, even with the best of intentions, those comments are not always acted on and removed in a timely manner. Thus, they can become mysterious, lingering cruft in a code base, reducing both readability and understand-ability.

This rule flags all FIXME and TODO comments that do not have an attribution matching the specified regular expression immediately after the FIXME or TODO. Ideally, such comments will also contain information about what needs to be fixed or done, but this rule does not enforce that.

Noncompliant Code Example

Using the default regular expression: [ ]*\([ _a-zA-Z0-9@.]+\):

// TODO

Compliant Solution

// TODO(ganncamp) per the business partners, more checks needed
c:S1762

Using "#pragma warning (default: ...)" resets the warning in question to its default settings, which may not be what the compiler was initially invoked with. Typically, this usage is seen after a warning is turned off, in preparation for code that is known to cause warnings. Instead, the warning's current state should be saved, and then restored after the code in question.

Noncompliant Code Example

#pragma warning (disable: TheWarning)
#include problem_code.h
#pragma warning (default: TheWarning)

Compliant Solution

#pragma warning (push)
#include problem_code.h
#pragma warning (pop)

See

c:S1768

Because the value in a variable of an unsigned type can never be less than zero, testing to see if it is negative is a useless operation which can only confuse future readers of the code.

Noncompliant Code Example

unsigned int i = 0; // the lowest value this var can have
...
if (i >= 0) { // Noncompliant
  do_x(i);
}

Compliant Solution

unsigned int i = 0;
...
do_x(i);
c:S1772

The result of the comparison is the same, regardless of whether the constant is on the left or right-hand side. But following this convention will help pinpoint the occasional error where = (assignment) is substituted for == (comparison).

If the constant is on the right-hand side of the expression in such cases, the code will still compile and run - just not as expected. If the constant is on the left-hand side, the error will be caught at the first attempt to compile.

Noncompliant Code Example

if ( var == constant )
if ( pointer == NULL )

Compliant Solution

if ( constant == var )
if ( NULL == pointer )
c:S1774

While the ternary operator is pleasingly compact, its use can make code more difficult to read. It should therefore be avoided in favor of the more verbose if/else structure.

Noncompliant Code Example

printf("%s", (i>10?"yes":"no"));

Compliant Solution

if (i > 10) {
  printf("yes");
} else {
  printf("no");
}
c:S1820

A structure, such as a struct, union or class that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain, and having a lot of fields is an indication that a structure has grown too large.

Above a specific threshold, it is strongly advised to refactor the structure into smaller ones that focus on well defined topics.

c:S1821

Nested switch structures are difficult to understand because you can easily confuse the cases of an inner switch as belonging to an outer statement. Therefore nested switch statements should be avoided.

Specifically, you should structure your code to avoid the need for nested switch statements, but if you cannot, then consider moving the inner switch to another function.

Noncompliant Code Example

void func(int n, int m) {

  switch (n) {
    case 1:
      // ...
    case 2:
      // ...
    case 3:
      switch (m) {  // Noncompliant
    case 4:  // Bad indentation makes this particularly hard to read properly
      // ...
    case 5:
      // ...
    case 6:
      // ...
    }
    case 4:
      // ...
    default:
      // ...
  }
}

Compliant Solution

void func(int n, int m) {

  switch (n) {
    case 1:
      // ...
    case 2:
      // ...
    case 3:
      int m2 = handle_m(m);
    case 4:
      // ...
    default:
      // ...
  }
}
c:S1862

A chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

Noncompliant Code Example

if (param == 1)
  openWindow();
else if (param == 2)
  closeWindow();
else if (param == 1)  // Noncompliant
  moveWindowToTheBackground();

Compliant Solution

if (param == 1)
  openWindow();
else if (param == 2)
  closeWindow();
else if (param == 3)
  moveWindowToTheBackground();

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
c:S1874

Code annotated as deprecated should not be used since it will be removed sooner or later.

Noncompliant Code Example

// C++14 attribute
[[deprecated]]
void fun();

// GNU attribute
__attribute__((deprecated))
void fun();

// Microsoft attribute
__declspec(deprecated)
void fun();

void example() {
  fun(); // Noncompliant
}

See

c:S2095

A call to the fopen()/open() function must be matched with a call to fclose()/close. Otherwise, you run the risk of using up all the OS's file handles, which could lock up not just your program but potentially everything on the box.

Noncompliant Code Example

int fun() {
  FILE *f = fopen("file", "r");
  if (f == NULL) {
    return -1;
  }
  // ...
  return 0; // Noncompliant, file f has not been closed
}

Compliant Solution

int fun() {
  FILE *f = fopen("file", "r");
  if (f == NULL) {
    return -1;
  }
  // ...
  fclose(f);
  return 0;
}

See

c:S2123

A value that is incremented or decremented and then not stored is at best wasted code and at worst a bug.

Noncompliant Code Example

int pickNumber() {
  int i = 0;
  int j = 0;

  i = i++; // Noncompliant; i is still zero

  return j++; // Noncompliant; 0 returned
}

Compliant Solution

int pickNumber() {
  int i = 0;
  int j = 0;

  i++;
  return ++j;
}
c:S2234

When the names of parameters in a method call match the names of the method arguments, it contributes to clearer, more readable code. However, when the names match, but are passed in a different order than the method arguments, it indicates a mistake in the parameter order which will likely lead to unexpected results.

Noncompliant Code Example

int divide(int divisor, int dividend) {
  return divisor / dividend;
}

void doTheThing() {
  int divisor = 15;
  int dividend = 5;

  int result = divide(dividend, divisor);  // Noncompliant; operation succeeds, but result is unexpected
  //...
}

Compliant Solution

int divide(int divisor, int dividend) {
  return divisor / dividend;
}

public void doTheThing() {
  int divisor = 15;
  int dividend = 5;

  int result = divide(divisor, dividend);
  //...
}
c:S2259

A pointer to null (the 0 memory address) should never be dereferenced/accessed. Doing so will at best cause abrupt program termination, without the ability to run any cleanup processes. At worst, it could expose debugging formation that would be useful to an attacker or it could allow an attacker to bypass security measures.

Noncompliant Code Example

char *p1 = ... ;
if (p1 == NULL && *p1 == '\t') { // Noncompliant, p1 will be dereferenced IFF it is null
  // ...
}

char *p2 = ... ;
if (p2 != NULL) {
    // ...
}
*p2 = '\t'; // Noncompliant; potential null-dereference

char *p3, *p4;
p3 = NULL;
// ...
p4 = p3;
*p4;  // Noncompliant

Compliant Solution

char *p1 = ... ;
if (p1 != NULL && *p1 == '\t') { // Compliant, *p1 cannot be evaluated when p1 is NULL
  // ...
}

char *p2 = ... ;
if (p2 != NULL) {
    // ...
  *p2 = '\t'; // Compliant
}

See

c:S2343

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all enumeration values match a provided regular expression.

Noncompliant Code Example

With default provided regular expression:

enum SomeEnumeration {
    some  // Non-Compliant
};

Compliant Solution

enum SomeEnumeration {
    SOME
};
c:S2637

Functions return values and parameters values marked nonnull are assumed to have non-null values and are not typically null-checked before use. Therefore setting one of these values to null, could cause null pointer dereferences at runtime.

Noncompliant Code Example

__attribute__((returns_nonnull))
int* nonnull(__attribute__((nonnull)) int* parameter) {
  parameter = 0; // Noncompliant - "parameter" is marked "nonnull" but is set to null.
  nonnull(0); // Noncompliant - Parameter "parameter" to this call is marked "nonnull" but null is passed.
  return 0; // Noncompliant - This function's return value is marked "nonnull" but null is returned.
}

See

c:S2665

Although some compilers will allow it, the use of sizeof and alignof with arguments that have a void type is forbidden by both the C and C++ standards.

Noncompliant Code Example

void fun() {
  void* p;
  sizeof(*p);  // Noncompliant
  sizeof(void);  // Noncompliant
}
c:S2668

It is possible to use the increment operator ++, to set the value of a bool(C++) or _Bool(C) variable to true. But this feature has been deprecated in C++ since the 1998 version of the standard, and even where allowed, is simply confusing.

Noncompliant Code Example

bool alive;
...
alive++;

Compliant Solution

bool alive;
...
alive = true;

See

  • ISO/IEC 14882:1998, 5.3.2
c:S2681

Curly braces can be omitted from a one-line block, such as with an if statement or for loop, but doing so can be misleading and induce bugs.

This rule raises an issue when the whitespacing of the lines after a one line block indicates an intent to include those lines in the block, but the omission of curly braces means the lines will be unconditionally executed once.

Noncompliant Code Example

if (condition)
  firstActionInBlock();
  secondAction();  // Noncompliant; executed unconditionally
thirdAction();

if (condition) firstActionInBlock(); secondAction();  // Noncompliant; secondAction executed unconditionally

if (condition) firstActionInBlock();  // Noncompliant
  secondAction();  // Executed unconditionally

if (condition); secondAction();  // Noncompliant; secondAction executed unconditionally

String str = null;
for (int i = 0; i < array.length; i++)
  str = array[i];
  doTheThing(str);  // Noncompliant; executed only on last array element

Compliant Solution

if (condition) {
  firstActionInBlock();
  secondAction();
}
thirdAction();

String str = null;
for (int i = 0; i < array.length; i++) {
  str = array[i];
  doTheThing(str);
}

See

c:S2754

Empty declarations are cruft; they (may) compile, but they violate the language standards, don't contribute anything of value, and clutter up the program. Like cobwebs, they should be swept away.

Noncompliant Code Example

int;  // Noncompliant

See

  • ISO/IEC 9899:2011, 6.7p2
  • ISO/IEC 14882:2011, 7p3.
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
c:S2757

The use of operators pairs (=+) where the reversed, single operator was meant (+=) will compile and run, but not produce the expected results.

This rule raises an issue when =+, =-, =!, =&, =*, +=+, and -=- are used without any space between the two operators and when there is at least one whitespace after.

Noncompliant Code Example

int target = -5;
int num = 3;

target =- num;  // Noncompliant; target = -3. Is that really what's meant?
target =+ num; // Noncompliant; target = 3

Compliant Solution

int target = -5;
int num = 3;

target = -num;  // Compliant; intent to assign inverse value of num is clear
target += num;
c:S2761

The needless repetition of an operator is usually a typo. After all, why write !!!i when !i will do?

On the other hand, the repetition of increment and decrement operators may have been done on purpose, but doing so obfuscates the meaning, and should be simplified.

This rule raises an issue for sequences of: !, ~, -, and +, and in C++ for repetitions of the increment and decrement operators.

Noncompliant Code Example

int i = 1;

int j = - - -i;  // Noncompliant; just use -i
int k = ~~i;     // Noncompliant; same as i
int m = + +i;    // Noncompliant; operators are useless here

bool b = false;
bool c = !!!b;   // Noncompliant

Compliant Solution

int i =  1;

int j = -i;
int k =  i;
int m =  i;

bool b = false;
bool c = !b;

Exceptions

Boolean normalization !! is ignored.

c:S2806

The real need for bit fields is narrow and highly specialized. Previously, they were used to save memory, but that's less a concern in modern systems than are the extra instructions required to interact with them. Today, they may be needed in direct hardware interaction, but since their behavior is platform-dependent, getting them right can be tricky, and since their use is increasingly rare these days, they're likely to confuse maintainers. For these reasons, it's simpler and more performant to use another field type instead of bit fields.

Noncompliant Code Example

unsigned int b1 : 3;  // Noncompliant
unsigned char b2 : 3;  // Noncompliant

Compliant Solution

unsigned int b1;
unsigned char b2;
c:S3231

Redundant forward declarations simply clutter the code, and like any duplications, should be removed.

Noncompliant Code Example

struct S {
  // ...
};
// ...
struct S;  // Noncompliant

Compliant Solution

struct S {
  // ...
};
c:S3358

Just because you can do something, doesn't mean you should, and that's the case with nested ternary operations. Nesting ternary operators results in the kind of code that may seem clear as day when you write it, but six months later will leave maintainers (or worse - future you) scratching their heads and cursing.

Instead, err on the side of clarity, and use another line to express the nested operation as a separate statement.

Noncompliant Code Example

int max(int p1, int p2, int p3) {
  return p1 > p2 ? (p1 > p3 ? p1 : p3) : (p2 > p3 ? p2 : p3); // Noncompliant
}

Compliant Solution

int max(int p1, int p2, int p3) {
  if (p1 > p2) {
    return p1 > p3 ? p1 : p3;
  } else {
    return p2 > p3 ? p2 : p3;
  }
}
c:S3400

There's no point in forcing the overhead of a method call for a method that always returns the same constant value. Even worse, the fact that a method call must be made will likely mislead developers who call the method thinking that something more is done. Declare a constant instead.

This rule raises an issue if on methods that contain only one statement: the return of a constant value.

Noncompliant Code Example

int getBestNumber() {
  return 12;  // Noncompliant
}

Compliant Solution

static int bestNumber = 12;

Exceptions

override, final, virtual and overriding functions are ignored.

c:S3458

Empty case clauses that fall through to the default are useless. Whether or not such a case is present, the default clause will be invoked. Such cases simply clutter the code, and should be removed.

Noncompliant Code Example

switch(ch)
{
  case 'a' :
    handleA();
    break;
  case 'b' :
    handleB();
    break;
  case 'c' :  // Noncompliant
  default:
    handleTheRest();
    break;
}

Compliant Solution

switch(ch)
{
  case 'a' :
    handleA();
    break;
  case 'b' :
    handleB();
    break;
  default:
    handleTheRest();
    break;
}
c:S3491

By contract, chaining the 'Address of' operator & with the 'Indirection' operator * results in a return to the initial value. Thus, such combinations are confusing at best, and bugs at worst.

Noncompliant Code Example

int *ptr = ...;
int *result1 = &(*ptr); //Noncompliant
int *result2 = &*ptr; //Noncompliant

int value = 4;
int result3 = *(&value); //Noncompliant
int result4 = *&value; //Noncompliant

Compliant Solution

int *ptr = ...;
int *result1 = ptr;
int *result2 = ptr;

int value = 4;
int result3 = value;
int result4 = value;

Exceptions

No issue is raised when the * or & operators are overloaded or when both operators are not located in the same piece of code (one being generated by a macro expansion and the other one located in the main source code for instance).

c:S3516

When a method is designed to return an invariant value, it may be poor design, but it shouldn't adversely affect the outcome of your program. However, when it happens on all paths through the logic, it is surely a bug.

This rule raises an issue when a method contains several return statements that all return the same value.

Noncompliant Code Example

int foo(int a) {
  int b = 12;
  if (a == 1) {
    return b;
  }
  return b;  // Noncompliant
}
c:S3518

If the denominator to a division or modulo operation is zero it would result in a fatal error.

Noncompliant Code Example

void test_divide() {
  int z = 0;
  if (unknown()) {
    // ..
    z = 3;
  } else {
    // ..
  }
  z = 1 / z; // Noncompliant, possible division by zero
}

Compliant Solution

void test_divide() {
  int z = 0;
  if (unknown()) {
    // ..
    z = 3;
  } else {
    // ..
    z = 1;
  }
  z = 1 / z;
}

See

  • MITRE, CWE-369 - Divide by zero
  • CERT, NUM02-J. - Ensure that division and remainder operations do not result in divide-by-zero errors
  • CERT, INT33-C. - Ensure that division and remainder operations do not result in divide-by-zero errors
c:S3519

Array overruns and buffer overflows happen when memory access accidentally goes beyond the boundary of the allocated array or buffer. These overreaching accesses cause some of the most damaging, and hard to track defects.

Noncompliant Code Example

int array[10];
array[10] = 0; // Noncompliant: index should be between 0 & 9

char *buffer1 = (char *) malloc(100);
char *buffer2 = (char *) malloc(50);
memcpy(buffer2, buffer1, 100); // Noncompliant: buffer2 will overflow.

Compliant Solution

int array[10];
array[9] = 0;

char *buffer1 = (char *) malloc(100);
char *buffer2 = (char *) malloc(50);
memcpy(buffer2, buffer1, 50);

See

  • MITRE, CWE-119 - Improper Restriction of Operations within the Bounds of a Memory Buffer
  • CERT, STR50-CPP. - Guarantee that storage for strings has sufficient space for character data and the null terminator
c:S3520

Using free(...) or delete releases the reservation on a memory location, making it immediately available for another purpose. So releasing the same memory location twice can lead to corrupting the program's memory.

A best practice to avoid this bug calls for setting just-freed pointers to NULL, and always null-testing before a free or delete.

Noncompliant Code Example

void doSomething(int size) {
  char *cp = (char *)malloc(sizeof(char)*size);

  // ...
  if(condition) {
    free(cp);
  }

  free(cp);  // Noncompliant
}

Compliant Solution

void doSomething(int size) {
  char *cp = (char *)malloc(sizeof(char)*size);

  // ...
  if(condition) {
    if (cp != NULL) {
      free(cp);
      cp = NULL;
    }
  }

  if (cp) {  // This is a common, short-hand null test
    free(cp);
    cp = NULL;
  }
}

See

c:S3529

Once a block of memory has been freed, it becomes available for other memory requests. Whether it's re-used immediately, some time later, or not at all is random, and may vary based on load. Because of that randomness, tests may pass when running locally, but the odds are that such code will fail spectacularly in production by returning strange values, executing unexpected code, or causing a program crash.

Noncompliant Code Example

char *cp = malloc(sizeof(char)*10);

// ...
free(cp);

cp[9] = 0;  // Noncompliant

See

c:S3562

For completeness, a switch over the values of an enum must either address each value in the enum or contain a default case. switch statements that are not over enum must end with a default case.

Noncompliant Code Example

typedef enum {APPLE, GRAPE, KIWI} fruit;

void example(fruit f, int i) {
  switch (f) {  // Noncompliant; no case for KIWI
    case APPLE:
      //...
    case GRAPE:
      //...
    case 3: // Noncompliant; case value not in enum
      // ...
  }

  switch (i) { // Noncompliant; no default
    case 0:
      // ...
    case 1:
      // ...
  }
}

Compliant Solution

typedef enum {APPLE, GRAPE, KIWI} fruit;

void example(fruit f) {
  switch (f) {
    case APPLE:
      //...
    case GRAPE:
      //...
    default:
      // ...
  }

  switch (i) {
    case 0:
      // ...
    case 1:
      // ...
    default:
      // ...
  }
}

or

typedef enum {APPLE, GRAPE, KIWI} fruit;

void example(fruit f) {
  switch (f) {
    case APPLE:
      //...
    case GRAPE:
      //...
    case KIWI:
      //...
  }

  switch (i) {
    case 0:
    case 1:
      // ...
    default:
      // ...
  }
}

See also

c:S3584

Memory allocated dynamically with calloc(...), malloc(...), realloc(...) or new should be released when it's not needed anymore. Failure to do so will result in a memory leak that could bring the box to its knees.

This rule raises an issue when memory is allocated and not freed in the same function. Allocated memory is ignored if a pointer to it is returned to the caller or stored in a structure that's external to the function.

Noncompliant Code Example

int fun() {
  char* name = (char *) malloc (size);
  if (!name) {
    return 1;
  }
  // ...
  return 0; // Noncompliant, memory pointed by "name" has not been released
}

Compliant Solution

int fun() {
  char* name = (char *) malloc (size);
  if (!name) {
    return 1;
  }
  // ...
  free(name);
  return 0;
}

See

  • MITRE, CWE-401 - Improper Release of Memory Before Removing Last Reference ('Memory Leak')
  • MEM00-C. - Allocate and free memory in the same module, at the same level of abstraction
  • CERT, MEM31-C. - Free dynamically allocated memory when no longer needed
c:S3588

Using the value of a pointer to a FILE object after the associated file is closed is undefined behavior.

Noncompliant Code Example

void fun() {
  FILE * pFile;
  pFile = fopen(fileName, "w");

  if (condition) {
    fclose(pFile);
    // ...
  }

  fclose(pFile); // Noncompliant, the file has already been closed
}

Compliant Solution

void fun() {
  FILE * pFile;
  pFile = fopen(fileName, "w");

  if (condition) {
    // ...
  }

  fclose(pFile);
}

See

c:S3626

Jump statements, such as return, break, goto, and continue let you change the default flow of program execution, but jump statements that direct the control flow to the original direction are just a waste of keystrokes.

Noncompliant Code Example

void Foo()
{
  goto A; // Noncompliant
  A:
  while (condition1)
  {
    if (condition2)
    {
      continue; // Noncompliant
    }
    else
    {
      DoTheThing();
    }
  }
  return; // Noncompliant; this is a void method
}

Compliant Solution

void Foo()
{
  while (condition1)
  {
    if (!condition2)
    {
      DoTheThing();
    }
  }
}
c:S3646

It is possible in the same statement, to declare a user-defined type (class, struct, union or enum) followed by variable declarations of this type. But mixing more than one concern in a single statement is confusing for maintainers.

This rule raises an issue when a variable is declared at the end of a user-defined type declaration statement.

Noncompliant Code Example

struct Container { int size; } container; // Noncompliant

Compliant Solution

struct Container { int size; };
Container container;
c:S3687

Except for interactions with extern volatile variables provided by libraries, C/C++ programmers should consider volatile an esoteric feature that is best avoided. In most cases, it is used in an attempt to provide atomicity, memory ordering, or inter-thread synchronization, but volatile does not provide those guarantees. It is only really needed for the kind of low-level code found in kernels, i.e. using memory-mapped I/O registers to manipulate hardware directly.

According to the C standard:

volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation.

Only C11/C++11 "atomic types" are free from data races.

This rule raises an issue when a volatile type is declared.

Noncompliant Code Example

volatile int counter; // Noncompliant
User * volatile vpUser; // Noncompliant; pointer is volatile
User volatile * pvUser;  // Compliant; User instance is volatile, not the pointer

Compliant Solution

atomic_int counter;
std::atomic<User*> vpUser;
User volatile * pvUser;
c:S3689

Redundant declaration specifiers should be removed or corrected. Typically, they represent bugs. A specifier modifies the type or pointer to its left. Only when it is at the far left does it apply to the right.

Noncompliant Code Example

const int const * v1a; // Noncompliant; both const specifiers apply to int
const int const * v1b; // Noncompliant
static static int v2;  // Noncompliant

Compliant Solution

const int *       v1a;  // pointer to a const int. same meaning as before but less confusing
int const * const v1b;  // const pointer to a const int
static int         v2;
c:S3715

Proprietary compiler extensions can be handy, but they commit you to always using that compiler. This rule raises an issue when the following GNU extensions are used:

  • A array initializer without =, which has been obsolete since GCC 2.5
  • A structure member initializer with a colon, which has been obsolete since GCC 2.5.
  • Case ranges
  • Ternary operator with omitted second operand

Noncompliant Code Example

struct S {
  int f;
};

struct S s[] = {
  [0] { // Noncompliant
    f : 0 // Noncompliant
  }
};

int fun(int p) {
  switch (p) {
    case 0 ... 1: // Noncompliant
      do_the_thing();
      break;
    case 2:
      //...
  }

  return p ?: 0; // Noncompliant
}

Compliant Solution

struct S {
  int f;
};

struct S s[] = {
  [0] = {
    .f = 0
  }
};

int fun(int p) {
  switch (p) {
    case 0:
    case 1:
      do_the_thing();
      break;
    case 2:
      //...
  }

  return p ? p: 0;
}
c:S3728

While in C, and derived languages, it is legal to concatenate two literals by putting them next to each other, this is only justified in a few cases. For instance if one is a macro or if the layout makes it clearer.

Noncompliant Code Example

  const char * v1 = "a""b";      // Noncompliant; same as "ab"
  const char * v2 = "a\n" "b\n"; // Noncompliant

Compliant Solution

  const char * v1 = "ab"
  const char * v2 = "a\n"
                    "b\n";

Exceptions

  const char * v3 = "a" /* comment */ "b";

  #define _s "b"
  const char * v4 = "a" _s; // concatenation with macro ignored
c:S3729

While C syntax considers array subscripts ([]) as symmetrical, meaning that a[i] and i[a] are equivalent, the convention is to put the index in the brackets rather than the array name. Inverting the index and array name serves no purpose, and is very confusing.

Noncompliant Code Example

10[P1] = 0; // Noncompliant
dostuff(i[arr]); // Noncompliant

Compliant Solution

P1[10] = 0;
dostuff(arr[i]);
c:S3730

#include_next is a gcc-specific language extension that alters the search path for the specified header file by starting the search from the header file directory after the one in which the directive was encountered. It also ignores the distinction between "file" and <file>. It is typically used when you have two (probably related) header files with the same name, although there is nothing in the extension to enforce or limit the use to same-name files.

Use of this extension can be tricky to get right, and is almost never justified. Instead, you should use an absolute path in the #include statement or rename one of the files.

Noncompliant Code Example

#include_next "foo.h" // Noncompliant

Compliant Solution

#include "/usr/local/include/foo.h"
c:S3744

A macro definition should not be redefined without marking that intent specifically by un-defining it first.

Noncompliant Code Example

#define A 1
#define A 2

Compliant Solution

#define A 1
#undef A
#define A 2

Exceptions

If the redefinition has the same value as the original one. This is consistent with most C compilers warnings.

#define A 1
#define A 1
c:S3805

#import comes from Objective-C and is a variant of #include. GCC does support it, but it requires the users of a header file to know that it should only be included once. It is much better for the header file's implementor to write the file so that users don't need to know this. Using a wrapper #ifndef accomplishes this goal.

Noncompliant Code Example

#import "foo.h" // Noncompliant

Compliant Solution

#include "foo.h"
c:S3806

The path provided here doesn't match the actual path on this file system (e.g. the case is different). While this may work on a particular environment, this is not portable and may fail on a different environment.

Noncompliant Code Example

#include "Foo.h" // Noncompliant, the file name is "foo.h"
c:S3807

The standard C library includes a number of functions for string and memory manipulation. They take pointers and a lengths as parameters. Passing NULL for the pointers will at best do nothing and at worst crash the application.

This rule raises an issue when NULL is passed as a pointer in to any of the following functions:

  • void *memcpy(void *dest, const void *src, size_t n);
  • void *memmove(void *dest, const void *src, size_t n);
  • void *memccpy(void *dest, const void *src, int c, size_t n);
  • void *memset(void *s, int c, size_t n);
  • int memcmp(const void *s1, const void *s2, size_t n);
  • void *memchr(const void *s, int c, size_t n);
  • void *rawmemchr(const void *s, int c);
  • void *memrchr(const void *s, int c, size_t n);
  • char *strcpy(char *dest, const char *src);
  • char *strncpy(char *dest, const char *src, size_t n);
  • char *strcat(char *dest, const char *src);
  • char *strncat(char *dest, const char *src, size_t n);
  • int strcmp(const char *s1, const char *s2);
  • int strncmp(const char *s1, const char *s2, size_t n);
  • int strcoll(const char *s1, const char *s2);
  • size_t strxfrm(char *dest, const char *src, size_t n);
  • int strcoll_l(const char *s1, const char *s2, locale_t loc);
  • size_t strxfrm_l(char *restrict s1, const char *restrict s2, size_t n, locale_t loc);
  • char *strdup(const char *s);
  • char *strndup(const char *s, size_t n);
  • char *strchr(const char *s, int c);
  • char *strrchr(const char *s, int c);
  • char *strchrnul(const char *s, int c);
  • size_t strcspn(const char *s, const char *reject);
  • size_t strspn(const char *s, const char *accept);
  • char *strpbrk(const char *s, const char *accept);
  • char *strstr(const char *haystack, const char *needle);
  • char *strtok(char *s, const char *delim);
  • char *strtok_r(char *str, const char *delim, char **saveptr);
  • char *strcasestr(const char *haystack, const char *needle);
  • void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);
  • void *mempcpy(void *dest, const void *src, size_t n);
  • size_t strlen(const char *s);
  • size_t strnlen(const char *s, size_t maxlen);
  • char *strerror_r(int errnum, char *buf, size_t buflen);
  • void bcopy(const void *src, void *dest, size_t n);
  • void bzero(void *s, size_t n);
  • int bcmp(const void *s1, const void *s2, size_t n);
  • char *index(const char *s, int c);
  • char *rindex(const char *s, int c);
  • int strcasecmp(const char *s1, const char *s2);
  • int strncasecmp(const char *s1, const char *s2, size_t n);
  • int strcasecmp_l(const char *s1, const char *s2, locale_t loc);
  • int strncasecmp_l(const char *s1, const char *s2, size_t n, locale_t loc);
  • char *strsep(char **stringp, const char *delim);
  • char *stpcpy(char *dest, const char *src);
  • char *stpncpy(char *dest, const char *src, size_t n);
  • int strverscmp(const char *s1, const char *s2);
  • char *strfry(char *string);
  • void *memfrob(void *s, size_t n);
  • char *basename(char *path);

This rule raises an issue when 0 is passed as a length to any of the following functions, since the last two parameters might have been swapped by mistake:

  • void *memccpy(void *dest, const void *src, int c, size_t n);
  • void *memset(void *s, int c, size_t n);
  • void *memchr(const void *s, int c, size_t n);
  • void *memrchr(const void *s, int c, size_t n);

Noncompliant Code Example

memcpy(NULL, src, 10); // Noncompliant, null pointer
memset(ptr, 0, 0); // Noncompliant, length is zero
c:S3935

The GNU compiler extension that allows cases to be specified with ranges will only recognize ranges specified from a smaller value to a larger value. Flip the order and the range will evaluate as empty.

Noncompliant Code Example

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 5 ... 3: // Noncompliant
    //...
    break;

Compliant Solution

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 3 ... 5
    //...
    break;
c:S3936

The GNU compiler extension that allows cases to be specified with ranges should only be used when a range is actually needed. Use it with the same number on both ends of the range, and you've either made a mistake because an actual range was intended, or you've used the syntax inappropriately in a way that is highly likely to confuse maintainers.

Noncompliant Code Example

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 3 ... 3: // Noncompliant
    //...
    break;
}

Compliant Solution

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 3:
    //...
    break;
}

or

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 3 ... 5:
    //...
    break;
}
c:S3972

Code is clearest when each statement has its own line. Nonetheless, it is a common pattern to combine on the same line an if and its resulting then statement. However, when an if is placed on the same line as the closing } from a preceding else or else if, it is either an error - else is missing - or the invitation to a future error as maintainers fail to understand that the two statements are unconnected.

Noncompliant Code Example

if (condition1) {
  // ...
} if (condition2) {  // Noncompliant
  //...
}

Compliant Solution

if (condition1) {
  // ...
} else if (condition2) {
  //...
}

Or

if (condition1) {
  // ...
}

if (condition2) {
  //...
}
c:S4143

It is highly suspicious when a value is saved for a key or index and then unconditionally overwritten. Such replacements are likely in error.

Noncompliant Code Example

towns[i] = "London";
towns[i] = "Chicago";  // Noncompliant
c:S4263

Microsoft's MSVC has a search strategy which differs from other compilers when resolving quoted include directives #include "file.h". Relying on such a strategy is not portable and may lead to compilation failure when trying to build with a different compiler.

This rule raises an issue whenever the file specified in a #include directive can only be found using the MSVC search strategy.

See

MSVC documentation

c:SizeofSizeof

A call to sizeof(sizeof(...)) is equivalent to sizeof(size_t), and indicates a misuse or misunderstanding of the sizeof construct.

Noncompliant Code Example

#include <string.h>

int main(int argc, char* argv[])
{
  char buffer[42];
  char buffer2[sizeof(sizeof(buffer))]; /* Noncompliant - a single sizeof() was intended */

  memcpy(buffer, "Hello, world!", strlen("Hello, world!")+1);
  memcpy(buffer2, buffer, sizeof(buffer)); /* Buffer overflow */

  return 0;
}

Compliant Solution

#include <string.h>

int main(int argc, char* argv[])
{
  char buffer[42];
  char buffer2[sizeof(buffer)]; /* Compliant */

  memcpy(buffer, "Hello, world!", strlen("Hello, world!")+1);
  memcpy(buffer2, buffer, sizeof(buffer));

  return 0;
}
c:TabCharacter

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

common-abap:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-abap:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-abap:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-abap:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-abap:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-c:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-c:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-c:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-c:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-c:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-cpp:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-cpp:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-cpp:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-cpp:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-cpp:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-cs:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-cs:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-cs:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-cs:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-cs:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-css:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-css:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-css:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-css:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-css:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-flex:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-flex:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-flex:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-flex:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-flex:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-go:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-go:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-go:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-go:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-go:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-java:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-java:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-java:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-java:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-java:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-js:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-js:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-js:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-js:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-js:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-kotlin:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-kotlin:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-kotlin:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-kotlin:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-kotlin:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-objc:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-objc:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-objc:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-objc:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-objc:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-php:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-php:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-php:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-php:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-php:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-py:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-py:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-py:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-py:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-py:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-ruby:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-ruby:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-ruby:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-ruby:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-ruby:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-swift:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-swift:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-swift:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-swift:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-swift:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-ts:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-ts:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-ts:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-ts:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-ts:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-tsql:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-tsql:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-tsql:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-tsql:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-tsql:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-vbnet:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-vbnet:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-vbnet:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-vbnet:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-vbnet:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-web:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-web:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-web:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-web:InsufficientLineCoverage
An issue is created on a file as soon as the line coverage on this file is less than the required threshold. It gives the number of lines to be covered in order to reach the required threshold.
common-web:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
common-xml:DuplicatedBlocks
An issue is created on a file as soon as there is at least one block of duplicated code on this file
common-xml:FailedUnitTests
Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.
common-xml:InsufficientCommentDensity
An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. The number of comment lines to be written in order to reach the required threshold is provided by each issue message.
common-xml:SkippedUnitTests
Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.
cpp:ClassComplexity

The cyclomatic complexity of a class should not exceed a defined threshold. Complex code can perform poorly and will in any case be difficult to understand and therefore to maintain.

Deprecated

This rule is deprecated, and will eventually be removed.

cpp:CommentMixedStyles

Use either the // ... or /* ... */ comment syntax, but be consistent and do not mix them within the same file.

Noncompliant Code Example

/* Noncompliant; both comment syntaxes are used in the same file */
// Foo
/* Bar */

Compliant Solution

// Compliant; uniform comment syntax
// Foo
// Bar

See

  • CERT, MSC55-J. - Use comments consistently and in a readable fashion
cpp:EmptyCompoundStatement

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

void foo()
{
  int x;
  if (x == 42)
  {                     /* Noncompliant */
    /* do nothing */
  }
  else
  {
    printf("x != 42");
  }
}

void bar()
{                       /* Compliant - functions are not nested blocks */
}

Compliant Solution

void foo()
{
  int x;
  if (x != 42)
  {                     /* Compliant */
    printf("x != 42");
  }
}

/* ... */

Exceptions

When a block contains a comment, this block is not considered to be empty.

cpp:FileComplexity

Most of the time, a very complex file breaks the Single Responsibility Principle and should be re-factored into several different files.

Deprecated

This rule is deprecated, and will eventually be removed.

cpp:FileLoc

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

cpp:FunctionComplexity

The Cyclomatic Complexity of functions should not exceed a defined threshold. Complex code may perform poorly and can be difficult to test thoroughly.

cpp:LineLength

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

cpp:NonReentrantFunction

A function is called reentrant if it can be interrupted in the middle of its execution and then safely called again ("re-entered") before its previous invocations complete execution.

It is especially important that multi-threaded applications do not call the same non-reentrant function from different threads.

This rule will trigger an issue each time a function in the configurable list is invoked.

Noncompliant Code Example

Given a function that includes localtime:

#include <stdio.h>
#include <time.h>

void print_date_and_time(struct tm *time_ptr)
{
  printf(
    "Current date and time: %d/%02d/%02d %02d:%02d:%02d\n",
    time_ptr->tm_year + 1900,
    time_ptr->tm_mon,
    time_ptr->tm_mday,
    time_ptr->tm_hour,
    time_ptr->tm_min,
    time_ptr->tm_sec);
}

void print_unix_epoch_date_and_time()
{
  time_t unix_epoch_time = (time_t)0;
  struct tm *local_time_ptr = localtime(&unix_epoch_time); // Noncompliant, call to the non-reentrant localtime() function
  print_date_and_time(local_time_ptr);
}

int main(int argc, char* argv[])
{
  time_t current_time;
  struct tm *local_time_ptr;

  time(&current_time);

  local_time_ptr = localtime(&current_time); // Noncompliant, call to the non-reentrant localtime() function

  // As expected, this will print: Current date and time: 1970/00/01 01:00:00
  print_unix_epoch_date_and_time();

  // This will actually also print Current date and time: 1970/00/01 01:00:00
  // Indeed, localtime() is non-reentrant, and always returns the same pointer
  print_date_and_time(local_time_ptr);

  return 0;
}

Compliant Solution

#include <stdio.h>
#include <time.h>

void print_date_and_time(struct tm *time_ptr)
{
  printf(
    "Current date and time: %d/%02d/%02d %02d:%02d:%02d\n",
    time_ptr->tm_year + 1900,
    time_ptr->tm_mon,
    time_ptr->tm_mday,
    time_ptr->tm_hour,
    time_ptr->tm_min,
    time_ptr->tm_sec);
}

void print_unix_epoch_date_and_time()
{
  time_t unix_epoch_time = (time_t)0;
  struct tm local_time;
  localtime_r(&unix_epoch_time, &local_time); // Compliant
  print_date_and_time(&local_time);
}

int main(int argc, char* argv[])
{
  time_t current_time;
  struct tm local_time;

  time(&current_time);

  localtime_r(&current_time, &local_time); // Compliant

  // As expected, this will print: Current date and time: 1970/00/01 01:00:00
  print_unix_epoch_date_and_time();

  // As expected, this will print the current date and time, as expected
  print_date_and_time(&local_time);

  return 0;
}
cpp:OneStatementPerLine

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

foo(); bar(); // Noncompliant

Compliant Solution

foo();
bar();

Exceptions

Control flow statements with a single nested statement are ignored.

if (condition) doSomething();       // Compliant
while (condition) doSomething();    // Compliant

case or default statements containing a single statement and followed by break are ignored.

switch (foo) {
  case  0: doSomething(); break;    // Compliant
  default: doSomething(); break;    // Compliant
}

Statements enclosed in curly braces on the same line are ignored.

auto lambda = [](int x) { doSomething(x); return x; }; // Compliant
cpp:ParsingError

When the parser fails, it is possible to record the failure as an issue on the file. This way, not only is it possible to track the number of files that do not parse but also to easily find out why they do not parse.

cpp:PPBackslashNotLastCharacter

The standard mentions that the line continuation character (\) should be immediately followed by a newline or be the very last character of the file in order for the lines to be joined.

Several compilers relax this requirement by allowing whitespace after the \ character, but this is not portable because other compilers may not do the same.

Compliant Solution

// There should be no whitespace after the '\'
#define FOO BAR \
            BAZ
cpp:PPDirectiveIndentation

Indenting preprocessor directives reduces the code readability, because it make preprocessor directives harder to spot.

Noncompliant Code Example

void optimal()
{
  #if INTEL             /* Noncompliant - hard to spot */
  specificIntelStuff();
  #endif                /* Noncompliant - hard to spot */
}

Compliant Solution

void optimal()
{
#if INTEL               /* Compliant */
  specificIntelStuff();
#endif                  /* Compliant */
}
cpp:PPErrorDirectiveReached

This rule creates a issue whenever an #error preprocessor directive is reached during the project's analysis. In most cases, this indicates that the preprocessor was badly configured. Some predefined macros or library include paths might be required to fix the configuration.

Noncompliant Code Example

#error This is an error
cpp:PPMacroName

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all macro names match a provided regular expression.

Noncompliant Code Example

#define foo // Noncompliant

Compliant Solution

#define FOO
cpp:PPNonStandardInclude

The iostream.h header was provided with the first C++ compiler, CFront, and became the de facto standard. During the formal standardization process of C++, many shortcomings in iostream.h were fixed, but at the cost of introducing incompatibilities. Therefore, it was decided not to change the existing iostream.h and introduce the standard version as a new iostream header.

Modern compilers tend to remove the support of the legacy iostream.h header, and migrating to the standard version is encouraged.

This rule applies not only to iostream, but to all standard C++ headers.

Noncompliant Code Example

#include <iostream.h> // Noncompliant
#include <fstream.h>  // Noncompliant

Compliant Solution

#include <iostream>
#include <fstream>
cpp:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression: [a-z][a-zA-Z0-9]*:

void DoSomething (void);

Compliant Solution

void doSomething (void);
cpp:S106

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

  • The user must be able to easily retrieve the logs
  • The format of all logged message must be uniform to allow the user to easily read the log
  • Logged data must actually be recorded
  • Sensitive data must only be logged securely

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

std::cout << "My Message";                // Noncompliant
std::cerr << "My Message";                // Noncompliant
printf("My Message");                     // Noncompliant

Compliant Solution

Log().Get(logINFO) << "My Message";

See

cpp:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if (condition1) {
  if (condition2) {             // NonCompliant
    /* ... */
  }
}

Compliant Solution

if (condition1 && condition2) { // Compliant
  /* ... */
}
cpp:S1067

The complexity of an expression is defined by the number of &&, || and condition ? ifTrue : ifFalse operators it contains.

A single expression's complexity should not become too high to keep the code readable.

Noncompliant Code Example

With the default threshold value 3.

if (((condition1 && condition2) || (condition3 && condition4)) && condition5) { ... }

Compliant Solution

if ((myFirstCondition() || mySecondCondition()) && myLastCondition()) { ... }
cpp:S1068

If a private field is declared but not used in the program, it can be considered dead code and should therefore be removed. This will improve maintainability because developers will not wonder what the variable is used for.

Noncompliant Code Example

class MyClass {
  private:
    int foo = 42;  // Noncompliant, foo is unused

  public:
    int compute(int a) {
      return a * 42;
    }
};

Compliant Solution

class MyClass {
  public:
    int compute(int a) {
      return a * 42;
    }
};
cpp:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

Noncompliant Code Example

With a maximum number of 4 parameters:

void doSomething(int param1, int param2, int param3, int param4, int param5) {
  ...
}

Compliant Solution

void doSomething(int param1, int param2, int param3, int param4) {
  ...
}
cpp:S110

Inheritance is certainly one of the most valuable concepts in object-oriented programming. It's a way to compartmentalize and reuse code by creating collections of attributes and behaviors called classes which can be based on previously created classes. But abusing this concept by creating a deep inheritance tree can lead to very complex and unmaintainable source code. Most of the time a too deep inheritance tree is due to bad object oriented design which has led to systematically use 'inheritance' when for instance 'composition' would suit better.

cpp:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

int x = (y / 2 + 1);   //Compliant even if the parenthesis are ignored by the compiler

if (a && ((x+y > 0))) {  // Noncompliant
  //...
}

return ((x + 1));  // Noncompliant

Compliant Solution

int x = (y / 2 + 1);

if (a && (x+y > 0)) {
  //...
}

return (x + 1);

Exceptions

When the result of an assignment is used as a condition, clang raises a warning to make sure the purpose was not to use == in place of =. Adding some parentheses around the assignment is a common way to silence this clang warning. So, no issue is raised in such case.

if ((x = 7)) {} // Compliant
cpp:S112

If you throw a general exception type, such as std::exception, std::logic_error or std::runtime_error, it forces consumers to catch all exceptions, including unknown exceptions they don't necessarily know how to handle.

Instead, either throw a subtype that already exists ( for example in <stdexcept> ), or create your own type that derives from a standard one.

Noncompliant Code Example

throw std::logic_error("Unexpected null 'user_id' argument."); // Noncompliant

Compliant Solution

throw std::invalid_argument("Unexpected null 'user_id' argument.");

See

cpp:S1123

The deprecated attribute can be applied with or without explanations, but marking something deprecated without including advice as to why it's deprecated or on what to use instead will lead maintainers to waste time trying to figure those things out - every single time the warning is encountered.

Noncompliant Code Example

[[deprecated]] // Noncompliant
void foo1();

__attribute__((deprecated)) // Noncompliant
void foo2();

__declspec(deprecated) // Noncompliant
void foo3();

Compliant Solution

[[deprecated("use 'bar' instead")]]
void foo1();

__attribute__((deprecated("use 'bar' instead")))
void foo2();

__declspec(deprecated("use 'bar' instead"))
void foo3();
cpp:S113

Some tools work better when files end with an empty line.

This rule simply generates an issue if it is missing.

For example, a Git diff looks like this if the empty line is missing at the end of the file:

+class Test {
+}
\ No newline at end of file
cpp:S1131

Trailing whitespaces are simply useless and should not stay in code. They may generate noise when comparing different versions of the same file.

If you encounter issues from this rule, this probably means that you are not using an automated code formatter - which you should if you have the opportunity to do so.

cpp:S1133

This rule is meant to be used as a way to track code which is marked as being deprecated. Deprecated code should eventually be removed.

Noncompliant Code Example

// C++14 attribute
[[deprecated]] // Noncompliant
void fun();

// GNU attribute
__attribute__((deprecated)) // Noncompliant
void fun();

// Microsoft attribute
__declspec(deprecated) // Noncompliant
void fun();
cpp:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

int divide(int numerator, int denominator) {
  return numerator / denominator;              // FIXME denominator value might be  0
}

See

cpp:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

void foo() {
  // TODO
}

See

cpp:S1142

Having too many return statements in a function increases the function's essential complexity because the flow of execution is broken each time a return statement is encountered. This makes it harder to read and understand the logic of the function.

Noncompliant Code Example

With the default threshold of 3:

int fun() {
  if (condition1) {
    return 1;
  } else {
    if (condition2) {
      return 0;
    } else {
      return 1;
    }
  }
  return 0;
}
cpp:S1151

The switch statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of case clause should be extracted in a dedicated function.

Noncompliant Code Example

With the default threshold of 5:

switch (myVariable) {
  case 0: // 6 lines till next case
    methodCall1("");
    methodCall2("");
    methodCall3("");
    methodCall4("");
    break;
  case 1:
  // ...
}

Compliant Solution

switch (myVariable) {
  case 0:
    doSomething();
    break;
  case 1:
  // ...
}
// ...
void doSomething(){
    methodCall1("");
    methodCall2("");
    methodCall3("");
    methodCall4("");
}
cpp:S116

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that field names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

class MyClass {
  int my_field;
};

Compliant Solution

class MyClass {
  int myField;
};
cpp:S117

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a local variable or function parameter name does not match the provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

void doSomething(int my_param) {
  int LOCAL;
  ...
}

Compliant Solution

void doSomething(int myParam) {
  int local;
  ...
}

Exceptions

Loop counters and const variables are ignored by this rule.

cpp:S1181

std::exception is the superclass of all exceptions in C++.

Catching std::exception will also catch std::bad_alloc and std::bad_exception, from which an application should not attempt to recover. More generally, catching generic exception types is a bad idea, because it implies that the "catch" bock is clever enough to handle any type of exception.

Noncompliant Code Example

try {
  /* code that may throw std::system_error */
} catch (const std::exception &ex) { // Noncompliant
  /*...*/
}

Compliant Solution

try {
  /* code that may throw std::system_error */
} catch (const std::system_error &ex) {
  /*...*/
}

See

cpp:S1185

Overriding a method just to call the same method from the super class without performing any other actions is useless and misleading. The only time this is justified is in final overriding methods, where the effect is to lock in the parent class behavior. This rule ignores such overrides of equals, hashCode and toString.

Noncompliant Code Example

class Base {
public:
  virtual void f();
};

class Derived : public Base {
public:
  virtual void f() {
    Base::f(); // Noncompliant
  }
};

Compliant Solution

class Base {
public:
  virtual void f();
};

class Derived : public Base {
};

or

class Base {
public:
  void f();
};

class Derived : public Base {
private: // change of visibility
  virtual void f() {
    Base::f();
  }
};

or

class Base {
public:
  void f();
};

class Derived : public Base {
public:
  void f() final { // final
    Base::f();
  }
};
cpp:S1186

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

  • 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 in languages where that mechanism is available.
  • The method is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.

Noncompliant Code Example

void fun(int p1) {
}

Compliant Solution

void fun(int p1) {
  int a = doSomething(p1);
  int threshold = 42;
  if (a > threshold) {
    // ...
  }
}

or

void fun(int p1) {
  // Intentionally unimplemented...
}

Exceptions

This rule doesn't raise an issue for empty class constructors or destructors. For instance this is the only way to define user-defined default constructors.

cpp:S1188

Lambdas (introduced in C++11) are a very convenient and compact way to inject a behavior without having to create a dedicated function. But those lambdas should be used only if the behavior to be injected can be defined in a few lines of code, otherwise the source code can quickly become unreadable.

cpp:S1199

Nested code blocks can be used to create a new scope and restrict the visibility of the variables defined inside it. Using this feature in a method typically indicates that the method has too many responsibilities, and should be refactored into smaller methods.

Noncompliant Code Example

public void evaluate(int operator) {
  switch (operator) {
    /* ... */
    case ADD: {                                // Noncompliant - nested code block '{' ... '}'
        int a = stack.pop();
        int b = stack.pop();
        int result = a + b;
        stack.push(result);
        break;
      }
    /* ... */
  }
}

Compliant Solution

public void evaluate(int operator) {
  switch (operator) {
    /* ... */
    case ADD:                                  // Compliant
      evaluateAdd();
      break;
    /* ... */
  }
}

private void evaluateAdd() {
  int a = stack.pop();
  int b = stack.pop();
  int result = a + b;
  stack.push(result);
}
cpp:S1227

break; is an unstructured control flow statement which makes code harder to read.

Ideally, every loop should have a single termination condition.

Noncompliant Code Example

for (element = list.first; element != null; element = element->next) { // First termination condition
  if (!matches(element->value)) {                                      // Second termination condition
    break; // Noncompliant
  }

  /* ... */
}

Compliant Solution

// Compliant
for (element = list.first; element != null && matches(element->value); element = element->next) {
  /* ... */
}
cpp:S1232

The same form that was used to create an object should always be used to delete it. Specifically, arrays should be deleted with delete [] and objects should be deleted with delete. To do otherwise will cause segfaults (in the case of deleting an object with delete []) and memory leaks (in the case of deleting an array with delete).

This is also true when memory was allocated with malloc, or one of its variants, then it must be released using free() not delete. Similarly memory allocated by new can not be released using free instead of delete.

Noncompliant Code Example

string* _pString1 = new string;
string* _pString2 = new string[100];
char* _pChar = (char *) malloc(100);

delete [] _pString1; // Noncompliant; an object was declared but array deletion is attempted
delete _pString2;  // Noncompliant; an array was declared but an object (the first in the array) is deleted
delete _pChar; // Noncompliant

Compliant Solution

string* _pString1 = new string;
string* _pString2 = new string[100];
char* _pChar = (char *) malloc(100);

delete _pString1;
delete [] _pString2;
free(_pChar);

See

cpp:S1235

When a class with virtual methods but no virtual destructor is used as a base class, surprises can occur if pointers to instances of this class are used. Specifically, if an instance of a derived class is assigned to a base class pointer, and delete is called, only the base class destructor will be invoked, so the object will only be partially destroyed. The resulting memory leak could eventually tie up enough resources to cause a denial of service.

If it is not expected for base class pointers to be deleted, then the destructor should be made protected to avoid such a misuse.

Noncompliant Code Example

class Base {
public:
  Base() {}
  ~Base() {} // Noncompliant; should be virtual to match virtual methods
  virtual void doSomething() {}
}

Compliant Solution

class Base {
public:
  Base() {}
  virtual ~Base() {}
  virtual void doSomething() {}
}

See

cpp:S1236

Returning a reference to the current object from operator= allows operator chaining, such as a = b = c = ....

Additionally, it is the convention and common expectation that operator= will return a reference to the left-hand side of the operation, i.e. *this. Ignoring that convention in a class will make it difficult for callers to use the class.

Noncompliant Code Example

String& String::operator=(const String& rhs)
{
  if (&rhs != this)
  {
    // ...
  }
  return rhs;
}

Compliant Solution

String& String::operator=(const String& rhs)
{
  if (&rhs != this)
  {
    // ...
  }
  return(*this);     // return reference to left-hand object
}
cpp:S1250

operator= must ensure that the object is not being reassigned to itself before performing the operation. If this check is not performed, a self-assignment could result in null pointer dereferences at worst, and wasted operations at best. Therefore operator= must always check for assignment to self before proceeding with the assignment.

Noncompliant Code Example

class MyClass
{
  private:
  int someVal;
  char* pData;

  MyClass& operator=(const MyClass& rhs)
  {
    this->someVal = rhs.someVal;               // useless operation in self-assignment
    delete [] pData;                          // data is lost in self-assignment
    pData = new char[strlen(rhs.pData) +1];   // null pointer dereference in self-assignment
    strcpy(pData, rhs.pData);

    return (*this);
  }
};

Compliant Solution

class MyClass
{
  private:
  int someVal;
  char* pData;

  MyClass& operator=(const MyClass& rhs)
  {
    if (this != &rhs)
    {
      this->someVal = rhs.someVal;
      delete [] pData;
      pData = new char[strlen(rhs.pData) +1];
      strcpy(pData, rhs.pData);
    }
    return (*this);
  }
};
cpp:S1259

Function pointer syntax can be hard on the eyes, particularly when one function is used as a parameter to another. Providing and using a typedef instead can make code easier to read, and should be preferred.

Noncompliant Code Example

extern void (*signal(int, void(*)(int)))(int);

Compliant Solution

typedef void (*SignalHandler)(int signum);
extern SignalHandler signal(int signum, SignalHandler handler);
cpp:S1264

When only the condition expression is defined in a for loop, and the initialization and increment expressions are missing, a while loop should be used instead to increase readability.

Noncompliant Code Example

for (;condition;) { /*...*/ }

Compliant Solution

while (condition) { /*...*/ }
cpp:S1265

Overriding operator new typically indicates that custom memory allocation is required for the class. When that's the case, it must be balanced with custom memory deallocation in an operator delete method. Otherwise memory leaks will result, potentially leading to a denial of service.

Noncompliant Code Example

class AirPlane
{
public:
  void* operator new(size_t size);
  void fly();
};

Compliant Solution

class AirPlane
{
public:
  void* operator new(size_t size);
  void operator delete(void* deadObject, size_t size);
  void fly();
};

See

  • CERT, DCL54-CPP. - Overload allocation and deallocation functions as a pair in the same scope
cpp:S1270

Explicitly specifying a void parameter list is required in C, but optional in C++. Using void for a parameter-less function decreases its readability. The at-a-glance impression is that the function does take a parameter, and it takes a second look to ascertain that it does not. Therefore the more compact notation is preferred.

Noncompliant Code Example

int fun(void);

int fun(void) {
  ...
}

Compliant Solution

int fun();

int fun() {
  ...
}
cpp:S1271

While it is possible to access a global variable or function without using the :: operator, it's considered by most to be misleading because it might imply to the readers of your code that this is a local or class variable/function and not a global one. It also allows more freedom in naming local variables without the chance of clashing with global names.

Noncompliant Code Example

int a = 10;
int main()
{
  ...
  int b = a;    // Noncompliant
  ...
}

Compliant Solution

int a = 10;
int main()
{
  ...
  int b = ::a;    // Compliant
  ...
}
cpp:S1291

Any issue to quality rule can be deactivated with the NOSONAR marker. This marker is pretty useful to exclude false-positive results but it can also be used abusively to hide real quality flaws.

This rule raises an issue when NOSONAR is used.

cpp:S134

Nested if, for, do, while, switch and try statements is a key ingredient 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:

  if (condition1) {                  // Compliant; depth = 1
    /* ... */
    if (condition2) {                // Compliant; depth = 2
      /* ... */
      for(int i = 0; i < 10; i++) {  // Compliant; depth = 3, not exceeding the limit
        /* ... */
        if (condition4) {            // Noncompliant; depth = 4
          if (condition5) {          // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
            /* ... */
          }
          return;
        }
      }
    }
  }

Exceptions

Each use of a macro containing control flow statements is counted as one nesting level, even if the macro contains more than one control flow statement.

  #define FOREACH(V,ARR) if(ARR!=nullptr) for(int V=0; V<(sizeof(ARR)/sizeof(ARR[0])); V++)

  if (condition1) {       // Compliant; depth = 1
    if (condition2) {     // Compliant; depth = 2
      FOREACH(i, arr) {     // Compliant; depth = 3 (not 4)
        if (condition3) {   // Noncompliant; depth = 4
          /* ... */
        }
      }
    }
  }
cpp:S138

A function that grows too large tends to aggregate too many responsibilities.

Such functions inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions which focus on well-defined tasks.

Those smaller functions will not only be easier to understand, but also probably easier to test.

cpp:S139

This rule verifies that single-line comments are not located at the ends of lines of code. The main idea behind this rule is that in order to be really readable, trailing comments would have to be properly written and formatted (correct alignment, no interference with the visual structure of the code, not too long to be visible) but most often, automatic code formatters would not handle this correctly: the code would end up less readable. Comments are far better placed on the previous empty line of code, where they will always be visible and properly formatted.

Noncompliant Code Example

a = b + c;   // This is a trailing comment that could be very very long

Compliant Solution

// This very long comment is better placed before the line of code
a = b + c;
cpp:S1448

A class that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor the class into smaller ones which focus on well defined topics.

cpp:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
cpp:S1479

When switch statements have large sets of case clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

cpp:S1578

Shared coding conventions allow teams to collaborate effectively. For that reason, file names should conform to a defined standard. This rule raises an issue when the names of analyzed files don't match the provided regular expression.

See

cpp:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

void setValue(int value) {
  value = value;
}

Compliant Solution

void setValue(int value) {
  this->value = value;
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
cpp:S1679

Rethrowing an unmodified copy of the caught exception is a waste of resources. Additionally, doing so may lead to a loss of precision in the object type and its data, since the copy will be an instance of the base class, rather than of the potentially more specific exception class originally caught.

Noncompliant Code Example

try {
  throw std::invalid_argument("x");
} catch (const std::exception& ex) {
  /* ... */
  throw ex; // Noncompliant; the received "std::invalid_argument" is copied into a less specialized class "std::exception"
}

Compliant Solution

try {
  throw std::invalid_argument("x");
} catch (const std::exception& ex) {
  /* ... */
  throw; // rethrows the initial "std::invalid_argument"
}
cpp:S1704

Rvalue references were introduced as part of C++11. They are thus a new feature of the language, and are not yet widely understood. Using them is complicated, and code using rvalue references may be difficult to understand.

Noncompliant Code Example

std::vector<int> return_vector(void)
{
    std::vector<int> tmp {1,2,3,4,5};
    return tmp;
}

std::vector<int> &&rval_ref = return_vector(); // Noncompliant

Compliant Solution

std::vector<int> return_vector(void)
{
    std::vector<int> tmp {1,2,3,4,5};
    return tmp;
}

const std::vector<int>& rval_ref = return_vector();
cpp:S1705

Postfix increment and decrement typically involves making a copy of the object being incremented or decremented, whereas its prefix form does not. Therefore the prefix form is usually the more efficient form, and should be preferred.

Noncompliant Code Example

void myFunc(int lim)
{
  int i;
  for (i = 0; i < lim; i++)
  {
    // do something
  }
}

Compliant Solution

void myFunc(int lim)
{
  int i;
  for (i = 0; i < lim; ++i)
  {
    // do something
  }
}
cpp:S1707

TODO and FIXME comments are typically intended to be short-lived; they are placeholders and reminders that programmers leave for themselves. Unfortunately, even with the best of intentions, those comments are not always acted on and removed in a timely manner. Thus, they can become mysterious, lingering cruft in a code base, reducing both readability and understand-ability.

This rule flags all FIXME and TODO comments that do not have an attribution matching the specified regular expression immediately after the FIXME or TODO. Ideally, such comments will also contain information about what needs to be fixed or done, but this rule does not enforce that.

Noncompliant Code Example

Using the default regular expression: [ ]*\([ _a-zA-Z0-9@.]+\):

// TODO

Compliant Solution

// TODO(ganncamp) per the business partners, more checks needed
cpp:S1708

C++ comments (//) require fewer keystrokes, and take less space. Perhaps most importantly, they do not have the nesting problems that C-style comments do. Therefore C++ comments are preferred.

Noncompliant Code Example

/* this is my comment ... */

Compliant Solution

// this is my comment ...

Exceptions

Because a C++ header file may be included by a C source file, header files are ignored by this rule.

cpp:S1712

Setting method parameter defaults seems like a tidy way to make a method more usable. However, function pointers to methods with defaulted parameters can be confusing, because the function signature may not seem to match the call signature. Therefore, the use of multiple, overloaded methods is preferred.

Noncompliant Code Example

void HelloWorld (string name="World")
{
    cout << "Hello " << name << endl;
}

Compliant Solution

void HelloWorld (string name)
{
    cout << "Hello " << name << endl;
}

void HelloWorld ()
{
    HelloWorld("World");
}
string Foo (string

See also

cpp:S1750

Lambdas are a concise way of creating anonymous functions - when those functions are themselves concise. However, the use of lambdas for sizable functions can make the code difficult to read. More importantly, following variable capture in lambdas can be difficult, potentially leading to dangling pointers. Therefore lambdas should be avoided.

Noncompliant Code Example

int main()
{
    auto func = [] () { cout << "Hello world"; };
    func();
}

Compliant Solution

int main()
{
    func();
}
void func ()
{
    cout << "Hello world";
}
cpp:S1762

Using "#pragma warning (default: ...)" resets the warning in question to its default settings, which may not be what the compiler was initially invoked with. Typically, this usage is seen after a warning is turned off, in preparation for code that is known to cause warnings. Instead, the warning's current state should be saved, and then restored after the code in question.

Noncompliant Code Example

#pragma warning (disable: TheWarning)
#include problem_code.h
#pragma warning (default: TheWarning)

Compliant Solution

#pragma warning (push)
#include problem_code.h
#pragma warning (pop)

See

cpp:S1768

Because the value in a variable of an unsigned type can never be less than zero, testing to see if it is negative is a useless operation which can only confuse future readers of the code.

Noncompliant Code Example

unsigned int i = 0; // the lowest value this var can have
...
if (i >= 0) { // Noncompliant
  do_x(i);
}

Compliant Solution

unsigned int i = 0;
...
do_x(i);
cpp:S1772

The result of the comparison is the same, regardless of whether the constant is on the left or right-hand side. But following this convention will help pinpoint the occasional error where = (assignment) is substituted for == (comparison).

If the constant is on the right-hand side of the expression in such cases, the code will still compile and run - just not as expected. If the constant is on the left-hand side, the error will be caught at the first attempt to compile.

Noncompliant Code Example

if ( var == constant )
if ( pointer == NULL )

Compliant Solution

if ( constant == var )
if ( NULL == pointer )
cpp:S1773

Coding conventions allow teams to work efficiently together. This rule checks that the public section of a class is declared first, followed by the protected section, and ending with the private section.

Noncompliant Code Example

class Point
{
  private:
    String _color;
    ...

  protected:
    ...

  public:
    String getColor();
    String setColor();
};

Compliant Solution

class Point
{
  public:
    String getColor();
    String setColor();

  protected:
    ...

  private:
    String _color;
    ...
};
cpp:S1774

While the ternary operator is pleasingly compact, its use can make code more difficult to read. It should therefore be avoided in favor of the more verbose if/else structure.

Noncompliant Code Example

printf("%s", (i>10?"yes":"no"));

Compliant Solution

if (i > 10) {
  printf("yes");
} else {
  printf("no");
}
cpp:S1820

A structure, such as a struct, union or class that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain, and having a lot of fields is an indication that a structure has grown too large.

Above a specific threshold, it is strongly advised to refactor the structure into smaller ones that focus on well defined topics.

cpp:S1821

Nested switch structures are difficult to understand because you can easily confuse the cases of an inner switch as belonging to an outer statement. Therefore nested switch statements should be avoided.

Specifically, you should structure your code to avoid the need for nested switch statements, but if you cannot, then consider moving the inner switch to another function.

Noncompliant Code Example

void func(int n, int m) {

  switch (n) {
    case 1:
      // ...
    case 2:
      // ...
    case 3:
      switch (m) {  // Noncompliant
    case 4:  // Bad indentation makes this particularly hard to read properly
      // ...
    case 5:
      // ...
    case 6:
      // ...
    }
    case 4:
      // ...
    default:
      // ...
  }
}

Compliant Solution

void func(int n, int m) {

  switch (n) {
    case 1:
      // ...
    case 2:
      // ...
    case 3:
      int m2 = handle_m(m);
    case 4:
      // ...
    default:
      // ...
  }
}
cpp:S1862

A chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

Noncompliant Code Example

if (param == 1)
  openWindow();
else if (param == 2)
  closeWindow();
else if (param == 1)  // Noncompliant
  moveWindowToTheBackground();

Compliant Solution

if (param == 1)
  openWindow();
else if (param == 2)
  closeWindow();
else if (param == 3)
  moveWindowToTheBackground();

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
cpp:S1874

Code annotated as deprecated should not be used since it will be removed sooner or later.

Noncompliant Code Example

// C++14 attribute
[[deprecated]]
void fun();

// GNU attribute
__attribute__((deprecated))
void fun();

// Microsoft attribute
__declspec(deprecated)
void fun();

void example() {
  fun(); // Noncompliant
}

See

cpp:S1990

There is no need to use the final specifier inside a final class. Everything in it is final by default.

Similarly, there is no need to use the final specifier for union, because unions can neither extend other classes nor be extended.

Noncompliant Code Example

class Base {
  virtual void fun();
};

class Derived final : Base {
  void fun() final;  // Noncompliant
};

union MyUnion final { // Noncompliant
  // ...
};

Compliant Solution

class Base {
  virtual void fun();
};

class Derived final : Base {
  void fun() override;
};

union MyUnion {
  // ...
};
cpp:S2095

A call to the fopen()/open() function must be matched with a call to fclose()/close. Otherwise, you run the risk of using up all the OS's file handles, which could lock up not just your program but potentially everything on the box.

Noncompliant Code Example

int fun() {
  FILE *f = fopen("file", "r");
  if (f == NULL) {
    return -1;
  }
  // ...
  return 0; // Noncompliant, file f has not been closed
}

Compliant Solution

int fun() {
  FILE *f = fopen("file", "r");
  if (f == NULL) {
    return -1;
  }
  // ...
  fclose(f);
  return 0;
}

See

cpp:S2123

A value that is incremented or decremented and then not stored is at best wasted code and at worst a bug.

Noncompliant Code Example

int pickNumber() {
  int i = 0;
  int j = 0;

  i = i++; // Noncompliant; i is still zero

  return j++; // Noncompliant; 0 returned
}

Compliant Solution

int pickNumber() {
  int i = 0;
  int j = 0;

  i++;
  return ++j;
}
cpp:S2209

While it is possible to access static members from a class instance, it's bad form, and considered by most to be misleading because it implies to the readers of your code that there's an instance of the member per class instance.

Noncompliant Code Example

class MyClass {
public :
  static void Mymethod() {
    // ...
  }
};

MyClass* pmyclass = new MyClass();
pmyclass->Mymethod(); // Noncompliant

Compliant Solution

class MyClass {
public :
  static Mymethod() {
    // ...
  }
};

Myclass::Mymethod();
cpp:S2234

When the names of parameters in a method call match the names of the method arguments, it contributes to clearer, more readable code. However, when the names match, but are passed in a different order than the method arguments, it indicates a mistake in the parameter order which will likely lead to unexpected results.

Noncompliant Code Example

int divide(int divisor, int dividend) {
  return divisor / dividend;
}

void doTheThing() {
  int divisor = 15;
  int dividend = 5;

  int result = divide(dividend, divisor);  // Noncompliant; operation succeeds, but result is unexpected
  //...
}

Compliant Solution

int divide(int divisor, int dividend) {
  return divisor / dividend;
}

public void doTheThing() {
  int divisor = 15;
  int dividend = 5;

  int result = divide(divisor, dividend);
  //...
}
cpp:S2259

A pointer to null (the 0 memory address) should never be dereferenced/accessed. Doing so will at best cause abrupt program termination, without the ability to run any cleanup processes. At worst, it could expose debugging formation that would be useful to an attacker or it could allow an attacker to bypass security measures.

Noncompliant Code Example

char *p1 = ... ;
if (p1 == NULL && *p1 == '\t') { // Noncompliant, p1 will be dereferenced IFF it is null
  // ...
}

char *p2 = ... ;
if (p2 != NULL) {
    // ...
}
*p2 = '\t'; // Noncompliant; potential null-dereference

char *p3, *p4;
p3 = NULL;
// ...
p4 = p3;
*p4;  // Noncompliant

Compliant Solution

char *p1 = ... ;
if (p1 != NULL && *p1 == '\t') { // Compliant, *p1 cannot be evaluated when p1 is NULL
  // ...
}

char *p2 = ... ;
if (p2 != NULL) {
    // ...
  *p2 = '\t'; // Compliant
}

See

cpp:S2343

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all enumeration values match a provided regular expression.

Noncompliant Code Example

With default provided regular expression:

enum SomeEnumeration {
    some  // Non-Compliant
};

Compliant Solution

enum SomeEnumeration {
    SOME
};
cpp:S2387

Having a variable with the same name in two unrelated classes is fine, but do the same thing within a class hierarchy and you'll get confusion at best, chaos at worst.

Noncompliant Code Example

class Fruit {
  protected:
    Season ripe;
    static Color flesh;

  // ...
};

class Raspberry : public Fruit {
  private:
    bool ripe;  // Noncompliant
    static Color FLESH; // Noncompliant
};

Compliant Solution

class Fruit {
  protected:
    Season ripe;
    static Color flesh;

  // ...
};

class Raspberry : public Fruit {
  private:
    bool ripened;
    static Color FLESH_COLOR;

};

Exceptions

This rule ignores same-name fields that are static in both the parent and child classes. This rule ignores private parent class fields, but in all other such cases, the child class field should be renamed.

class Fruit {
  private:
    Season ripe;
  // ...
};

class Raspberry : public Fruit {
  private:
    Season ripe;  // Compliant as parent field 'ripe' is anyway not visible from Raspberry
  // ...
};

or

class Fruit {
  public:
    Season ripe;
  // ...
};

class RedFruit : private Fruit {
};

class Raspberry : public RedFruit { // RedFruit inherits from Fruit privately
  private:
    Season ripe;  // Compliant as parent field 'ripe' is anyway not visible from Raspberry
  // ...
};
cpp:S2637

Functions return values and parameters values marked nonnull are assumed to have non-null values and are not typically null-checked before use. Therefore setting one of these values to null, could cause null pointer dereferences at runtime.

Noncompliant Code Example

__attribute__((returns_nonnull))
int* nonnull(__attribute__((nonnull)) int* parameter) {
  parameter = 0; // Noncompliant - "parameter" is marked "nonnull" but is set to null.
  nonnull(0); // Noncompliant - Parameter "parameter" to this call is marked "nonnull" but null is passed.
  return 0; // Noncompliant - This function's return value is marked "nonnull" but null is returned.
}

See

cpp:S2665

Although some compilers will allow it, the use of sizeof and alignof with arguments that have a void type is forbidden by both the C and C++ standards.

Noncompliant Code Example

void fun() {
  void* p;
  sizeof(*p);  // Noncompliant
  sizeof(void);  // Noncompliant
}
cpp:S2668

It is possible to use the increment operator ++, to set the value of a bool(C++) or _Bool(C) variable to true. But this feature has been deprecated in C++ since the 1998 version of the standard, and even where allowed, is simply confusing.

Noncompliant Code Example

bool alive;
...
alive++;

Compliant Solution

bool alive;
...
alive = true;

See

  • ISO/IEC 14882:1998, 5.3.2
cpp:S2681

Curly braces can be omitted from a one-line block, such as with an if statement or for loop, but doing so can be misleading and induce bugs.

This rule raises an issue when the whitespacing of the lines after a one line block indicates an intent to include those lines in the block, but the omission of curly braces means the lines will be unconditionally executed once.

Noncompliant Code Example

if (condition)
  firstActionInBlock();
  secondAction();  // Noncompliant; executed unconditionally
thirdAction();

if (condition) firstActionInBlock(); secondAction();  // Noncompliant; secondAction executed unconditionally

if (condition) firstActionInBlock();  // Noncompliant
  secondAction();  // Executed unconditionally

if (condition); secondAction();  // Noncompliant; secondAction executed unconditionally

String str = null;
for (int i = 0; i < array.length; i++)
  str = array[i];
  doTheThing(str);  // Noncompliant; executed only on last array element

Compliant Solution

if (condition) {
  firstActionInBlock();
  secondAction();
}
thirdAction();

String str = null;
for (int i = 0; i < array.length; i++) {
  str = array[i];
  doTheThing(str);
}

See

cpp:S2738

A general catch block seems like an efficient way to handle multiple possible exceptions. Unfortunately, it traps all exception types, casting too broad a net, and perhaps mishandling extraordinary cases. Instead, specific exception sub-types should be caught.

Noncompliant Code Example

try {
  file.open("test.txt");
} catch (...) {  // Noncompliant
  // ...
}

Compliant Solution

try {
  file.open("test.txt");
} catch (std::ifstream::failure e) {
  // ...
}
cpp:S2754

Empty declarations are cruft; they (may) compile, but they violate the language standards, don't contribute anything of value, and clutter up the program. Like cobwebs, they should be swept away.

Noncompliant Code Example

int;  // Noncompliant

See

  • ISO/IEC 9899:2011, 6.7p2
  • ISO/IEC 14882:2011, 7p3.
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
cpp:S2757

The use of operators pairs (=+) where the reversed, single operator was meant (+=) will compile and run, but not produce the expected results.

This rule raises an issue when =+, =-, =!, =&, =*, +=+, and -=- are used without any space between the two operators and when there is at least one whitespace after.

Noncompliant Code Example

int target = -5;
int num = 3;

target =- num;  // Noncompliant; target = -3. Is that really what's meant?
target =+ num; // Noncompliant; target = 3

Compliant Solution

int target = -5;
int num = 3;

target = -num;  // Compliant; intent to assign inverse value of num is clear
target += num;
cpp:S2761

The needless repetition of an operator is usually a typo. After all, why write !!!i when !i will do?

On the other hand, the repetition of increment and decrement operators may have been done on purpose, but doing so obfuscates the meaning, and should be simplified.

This rule raises an issue for sequences of: !, ~, -, and +, and in C++ for repetitions of the increment and decrement operators.

Noncompliant Code Example

int i = 1;

int j = - - -i;  // Noncompliant; just use -i
int k = ~~i;     // Noncompliant; same as i
int m = + +i;    // Noncompliant; operators are useless here

bool b = false;
bool c = !!!b;   // Noncompliant

Compliant Solution

int i =  1;

int j = -i;
int k =  i;
int m =  i;

bool b = false;
bool c = !b;

Exceptions

Boolean normalization !! is ignored.

cpp:S2807

Member functions can only be used with an instance of a class. But friend functions can be used with an implicitly converted type. So loosening access privileges to friend on overloaded binary operators makes them more flexible. Specifically, with a friend function, the class instance can be on either the right or the left of the operator, but with a member function, it can only be on the left.

This rule raises an issue for all non-friend overloaded binary operators except =, [ ], and ->, which cannot be overloaded as friend functions.

Noncompliant Code Example

bool operator==(const MyClass &RHS);  // Noncompliant

Compliant Solution

friend bool operator==(const MyClass &LHS, const MyClass &RHS);
cpp:S2808

The delete operator expects a pointer argument. Passing it an object may compile and seem to run (with an implicit cast to pointer type) but it can result in unexpected behavior at runtime.

Noncompliant Code Example

class CString {
public:
  operator const char*();
  // ...
};

void fun() {
  CString str;
  // ...
  delete str;  // Noncompliant
}

Compliant Solution

void fun() {
  CString *pstr = new CString;
  // ...
  delete pstr;
}
cpp:S2813

There is no point in creating a const reference to a literal numeric value. Most likely the intent was not to create a reference, but a constant value.

Noncompliant Code Example

const int & weekdayCount = 7;  // Noncompliant

Compliant Solution

const int weekdayCount = 7;
cpp:S2815

According to the C++ standard, this can never be null, so comparisons of the two are pointless at best. At worst, because of compiler optimizations, such comparisons could lead to null pointer dereferences or obscure, difficult-to-diagnose errors in production.

This rule raises an issue when this is compared to nullptr or 0 or anything #defined as nullptr or 0, such as NULL in most environments.

Noncompliant Code Example

class MyClass {
  string name;

  string GetName() {
    if (this != 0) {  // Noncompliant
      return name;
    }
    return 0;
  }
}

Compliant Solution

class MyClass {
  string name;

  string GetName() {
    return name;
  }
}
cpp:S3229

Class members are initialized in the order in which they are declared in the class, not the order in which they appear in the class initializer list. To avoid errors caused by order-dependent initialization, the order of members in the initialization list should match the order in which members are declared in a class.

Noncompliant Code Example

#include <iostream>

class C {
public:
  int x;
  int y;

  C(int i) : y(i), x(y + 1) { }  // Noncompliant
};

int main() {
  C c(1);
  std::cout << c.x << " " << c.y << std::endl;  // prints 1 1
}

See

  • CERT, OOP53-CPP. - Write constructor member initializers in the canonical order
cpp:S3230

The omission of an initialization list means that your class members will first be initialized with default values before their assignments to their actual values in the class body. For primitive class members, this overhead is negligible, but for non-trivial, user classes it could be significant.

Noncompliant Code Example

class MyClass {
  private:
    FatClass first, second;

  public:
    MyClass(FatClass first_var, FatClass sec_var) {
      first = first_var; // Noncompliant
      second = sec_var; // Noncompliant
    }
};

Compliant Solution

class MyClass {
  private:
    FatClass first, second;

  public:
    MyClass(FatClass first_var, FatClass sec_var): first(first_var), second(sec_var) { }
};
cpp:S3231

Redundant forward declarations simply clutter the code, and like any duplications, should be removed.

Noncompliant Code Example

struct S {
  // ...
};
// ...
struct S;  // Noncompliant

Compliant Solution

struct S {
  // ...
};
cpp:S3261

Namespaces with no lines of code clutter a project and should be removed.

Noncompliant Code Example

namespace MyEmptyNamespace // Noncompliant
{

}
cpp:S3358

Just because you can do something, doesn't mean you should, and that's the case with nested ternary operations. Nesting ternary operators results in the kind of code that may seem clear as day when you write it, but six months later will leave maintainers (or worse - future you) scratching their heads and cursing.

Instead, err on the side of clarity, and use another line to express the nested operation as a separate statement.

Noncompliant Code Example

int max(int p1, int p2, int p3) {
  return p1 > p2 ? (p1 > p3 ? p1 : p3) : (p2 > p3 ? p2 : p3); // Noncompliant
}

Compliant Solution

int max(int p1, int p2, int p3) {
  if (p1 > p2) {
    return p1 > p3 ? p1 : p3;
  } else {
    return p2 > p3 ? p2 : p3;
  }
}
cpp:S3400

There's no point in forcing the overhead of a method call for a method that always returns the same constant value. Even worse, the fact that a method call must be made will likely mislead developers who call the method thinking that something more is done. Declare a constant instead.

This rule raises an issue if on methods that contain only one statement: the return of a constant value.

Noncompliant Code Example

int getBestNumber() {
  return 12;  // Noncompliant
}

Compliant Solution

static int bestNumber = 12;

Exceptions

override, final, virtual and overriding functions are ignored.

cpp:S3432

Destructors are invoked automatically when control leaves the scope in which the object was created. Add an explicit destructor call to that, and you end up with undefined behavior because the automatic destructor invocation will be invoked on an object that no longer exists. However sometimes it is acceptable to have destructor calls for some specific use-cases, i.e. when it is desired to destroy the object but without releasing the memory.

Noncompliant Code Example

MyClass mc;
//...
mc.~MyClass();  // Noncompliant
cpp:S3458

Empty case clauses that fall through to the default are useless. Whether or not such a case is present, the default clause will be invoked. Such cases simply clutter the code, and should be removed.

Noncompliant Code Example

switch(ch)
{
  case 'a' :
    handleA();
    break;
  case 'b' :
    handleB();
    break;
  case 'c' :  // Noncompliant
  default:
    handleTheRest();
    break;
}

Compliant Solution

switch(ch)
{
  case 'a' :
    handleA();
    break;
  case 'b' :
    handleB();
    break;
  default:
    handleTheRest();
    break;
}
cpp:S3469

While it's possible for inheritance to be non-public, it is rarely justified, and complicates the use of the derived class. For instance, inherited member visibility is diminished, and implicit and static_cast casts from the base class to the derived class won't work.

It is sometimes used to limit the base class functionality available in the derived class. When that's the desire, composition should be used instead.

Noncompliant Code Example

class B : private A {  // Noncompliant
  // ...
}

Compliant Solution

class B : public A {
  // ...
}

or

class B {
  private:
  A a;
  // ...
}
cpp:S3471

In a base class, virtual indicates that a function can be overridden. In a derived class, it indicates an override. But given the specifier's dual meaning, it would be both clearer and more sound to use derived class-specific specifiers instead: override or final.

  • final indicates a function override that cannot itself be overridden. The compiler will issue a warning if the signature does not match the signature of a base-class virtual function.
  • override indicates that a function is intended to override a base-class function. The compiler will issue a warning if this is not the case. It is redundant in combination with final.

Noncompliant Code Example

class Counter {
protected:
  int c = 0;
public:
  virtual void count() {
    c++;
  }
};

class FastCounter: public Counter {
public:
  virtual void count() {  // Noncompliant
    c += 2;
  }
};

Compliant Solution

class Counter {
protected:
  int c = 0;
public:
  virtual void count() {
    c++;
  }
};

class FastCounter: public Counter {
public:
  void count() override {
    c += 2;
  }
};

or

class Counter {
protected:
  int c = 0;
public:
  virtual void count() {
    c++;
  }
};

class FastCounter: public Counter {
public:
  void count() final {
    c += 2;
  }
};

See also

cpp:S3490

C++11 adds the ability to explicitly reinstate the default generation of special member functions that were suppressed by the definition of others. Using = default instead of manually rewriting the default implementation has two advantages:

  • The new syntax is clearer to maintainers.
  • It's more efficient for POD (Plain Old Data) types. POD types can contain explicitly defaulted functions; they are still considered as trivial by the compiler. But providing an implementation makes the types non-trivial, and prevents them from being true POD types.

This rule raises an issue when any of the following provides the default implementation:

  • default constructor
  • destructor
  • move constructor
  • move-assignment operator
  • copy constructor
  • copy-assignment operator

Noncompliant Code Example

struct Book {
  string Name;
  int    Reference;

  Book() { } // Noncompliant
  Book(const Book &Other) : Name(Other.Name), Reference(Other.Reference) { } // Noncompliant
  Book &operator=(const Book &);
};

Book &Book::operator=(const Book &Other) { // Noncompliant
  Name      = Other.Name;
  Reference = Other.Reference;
  return *this;
}

Compliant Solution

struct Book {
  string Name;
  int    Reference;

  Book() = default; // restores generation of default
  Book(const Book &Other) = default;
  Book &operator=(const Book &);
};

Book &Book::operator=(const Book &Other) = default;
cpp:S3516

When a method is designed to return an invariant value, it may be poor design, but it shouldn't adversely affect the outcome of your program. However, when it happens on all paths through the logic, it is surely a bug.

This rule raises an issue when a method contains several return statements that all return the same value.

Noncompliant Code Example

int foo(int a) {
  int b = 12;
  if (a == 1) {
    return b;
  }
  return b;  // Noncompliant
}
cpp:S3518

If the denominator to a division or modulo operation is zero it would result in a fatal error.

Noncompliant Code Example

void test_divide() {
  int z = 0;
  if (unknown()) {
    // ..
    z = 3;
  } else {
    // ..
  }
  z = 1 / z; // Noncompliant, possible division by zero
}

Compliant Solution

void test_divide() {
  int z = 0;
  if (unknown()) {
    // ..
    z = 3;
  } else {
    // ..
    z = 1;
  }
  z = 1 / z;
}

See

  • MITRE, CWE-369 - Divide by zero
  • CERT, NUM02-J. - Ensure that division and remainder operations do not result in divide-by-zero errors
  • CERT, INT33-C. - Ensure that division and remainder operations do not result in divide-by-zero errors
cpp:S3519

Array overruns and buffer overflows happen when memory access accidentally goes beyond the boundary of the allocated array or buffer. These overreaching accesses cause some of the most damaging, and hard to track defects.

Noncompliant Code Example

int array[10];
array[10] = 0; // Noncompliant: index should be between 0 & 9

char *buffer1 = (char *) malloc(100);
char *buffer2 = (char *) malloc(50);
memcpy(buffer2, buffer1, 100); // Noncompliant: buffer2 will overflow.

Compliant Solution

int array[10];
array[9] = 0;

char *buffer1 = (char *) malloc(100);
char *buffer2 = (char *) malloc(50);
memcpy(buffer2, buffer1, 50);

See

  • MITRE, CWE-119 - Improper Restriction of Operations within the Bounds of a Memory Buffer
  • CERT, STR50-CPP. - Guarantee that storage for strings has sufficient space for character data and the null terminator
cpp:S3520

Using free(...) or delete releases the reservation on a memory location, making it immediately available for another purpose. So releasing the same memory location twice can lead to corrupting the program's memory.

A best practice to avoid this bug calls for setting just-freed pointers to NULL, and always null-testing before a free or delete.

Noncompliant Code Example

void doSomething(int size) {
  char *cp = (char *)malloc(sizeof(char)*size);

  // ...
  if(condition) {
    free(cp);
  }

  free(cp);  // Noncompliant
}

Compliant Solution

void doSomething(int size) {
  char *cp = (char *)malloc(sizeof(char)*size);

  // ...
  if(condition) {
    if (cp != NULL) {
      free(cp);
      cp = NULL;
    }
  }

  if (cp) {  // This is a common, short-hand null test
    free(cp);
    cp = NULL;
  }
}

See

cpp:S3522

According to ISO/IEC 14882 (third edition 2011-09-01) : C++11

The register specifier shall be applied only to names of variables declared in a block or to function parameters. It specifies that the named variable has automatic storage duration. A variable declared without a storage-class-specifier at block scope or declared as a function parameter has automatic storage duration by default.

A register specifier is a hint to the implementation that the variable so declared will be heavily used.[ Note: The hint can be ignored and in most implementations it will be ignored if the address of the variable is taken. This use is deprecated - end note ]

In upcoming versions of C/C++ we can expect this deprecated specifier to not be supported anymore.

cpp:S3529

Once a block of memory has been freed, it becomes available for other memory requests. Whether it's re-used immediately, some time later, or not at all is random, and may vary based on load. Because of that randomness, tests may pass when running locally, but the odds are that such code will fail spectacularly in production by returning strange values, executing unexpected code, or causing a program crash.

Noncompliant Code Example

char *cp = malloc(sizeof(char)*10);

// ...
free(cp);

cp[9] = 0;  // Noncompliant

See

cpp:S3539

Redundant access specifiers should be removed because they needlessly clutter the code.

Noncompliant Code Example

struct S {
  public: // Noncompliant; does not affect any declaration
  private:
    void method();
  private: // Noncompliant; does not change accessibility level
    int member;
  private: // Noncompliant; does not affect any declaration
};
class C {
    int member;
  private: // Noncompliant;  does not change accessibility level
    void method();
};

Compliant Solution

struct S {
  private:
    void method();
    int member;
};
class C {
    int member;
    void method();
};

Exceptions

An access specifier at the very beginning of a class or struct that matches the default access level is ignored even when it doesn't change any accessibility levels.

class C {
  private: // redundant but accepted
    // ...
};
struct S {
  public: // redundant but accepted
    // ...
};

Such a specifier is redundant, but ignored to allow classes and structs to be described uniformly.

class C {
  public:
    void call();

  protected:
    int delete();

  private:
    int code;
};
struct S {
  public: // redundant but accepted
    int sum();

  protected:
    int min();

  private:
    int count;
};
cpp:S3540

Adding an access specifier that matches the class' current access level needlessly clutters the code.

Noncompliant Code Example

struct B {
};

struct S : public B { // Noncompliant; "struct" has public access for its base classes by default
};

class C : private B { // Noncompliant; "class" has private access for its base classes by default
};

Compliant Solution

struct B {
};

struct S : B {
};

class C : B {
};
cpp:S3541

Allocation functions are always static. Explicitly declaring such a function static needlessly clutters the code.

Noncompliant Code Example

struct S {
  static void* operator new(std::size_t); // Noncompliant; static is redundant
  static void  operator delete(void*);    // Noncompliant; static is redundant
};

Compliant Solution

struct S {
  void* operator new(std::size_t);
  void  operator delete(void*);
};

See

  • Reference: Since C++98 (ISO IEC 14882 1998) 12.5 §1 and §6

Any allocation function for a class T is a static member (even if not explicitly declared static).

Any deallocation function for a class X is a static member (even if not explicitly declared static).

cpp:S3542

C++14 adds the ability to write numbers with digit separators for better readability. Splitting a number that has more than 4 consecutive digits improves readability.

This rule verifies that numbers are written using digit separators when they have more than 4 consecutive digits.

Noncompliant Code Example

long decimal_int_value     = 5543124;            // Noncompliant; insert ' between groups of 3 digits.
double decimal_float_value = 7918714.3456;       // Noncompliant; insert ' between groups of 3 digits.
long hexadecimal_value     = 0x83A32486E2;       // Noncompliant; insert ' between groups of 2 or 4 digits.
long octal_value           = 04420343313726;     // Noncompliant; insert ' between groups of 2, 3 or 4 digits.
long binary_value          = 0b0101011011101010; // Noncompliant; insert ' between groups of 2, 3 or 4 digits.

Compliant Solution

long decimal_int_value     = 5'543'124;
double decimal_float_value = 7'918'714.3456;
long hexadecimal_value     = 0x83'A324'86E2;
long octal_value           = 04'4203'4331'3726;
long binary_value          = 0b0101'0110'1110'1010;

Exceptions

No issue is raised on the fractional or exponent part of floating point numbers, only the integral part should comply.

cpp:S3543

C++14 introduced the ability to use a digit separator (') to split a literal number into groups of digits for better readability.

To ensure that readability is really improved by using digit separators, this rule verifies:

  • Homogeneity
    • Except for the left-most group, which can be smaller, all groups in a number should contain the same number of digits. Mixing group sizes is at best confusing for maintainers, and at worst a typographical error that is potentially a bug.
  • Standardization
    • It is also confusing to regroup digits using a size that is not standard. This rule enforce the following standards:
      • Decimal numbers should be separated using groups of 3 digits.
      • Hexadecimal numbers should be separated using groups of 2 or 4 digits.
      • Octal and Binary should be separated using groups of 2, 3 or 4 digits.

Furthermore, using groups with more than 4 consecutive digits is not allowed because they are difficult for maintainers to read.

Noncompliant Code Example

long decimal_int_value     = 1'554'3124;          // Noncompliant; mixing groups of 3 and 4 digits
double decimal_float_value = 7'91'87'14.3456;     // Noncompliant; using groups of 2 instead of 3 digits
long hexadecimal_value     = 0x8'3A3'248'6E2;     // Noncompliant; using groups of 3 instead of 2 or 4 digits
long octal_value           = 0442'03433'13726;    // Noncompliant; using groups of 5 instead of 2, 3 or 4 digits.
long binary_value          = 0b01010110'11101010; // Noncompliant; using groups of 8 instead of 2, 3 or 4 digits.

Compliant Solution

long decimal_int_value     = 15'543'124;
double decimal_float_value = 7'918'714.3456;
long hexadecimal_value     = 0x83'A324'86E2;
long octal_value           = 04'4203'4331'3726;
long binary_value          = 0b0101'0110'1110'1010;

Exceptions

No issue is raised on the fractional or exponent part of floating point numbers, only the integral part should comply.

cpp:S3549

Since C++03, a member function that is contained within a class definition is by definition inline, so an using an inline specifier on such functions is redundant.

Noncompliant Code Example

class Foo {
  inline void method() { // Noncompliant
    // ...
  }
};

Compliant Solution

class Foo {
  void method() {
    // ...
  }
};
cpp:S3562

For completeness, a switch over the values of an enum must either address each value in the enum or contain a default case. switch statements that are not over enum must end with a default case.

Noncompliant Code Example

typedef enum {APPLE, GRAPE, KIWI} fruit;

void example(fruit f, int i) {
  switch (f) {  // Noncompliant; no case for KIWI
    case APPLE:
      //...
    case GRAPE:
      //...
    case 3: // Noncompliant; case value not in enum
      // ...
  }

  switch (i) { // Noncompliant; no default
    case 0:
      // ...
    case 1:
      // ...
  }
}

Compliant Solution

typedef enum {APPLE, GRAPE, KIWI} fruit;

void example(fruit f) {
  switch (f) {
    case APPLE:
      //...
    case GRAPE:
      //...
    default:
      // ...
  }

  switch (i) {
    case 0:
      // ...
    case 1:
      // ...
    default:
      // ...
  }
}

or

typedef enum {APPLE, GRAPE, KIWI} fruit;

void example(fruit f) {
  switch (f) {
    case APPLE:
      //...
    case GRAPE:
      //...
    case KIWI:
      //...
  }

  switch (i) {
    case 0:
    case 1:
      // ...
    default:
      // ...
  }
}

See also

cpp:S3574

It is a best practice to make lambda return types implicit. First and foremost, doing so avoids implicit conversions which could result in data or precision loss. Second, omitting the return type helps future-proof the code.

Noncompliant Code Example

[](int i) -> int // Noncompliant
{ return i + 42; }

Compliant Solution

[](int i)
{ return i + 42; }
cpp:S3576

Since final classes can't be extended, indicating that functions in such a class are overrideable by adding the virtual specifier is possibly misguided, and definitely confusing.

Noncompliant Code Example

class Base {
  virtual void f1();
};

class C final : Base {
  virtual void f1();  // Noncompliant
  virtual void f2();  // Noncompliant
};

Compliant Solution

class Base {
  virtual void f1();
};

class C final : Base {
  void f1() override;
  void f2();
};

See

  • S3471 - "override" or "final" should be used instead of "virtual"
cpp:S3584

Memory allocated dynamically with calloc(...), malloc(...), realloc(...) or new should be released when it's not needed anymore. Failure to do so will result in a memory leak that could bring the box to its knees.

This rule raises an issue when memory is allocated and not freed in the same function. Allocated memory is ignored if a pointer to it is returned to the caller or stored in a structure that's external to the function.

Noncompliant Code Example

int fun() {
  char* name = (char *) malloc (size);
  if (!name) {
    return 1;
  }
  // ...
  return 0; // Noncompliant, memory pointed by "name" has not been released
}

Compliant Solution

int fun() {
  char* name = (char *) malloc (size);
  if (!name) {
    return 1;
  }
  // ...
  free(name);
  return 0;
}

See

  • MITRE, CWE-401 - Improper Release of Memory Before Removing Last Reference ('Memory Leak')
  • MEM00-C. - Allocate and free memory in the same module, at the same level of abstraction
  • CERT, MEM31-C. - Free dynamically allocated memory when no longer needed
cpp:S3588

Using the value of a pointer to a FILE object after the associated file is closed is undefined behavior.

Noncompliant Code Example

void fun() {
  FILE * pFile;
  pFile = fopen(fileName, "w");

  if (condition) {
    fclose(pFile);
    // ...
  }

  fclose(pFile); // Noncompliant, the file has already been closed
}

Compliant Solution

void fun() {
  FILE * pFile;
  pFile = fopen(fileName, "w");

  if (condition) {
    // ...
  }

  fclose(pFile);
}

See

cpp:S3608

Lambdas can use variables from their enclosing scope (called "capture") either by reference or by value. Since lambdas may run asynchronously, reference capture should be used with caution because by the time the lambda runs, the referenced variable may be out of scope, resulting in an access violation at run time.

You can specify default capture by reference ([&]), or by value ([=]). Clearly default reference capture can cause scope issues, but default value capture can also lead to problems. That's because both forms of default capture implicitly also capture *this, which would automatically be used if for example you referenced a method from the enclosing scope.

This rule raises an issue when default capture is used.

Noncompliant Code Example

void fun() {
  Foo foo;
  ...
  executor->Schedule([&] {  // Noncompliant
    maybeMember(foo);  // implicit use of *this reference if maybeMember is a member function. foo and maybeMember may both be gone by the time this is invoked
  });
}

Compliant Solution

void fun() {
  Foo foo;
  ...
  executor->Schedule([&foo] { // it is clear that foo is captured by reference and compilation is going to fail if maybeMember is a member function
    maybeMember(foo);
  });
}
cpp:S3609

Since C++11, declaring a variable, class, or function in an unnamed namespace gives it internal linkage. Similarly, marking a declaration static also gives it internal linkage. Because both mechanisms have the same effect (although static has a narrower application) using them together is clearly redundant.

Noncompliant Code Example

namespace {
  static int i = 3;  // Noncompliant
}

Compliant Solution

namespace {
  int i = 3;
}

See

  • ISO/IEC 14882:2011 §3.5 paragraph 4
cpp:S3626

Jump statements, such as return, break, goto, and continue let you change the default flow of program execution, but jump statements that direct the control flow to the original direction are just a waste of keystrokes.

Noncompliant Code Example

void Foo()
{
  goto A; // Noncompliant
  A:
  while (condition1)
  {
    if (condition2)
    {
      continue; // Noncompliant
    }
    else
    {
      DoTheThing();
    }
  }
  return; // Noncompliant; this is a void method
}

Compliant Solution

void Foo()
{
  while (condition1)
  {
    if (!condition2)
    {
      DoTheThing();
    }
  }
}
cpp:S3628

Since C++11, raw string literals can be used to avoid the need to escape characters in a string. Such character string literals are easier to read.

This rule raises an issue when a non-raw string contains one of the following escaped characters: \' \\ \" \?.

Noncompliant Code Example

const char* Path = "C:\\Program Files\\Microsoft Office\\Office16\\";  // Noncompliant, contains \\
const char* RegEx = "\\\\(\\\\.\\\\)"; // Noncompliant, contains \\
const char* QuestionMark = "a\?b"; // Noncompliant, contains \?
const char* TwoLines = "one\r\ntwo"; // Compliant, contains \r \n
const char* OneChar = "\\"; // Compliant, only one character

Compliant Solution

const char* Path = R"(C:\Program Files\Microsoft Office\Office16\)";
const char* RegEx = R"(\(\.\))";
const char* QuestionMark = R"(a?b)";
const char* TwoLines = "one\r\ntwo";
const char* OneChar = "\\";

Exceptions

To preserve readability, this rule ignores strings containing only one character and strings with escaped whitespace or non-printable characters:

  • Non-printable characters: \a \b \f \v \nnn \xnn \unnnn \Unnnnnnnn
  • Tab: \t
  • New line: \r \n
cpp:S3630

Because reinterpret_cast does not perform any type safety validations, it is capable of performing dangerous conversions between unrelated types.

This rule raises an issue when reinterpret_cast is used.

Noncompliant Code Example

  class A { public: virtual ~A(){} };
  class B : public A { public: void doSomething(){} };

  void func(A *a) {
    if (B* b = reinterpret_cast<B*>(a)) { // Noncompliant
      b->doSomething();
    }
  }

Compliant Solution

  class A { public: virtual ~A(){} };
  class B : public A { public: void doSomething(){} };

  void func(A *a) {
    if (B* b = dynamic_cast<B*>(a)) {
      b->doSomething();
    }
  }

See

  • CppCoreGuidelines, Type safety profile - Type.1: Don't use reinterpret_cast.
cpp:S3636

Since C++11, it's possible to declare the underlying type of an enum, and like any type declration, enum declarations can contain the const or volatile specifier. But because enum values are named constants and cannot be re-assigned, those specifiers are ignored by the compiler, and are therefore useless.

This rule raises an issue if const or volatile is present in the declaration of the underlying type of an enum.

Noncompliant Code Example

enum class Color : const long int {  // Noncompliant; Remove this "const" specifier.
  Red   = 0xff0000,
  Green = 0x00ff00,
  Blue  = 0x0000ff
};

enum class Size : volatile char {  // Noncompliant; Remove this "volatile" specifier.
  Small   = 's',
  Big     = 'b'
};

Compliant Solution

enum class Color : long int {
  Red   = 0xff0000,
  Green = 0x00ff00,
  Blue  = 0x0000ff
};

enum class Size : char {
  Small   = 's',
  Big     = 'b'
};
cpp:S3642

There are two kinds of enumeration:

  • The unscoped enum inherited from C
  • The scoped enumeration enum class or enum struct added in C++ 11

Unscoped enumerations have two major drawbacks that are fixed by scoped enumerations:

  • enum elements are visible from their enclosing scope, instead of requiring the scope resolution operator (ex: Red instead of Color::Red)
  • enum elements convert implicitly to int, so that heterogeneous comparisons such as Red == Big don't result in compile errors.

This rule raises an issue when an unscoped enumeration is used.

Noncompliant Code Example

enum Color { // Noncompliant; replace this "enum" with "enum class".
  Red   = 0xff0000,
  Green = 0x00ff00,
  Blue  = 0x0000ff
};

enum ProductType { // Noncompliant; replace this "enum" with "enum class".
  Small   = 1,
  Big     = 2
};

void printColor(int color);
void printInt(int value);

void report() {
  printColor(Red); // correct
  printColor(Big); // clearly buggy
  printInt(Red);   // conversion is implicit
}

Compliant Solution

enum class Color { // declared using "enum class"
  Red   = 0xff0000,
  Green = 0x00ff00,
  Blue  = 0x0000ff
};

enum class ProductType { // declared using "enum class"
  Small   = 1,
  Big     = 2
};

void printColor(Color color); // requires "Color" instead of "int"
void printInt(int value);

void report() {
  printColor(Color::Red);       // correct
  // printColor(ProductType::Big); => Compilation error, no known conversion from 'ProductType' to 'Color'
  printInt(static_cast<int>(Color::Red)); // conversion never occurs implicitly and must be explicit
}
cpp:S3646

It is possible in the same statement, to declare a user-defined type (class, struct, union or enum) followed by variable declarations of this type. But mixing more than one concern in a single statement is confusing for maintainers.

This rule raises an issue when a variable is declared at the end of a user-defined type declaration statement.

Noncompliant Code Example

struct Container { int size; } container; // Noncompliant

Compliant Solution

struct Container { int size; };
Container container;
cpp:S3657

C++ does not support polymorphic copy or move assignment operators. For example, the signature of a copy assignment operator on a "Base" class would be Base& operator=(const Base& other).

And on a "Derived" class that extends "Base", it would be Derived& operator=(const Derived& other).

Because these are two entirely different method signatures, the second method does not override the first, and adding virtual to the "Base" signature does not change which method is called.

It is possible to add an operator= override in a derived class, but doing so is an indication that you may need to reexamine your application architecture.

Noncompliant Code Example

class Base {
public:
  virtual Base& operator=(const Base& other); // Noncompliant
};

class Derived : public Base {
public:
  Derived& operator=(const Derived& other);
};

Compliant Solution

class Base {
protected:
  Base& operator=(const Base& other); // not virtual
};

class Derived : public Base {
public:
  Derived& operator=(const Derived& other);
};
cpp:S3659

Even though the C++ standard defines both "Primary" and "Alternative" operators, it is not a good idea to use the alternatives. Developers seeing an alphabetical name expect a variable, a function, a class, a namespace... in short, anything but an operator, and they will be confused at best by code that uses such operators.

Primary Alternative
&& and
&= and_eq
& bitand
| bitor
~ compl
! not
!= not_eq
|| or
|= or_eq
^ xor
^= xor_eq

Noncompliant Code Example

if (not valid or error) { // Noncompliant
  /* ... */
}

Compliant Solution

if (!valid || error) {
  /* ... */
}
cpp:S3685

C++ allows you to append a macro value onto the end of a string literal. Prior to C++11, it was possible to do this either with or without a space between the two. But with the introduction of user-defined literals in C++11, the preprocessing of string suffixes changed. To get the same string + macro behavior under C++ 11, you must separate the string literal and the macro with a space. Without the space, you'll get a compile error.

For the purpose of preparing for migration to C++11, this rule raises an issue when there's no space between a string literal and a macro.

Noncompliant Code Example

#define _Hrs " hours"
static const char* OPENING = "7"_Hrs; // Noncompliant

Compliant Solution

#define _Hrs " hours"
static const char* OPENING = "7" _Hrs; // there's one space after "7"
cpp:S3687

Except for interactions with extern volatile variables provided by libraries, C/C++ programmers should consider volatile an esoteric feature that is best avoided. In most cases, it is used in an attempt to provide atomicity, memory ordering, or inter-thread synchronization, but volatile does not provide those guarantees. It is only really needed for the kind of low-level code found in kernels, i.e. using memory-mapped I/O registers to manipulate hardware directly.

According to the C standard:

volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation.

Only C11/C++11 "atomic types" are free from data races.

This rule raises an issue when a volatile type is declared.

Noncompliant Code Example

volatile int counter; // Noncompliant
User * volatile vpUser; // Noncompliant; pointer is volatile
User volatile * pvUser;  // Compliant; User instance is volatile, not the pointer

Compliant Solution

atomic_int counter;
std::atomic<User*> vpUser;
User volatile * pvUser;
cpp:S3689

Redundant declaration specifiers should be removed or corrected. Typically, they represent bugs. A specifier modifies the type or pointer to its left. Only when it is at the far left does it apply to the right.

Noncompliant Code Example

const int const * v1a; // Noncompliant; both const specifiers apply to int
const int const * v1b; // Noncompliant
static static int v2;  // Noncompliant

Compliant Solution

const int *       v1a;  // pointer to a const int. same meaning as before but less confusing
int const * const v1b;  // const pointer to a const int
static int         v2;
cpp:S3691

Class templates can be explicitly or partially specialized. But according to the C++ standard, function templates cannot be partially specialized. Under certain conditions, the MicrosoftĀ® compiler will silently ignore the confusing application of partial specialization syntax to a function, but other compilers will raise an error for it and fail compilation.

Noncompliant Code Example

template<typename T>
void fun(T p);

template<typename T>
void fun<T>(T p) { // Noncompliant
  // ...
}

Compliant Solution

template<typename T>
void fun(T p);

template<typename T>
void fun(T p) {
  // ...
}
cpp:S3692

Making a comparison operator virtual implies that you want to compare objects of different types by overriding operator==, for instance, in a subclass to compare instances of the base class with instances of the subclass. But polymorphic comparison operators are very difficult to get right, and are actually questionable in concept. After all, can two objects with only a few common members really be equal?

This rule raises issues on virtual comparison operators.

Noncompliant Code Example

struct Foo {
  virtual bool operator==(const Foo &other) const; // Noncompliant
  virtual bool operator!=(const Foo &other) const; // Noncompliant
};

Compliant Solution

struct Foo {
  bool operator==(const Foo &other) const;
  bool operator!=(const Foo &other) const;
};
cpp:S3698

Throwing as an exception an object that is not derived from std::exception is a bad practice. It is usually unreliable, meaningless, and a source of type clashes.

For the same reason, catching a non-exception type is a sign that your application has a bad exception-handling design. You should use standard exception types or create your own exception types that inherit at some level from std::exception.

Noncompliant Code Example

try {
  /* code that can throw: 42 */
} catch (int ex) { // Noncompliant
  if (ex == 42) {
    /*...*/
  }
}

Compliant Solution

try {
  /* code that can throw: std::domain_error("User ID not found.") */
} catch (const std::domain_error& ex) {
  /*...*/
}
cpp:S3708

The C++ specification forbids the qualification of reference types with const or volatile unless it happens via a typedef, in which case it's ignored. Most compilers treat such direct qualifications as errors, but the Microsoft compiler allows them.

This rule raises an issue on both types of const qualification.

Noncompliant Code Example

void example(char c) {
  char & const direct = c; // Noncompliant

  typedef char & T;
  const T indirect = c; // Noncompliant
}

Compliant Solution

void example(char c) {
  char & direct = c; // or: const char & direct = c;

  typedef char & T;
  T indirect = c;
}

See

cpp:S3715

Proprietary compiler extensions can be handy, but they commit you to always using that compiler. This rule raises an issue when the following GNU extensions are used:

  • A array initializer without =, which has been obsolete since GCC 2.5
  • A structure member initializer with a colon, which has been obsolete since GCC 2.5.
  • Case ranges
  • Ternary operator with omitted second operand

Noncompliant Code Example

struct S {
  int f;
};

struct S s[] = {
  [0] { // Noncompliant
    f : 0 // Noncompliant
  }
};

int fun(int p) {
  switch (p) {
    case 0 ... 1: // Noncompliant
      do_the_thing();
      break;
    case 2:
      //...
  }

  return p ?: 0; // Noncompliant
}

Compliant Solution

struct S {
  int f;
};

struct S s[] = {
  [0] = {
    .f = 0
  }
};

int fun(int p) {
  switch (p) {
    case 0:
    case 1:
      do_the_thing();
      break;
    case 2:
      //...
  }

  return p ? p: 0;
}
cpp:S3719

It's best to avoid giving default argument initializers to virtual functions. While doing so is legal, the code is unlikely to be correctly maintained over time and will lead to incorrect polymorphic code and unnecessary complexity in a class hierarchy.

Noncompliant Code Example

class Base {
public:
  virtual void fun(int p = 42) { // Noncompliant
    // ...
  }
};

class Derived : public Base {
public:
  void fun(int p = 13) override { // Noncompliant
    // ...
  }
};

class Derived2 : public Base {
public:
  void fun(int p) override {
    // ...
  }
};

int main() {
  Derived *d = new Derived;
  Base *b = d;
  b->fun(); // uses default argument 42
  d->fun(); // uses default argument 13; was that expected?

  Base *b2 = new Base;
  Derived2 *d2 = new Derived2;
  b2->fun(); // uses default argument 42
  d2->fun(); // compile time error; was that expected?
}

Compliant Solution

class Base {
public:
  void fun(int p = 42) { // non-virtual forwarding function
    fun_impl(p);
  }
protected:
  virtual void fun_impl(int p) {
    // ...
  }
};

class Derived : public Base {
protected:
  void fun_impl(int p) override {
    // ...
  }
};

class Derived2 : public Base {
protected:
  void fun_impl(int p) override {
    // ...
  }
};

See also

cpp:S3726

Data members and member functions cannot be defined as external, although entire objects can. When a member is declared as extern, the compiler simply ignores the keyword, making it both extraneous and confusing.

Noncompliant Code Example

class C {
  void fun();
};

extern void C::fun() { // Noncompliant
}

Compliant Solution

class C {
  void fun();
};

void C::fun() {
}
cpp:S3728

While in C, and derived languages, it is legal to concatenate two literals by putting them next to each other, this is only justified in a few cases. For instance if one is a macro or if the layout makes it clearer.

Noncompliant Code Example

  const char * v1 = "a""b";      // Noncompliant; same as "ab"
  const char * v2 = "a\n" "b\n"; // Noncompliant

Compliant Solution

  const char * v1 = "ab"
  const char * v2 = "a\n"
                    "b\n";

Exceptions

  const char * v3 = "a" /* comment */ "b";

  #define _s "b"
  const char * v4 = "a" _s; // concatenation with macro ignored
cpp:S3729

While C syntax considers array subscripts ([]) as symmetrical, meaning that a[i] and i[a] are equivalent, the convention is to put the index in the brackets rather than the array name. Inverting the index and array name serves no purpose, and is very confusing.

Noncompliant Code Example

10[P1] = 0; // Noncompliant
dostuff(i[arr]); // Noncompliant

Compliant Solution

P1[10] = 0;
dostuff(arr[i]);
cpp:S3730

#include_next is a gcc-specific language extension that alters the search path for the specified header file by starting the search from the header file directory after the one in which the directive was encountered. It also ignores the distinction between "file" and <file>. It is typically used when you have two (probably related) header files with the same name, although there is nothing in the extension to enforce or limit the use to same-name files.

Use of this extension can be tricky to get right, and is almost never justified. Instead, you should use an absolute path in the #include statement or rename one of the files.

Noncompliant Code Example

#include_next "foo.h" // Noncompliant

Compliant Solution

#include "/usr/local/include/foo.h"
cpp:S3731

Before C++11, auto was used as a storage class specifier that indicated automatic duration. Since that's the default, the use of auto in that context was wholly redundant.

Because the keyword was redundant and therefore rarely used, C++11 repurposes it. auto is now used to specify that the type of the variable or function should be deduced from its context.

Since it is redundant under older standards and problematic under C++11, auto's use as a storage-class identifier should be removed.

Noncompliant Code Example

auto int x; // Noncompliant: redundant before C++11, error as of C++11

auto int y;  // Noncompliant

Compliant Solution

int x;

auto y = 1 + 2; // C++11: type of 'y' will be inferred
cpp:S3732

The C linkage declaration extern "C" can not be combined with a namespace. In practical terms only one function with that name can be declared as extern "C" because the namespace is functionally ignored.

Noncompliant Code Example

namespace ns1 {
    extern "C" void doSomething();  // Noncompliant
    // ...
}

extern "C" {
  namespace ns2 {  // Noncompliant
    // ...
  }
  // ...
}

ns1::doSomething();
doSomething(); // Works too, same as above

Compliant Solution

extern "C" void doSomething();

namespace ns1 {
  // ...
}

extern "C" {
  // ...
}

namespace ns2 {  // Noncompliant
  // ...
}

doSomething();

Exceptions

extern "C" can prefix typedef.

namespace ns1 {
    extern "C" typedef void c_function();  // Compliant, type named 'c_function' exists only in 'ns1' and not in the global namespace
    // ...
}
cpp:S3743

If you declare a function with noexcept or throw(), it's unexpected and confusing from a maintainer point of view to find a throw clause in the definition of the function.

Noncompliant Code Example

int divide(int numerator, int denominator) noexcept { // Promises that nothing will be thrown
  if (denominator == 0) {
    throw std::invalid_argument("invalid denominator"); // Noncompliant; implementation breaks promise
  }
  return numerator / denominator;
}

Compliant Solution

int divide(int numerator, int denominator) noexcept {
  if (denominator == 0) {
    return numerator < 0 ? INT_MIN : INT_MAX; // throw clause has been removed
  }
  return numerator / denominator;
}
cpp:S3744

A macro definition should not be redefined without marking that intent specifically by un-defining it first.

Noncompliant Code Example

#define A 1
#define A 2

Compliant Solution

#define A 1
#undef A
#define A 2

Exceptions

If the redefinition has the same value as the original one. This is consistent with most C compilers warnings.

#define A 1
#define A 1
cpp:S3805

#import comes from Objective-C and is a variant of #include. GCC does support it, but it requires the users of a header file to know that it should only be included once. It is much better for the header file's implementor to write the file so that users don't need to know this. Using a wrapper #ifndef accomplishes this goal.

Noncompliant Code Example

#import "foo.h" // Noncompliant

Compliant Solution

#include "foo.h"
cpp:S3806

The path provided here doesn't match the actual path on this file system (e.g. the case is different). While this may work on a particular environment, this is not portable and may fail on a different environment.

Noncompliant Code Example

#include "Foo.h" // Noncompliant, the file name is "foo.h"
cpp:S3807

The standard C library includes a number of functions for string and memory manipulation. They take pointers and a lengths as parameters. Passing NULL for the pointers will at best do nothing and at worst crash the application.

This rule raises an issue when NULL is passed as a pointer in to any of the following functions:

  • void *memcpy(void *dest, const void *src, size_t n);
  • void *memmove(void *dest, const void *src, size_t n);
  • void *memccpy(void *dest, const void *src, int c, size_t n);
  • void *memset(void *s, int c, size_t n);
  • int memcmp(const void *s1, const void *s2, size_t n);
  • void *memchr(const void *s, int c, size_t n);
  • void *rawmemchr(const void *s, int c);
  • void *memrchr(const void *s, int c, size_t n);
  • char *strcpy(char *dest, const char *src);
  • char *strncpy(char *dest, const char *src, size_t n);
  • char *strcat(char *dest, const char *src);
  • char *strncat(char *dest, const char *src, size_t n);
  • int strcmp(const char *s1, const char *s2);
  • int strncmp(const char *s1, const char *s2, size_t n);
  • int strcoll(const char *s1, const char *s2);
  • size_t strxfrm(char *dest, const char *src, size_t n);
  • int strcoll_l(const char *s1, const char *s2, locale_t loc);
  • size_t strxfrm_l(char *restrict s1, const char *restrict s2, size_t n, locale_t loc);
  • char *strdup(const char *s);
  • char *strndup(const char *s, size_t n);
  • char *strchr(const char *s, int c);
  • char *strrchr(const char *s, int c);
  • char *strchrnul(const char *s, int c);
  • size_t strcspn(const char *s, const char *reject);
  • size_t strspn(const char *s, const char *accept);
  • char *strpbrk(const char *s, const char *accept);
  • char *strstr(const char *haystack, const char *needle);
  • char *strtok(char *s, const char *delim);
  • char *strtok_r(char *str, const char *delim, char **saveptr);
  • char *strcasestr(const char *haystack, const char *needle);
  • void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);
  • void *mempcpy(void *dest, const void *src, size_t n);
  • size_t strlen(const char *s);
  • size_t strnlen(const char *s, size_t maxlen);
  • char *strerror_r(int errnum, char *buf, size_t buflen);
  • void bcopy(const void *src, void *dest, size_t n);
  • void bzero(void *s, size_t n);
  • int bcmp(const void *s1, const void *s2, size_t n);
  • char *index(const char *s, int c);
  • char *rindex(const char *s, int c);
  • int strcasecmp(const char *s1, const char *s2);
  • int strncasecmp(const char *s1, const char *s2, size_t n);
  • int strcasecmp_l(const char *s1, const char *s2, locale_t loc);
  • int strncasecmp_l(const char *s1, const char *s2, size_t n, locale_t loc);
  • char *strsep(char **stringp, const char *delim);
  • char *stpcpy(char *dest, const char *src);
  • char *stpncpy(char *dest, const char *src, size_t n);
  • int strverscmp(const char *s1, const char *s2);
  • char *strfry(char *string);
  • void *memfrob(void *s, size_t n);
  • char *basename(char *path);

This rule raises an issue when 0 is passed as a length to any of the following functions, since the last two parameters might have been swapped by mistake:

  • void *memccpy(void *dest, const void *src, int c, size_t n);
  • void *memset(void *s, int c, size_t n);
  • void *memchr(const void *s, int c, size_t n);
  • void *memrchr(const void *s, int c, size_t n);

Noncompliant Code Example

memcpy(NULL, src, 10); // Noncompliant, null pointer
memset(ptr, 0, 0); // Noncompliant, length is zero
cpp:S3935

The GNU compiler extension that allows cases to be specified with ranges will only recognize ranges specified from a smaller value to a larger value. Flip the order and the range will evaluate as empty.

Noncompliant Code Example

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 5 ... 3: // Noncompliant
    //...
    break;

Compliant Solution

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 3 ... 5
    //...
    break;
cpp:S3936

The GNU compiler extension that allows cases to be specified with ranges should only be used when a range is actually needed. Use it with the same number on both ends of the range, and you've either made a mistake because an actual range was intended, or you've used the syntax inappropriately in a way that is highly likely to confuse maintainers.

Noncompliant Code Example

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 3 ... 3: // Noncompliant
    //...
    break;
}

Compliant Solution

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 3:
    //...
    break;
}

or

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 3 ... 5:
    //...
    break;
}
cpp:S3972

Code is clearest when each statement has its own line. Nonetheless, it is a common pattern to combine on the same line an if and its resulting then statement. However, when an if is placed on the same line as the closing } from a preceding else or else if, it is either an error - else is missing - or the invitation to a future error as maintainers fail to understand that the two statements are unconnected.

Noncompliant Code Example

if (condition1) {
  // ...
} if (condition2) {  // Noncompliant
  //...
}

Compliant Solution

if (condition1) {
  // ...
} else if (condition2) {
  //...
}

Or

if (condition1) {
  // ...
}

if (condition2) {
  //...
}
cpp:S4143

It is highly suspicious when a value is saved for a key or index and then unconditionally overwritten. Such replacements are likely in error.

Noncompliant Code Example

towns[i] = "London";
towns[i] = "Chicago";  // Noncompliant
cpp:S4144

When two methods have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, one implementation should invoke the other.

This rule raises an exception when two methods implemented inside the class definition share the same implementation.

Noncompliant Code Example

class Point {
  int x;
  int y;

// .....

public:
  void setX(int v) {
    if (v >= 0 && v < MAX_X) {
      x = v;
      return;
    }
    error();
  }

  void setY(int v) {  // Noncompliant
    if (v >= 0 && v < MAX_X) {
      x = v;
      return;
    }
    error();
  }
};

Compliant Solution

class Point {
  int x;
  int y;

// .....

public:
 void setX(int v) {
    if (v >= 0 && v < MAX_X) {
      x = v;
      return;
    }
    error();
  }

  void setY(int v) {
    if (v >= 0 && v < MAX_X) {
      y = v;
      return;
    }
    error();
  }
};

Exceptions

Empty methods, methods with the same name (overload) and methods with only one statement are ignored.

cpp:S4263

Microsoft's MSVC has a search strategy which differs from other compilers when resolving quoted include directives #include "file.h". Relying on such a strategy is not portable and may lead to compilation failure when trying to build with a different compiler.

This rule raises an issue whenever the file specified in a #include directive can only be found using the MSVC search strategy.

See

MSVC documentation

cpp:S4334

Using auto when the type that would be deduced is a pointer type can cause confusion. It is much better to specify the pointer part outside of auto.

Noncompliant Code Example

auto item = new Item(); // Noncompliant

Compliant Solution

auto* item = new Item();
cpp:SizeofSizeof

A call to sizeof(sizeof(...)) is equivalent to sizeof(size_t), and indicates a misuse or misunderstanding of the sizeof construct.

Noncompliant Code Example

#include <string.h>

int main(int argc, char* argv[])
{
  char buffer[42];
  char buffer2[sizeof(sizeof(buffer))]; /* Noncompliant - a single sizeof() was intended */

  memcpy(buffer, "Hello, world!", strlen("Hello, world!")+1);
  memcpy(buffer2, buffer, sizeof(buffer)); /* Buffer overflow */

  return 0;
}

Compliant Solution

#include <string.h>

int main(int argc, char* argv[])
{
  char buffer[42];
  char buffer2[sizeof(buffer)]; /* Compliant */

  memcpy(buffer, "Hello, world!", strlen("Hello, world!")+1);
  memcpy(buffer2, buffer, sizeof(buffer));

  return 0;
}
cpp:TabCharacter

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

csharpsquid:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

csharpsquid:S105

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

csharpsquid:S1067

The complexity of an expression is defined by the number of &&, || and condition ? ifTrue : ifFalse operators it contains.

A single expression's complexity should not become too high to keep the code readable.

Noncompliant Code Example

With the default threshold value of 3

if (((condition1 && condition2) || (condition3 && condition4)) && condition5) { ... }

Compliant Solution

if ((MyFirstCondition() || MySecondCondition()) && MyLastCondition()) { ... }
csharpsquid:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

Noncompliant Code Example

With a maximum number of 4 parameters:

public void doSomething(int param1, int param2, int param3, string param4, long param5)
{
...
}

Compliant Solution

public void doSomething(int param1, int param2, int param3, string param4)
{
...
}
csharpsquid:S108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

for (int i = 0; i < 42; i++){}  // Empty on purpose or missing piece of code ?

Exceptions

When a block contains a comment, this block is not considered to be empty.

csharpsquid:S109

A magic number is a number that comes out of nowhere, and is directly used in a statement. Magic numbers are often used, for instance to limit the number of iterations of a loops, to test the value of a property, etc.

Using magic numbers may seem obvious and straightforward when you're writing a piece of code, but they are much less obvious and straightforward at debugging time.

That is why magic numbers must be demystified by first being assigned to clearly named variables before being used.

-1, 0 and 1 are not considered magic numbers.

Noncompliant Code Example

public static void DoSomething()
{
    for(int i = 0; i < 4; i++)  // Noncompliant, 4 is a magic number
    {
        ...
    }
}

Compliant Solution

private const int NUMBER_OF_CYCLES = 4;

public static void DoSomething()
{
    for(int i = 0; i < NUMBER_OF_CYCLES ; i++)  //Compliant
    {
        ...
    }
}

Exceptions

This rule doesn't raise an issue when the magic number is used as part of the GetHashCode method or a variable/field declaration.

csharpsquid:S110

Inheritance is certainly one of the most valuable concepts in object-oriented programming. It's a way to compartmentalize and reuse code by creating collections of attributes and behaviors called classes which can be based on previously created classes. But abusing this concept by creating a deep inheritance tree can lead to very complex and unmaintainable source code. Most of the time a too deep inheritance tree is due to bad object oriented design which has led to systematically use 'inheritance' when for instance 'composition' would suit better.

This rule raises an issue when the inheritance tree, starting from Object has a greater depth than is allowed.

csharpsquid:S1104

Public fields in public classes do not respect the encapsulation principle and has three main disadvantages:

  • Additional behavior such as validation cannot be added.
  • The internal representation is exposed, and cannot be changed afterwards.
  • Member values are subject to change from anywhere in the code and may not meet the programmer's assumptions.

By using private fields and public properties (set and get), unauthorized modifications are prevented. Properties also benefit from additional protection (security) features such as Link Demands.

Note that due to optimizations on simple properties, public fields provide only very little performance gain.

Noncompliant Code Example

public class Foo
{
    public int instanceData = 32; // Noncompliant
}

Compliant Solution

public class Foo
{
    private int instanceData = 32;

    public int InstanceData
    {
        get { return instanceData; }
	set { instanceData = value ; }
    }
}

Exceptions

Fields marked as readonly or const are ignored by this rule.

Fields inside classes or structs annotated with the StructLayoutAttribute are ignored by this rule.

See

csharpsquid:S1109

Shared coding conventions make it possible for a team to efficiently collaborate. This rule makes it mandatory to place a close curly brace at the beginning of a line.

Noncompliant Code Example

if(condition)
{
  doSomething();}

Compliant Solution

if(condition)
{
  doSomething();
}

Exceptions

When blocks are inlined (open and close curly braces on the same line), no issue is triggered.

if(condition) {doSomething();}
csharpsquid:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

if (a && ((x + y > 0))) // Noncompliant
{
  //...
}

return ((x + 1));  // Noncompliant

Compliant Solution

if (a && (x + y > 0))
{
  //...
}

return x + 1;

return (x + 1);
csharpsquid:S1118

Utility classes, which are collections of static members, are not meant to be instantiated.

C# adds an implicit public constructor to every class which does not explicitly define at least one constructor. Hence, at least one protected constructor should be defined if you wish to subclass this utility class. Or the static keyword should be added to the class declaration to prevent subclassing.

Noncompliant Code Example

public class StringUtils // Noncompliant
{
  public static string Concatenate(string s1, string s2)
  {
    return s1 + s2;
  }
}

Compliant Solution

public static class StringUtils
{
  public static string Concatenate(string s1, string s2)
  {
    return s1 + s2;
  }
}

or

public class StringUtils
{
  protected StringUtils()
  {
  }
  public static string Concatenate(string s1, string s2)
  {
    return s1 + s2;
  }
}
csharpsquid:S1123

The Obsolete attribute can be applied with or without arguments, but marking something Obsolete without including advice as to why it's obsolete or on what to use instead will lead maintainers to waste time trying to figure those things out - every single time the warning is encountered.

Noncompliant Code Example

public class Car
{

  [Obsolete]  // Noncompliant
  public void CrankEngine(int turnsOfCrank)
  { ... }
}

Compliant Solution

public class Car
{

  [Obsolete("Replaced by the automatic starter")]
  public void CrankEngine(int turnsOfCrank)
  { ... }
}
csharpsquid:S1125

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

Noncompliant Code Example

if (booleanMethod() == true) { /* ... */ }
if (booleanMethod() == false) { /* ... */ }
if (booleanMethod() || false) { /* ... */ }
doSomething(!false);
doSomething(booleanMethod() == true);

booleanVariable = booleanMethod() ? true : false;
booleanVariable = booleanMethod() ? true : exp;
booleanVariable = booleanMethod() ? false : exp;
booleanVariable = booleanMethod() ? exp : true;
booleanVariable = booleanMethod() ? exp : false;

for (var x = 0; true; x++)
{
 ...
}

Compliant Solution

if (booleanMethod()) { /* ... */ }
if (!booleanMethod()) { /* ... */ }
if (booleanMethod()) { /* ... */ }
doSomething(true);
doSomething(booleanMethod());

booleanVariable = booleanMethod();
booleanVariable = booleanMethod() || exp;
booleanVariable = !booleanMethod() && exp;
booleanVariable = !booleanMethod() || exp;
booleanVariable = booleanMethod() && exp;

for (var x = 0; ; x++)
{
 ...
}
csharpsquid:S113

Some tools work better when files end with an empty line.

This rule simply generates an issue if it is missing.

For example, a Git diff looks like this if the empty line is missing at the end of the file:

+class Test
+{
+}
\ No newline at end of file
csharpsquid:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

private void DoSomething()
{
  // TODO
}

See

csharpsquid:S1151

The switch statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the case clause should be extracted into a dedicated method.

Noncompliant Code Example

With the default threshold of 3:

switch (myVariable)
{
    case 0: // Noncompliant: 5 statements in the case
        methodCall1("");
        methodCall2("");
        methodCall3("");
        methodCall4("");
        break;
    case 1:
        ...
}

Compliant Solution

switch (myVariable)
{
    case 0:
        DoSomething()
        break;
    case 1:
        ...
}
...
private void DoSomething()
{
    methodCall1("");
    methodCall2("");
    methodCall3("");
    methodCall4("");
}
csharpsquid:S1155

Using .Count() to test for emptiness works, but using .Any() makes the intent clearer, and the code more readable. However, there are some cases where special attention should be paid:

- if the collection is an EntityFramework or other ORM query, calling .Count() will cause executing a potentially massive SQL query and could put a large overhead on the application database. Calling .Any() will also connect to the database, but will generate much more efficient SQL.

- if the collection is part of a LINQ query that contains .Select() statements that create objects, a large amount of memory could be unnecessarily allocated. Calling .Any() will be much more efficient because it will execute fewer iterations of the enumerable.

Noncompliant Code Example

private static bool HasContent(IEnumerable<string> strings)
{
  return strings.Count() > 0;  // Noncompliant
}

private static bool HasContent2(IEnumerable<string> strings)
{
  return strings.Count() >= 1;  // Noncompliant
}

private static bool IsEmpty(IEnumerable<string> strings)
{
  return strings.Count() == 0;  // Noncompliant
}

Compliant Solution

private static bool HasContent(IEnumerable<string> strings)
{
  return strings.Any();
}

private static bool IsEmpty(IEnumerable<string> strings)
{
  return !strings.Any();
}
csharpsquid:S1185

Overriding a method just to call the same method from the base class without performing any other actions is useless and misleading. The only time this is justified is in sealed overriding methods, where the effect is to lock in the parent class behavior. This rule ignores overrides of Equals and GetHashCode.

NOTE: In some cases it might be dangerous to add or remove empty overrides, as they might be breaking changes.

Noncompliant Code Example

public override void Method() // Noncompliant
{
  base.Method();
}

Compliant Solution

public override void Method()
{
  //do something else
}

Exceptions

If there is an attribute in any level of the overriding chain, then the overridden member is ignored.

public class Base
{
  [Required]
  public virtual string Name { get; set; }
}

public class Derived : Base
{
  public override string Name
  {
    get
    {
      return base.Name;
    }
    set
    {
      base.Name = value;
    }
  }
}

If there is a documentation comment on the overriding method, it will be ignored:

public class Foo : Bar
{
    /// <summary>
    /// Keep this method for backwards compatibility.
    /// </summary>
    public override void DoSomething()
    {
        base.DoSomething();
    }
}
csharpsquid:S1186

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

  • It is an unintentional omission, and should be fixed.
  • It is not yet, or never will be, supported. In this case a NotSupportedException should be thrown.
  • The method is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.

Noncompliant Code Example

public override void DoSomething()
{
}

public override void DoSomethingElse()
{
}

Compliant Solution

public override void DoSomething()
{
  // Do nothing because of X and Y.
}

public override void DoSomethingElse()
{
  throw new NotSupportedException();
}

Exceptions

The following methods are ignored:

  • empty virtual methods,
  • empty methods that override an abstract method,
  • empty overrides in test assemblies.
csharpsquid:S1192

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

public class Foo
{
    private string name = "foobar"; // Noncompliant

    public string DefaultName { get; } = "foobar"; // Noncompliant

    public Foo(string value = "foobar") // Noncompliant
    {
        var something = value ?? "foobar"; // Noncompliant
    }
}

Compliant Solution

public class Foo
{
    private const string Foobar = "foobar";

    private string name = Foobar;

    public string DefaultName { get; } = Foobar;

    public Foo(string value = Foobar)
    {
        var something = value ?? Foobar;
    }
}

Exceptions

The following are ignored:

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

According to the Single Responsibility Principle, introduced by Robert C. Martin in his book "Principles of Object Oriented Design", a class should have only one responsibility:

If a class has more than one responsibility, then the responsibilities become coupled.

Changes to one responsibility may impair or inhibit the class' ability to meet the others.

This kind of coupling leads to fragile designs that break in unexpected ways when changed.

Classes which rely on many other classes tend to aggregate too many responsibilities and should be split into several smaller ones.

Nested classes dependencies are not counted as dependencies of the outer class.

Noncompliant Code Example

With a threshold of 5:

public class Foo    // Noncompliant - Foo depends on too many classes: T1, T2, T3, T4, T5, T6 and T7
{
  private T1 a1;    // Foo is coupled to T1
  private T2 a2;    // Foo is coupled to T2
  private T3 a3;    // Foo is coupled to T3

  public T4 Compute(T5 a, T6 b)    // Foo is coupled to T4, T5 and T6
  {
    T7 result = a.Process(b);    // Foo is coupled to T7
    return result;
  }

  public static class Bar    // Compliant - Bar depends on 2 classes: T8 and T9
  {
    public T8 a8;
    public T9 a9;
  }
}
csharpsquid:S1210

When you implement IComparable or IComparable<T> on a class you should also override Equals(object) and overload the comparison operators (==, !=, <, <=, >, >=). That's because the CLR cannot automatically call your CompareTo implementation from Equals(object) or from the base comparison operator implementations. Additionally, it is best practice to override GetHashCode along with Equals.

This rule raises an issue when a class implements IComparable without also overriding Equals(object) and the comparison operators.

Noncompliant Code Example

public class Foo: IComparable  // Noncompliant
{
  public int CompareTo(object obj) { /* ... */ }
}

Compliant Solution

public class Foo: IComparable
{
  public int CompareTo(object obj) { /* ... */ }
  public override bool Equals(object obj)
  {
    var other = obj as Foo;
    if (object.ReferenceEquals(other, null))
    {
      return false;
    }
    return this.CompareTo(other) == 0;
  }
  public int GetHashCode() { /* ... */ }
  public static bool operator == (Foo left, Foo right)
  {
    if (object.ReferenceEquals(left, null))
    {
      return object.ReferenceEquals(right, null);
    }
    return left.Equals(right);
  }
  public static bool operator > (Foo left, Foo right)
  {
    return Compare(left, right) > 0;
  }
  public static bool operator < (Foo left, Foo right)
  {
    return Compare(left, right) < 0;
  }
  public static bool operator != (Foo left, Foo right)
  {
    return !(left == right);
  }
}
csharpsquid:S122

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

if(someCondition) DoSomething();

Compliant Solution

if(someCondition)
{
  DoSomething();
}

Exceptions

Anonymous functions containing a single statement are ignored. Block statements are not considered either.

Func<object, bool> item1 = o => { return true; }; // Compliant
Func<object, bool> item1 = o => { var r = false; return r; }; // Noncompliant
csharpsquid:S1227

break; is an unstructured control flow statement which makes code harder to read.

Ideally, every loop should have a single termination condition.

Noncompliant Code Example

int i = 0;
while (true)
{
  if (i == 10)
  {
    break;      // Non-Compliant
  }

  Console.WriteLine(i);
  i++;
}

Compliant Solution

int i = 0;
while (i != 10) // Compliant
{
  Console.WriteLine(i);
  i++;
}
csharpsquid:S1264

When only the condition expression is defined in a for loop, and the initialization and increment expressions are missing, a while loop should be used instead to increase readability.

Noncompliant Code Example

for (;condition;) { /*...*/ }

Compliant Solution

while (condition) { /*...*/ }
csharpsquid:S1309

This rule allows you to track the usage of the SuppressMessage attributes and #pragma warning disable mechanism.

Noncompliant Code Example

[SuppressMessage("", "S100")]
...

#pragma warning disable S100
...
#pragma warning restore S100
csharpsquid:S134

Nested if, switch, for, foreach, 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:

if (condition1) // Compliant - depth = 1
{
  /* ... */
  if (condition2) // Compliant - depth = 2
  {
    /* ... */
    for(int i = 0; i < 10; i++) // Compliant - depth = 3, not exceeding the limit
    {
      /* ... */
      if (condition4) // Noncompliant - depth = 4
      {
        if (condition5) // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
        {
          /* ... */
        }
        return;
      }
    }
  }
}
csharpsquid:S138

A function that grows too large tends to aggregate too many responsibilities.

Such functions inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions which focus on well-defined tasks.

Those smaller functions will not only be easier to understand, but also probably easier to test.

csharpsquid:S1450

When the value of a private field is always assigned to in a class' methods before being read, then it is not being used to store class information. Therefore, it should become a local variable in the relevant methods to prevent any misunderstanding.

Noncompliant Code Example

public class Foo
{
  private int singularField;

  public void DoSomething(int x)
  {
    singularField = x + 5;

    if (singularField == 0) { /* ... */ }
  }
}

Compliant Solution

public class Foo
{
  public void DoSomething(int x)
  {
    int localVariable = x + 5;

    if (localVariable == 0) { /* ... */ }
  }
}
csharpsquid:S1479

When switch statements have large sets of case clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

Exceptions

This rule ignores switches over Enums and empty, fall-through cases.

csharpsquid:S1481

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

public int NumberOfMinutes(int hours)
{
  int seconds = 0;   // seconds is never used
  return hours * 60;
}

Compliant Solution

public int NumberOfMinutes(int hours)
{
  return hours * 60;
}

Exceptions

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

using(var t = new TestTimer()) // t never used, but compliant.
{
  //...
}
csharpsquid:S1541

The cyclomatic complexity of methods and properties should not exceed a defined threshold. Complex code can perform poorly and will in any case be difficult to understand and therefore to maintain.

csharpsquid:S1607

When a test fails due, for example, to infrastructure issues, you might want to ignore it temporarily. But without some kind of notation about why the test is being ignored, it may never be reactivated. Such tests are difficult to address without comprehensive knowledge of the project, and end up polluting their projects.

This rule raises an issue for each ignored test that does not have a WorkItem attribute nor a comment about why it is being skipped on the right side of the Ignore attribute.

Noncompliant Code Example

[TestMethod]
[Ignore]  // Noncompliant
public void Test_DoTheThing()
{
  // ...
}

Compliant Solution

[TestMethod]
[Ignore]  // renable when TCKT-1234 is fixed
public void Test_DoTheThing()
{
  // ...
}

or

[TestMethod]
[Ignore]
[WorkItem(1234)]
public void Test_DoTheThing()
{
  // ...
}

Exceptions

The rule doesn't raise an issue if:

- the test method is also marked with WorkItem attribute

- there is a comment on the right side of the Ignore attribute

csharpsquid:S1643

StringBuilder is more efficient than string concatenation, especially when the operator is repeated over and over as in loops.

Noncompliant Code Example

string str = "";
for (int i = 0; i < arrayOfStrings.Length ; ++i)
{
  str = str + arrayOfStrings[i];
}

Compliant Solution

StringBuilder bld = new StringBuilder();
for (int i = 0; i < arrayOfStrings.Length; ++i)
{
  bld.Append(arrayOfStrings[i]);
}
string str = bld.ToString();
csharpsquid:S1694

The purpose of an abstract class is to provide some heritable behaviors while also defining methods which must be implemented by sub-classes.

A class with no abstract methods that was made abstract purely to prevent instantiation should be converted to a concrete class (i.e. remove the abstract keyword) with a protected constructor.

A class with only abstract methods and no inheritable behavior should be converted to an interface.

Noncompliant Code Example

public abstract class Animal //Noncompliant; should be an interface
{
  abstract void Move();
  abstract void Feed();
}

public abstract class Color //Noncompliant; should be concrete with a private constructor
{
  private int red = 0;
  private int green = 0;
  private int blue = 0;

  public int GetRed()
  {
    return red;
  }
}

Compliant Solution

public interface Animal
{
  void Move();
  void Feed();
}

public class Color
{
  private int red = 0;
  private int green = 0;
  private int blue = 0;

  protected Color()
  {}

  public int GetRed()
  {
    return red;
  }
}

public abstract class Lamp
{
  private bool switchLamp = false;

  public abstract void Glow();

  public void FlipSwitch()
  {
    switchLamp = !switchLamp;
    if (switchLamp)
    {
      Glow();
    }
  }
}
csharpsquid:S1697

When either the equality operator in a null test or the logical operator that follows it is reversed, the code has the appearance of safely null-testing the object before dereferencing it. Unfortunately the effect is just the opposite - the object is null-tested and then dereferenced only if it is null, leading to a guaranteed null pointer dereference.

Noncompliant Code Example

if (str == null && str.Length == 0)
{
  Console.WriteLine("String is empty");
}

if (str != null || str.Length > 0)
{
  Console.WriteLine("String is not empty");
}

Compliant Solution

if (str == null || str.Length == 0)
{
  Console.WriteLine("String is empty");
}

if (str != null && str.Length > 0)
{
  Console.WriteLine("String is not empty");
}

Deprecated

This rule is deprecated; use S2259 instead.

csharpsquid:S1821

Nested switch structures are difficult to understand because you can easily confuse the cases of an inner switch as belonging to an outer statement. Therefore nested switch statements should be avoided.

Specifically, you should structure your code to avoid the need for nested switch statements, but if you cannot, then consider moving the inner switch to another function.

csharpsquid:S1848

There is no good reason to create a new object to not do anything with it. Most of the time, this is due to a missing piece of code and so could lead to an unexpected behavior in production.

If it was done on purpose because the constructor has side-effects, then that side-effect code should be moved into a separate, static method and called directly.

Noncompliant Code Example

if (x < 0)
  new ArgumentException("x must be nonnegative");

Compliant Solution

if (x < 0)
  throw new ArgumentException("x must be nonnegative");
csharpsquid:S1858

Invoking a method designed to return a string representation of an object which is already a string is a waste of keystrokes. Similarly, explicitly invoking ToString() when the compiler would do it implicitly is also needless code-bloat.

This rule raises an issue when ToString() is invoked:

  • on a string
  • on a non-string operand to concatenation
  • on an argument to string.Format

Noncompliant Code Example

var s = "foo";
var t = "fee fie foe " + s.ToString();  // Noncompliant
var someObject = new object();
var u = "" + someObject.ToString(); // Noncompliant
var v = string.Format("{0}", someObject.ToString()); // Noncompliant

Compliant Solution

var s = "foo";
var t = "fee fie foe " + s;
var someObject = new object();
var u = "" + someObject;
var v = string.Format("{0}", someObject);

Exceptions

The rule does not report on value types, where leaving off the ToString() call would result in automatic boxing.

var v = string.Format("{0}", 1.ToString());
csharpsquid:S1871

Having two cases in the same switch 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 switch, one should fall through to the other.

Noncompliant Code Example

switch (i)
{
  case 1:
    DoFirst();
    DoSomething();
    break;
  case 2:
    DoSomethingDifferent();
    break;
  case 3:  // Noncompliant; duplicates case 1's implementation
    DoFirst();
    DoSomething();
    break;
  default:
    DoTheRest();
}

if (a >= 0 && a < 10)
{
  DoFirst();
  DoTheThing();
}
else if (a >= 10 && a < 20)
{
  DoTheOtherThing();
}
else if (a >= 20 && a < 50)   // Noncompliant; duplicates first condition
{
  DoFirst();
  DoTheThing();
}

Exceptions

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a switch statement that contain a single line of code with or without a following break.

if (a >= 0 && a < 10)
{
  DoTheThing();
}
else if (a >= 10 && a < 20)
{
  DoTheOtherThing();
}
else if (a >= 20 && a < 50)    //no issue, usually this is done on purpose to increase the readability
{
  DoTheThing();
}

But this exception does not apply to if chains without else-s, or to switch-es without default clauses when all branches have the same single line of code. In case of if chains with else-s, or of switch-es with default clauses, rule S3923 raises a bug.

if(a == 1)
{
  doSomething();  //Noncompliant, this might have been done on purpose but probably not
}
else if (a == 2)
{
  doSomething();
}
csharpsquid:S1939

An inheritance list entry is redundant if:

  • It is Object - all classes extend Object implicitly.
  • It is int for an enum
  • It is a base class of another listed inheritance.

Such redundant declarations should be removed because they needlessly clutter the code and can be confusing.

Noncompliant Code Example

public class MyClass : Object  // Noncompliant

enum MyEnum : int  // Noncompliant

Compliant Solution

public class MyClass

enum MyEnum
csharpsquid:S1940

It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.

Noncompliant Code Example

if ( !(a == 2)) { ...}  // Noncompliant
bool b = !(i < 10);  // Noncompliant

Compliant Solution

if (a != 2) { ...}
bool b = (i >= 10);
csharpsquid:S1994

It can be extremely confusing when a for loop's counter is incremented outside of its increment clause. In such cases, the increment should be moved to the loop's increment clause if at all possible.

Noncompliant Code Example

for (i = 0; i < 10; j++) // Noncompliant
{
  // ...
}

Compliant Solution

for (i = 0; i < 10; i++)
{
  // ...
}
csharpsquid:S2114

Passing a collection as an argument to the collection's own method is either an error - some other argument was intended - or simply nonsensical code.

Further, because some methods require that the argument remain unmodified during the execution, passing a collection to itself can result in an unexpected behavior.

Noncompliant Code Example

var list = new List<int>();

list.AddRange(list); // Noncompliant
list.Concat(list); // Noncompliant

list.Union(list); // Noncompliant; always returns list
list.Except(list); // Noncompliant; always empty
list.Intersect(list); // Noncompliant; always list
list.SequenceEqual(list); // Noncompliant; always true

var set = new HashSet<int>();
set.UnionWith(set); // Noncompliant; no changes
set.ExceptWith(set); // Noncompliant; always empty
set.IntersectWith(set); // Noncompliant; no changes
set.IsProperSubsetOf(set); // Noncompliant; always false
set.IsProperSupersetOf(set); // Noncompliant; always false
set.IsSubsetOf(set); // Noncompliant; always true
set.IsSupersetOf(set); // Noncompliant; always true
set.Overlaps(set); // Noncompliant; always true
set.SetEquals(set); // Noncompliant; always true
set.SymmetricExceptWith(set); // Noncompliant; always empty
csharpsquid:S2123

A value that is incremented or decremented and then not stored is at best wasted code and at worst a bug.

Noncompliant Code Example

public int PickNumber()
{
  int i = 0;
  int j = 0;

  i = i++; // Noncompliant; i is still zero

  return j++; // Noncompliant; 0 returned
}

Compliant Solution

public int PickNumber()
{
  int i = 0;
  int j = 0;

  i++;
  return ++j;
}
csharpsquid:S2156

The difference between private and protected visibility is that child classes can see and use protected members, but they cannot see private ones. Since a sealed class cannot have children, marking its members protected is confusingly pointless.

Noncompliant Code Example

public sealed class MySealedClass
{
    protected string name = "Fred";  // Noncompliant
    protected void SetName(string name) // Noncompliant
    {
        // ...
    }
}

Compliant Solution

public sealed class MySealedClass
{
    private string name = "Fred";
    public void SetName(string name)
    {
        // ...
    }
}
csharpsquid:S2221

Catching System.Exception seems like an efficient way to handle multiple possible exceptions. Unfortunately, it traps all exception types, including the ones that were not intended to be caught. To prevent any misunderstandings, the exception filters should be used. Alternatively each exception type should be in a separate catch block.

Noncompliant Code Example

try
{
  // do something that might throw a FileNotFoundException or IOException
}
catch (Exception e) // Noncompliant
{
  // log exception ...
}

Compliant Solution

try
{
  // do something
}
catch (Exception e) when (e is FileNotFoundException || e is IOException)
{
  // do something
}

Exceptions

The final option is to catch System.Exception and throw it in the last statement in the catch block. This is the least-preferred option, as it is an old-style code, which also suffers from performance penalty compared to exception filters.

try
{
  // do something
}
catch (Exception e)
{
  if (e is FileNotFoundException || e is IOException)
  {
    // do something
  }
  else
  {
    throw;
  }
}

See

csharpsquid:S2223

A static field that is neither constant nor read-only is not thread-safe. Correctly accessing these fields from different threads needs synchronization with locks. Improper synchronization may lead to unexpected results, thus publicly visible static fields are best suited for storing non-changing data shared by many consumers. To enforce this intent, these fields should be marked readonly or converted to constants.

Noncompliant Code Example

public class Math
{
  public static double Pi = 3.14;  // Noncompliant
}

or

public class Shape
{
  public static Shape Empty = new EmptyShape();  // Noncompliant

  private class EmptyShape : Shape
  {
  }
}

Compliant Solution

public class Math
{
  public const double Pi = 3.14;
}

or

public class Shape
{
  public static readonly Shape Empty = new EmptyShape();

  private class EmptyShape : Shape
  {
  }
}
csharpsquid:S2290

Field-like events are events that do not have explicit add and remove methods. The compiler generates a private delegate field to back the event, as well as generating the implicit add and remove methods.

When a virtual field-like event is overridden by another field-like event, the behavior of the C# compiler is to generate a new private delegate field in the derived class, separate from the parent's field. This results in multiple and separate events being created, which is rarely what's actually intended.

To prevent this, remove the virtual designation from the parent class event.

Noncompliant Code Example

abstract class Car
{
  public virtual event EventHandler OnRefueled; // Noncompliant

  public void Refuel()
  {
    // This OnRefueld will always be null
     if (OnRefueled != null)
     {
       OnRefueled(this, null);
     }
  }
}

class R2 : Car
{
  public override event EventHandler OnRefueled;
}

class Program
{
  static void Main(string[] args)
  {
    var r2 = new R2();
    r2.OnRefueled += new EventHandler((o, a) =>
    {
      Console.WriteLine("This event will never be called");
    });
    r2.Refuel();
  }
}

Compliant Solution

abstract class Car
{
  public event EventHandler OnRefueled; // Compliant

  public void Refuel()
  {
    if (OnRefueled != null)
    {
      OnRefueled(this, null);
    }
  }
}

class R2 : Car {}

class Program
{
  static void Main(string[] args)
  {
    var r2 = new R2();
    r2.OnRefueled += new EventHandler((o, a) =>
    {
      Console.WriteLine("This event will be called");
    });
    r2.Refuel();
  }
}
csharpsquid:S2291

Enumerable.Sum() always executes addition in a checked context, so an OverflowException will be thrown if the value exceeds MaxValue even if an unchecked context was specified. Using an unchecked context anyway represents a misunderstanding of how Sum works.

This rule raises an issue when an unchecked context is specified for a Sum on integer types.

Noncompliant Code Example

void Add(List<int> list)
{
  int d = unchecked(list.Sum());  // Noncompliant

  unchecked
  {
    int e = list.Sum();  // Noncompliant
  }
}

Compliant Solution

void Add(List<int> list)
{
  int d = list.Sum();

  try
  {
    int e = list.Sum();
  }
  catch (System.OverflowException e)
  {
    // exception handling...
  }
}

Exceptions

When the Sum() call is inside a try-catch block, no issues are reported.

void Add(List<int> list)
{
  unchecked
  {
    try
    {
      int e = list.Sum();
    }
    catch (System.OverflowException e)
    {
      // exception handling...
    }
  }
}
csharpsquid:S2292

Trivial properties, which include no logic but setting and getting a backing field should be converted to auto-implemented properties, yielding cleaner and more readable code.

Noncompliant Code Example

public class Car
{
  private string _make;
  public string Make // Noncompliant
  {
    get { return _make; }
    set { _make = value; }
  }
}

Compliant Solution

public class Car
{
  public string Make { get; set; }
}
csharpsquid:S2302

Because parameter names could be changed during refactoring, they should not be spelled out literally in strings. Instead, use nameof(), and the string that's output will always be correct.

This rule raises an issue when any string in the throw statement is an exact match for the name of one of the method parameters.

Noncompliant Code Example

void DoSomething(int someParameter)
{
    if (someParameter < 0)
    {
        throw new ArgumentException("Bad argument", "someParameter");  // Noncompliant
    }
}

Compliant Solution

void DoSomething(int someParameter)
{
    if (someParameter < 0)
    {
        throw new ArgumentException("Bad argument", nameof(someParameter));
    }
}

Exceptions

The rule doesn't raise any issue when using C# < 6.0.

csharpsquid:S2306

Since C# 5.0, async and await are contextual keywords. Contextual keywords do have a particular meaning in some contexts, but can still be used as variable names. Keywords, on the other hand, are always reserved, and therefore are not valid variable names. To avoid any confusion though, it is best to not use async and await as identifiers.

Noncompliant Code Example

int await = 42; // Noncompliant

Compliant Solution

int someOtherName = 42;
csharpsquid:S2328

GetHashCode is used to file an object in a Dictionary or Hashtable. If GetHashCode uses non-readonly fields and those fields change after the object is stored, the object immediately becomes mis-filed in the Hashtable. Any subsequent test to see if the object is in the Hashtable will return a false negative.

Noncompliant Code Example

public class Person
{
  public int age;
  public string name;

  public override int GetHashCode()
  {
    int hash = 12;
    hash += this.age.GetHashCode(); // Noncompliant
    hash += this.name.GetHashCode(); // Noncompliant
    return hash;
  }

Compliant Solution

public class Person
{
  public readonly DateTime birthday;
  public string name;

  public override int GetHashCode()
  {
    int hash = 12;
    hash += this.birthday.GetHashCode();
    return hash;
  }
csharpsquid:S2330

Array covariance is the principle that if an implicit or explicit reference conversion exits from type A to B, then the same conversion exists from the array type A[] to B[].

While this array conversion can be useful in readonly situations to pass instances of A[] where B[] is expected, it must be used with care, since assigning an instance of B into an array of A will cause an ArrayTypeMismatchException to be thrown at runtime.

Noncompliant Code Example

abstract class Fruit { }
class Apple : Fruit { }
class Orange : Fruit { }

class Program
{
  static void Main(string[] args)
  {
    Fruit[] fruits = new Apple[1]; // Noncompliant - array covariance is used
    FillWithOranges(fruits);
  }

  // Just looking at the code doesn't reveal anything suspicious
  static void FillWithOranges(Fruit[] fruits)
  {
    for (int i = 0; i < fruits.Length; i++)
    {
      fruits[i] = new Orange(); // Will throw an ArrayTypeMismatchException
    }
  }
}

Compliant Solution

abstract class Fruit { }
class Apple : Fruit { }
class Orange : Fruit { }

class Program
{
  static void Main(string[] args)
  {
    Orange[] fruits = new Orange[1]; // Compliant
    FillWithOranges(fruits);
  }

  static void FillWithOranges(Orange[] fruits)
  {
    for (int i = 0; i < fruits.Length; i++)
    {
      fruits[i] = new Orange();
    }
  }
}
csharpsquid:S2333

Unnecessary keywords simply clutter the code and should be removed. Specifically:

  • partial on type declarations that are completely defined in one place
  • sealed on members of sealed classes
  • unsafe method or block inside construct already marked with unsafe, or when there are no unsafe constructs in the block
  • checked and unchecked blocks with no integral-type arithmetic operations

Noncompliant Code Example

public partial class MyClass // Noncompliant
{
  public virtual void Method()
  {
  }
}

public sealed class MyOtherClass : MyClass
{
  public sealed override void Method() // Noncompliant
  {
  }
}

Compliant Solution

public class MyClass
{
  public virtual void Method()
  {
  }
}

public sealed class MyOtherClass : MyClass
{
  public override void Method()
  {
  }
}
csharpsquid:S2339

Constant members are copied at compile time to the call sites, instead of being fetched at runtime.

As an example, say you have a library with a constant Version member set to 1.0, and a client application linked to it. This library is then updated and Version is set to 2.0. Unfortunately, even after the old DLL is replaced by the new one, Version will still be 1.0 for the client application. In order to see 2.0, the client application would need to be rebuilt against the new version of the library.

This means that you should use constants to hold values that by definition will never change, such as Zero. In practice, those cases are uncommon, and therefore it is generally better to avoid constant members.

This rule only reports issues on public constant fields, which can be reached from outside the defining assembly.

Noncompliant Code Example

public class Foo
{
    public const double Version = 1.0;           // Noncompliant
}

Compliant Solution

public class Foo
{
    public static double Version
    {
      get { return 1.0; }
    }
}
csharpsquid:S2342

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all enum names match a provided regular expression.

The default configuration is the one recommended by Microsoft:

  • Pascal casing, starting with an upper case character, e.g. BackColor
  • Short abbreviations of 2 letters can be capitalized, e.g. GetID
  • Longer abbreviations need to be lower case, e.g. GetHtml
  • If the enum is marked as [Flags] then its name should be plural (e.g. MyOptions), otherwise, names should be singular (e.g. MyOption)

Noncompliant Code Example

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

public enum foo // Noncompliant
{
    FooValue = 0
}

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

[Flags]
public enum Option // Noncompliant
{
    None = 0,
    Option1 = 1,
    Option2 = 2
}

Compliant Solution

public enum Foo
{
    FooValue = 0
}
[Flags]
public enum Options
{
    None = 0,
    Option1 = 1,
    Option2 = 2
}
csharpsquid:S2344

The information that an enumeration type is actually an enumeration or a set of flags should not be duplicated in its name.

Noncompliant Code Example

enum FooFlags // Noncompliant
{
    Foo = 1
    Bar = 2
    Baz = 4
}

Compliant Solution

enum Foo
{
    Foo = 1
    Bar = 2
    Baz = 4
}
csharpsquid:S2345

Flags enumerations should not rely on the language to initialize the values of their members. Implicit initialization will set the first member to 0, and increment the value by one for each subsequent member. This implicit behavior does not allow members to be combined using the bitwise or operator in a useful way.

Instead, 0 and powers of two (i.e. 1, 2, 4, 8, 16, ...) should be used to explicitly initialize all the members.

Noncompliant Code Example

[Flags]
enum FruitType    // Noncompliant
{
  None,
  Banana,
  Orange,
  Strawberry
}
class Program
{
    static void Main()
    {
        var bananaAndStrawberry = FruitType.Banana | FruitType.Strawberry;
        // Will display only Strawberry!
        Console.WriteLine(bananaAndStrawberry.ToString());
    }
}

Compliant Solution

[Flags]
enum FruitType
{
  None = 0,
  Banana = 1,
  Orange = 2,
  Strawberry = 4
}
class Program
{
    static void Main()
    {
        var bananaAndStrawberry = FruitType.Banana | FruitType.Strawberry;
        // Will display Banana and Strawberry, as expected.
        Console.WriteLine(bananaAndStrawberry.ToString());
    }
}

Exceptions

The default initialization of 0, 1, 2, 3, 4, ... matches 0, 1, 2, 4, 8 ... in the first three values, so no issue is reported if the first three members of the enumeration is not initialized.

csharpsquid:S2346

Consistent use of "None" in flags enumerations indicates that all flag values are cleared. The value 0 should not be used to indicate any other state, since there is no way to check that the bit 0 is set.

Noncompliant Code Example

[Flags]
enum FruitType
{
    Void = 0,        // Non-Compliant
    Banana = 1,
    Orange = 2,
    Strawberry = 4
}

Compliant Solution

[Flags]
enum FruitType
{
    None = 0,        // Compliant
    Banana = 1,
    Orange = 2,
    Strawberry = 4
}
csharpsquid:S2357

Fields should not be part of an API, and therefore should always be private. Indeed, they cannot be added to an interface for instance, and validation cannot be added later on without breaking backward compatibility. Instead, developers should encapsulate their fields into properties. Explicit property getters and setters can be introduced for validation purposes or to smooth the transition to a newer system.

Noncompliant Code Example

public class Foo
{
  public int MagicNumber = 42;
}

Compliant Solution

public class Foo
{
  public int MagicNumber
  {
    get { return 42; }
  }
}

or

public class Foo
{
  private int MagicNumber = 42;
}

Exceptions

structs are ignored, as are static and const fields in classes.

Further, an issue is only raised when the real accessibility is public, taking into account the class accessibility.

csharpsquid:S2368

Exposing methods with multidimensional array parameters requires developers to have advanced knowledge about the language in order to be able to use them. Moreover, what exactly to pass to such parameters is not intuitive. Therefore, such methods should not be exposed, but can be used internally.

Noncompliant Code Example

public class Program
{
    public void WriteMatrix(int[][] matrix) // Non-Compliant
    {
    }
}

Compliant Solution

public class Matrix
{
    // ...
}

public class Program
{
    public void WriteMatrix(Matrix matrix) // Compliant
    {
    }
}
csharpsquid:S2372

Property getters should be simple operations that are always safe to call. If exceptions need to be thrown, it is best to convert the property to a method.

It is valid to throw exceptions from indexed property getters and from property setters, which are not detected by this rule.

Noncompliant Code Example

public int Foo
{
    get
    {
        throw new Exception(); // Noncompliant
    }
}

Compliant Solution

public int Foo
{
    get
    {
        return 42;
    }
}

Exceptions

No issue is raised when the thrown exception derives from or is of type NotImplementedException, NotSupportedException or InvalidOperationException.

csharpsquid:S2376

Properties with only setters are confusing and counterintuitive. Instead, a property getter should be added if possible, or the property should be replaced with a setter method.

Noncompliant Code Example

class Program
{
    public int Foo  //Non-Compliant
    {
        set
        {
            // ... some code ...
        }
    }
}

Compliant Solution

class Program
{
    private int foo;

    public void SetFoo(int value)
    {
        // ... some code ...
        foo = value;
    }
}

or

class Program
{
  public int Foo { get; set; } // Compliant
}
csharpsquid:S2387

Having a variable with the same name in two unrelated classes is fine, but do the same thing within a class hierarchy and you'll get confusion at best, chaos at worst.

Noncompliant Code Example

public class Fruit
{
  protected Season ripe;
  protected Color flesh;

  // ...
}

public class Raspberry : Fruit
{
  private bool ripe; // Noncompliant
  private static Color FLESH; // Noncompliant
}

Compliant Solution

public class Fruit
{
  protected Season ripe;
  protected Color flesh;

  // ...
}

public class Raspberry : Fruit
{
  private bool ripened;
  private static Color FLESH_COLOR;
}

Exceptions

This rule ignores same-name fields that are static in both the parent and child classes. It also ignores private parent class fields, but in all other such cases, the child class field should be renamed.

public class Fruit
{
  private Season ripe;
  // ...
}

public class Raspberry : Fruit
{
  private Season ripe;  // Compliant as parent field 'ripe' is anyway not visible from Raspberry
  // ...
}
csharpsquid:S2437

Certain bit operations are just silly and should not be performed because their results are predictable.

Specifically, using & -1 with any value will always result in the original value, as will anyValue ^ 0 and anyValue | 0.

csharpsquid:S2692

Most checks against an IndexOf value compare it with -1 because 0 is a valid index. Any checks which look for values >0 ignore the first element, which is likely a bug. If the intent is merely to check inclusion of a value in a string, List, or an array, consider using the Contains method instead.

This rule raises an issue when an IndexOf value retrieved from a string, List, or array is tested against >0.

Noncompliant Code Example

string color = "blue";
string name = "ishmael";

List<string> strings = new List<string>();
strings.Add(color);
strings.Add(name);
string[] stringArray = strings.ToArray();

if (strings.IndexOf(color) > 0) // Noncompliant
{
  // ...
}
if (name.IndexOf("ish") > 0) // Noncompliant
{
  // ...
}
if (name.IndexOf("ae") > 0) // Noncompliant
{
  // ...
}
if (Array.IndexOf(stringArray, color) > 0) // Noncompliant
{
  // ...
}

Compliant Solution

string color = "blue";
string name = "ishmael";

List<string> strings = new List<string> ();
strings.Add(color);
strings.Add(name);
string[] stringArray = strings.ToArray();

if (strings.IndexOf(color) > -1)
{
  // ...
}
if (name.IndexOf("ish") >= 0)
{
  // ...
}
if (name.Contains("ae"))
{
  // ...
}
if (Array.IndexOf(stringArray, color) >= 0)
{
  // ...
}
csharpsquid:S2696

Correctly updating a static field from a non-static method is tricky to get right and could easily lead to bugs if there are multiple class instances and/or multiple threads in play.

This rule raises an issue each time a static field is updated from a non-static method or property.

Noncompliant Code Example

public class MyClass
{
  private static int count = 0;

  public void DoSomething()
  {
    //...
    count++;  // Noncompliant
  }
}
csharpsquid:S2701

There's no reason to use literal boolean values in assertions. Doing so is at best confusing for maintainers, and at worst a bug.

Noncompliant Code Example

bool b = true;
NUnit.Framework.Assert.AreEqual(true, b);
Xunit.Assert.NotSame(true, b);
Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(true, b);
System.Diagnostics.Debug.Assert(true);
csharpsquid:S2743

A static field in a generic type is not shared among instances of different closed constructed types, thus LengthLimitedSingletonCollection<int>.instances and LengthLimitedSingletonCollection<string>.instances will point to different objects, even though instances is seemingly shared among all LengthLimitedSingletonCollection<> generic classes.

If you need to have a static field shared among instances with different generic arguments, define a non-generic base class to store your static members, then set your generic type to inherit from the base class.

Noncompliant Code Example

public class LengthLimitedSingletonCollection<T> where T : new()
{
  protected const int MaxAllowedLength = 5;
  protected static Dictionary<Type, object> instances = new Dictionary<Type, object>(); // Noncompliant

  public static T GetInstance()
  {
    object instance;

    if (!instances.TryGetValue(typeof(T), out instance))
    {
      if (instances.Count >= MaxAllowedLength)
      {
        throw new Exception();
      }
      instance = new T();
      instances.Add(typeof(T), instance);
    }
    return (T)instance;
  }
}

Compliant Solution

public class SingletonCollectionBase
{
  protected static Dictionary<Type, object> instances = new Dictionary<Type, object>();
}

public class LengthLimitedSingletonCollection<T> : SingletonCollectionBase where T : new()
{
  protected const int MaxAllowedLength = 5;

  public static T GetInstance()
  {
    object instance;

    if (!instances.TryGetValue(typeof(T), out instance))
    {
      if (instances.Count >= MaxAllowedLength)
      {
        throw new Exception();
      }
      instance = new T();
      instances.Add(typeof(T), instance);
    }
    return (T)instance;
  }
}

Exceptions

If the static field or property uses a type parameter, then the developer is assumed to understand that the static member is not shared among the closed constructed types.

public class Cache<T>
{
   private static Dictionary<string, T> CacheDictionary { get; set; } // Compliant
}
csharpsquid:S2757

The use of operators pairs ( =+, =- or =! ) where the reversed, single operator was meant (+=, -= or !=) will compile and run, but not produce the expected results.

This rule raises an issue when =+, =-, or =! is used without any spacing between the two operators and when there is at least one whitespace character after.

Noncompliant Code Example

int target = -5;
int num = 3;

target =- num;  // Noncompliant; target = -3. Is that really what's meant?
target =+ num; // Noncompliant; target = 3

Compliant Solution

int target = -5;
int num = 3;

target = -num;  // Compliant; intent to assign inverse value of num is clear
target += num;
csharpsquid:S2758

When the second and third operands of a ternary operator are the same, the operator will always return the same value regardless of the condition. Either the operator itself is pointless, or a mistake was made in coding it.

Noncompliant Code Example

public bool CanVote(Person person)
{
  return person.GetAge() > 18 ? true : true; // Noncompliant; is this what was intended?
}

Compliant Solution

public bool CanVote(Person person)
{
  return person.GetAge() > 18 ? true : false;
  // or even better:
  // return person.GetAge() > 18;
}

Deprecated

This rule is deprecated; use S3923 instead.

csharpsquid:S2760

When the same condition is checked twice in a row, it is either confusing - why have separate checks? - or an error - some other condition should have been checked in the second test.

Noncompliant Code Example

if (a == b)
{
  doTheThing(b);
}
if (a == b) // Noncompliant; is this really what was intended?
{
  doTheThing(c);
}

Compliant Solution

if (a == b)
{
  doTheThing(b);
  doTheThing(c);
}

or

if (a == b)
{
  doTheThing(b);
}
if (b == c)
{
  doTheThing(c);
}

Exceptions

Since it is a common pattern to test a variable, reassign it if it fails the test, then re-test it, that pattern is ignored.

csharpsquid:S2761

Calling the ! or ~ prefix operator twice does nothing: the second invocation undoes the first. Such mistakes are typically caused by accidentally double-tapping the key in question without noticing.

Either this is a bug, if the operator was actually meant to be called once, or misleading if done on purpose.

Noncompliant Code Example

int v1 = 0;
bool v2 = false;

var v3 = !!v1; // Noncompliant
var v4 = ~~v2; // Noncompliant

Compliant Solution

int v1 = 0;
bool v2 = false;

var v3 = !v1;
var v4 = ~v2;
csharpsquid:S2930

When writing managed code, you don't need to worry about allocating or freeing memory: The garbage collector takes care of it. For efficiency reasons, some objects such as Bitmap use unmanaged memory, enabling for example the use of pointer arithmetic. Such objects have potentially huge unmanaged memory footprints, but will have tiny managed ones. Unfortunately, the garbage collector only sees the tiny managed footprint, and fails to reclaim the unmanaged memory (by calling Bitmap's finalizer method) in a timely fashion.

Moreover, memory is not the only system resource which needs to be managed in a timely fashion: The operating system can only handle having so many file descriptors (e.g. FileStream) or sockets (e.g. WebClient) open at any given time. Therefore, it is important to Dispose of them as soon as they are no longer needed, rather than relying on the garbage collector to call these objects' finalizers at some nondeterministic point in the future.

This rule tracks private fields and local variables of the following IDisposable types, which are never disposed, closed, aliased, returned, or passed to other methods.

  • System.IO namespace
    • System.IO.FileStream
    • System.IO.StreamReader
    • System.IO.StreamWriter
  • System.Net namespace
    • System.Net.WebClient
  • System.Net.Sockets namespace
    • System.Net.Sockets.Socket
    • System.Net.Sockets.TcpClient
    • System.Net.Sockets.UdpClient
  • System.Drawing namespace
    • System.Drawing.Image
    • System.Drawing.Bitmap

which are either instantiated directly using the new operator, or using one of the following factory methods:

  • System.IO.File.Create()
  • System.IO.File.Open()
  • System.Drawing.Image.FromFile()
  • System.Drawing.Image.FromStream()

on both private fields and local variables.

Noncompliant Code Example

public class ResourceHolder
{
  private FileStream fs; // Noncompliant; Dispose or Close are never called

  public void OpenResource(string path)
  {
    this.fs = new FileStream(path, FileMode.Open);
  }

  public void WriteToFile(string path, string text)
  {
    var fs = new FileStream(path, FileMode.Open); // Noncompliant
    var bytes = Encoding.UTF8.GetBytes(text);
    fs.Write(bytes, 0, bytes.Length);
  }
}

Compliant Solution

public class ResourceHolder : IDisposable
{
  private FileStream fs;

  public void OpenResource(string path)
  {
    this.fs = new FileStream(path, FileMode.Open);
  }

  public void Dispose()
  {
    this.fs.Dispose();
  }

  public void WriteToFile(string path, string text)
  {
    using (var fs = new FileStream(path, FileMode.Open))
    {
      var bytes = Encoding.UTF8.GetBytes(text);
      fs.Write(bytes, 0, bytes.Length);
    }
  }
}

Exceptions

IDisposable variables returned from a method or passed to other methods are ignored, as are local IDisposables that are initialized with other IDisposables.

public Stream WriteToFile(string path, string text)
{
  var fs = new FileStream(path, FileMode.Open); // Compliant, because it is returned
  var bytes = Encoding.UTF8.GetBytes(text);
  fs.Write(bytes, 0, bytes.Length);
  return fs;
}

public void ReadFromStream(Stream s)
{
  var sr = new StreamReader(s); // Compliant as it would close the underlying stream.
  // ...
}

See

csharpsquid:S2934

While the properties of a readonly reference type field can still be changed after initialization, those of a readonly value field, such as a struct, cannot.

If the member could be either a class or a struct then assignment to its properties could be unreliable, working sometimes but not others.

Noncompliant Code Example

interface IPoint
{
  int X { get; set; }
  int Y { get; set; }
}

class PointManager<T> where T: IPoint
{
  readonly T point;  // this could be a struct
  public PointManager(T point)
  {
    this.point = point;
  }

  public void MovePointVertically(int newX)
  {
    point.X = newX; //Noncompliant; if point is a struct, then nothing happened
    Console.WriteLine(point.X);
  }
}

Compliant Solution

interface IPoint
{
  int X { get; set; }
  int Y { get; set; }
}

class PointManager<T> where T : IPoint
{
  readonly T point;  // this could be a struct
  public PointManager(T point)
  {
    this.point = point;
  }

  public void MovePointVertically(int newX) // assignment has been removed
  {
    Console.WriteLine(point.X);
  }
}

or

interface IPoint
{
  int X { get; set; }
  int Y { get; set; }
}

class PointManager<T> where T : class, IPoint
{
  readonly T point;  // this can only be a class
  public PointManager(T point)
  {
    this.point = point;
  }

  public void MovePointVertically(int newX)
  {
    point.X = newX;  // this assignment is guaranteed to work
    Console.WriteLine(point.X);
  }
}
csharpsquid:S2952

It is possible in an IDisposable to call Dispose on class members from any method, but the contract of Dispose is that it will clean up all unmanaged resources. Move disposing of members to some other method, and you risk resource leaks.

Noncompliant Code Example

public class ResourceHolder : IDisposable
{
  private FileStream fs;
  public void OpenResource(string path)
  {
    this.fs = new FileStream(path, FileMode.Open);
  }
  public void CloseResource()
  {
    this.fs.Close();
  }

  public void CleanUp()
  {
    this.fs.Dispose(); // Noncompliant; Dispose not called in class' Dispose method
  }

  public void Dispose()
  {
    // method added to satisfy demands of interface
  }
}

Compliant Solution

public class ResourceHolder : IDisposable
{
  private FileStream fs;
  public void OpenResource(string path)
  {
    this.fs = new FileStream(path, FileMode.Open);
  }
  public void CloseResource()
  {
    this.fs.Close();
  }

  public void Dispose()
  {
    this.fs.Dispose();
  }
}

See

csharpsquid:S2953

Dispose as a method name should be used exclusively to implement IDisposable.Dispose to prevent any confusion.

It may be tempting to create a Dispose method for other purposes, but doing so will result in confusion and likely lead to problems in production.

Noncompliant Code Example

public class GarbageDisposal
{
  private int Dispose()  // Noncompliant
  {
    // ...
  }
}

Compliant Solution

public class GarbageDisposal : IDisposable
{
  public void Dispose()
  {
    // ...
  }
}

or

public class GarbageDisposal
{
  private int Grind()
  {
    // ...
  }
}

Exceptions

Methods named Dispose and invoked from the IDisposable.Dispose implementation are not reported.

public class GarbageDisposal  :  IDisposable
{
  protected virtual void Dispose(bool disposing)
  {
    //...
  }
  public void Dispose()
  {
    Dispose(true);
    GC.SuppressFinalize(this);
  }
}
csharpsquid:S2955

When constraints have not been applied to restrict a generic type parameter to be a reference type, then a value type, such as a struct, could also be passed. In such cases, comparing the type parameter to null would always be false, because a struct can be empty, but never null. If a value type is truly what's expected, then the comparison should use default(). If it's not, then constraints should be added so that no value type can be passed.

Noncompliant Code Example

private bool IsDefault<T>(T value)
{
  if (value == null) // Noncompliant
  {
    // ...
  }
  // ...
}

Compliant Solution

private bool IsDefault<T>(T value)
{
  if(object.Equals(value, default(T)))
  {
    // ...
  }
  // ...
}

or

private bool IsDefault<T>(T value) where T : class
{
  if (value == null)
  {
    // ...
  }
  // ...
}
csharpsquid:S2971

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

  • 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.

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])

var num = seq6.Count(); // Noncompliant
var arr = seq.ToList().ToArray(); //Noncompliant
var count = seq.ToList().Count(x=>[condition]); //Noncompliant

Compliant Solution

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

var num = seq6.Count;
var arr = seq.ToArray();
var count = seq.Count(x=>[condition]);
csharpsquid:S2995

Using Object.ReferenceEquals to compare the references of two value types simply won't return the expected results most of the time because such types are passed by value, not by reference.

Noncompliant Code Example

public class MyClass
{
  private MyStruct myStruct;

  public void DoSomething(MyStruct s1) {
    int a = 1;
    int b = 1;

    if (Object.ReferenceEquals(myStruct, s1))  // Noncompliant; this can never be true
    {
      // ...
    }
    else if (Object.ReferenceEquals(a,b)) // Noncompliant
    {
      // ...
    }
  }
}
csharpsquid:S2996

When an object has a field annotated with ThreadStatic, that field is shared within a given thread, but unique across threads. Since a class' static initializer is only invoked for the first thread created, it also means that only the first thread will have the expected initial values.

Instead, allow such fields to be initialized to their default values or make the initialization lazy.

Noncompliant Code Example

public class Foo
{
  [ThreadStatic]
  public static object PerThreadObject = new object(); // Noncompliant. Will be null in all the threads except the first one.
}

Compliant Solution

public class Foo
{
  [ThreadStatic]
  public static object _perThreadObject;
  public static object PerThreadObject
  {
    get
    {
      if (_perThreadObject == null)
      {
        _perThreadObject = new object();
      }
      return _perThreadObject;
    }
  }
}
csharpsquid:S2997

Typically you want to use using to create a local IDisposable variable; it will trigger disposal of the object when control passes out of the block's scope. The exception to this rule is when your method returns that IDisposable. In that case using disposes of the object before the caller can make use of it, likely causing exceptions at runtime. So you should either remove using or avoid returning the IDisposable.

Noncompliant Code Example

public FileStream WriteToFile(string path, string text)
{
  using (var fs = File.Create(path)) // Noncompliant
  {
    var bytes = Encoding.UTF8.GetBytes(text);
    fs.Write(bytes, 0, bytes.Length);
    return fs;
  }
}

Compliant Solution

public FileStream WriteToFile(string path, string text)
{
  var fs = File.Create(path);
  var bytes = Encoding.UTF8.GetBytes(text);
  fs.Write(bytes, 0, bytes.Length);
  return fs;
}
csharpsquid:S3005

When a non-static class field is annotated with ThreadStatic, the code seems to show that the field can have different values for different calling threads, but that's not the case, since the ThreadStatic attribute is simply ignored on non-static fields.

So ThreadStatic should either be removed or replaced with a use of the ThreadLocal<T> class, which gives a similar behavior for non-static fields.

Noncompliant Code Example

public class MyClass
{
  [ThreadStatic]  // Noncompliant
  private int count = 0;

  // ...
}

Compliant Solution

public class MyClass
{
  private int count = 0;

  // ...
}

or

public class MyClass
{
  private readonly ThreadLocal<int> count = new ThreadLocal<int>();
  public int Count
  {
    get { return count.Value; }
    set { count.Value = value; }
  }
  // ...
}
csharpsquid:S3010

Assigning a value to a static field in a constructor could cause unreliable behavior at runtime since it will change the value for all instances of the class.

Instead remove the field's static modifier, or initialize it statically.

Noncompliant Code Example

public class Person
{
  private static DateTime dateOfBirth;
  private static int expectedFingers;

  public Person(DateTime birthday)
  {
    dateOfBirth = birthday;  // Noncompliant; now everyone has this birthday
    expectedFingers = 10;  // Noncompliant
  }
}

Compliant Solution

public class Person
{
  private DateTime dateOfBirth;
  private static int expectedFingers = 10;

  public Person(DateTime birthday)
  {
    this.dateOfBirth = birthday;
  }
}
csharpsquid:S3052

The compiler automatically initializes class fields, auto-properties and events to their default values before setting them with any initialization values, so there is no need to explicitly set a member to its default value. Further, under the logic that cleaner code is better code, it's considered poor style to do so.

Noncompliant Code Example

class X
{
  public int field = 0; // Noncompliant
  public object o = null; // Noncompliant
  public object MyProperty { get; set; } = null; // Noncompliant
  public event EventHandler MyEvent = null;  // Noncompliant
}

Compliant Solution

class X
{
  public int field;
  public object o;
  public object MyProperty { get; set; }
  public event EventHandler MyEvent;
}

Exceptions

const fields are ignored.

csharpsquid:S3060

There's no valid reason to test this with is. The only plausible explanation for such a test is that you're executing code in a parent class conditionally based on the kind of child class this is. But code that's specific to a child class should be in that child class, not in the parent.

Noncompliant Code Example

public class JunkFood
{
  public void DoSomething()
  {
    if (this is Pizza) // Noncompliant
    {
      // ...
    } else if (...
  }
}
csharpsquid:S3168

An async method with a void return type is a "fire and forget" method best reserved for event handlers because there's no way to wait for the method's execution to complete and respond accordingly. There's also no way to catch exceptions thrown from the method.

Having an async void method that is not an event handler could mean your program works some times and not others because of timing issues. Instead, async methods should return Task.

This rule raises an issue when non-event handler methods are both async and void.

Noncompliant Code Example

class HttpPrinter
{
  private string content;

  public async void CallNetwork(string url) //Noncompliant
  {
    var client = new HttpClient();
    var response = await client.GetAsync(url);
    content = await response.Content.ReadAsStringAsync();
  }

  public async Task PrintContent(string url)  // works correctly if web request finishes in under 1 second, otherwise content will be null
  {
    CallNetwork(url);
    await Task.Delay(1000);
    Console.Write(content);
  }
}

Compliant Solution

class HttpPrinter
{
  private string content;

  public async Task CallNetwork(string url)
  {
    var client = new HttpClient();
    var response = await client.GetAsync(url);
    content = await response.Content.ReadAsStringAsync();
  }

  public async Task PrintContent(string url)
  {
    await CallNetwork(url); // <----- call changed here. If await is not added warning CS4014 will be triggered
    await Task.Delay(1000);
    Console.Write(content);
  }
}

Exceptions

Event handlers, i.e. methods with two arguments, first one matching object sender and the second being or inheriting from EventArgs, are ignored.

csharpsquid:S3169

There's no point in chaining multiple OrderBy calls in a LINQ; only the last one will be reflected in the result because each subsequent call completely reorders the list. Thus, calling OrderBy multiple times is a performance issue as well, because all of the sorting will be executed, but only the result of the last sort will be kept.

Instead, use ThenBy for each call after the first.

Noncompliant Code Example

var x = personList
  .OrderBy(person => person.Age)
  .OrderBy(person => person.Name)  // Noncompliant
  .ToList();  // x is sorted by Name, not sub-sorted

Compliant Solution

var x = personList
  .OrderBy(person => person.Age)
  .ThenBy(person => person.Name)
  .ToList();
csharpsquid:S3172

In C#, delegates can be added together to chain their execution, and subtracted to remove their execution from the chain.

Subtracting a chain of delegates from another one might yield unexpected results as shown hereunder - and is likely to be a bug.

Noncompliant Code Example

MyDelegate first, second, third, fourth;
first = () => Console.Write("1");
second = () => Console.Write("2");
third = () => Console.Write("3");
fourth = () => Console.Write("4");

MyDelegate chain1234 = first + second + third + fourth; // Compliant - chain sequence = "1234"
MyDelegate chain12 = chain1234 - third - fourth; // Compliant - chain sequence = "12"


MyDelegate chain14 = first + fourth; // creates a new MyDelegate instance which is a list under the covers
MyDelegate chain23 = chain1234 - chain14; // Noncompliant; (first + fourth) doesn't exist in chain1234


// The chain sequence of "chain23" will be "1234" instead of "23"!
// Indeed, the sequence "1234" does not contain the subsequence "14", so nothing is subtracted
// (but note that "1234" contains both the "1" and "4" subsequences)
chain23 = chain1234 - (first + fourth); // Noncompliant

chain23(); // will print "1234"!

Compliant Solution

MyDelegate chain23 = chain1234 - first - fourth; // Compliant - "1" is first removed, followed by "4"

chain23(); // will print "23"
csharpsquid:S3215

Needing to cast from an interface to a concrete type indicates that something is wrong with the abstractions in use, likely that something is missing from the interface. Instead of casting to a discrete type, the missing functionality should be added to the interface. Otherwise there is a risk of runtime exceptions.

Noncompliant Code Example

public interface IMyInterface
{
  void DoStuff();
}

public class MyClass1 : IMyInterface
{
  public int Data { get { return new Random().Next(); } }

  public void DoStuff()
  {
    // TODO...
  }
}

public static class DowncastExampleProgram
{
  static void EntryPoint(IMyInterface interfaceRef)
  {
    MyClass1 class1 = (MyClass1)interfaceRef;  // Noncompliant
    int privateData = class1.Data;

    class1 = interfaceRef as MyClass1;  // Noncompliant
    if (class1 != null)
    {
      // ...
    }
  }
}

Exceptions

Casting to object doesn't raise an issue, because it can never fail.

static void EntryPoint(IMyInterface interfaceRef)
{
  var o = (object)interfaceRef;
  ...
}
csharpsquid:S3217

The foreach statement was introduced in the C# language prior to generics to make it easier to work with the non-generic collections available at that time such as ArrayList. The foreach statements allows you to downcast elements of a collection of Objects to any other type. The problem is that to achieve the cast, the foreach statements silently performs explicit type conversion, which at runtime can result in an InvalidCastException.

C# code iterating on generic collections or arrays should not rely on foreach statement's silent explicit conversions.

Noncompliant Code Example

public class Fruit { }
public class Orange : Fruit { }
public class Apple : Fruit { }

class MyTest
{
  public void Test()
  {
    var fruitBasket = new List<Fruit>();
    fruitBasket.Add(new Orange());
    fruitBasket.Add(new Orange());
    // fruitBasket.Add(new Apple());  // uncommenting this line will make both foreach below throw an InvalidCastException

    foreach (Fruit fruit in fruitBasket)
    {
      var orange = (Orange)fruit; // This "explicit" conversion is hidden within the foreach loop below
      ...
    }

    foreach (Orange orange in fruitBasket) // Noncompliant
    {
      ...
    }
  }
}

Compliant Solution

var fruitBasket = new List<Orange>();
fruitBasket.Add(new Orange());
fruitBasket.Add(new Orange());
// fruitBasket.Add(new Apple());  // uncommenting this line won't compile

foreach (Orange orange in fruitBasket)
{
  ...
}

or

var fruitBasket = new List<Fruit>();
fruitBasket.Add(new Orange());
fruitBasket.Add(new Orange());
fruitBasket.Add(new Apple());

foreach (Orange orange in fruitBasket.OfType<Orange>())
{
  ...
}

Exceptions

The rule ignores iterations on collections of objects. This includes legacy code that uses ArrayList. Furthermore, the rule does not report on cases when user defined conversions are being called.

csharpsquid:S3234

GC.SuppressFinalize asks the Common Language Runtime not to call the finalizer of an object. This is useful when implementing the dispose pattern where object finalization is already handled in IDisposable.Dispose. However, it has no effect if there is no finalizer defined in the object's type, so using it in such cases is just confusing.

This rule raises an issue when GC.SuppressFinalize is called for objects of sealed types without a finalizer.

Note:** S3971 is a stricter version of this rule. Typically it makes sense to activate only one of these 2 rules.

Noncompliant Code Example

sealed class MyClass
{
  public void Method()
  {
    ...
    GC.SuppressFinalize(this); //Noncompliant
  }
}

Compliant Solution

sealed class MyClass
{
  public void Method()
  {
    ...
  }
}
csharpsquid:S3235

Redundant parentheses are simply wasted keystrokes, and should be removed.

Noncompliant Code Example

[MyAttribute()] //Noncompliant
class MyClass
{
  public int MyProperty { get; set; }
  public static MyClass CreateNew(int propertyValue)
  {
    return new MyClass() //Noncompliant
    {
      MyProperty = propertyValue
    };
  }
}

Compliant Solution

[MyAttribute]
class MyClass
{
  public int MyProperty { get; set; }
  public static MyClass CreateNew(int propertyValue)
  {
    return new MyClass
    {
      MyProperty = propertyValue
    };
  }
}
csharpsquid:S3236

Caller information attributes: CallerFilePathAttribute and CallerLineNumberAttribute provide a way to get information about the caller of a method through optional parameters. But the arguments for these optional parameters are only generated if they are not explicitly defined in the call. Thus, specifying the argument values defeats the purpose of the attributes.

Noncompliant Code Example

void TraceMessage(string message,
  [CallerFilePath] string filePath = null,
  [CallerLineNumber] int lineNumber = 0)
{
  /* ... */
}

void MyMethod()
{
  TraceMessage("my message", "A.B.C.Foo.cs", 42); // Noncompliant
}

Compliant Solution

void TraceMessage(string message,
  [CallerFilePath] string filePath = "",
  [CallerLineNumber] int lineNumber = 0)
{
  /* ... */
}

void MyMethod()
{
  TraceMessage("my message");
}

Exceptions

CallerMemberName is not checked to avoid False-Positives with WPF/UWP applications.

csharpsquid:S3237

In property and indexer set methods, and in event add and remove methods, the implicit value parameter holds the value the accessor was called with. Not using the value means that the accessor ignores the caller's intent which could cause unexpected results at runtime.

Noncompliant Code Example

private int count;
public int Count
{
  get { return count; }
  set { count = 42; } // Noncompliant
}

Compliant Solution

private int count;
public int Count
{
  get { return count; }
  set { count = value; }
}

or

public int Count
{
  get { return count; }
  set { throw new InvalidOperationException(); }
}

Exceptions

This rule doesn't raise an issue when the setter is empty and part of the implementation of an interface . The assumption is that this part of the interface is not meaningful to that particular implementation. A good example of that would be a "sink" logger that discards any logs.

csharpsquid:S3240

In the interests of keeping code clean, the simplest possible conditional syntax should be used. That means

  • using the ?? operator for an assign-if-not-null operator,
  • using the ternary operator ?: for assignment to a single variable, and
  • removing the ?? when the left operand is known to be null, or known to be definitely not null.

Noncompliant Code Example

object a = null, b = null, x;

if (a != null) // Noncompliant; needlessly verbose
{
  x = a;
}
else
{
  x = b;
}

x = a != null ? a : b; // Noncompliant; better but could still be simplified

x = (a == null) ? new object() : a; // Noncompliant

if (condition) // Noncompliant
{
  x = a;
}
else
{
  x = b;
}

var y = null ?? new object(); // Noncompliant

Compliant Solution

object x;

x = a ?? b;
x = a ?? b;
x = a ?? new object();
x = condition ? a : b;
var y = new object();
csharpsquid:S3241

Private methods are clearly intended for use only within their own scope. When such methods return values that are never used by any of their callers, then clearly there is no need to actually make the return, and it should be removed in the interests of efficiency and clarity.

csharpsquid:S3242

When a derived type is used as a parameter instead of the base type, it limits the uses of the method. If the additional functionality that is provided in the derived type is not requires then that limitation isn't required, and should be removed.

This rule raises an issue when a method declaration includes a parameter that is a derived type and accesses only members of the base type.

Noncompliant Code Example

using System;
using System.IO;

namespace MyLibrary
{
  public class Foo
  {
    public void ReadStream(FileStream stream) // Noncompliant: Uses only System.IO.Stream methods
    {
      int a;
      while ((a = stream.ReadByte()) != -1)
      {
            // Do something.
      }
    }
  }
}

Compliant Solution

using System;
using System.IO;

namespace MyLibrary
{
  public class Foo
  {
    public void ReadStream(Stream stream)
    {
      int a;
      while ((a = stream.ReadByte()) != -1)
      {
            // Do something.
      }
    }
  }
}
csharpsquid:S3244

It is possible to subscribe to events with anonymous delegates, but having done so, it is impossible to unsubscribe from them. That's because the process of subscribing adds the delegate to a list. The process of unsubscribing essentially says: remove this item from the subscription list. But because an anonymous delegate was used in both cases, the unsubscribe attempt tries to remove a different item from the list than was added. The result: NOOP.

Instead, save the delegate to a variable and use the variable to subscribe and unsubscribe.

Noncompliant Code Example

listView.PreviewTextInput += (obj,args) =>
        listView_PreviewTextInput(obj,args,listView);

// ...

listView.PreviewTextInput -= (obj, args) =>
        listView_PreviewTextInput(obj, args, listView); // Noncompliant; this delegate was never subscribed

Compliant Solution

EventHandler func = (obj,args) => listView_PreviewTextInput(obj,args,listView);

listView.PreviewTextInput += func;

// ...

listView.PreviewTextInput -= func;
csharpsquid:S3246

In the interests of making code as usable as possible, interfaces and delegates with generic parameters should use the out and in modifiers when possible to make the interfaces and delegates covariant and contravariant, respectively.

The out keyword can be used when the type parameter is used only as a return type in the interface or delegate. Doing so makes the parameter covariant, and allows interface and delegate instances created with a sub-type to be used as instances created with a base type. The most notable example of this is IEnumerable<out T>, which allows the assignment of an IEnumerable<string> instance to an IEnumerable<object> variable, for instance.

The in keyword can be used when the type parameter is used only as a method parameter in the interface or a parameter in the delegate. Doing so makes the parameter contravariant, and allows interface and delegate instances created with a base type to be used as instances created with a sub-type. I.e. this is the inversion of covariance. The most notable example of this is the Action<in T> delegate, which allows the assignment of an Action<object> instance to a Action<string> variable, for instance.

Noncompliant Code Example

interface IConsumer<T>  // Noncompliant
{
    bool Eat(T fruit);
}

Compliant Solution

interface IConsumer<in T>
{
    bool Eat(T fruit);
}
csharpsquid:S3247

Because the is operator performs a cast if the object is not null, using is to check type and then casting the same argument to that type, necessarily performs two casts. The same result can be achieved more efficiently with a single cast using as, followed by a null-check.

Noncompliant Code Example

if (x is Fruit)  // Noncompliant
{
  var f = (Fruit)x; // or x as Fruit
  // ...
}

Compliant Solution

var f = x as Fruit;
if (f != null)
{
  // code
}
csharpsquid:S3249

Making a base call in an overriding method is generally a good idea, but not in GetHashCode and Equals for classes that directly extend object because those methods are based on the object reference. Meaning that no two objects that use those base methods will ever be equal or have the same hash.

Noncompliant Code Example

public class Point
{
  private readonly int x;
  public MyClass(int x)
  {
    this.x = x;
  }
  public override int GetHashCode()
  {
    return x.GetHashCode() ^ base.GetHashCode(); //Noncompliant
  }
}

Compliant Solution

public class Point
{
  private readonly int x;
  public MyClass(int x)
  {
    this.x = x;
  }
  public override int GetHashCode()
  {
    return x.GetHashCode();
  }
}

Exceptions

This rule doesn't report on guard conditions checking for reference equality.

public class Point
{
  public override bool Equals(object obj)
  {
    if (base.Equals(obj)) // Compliant, although it could be replaced with object.ReferenceEquals(obj, this), which is clearer
    {
      return true;
    }
    ...
  }
}
csharpsquid:S3251

partial methods allow an increased degree of flexibility in programming a system. Hooks can be added to generated code by invoking methods that define their signature, but might not have an implementation yet. But if the implementation is still missing when the code makes it to production, the compiler silently removes the call. In the best case scenario, such calls simply represent cruft, but in they worst case they are critical, missing functionality, the loss of which will lead to unexpected results at runtime.

This rule raises an issue for partial methods for which no implementation can be found in the assembly.

Noncompliant Code Example

partial class C
{
  partial void M(); //Noncompliant

  void OtherM()
  {
    M(); //Noncompliant. Will be removed.
  }
}
csharpsquid:S3253

Since the compiler will automatically invoke the base type's no-argument constructor, there's no need to specify its invocation explicitly. Also, when only a single public parameterless constructor is defined in a class, then that constructor can be removed because the compiler would generate it automatically. Similarly, empty static constructors and empty destructors are also wasted keystrokes.

Noncompliant Code Example

class X
{
  public X() { } // Noncompliant
  static X() { }  // Noncompliant
  ~X() { } // Noncompliant

  ...
}

class Y : X
{
  public Y(int parameter) : base() // Noncompliant
  {
    /* does something with the parameter */
  }
}

Compliant Solution

class X
{
  ...
}

class Y : X
{
  public Y(int parameter)
  {
    /* does something with the parameter */
  }
}
csharpsquid:S3254

Specifying the default parameter values in a method call is redundant. Such values should be omitted in the interests of readability.

Noncompliant Code Example

public void M(int x, int y=5, int z = 7) { /* ... */ }

// ...
M(1, 5); //Noncompliant, y has the default value
M(1, z: 7); //Noncompliant, z has the default value

Compliant Solution

public void M(int x, int y=5, int z = 7) { /* ... */ }

// ...
M(1);
M(1);
csharpsquid:S3256

Using string.Equals to determine if a string is empty is significantly slower than using string.IsNullOrEmpty() or checking for string.Length == 0. string.IsNullOrEmpty() is both clear and concise, and therefore preferred to laborious, error-prone, manual null- and emptiness-checking.

Noncompliant Code Example

"".Equals(name); // Noncompliant
!name.Equals(""); // Noncompliant
name.Equals(string.Empty); // Noncompliant

Compliant Solution

name != null && name.Length > 0 // Compliant but more error prone
!string.IsNullOrEmpty(name)
string.IsNullOrEmpty(name)
csharpsquid:S3257

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:

  • array element type
  • array size
  • new DelegateType
  • new Nullable<Type>
  • object or collection initializers ({})
  • type of lambda expression parameters
  • parameter declarations of anonymous methods when the parameters are not used.

Noncompliant Code Example

var l = new List<int>() {}; // Noncompliant, {} can be removed
var o = new object() {}; // Noncompliant, {} can be removed

var ints = new int[] {1, 2, 3}; // Noncompliant, int can be omitted
ints = new int[3] {1, 2, 3}; // Noncompliant, the size specification can be removed

int? i = new int?(5); // Noncompliant new int? could be omitted, it can be inferred from the declaration, and there's implicit conversion from T to T?
var j = new int?(5);

Func<int, int> f1 = (int i) => 1; //Noncompliant, can be simplified

class Class
{
    private event EventHandler MyEvent;

    public Class()
    {
        MyEvent += new EventHandler((a,b)=>{ }); // Noncompliant, needlessly verbose
    }
}

Compliant Solution

var l = new List<int>();
var o = new object();

var ints = new [] {1, 2, 3};
ints = new [] {1, 2, 3};

int? i = 5;
var j = new int?(5);

Func<int, int> f1 = (i) => 1;

class Class
{
    private event EventHandler MyEvent;

    public Class()
    {
        MyEvent += (a,b)=>{ };
    }
}
csharpsquid:S3261

Namespaces with no lines of code clutter a project and should be removed.

Noncompliant Code Example

namespace MyEmptyNamespace // Noncompliant
{

}
csharpsquid:S3262

Overriding methods automatically inherit the params behavior. To ease readability, this modifier should be explicitly used in the overriding method as well.

Noncompliant Code Example

class Base
{
  public virtual void Method(params int[] numbers)
  {
    ...
  }
}
class Derived : Base
{
  public override void Method(int[] numbers) // Noncompliant, the params is missing.
  {
    ...
  }
}

Compliant Solution

class Base
{
  public virtual void Method(params int[] numbers)
  {
    ...
  }
}
class Derived : Base
{
  public override void Method(params int[] numbers)
  {
    ...
  }
}
csharpsquid:S3263

Static field initializers are executed in the order in which they appear in the class from top to bottom. Thus, placing a static field in a class above the field or fields required for its initialization will yield unexpected results.

Noncompliant Code Example

class MyClass
{
  public static int X = Y; // Noncompliant; Y at this time is still assigned default(int), i.e. 0
  public static int Y = 42;
}

Compliant Solution

class MyClass
{
  public static int Y = 42;
  public static int X = Y;
}

or

class MyClass
{
  public static int X;
  public static int Y = 42;

  static MyClass()
  {
    X = Y;
  }
}
csharpsquid:S3264

Events that are not invoked anywhere are dead code, and there's no good reason to keep them in the source.

Noncompliant Code Example

class UninvokedEventSample
{
    private event Action<object, EventArgs> Happened; //Noncompliant

    public void RegisterEventHandler(Action<object, EventArgs> handler)
    {
        Happened += handler; //we register some event handlers
    }

    public void RaiseEvent()
    {
        if (Happened != null)
        {
            // Happened(this, null); // the event is never triggered, because this line is commented out.
        }
    }
}
csharpsquid:S3265

enums are usually used to identify distinct elements in a set of values. However enums can be treated as bit fields and bitwise operations can be used on them to combine the values. This is a good way of specifying multiple elements of set with a single value. When enums are used this way, it is a best practice to mark the enum with the FlagsAttribute.

Noncompliant Code Example

enum Permissions
{
  None = 0,
  Read = 1,
  Write = 2,
  Execute = 4
}
// ...

var x = Permissions.Read | Permissions.Write;  // Noncompliant; enum is not marked with [Flags]

Compliant Solution

[Flags]
enum Permissions
{
  None = 0,
  Read = 1,
  Write = 2,
  Execute = 4
}
// ...

var x = Permissions.Read | Permissions.Write;
csharpsquid:S3343

Caller information attributes (CallerFilePathAttribute, CallerLineNumberAttribute, and CallerMemberNameAttribute) provide a way to get information about the caller of a method through optional parameters. But they only work right if their values aren't provided explicitly. So if you define a method with caller info attributes in the middle of the parameter list, you put your callers in a bad position: they are forced to use named arguments if they want to use the method properly.

Noncompliant Code Example

void TraceMessage([CallerMemberName] string memberName = "",
  [CallerFilePath] string filePath = "",
  [CallerLineNumber] int lineNumber = 0,
  string message = null)  // Noncompliant
{
  /* ... */
}

Compliant Solution

void TraceMessage(string message = null,
  [CallerMemberName] string memberName = "",
  [CallerFilePath] string filePath = "",
  [CallerLineNumber] int lineNumber = 0)
{
  /* ... */
}
csharpsquid:S3353

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

public bool Seek(int[] input)
{
  int target = 32;  // Noncompliant
  foreach (int i in input)
  {
    if (i == target)
    {
      return true;
    }
  }
  return false;
}

Compliant Solution

public bool Seek(int[] input)
{
  const int target = 32;
  foreach (int i in input)
  {
    if (i == target)
    {
      return true;
    }
  }
  return false;
}
csharpsquid:S3358

Just because you can do something, doesn't mean you should, and that's the case with nested ternary operations. Nesting ternary operators results in the kind of code that may seem clear as day when you write it, but six months later will leave maintainers (or worse - future you) scratching their heads and cursing.

Instead, err on the side of clarity, and use another line to express the nested operation as a separate statement.

Noncompliant Code Example

public string GetTitle(Person p)
{
  return p.Gender == Gender.MALE ? "Mr. " : p.IsMarried ? "Mrs. " : "Miss ";  // Noncompliant
}

Compliant Solution

public string GetTitle(Person p)
{
  if (p.Gender == Gender.MALE)
  {
    return "Mr. ";
  }
  return p.IsMarried ? "Mrs. " : "Miss ";
}
csharpsquid:S3376

Adherence to the standard naming conventions makes your code not only more readable, but more usable. For instance, class FirstAttribute : Attribute can be used simply with First, but you must use the full name for class AttributeOne : Attribute.

This rule raises an issue when classes extending Attribute, EventArgs, or Exception, do not end with their parent class names.

Noncompliant Code Example

class AttributeOne : Attribute  // Noncompliant
{
}

Compliant Solution

class FirstAttribute : Attribute
{
}

Exceptions

If a class' direct base class doesn't follow the convention, then no issue is reported on the class itself, regardless of whether or not it conforms to the convention.

class Timeout : Exception // Noncompliant
{
}
class ExtendedTimeout : Timeout // Ignored; doesn't conform to convention, but the direct base doesn't conform either
{
}
csharpsquid:S3397

object.Equals() overrides can be optimized by checking first for reference equality between this and the parameter. This check can be implemented by calling object.ReferenceEquals() or base.Equals(), where base is object. However, using base.Equals() is a maintenance hazard because while it works if you extend Object directly, if you introduce a new base class that overrides Equals, it suddenly stops working.

This rule raises an issue if base.Equals() is used but base is not object.

Noncompliant Code Example

class Base
{
  private int baseField;

  public override bool Equals(object other)
  {
    if (base.Equals(other)) // Okay; base is object
    {
      return true;
    }

    return this.baseField == ((Base)other).baseField;
  }
}

class Derived : Base
{
  private int derivedField;

  public override bool Equals(object other)
  {
    if (base.Equals(other))  // Noncompliant
    {
      return true;
    }

    return this.derivedField == ((Derived)other).derivedField;
  }
}

Compliant Solution

class Base
{
  private int baseField;

  public override bool Equals(object other)
  {
    if (object.ReferenceEquals(this, other))  // base.Equals is okay here, but object.ReferenceEquals is better
    {
      return true;
    }

    return this.baseField == ((Base)other).baseField;
  }
}

class Derived : Base
{
  private int derivedField;

  public override bool Equals(object other)
  {
    if (object.ReferenceEquals(this, other))
    {
      return true;
    }

    return base.Equals(other) && this.derivedField == ((Derived)other).derivedField;
  }
}
csharpsquid:S3400

There's no point in forcing the overhead of a method call for a method that always returns the same constant value. Even worse, the fact that a method call must be made will likely mislead developers who call the method thinking that something more is done. Declare a constant instead.

This rule raises an issue if on methods that contain only one statement: the return of a constant value.

Noncompliant Code Example

int GetBestNumber()
{
  return 12;  // Noncompliant
}

Compliant Solution

const int BestNumber = 12;

or

static readonly int BestNumber = 12;
csharpsquid:S3415

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

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

Compliant Solution

Assert.AreEqual(0, runner.ExitCode, "Unexpected exit code");
csharpsquid:S3427

The rules for method resolution are complex and perhaps not properly understood by all coders. Having overloads with optional parameter values makes the matter even harder to understand.

This rule raises an issue when an overload with default parameter values is hidden by one without the optional parameters.

Noncompliant Code Example

public class MyClass
{
  void Print(string[] messages) {...}
  void Print(string[] messages, string delimiter = "\n") {...} // Noncompliant; default parameter value is hidden by overload
}

// ...
MyClass myClass = new MyClass();

myClass.Print(new string[3] {"yes", "no", "maybe"});  // which version of Print will be called?
csharpsquid:S3431

It should be clear to a casual reader what code a test is testing and what results are expected. Unfortunately, that's not usually the case with the [ExpectedException] attribute since an exception could be thrown from almost any line in the method.

This rule detects MSTest and NUnit ExpectedException attribute.

Noncompliant Code Example

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]  // Noncompliant
public void TestNullArg()
{
  //...
}

Compliant Solution

[TestMethod]
public void TestNullArg()
{
  bool callFailed = false;
  try
  {
    //...
  }
  catch (ArgumentNullException)
  {
    callFailed = true;
  }
  Assert.IsTrue(callFailed, "Expected call to MyMethod to fail with ArgumentNullException");
}

Exceptions

This rule ignores one-line test methods, since it is obvious in such methods where the exception is expected to be thrown.

csharpsquid:S3441

When an anonymous type's properties are copied from properties or variables with the same names, it yields cleaner code to omit the new type's property name and the assignment operator.

Noncompliant Code Example

var X = 5;

var anon = new
{
  X = X, //Noncompliant, the new object would have the same property without the "X =" part.
  Y = "my string"
};

Compliant Solution

var X = 5;

var anon = new
{
  X,
  Y = "my string"
};
csharpsquid:S3442

Since abstract classes can't be instantiated, there's no point in their having public or internal constructors. If there is basic initialization logic that should run when an extending class instance is created, you can by all means put it in a constructor, but make that constructor private or protected.

Noncompliant Code Example

abstract class Base
{
    public Base() // Noncompliant, should be private or protected
    {
      //...
    }
}

Compliant Solution

abstract class Base
{
    protected Base()
    {
      //...
    }
}
csharpsquid:S3443

If you call GetType() on a Type variable, the return value will always be typeof(System.Type). So there's no real point in making that call. The same applies to passing a type argument to IsInstanceOfType. In both cases the results are entirely predictable.

Noncompliant Code Example

var type = typeof(int);
var ttype = type.GetType(); //Noncompliant, always typeof(System.Type)

var s = "abc";

if (s.GetType().IsInstanceOfType(typeof(string))) //Noncompliant; false
{ /* ... */ }

Compliant Solution

var s = "abc";

if (s.GetType().IsInstanceOfType("ssss"))
{ /* ... */ }
csharpsquid:S3444

When an interface inherits from two interfaces that both define a member with the same name, trying to access that member through the derived interface will result in the compiler error CS0229 Ambiguity between 'IBase1.SomeProperty' and 'IBase2.SomeProperty'.

So instead, every caller will be forced to cast instances of the derived interface to one or the other of its base interfaces to resolve the ambiguity and be able to access the member. Instead, it is better to resolve the ambiguity in the definition of the derived interface either by:

  • renaming the member in one of the base interfaces to remove the collision
  • also defining that member in the derived interface. Use this only if all copies of the member are meant to hold the same value.

Noncompliant Code Example

public interface IBase1
{
  string SomeProperty { get; set; }
}

public interface IBase2
{
  string SomeProperty { get; set; }
}

public interface IDerived : IBase1, IBase2 // Noncompliant, accessing IDerived.SomeProperty is ambiguous
{
}

public class MyClass : IDerived
{
  // Implements both IBase1.SomeProperty and IBase2.SomeProperty
  public string SomeProperty { get; set; } = "Hello";

  public static void Main()
  {
    MyClass myClass = new MyClass();
    Console.WriteLine(myClass.SomeProperty); // Writes "Hello" as expected
    Console.WriteLine(((IBase1)myClass).SomeProperty); // Writes "Hello" as expected
    Console.WriteLine(((IBase2)myClass).SomeProperty); // Writes "Hello" as expected
    Console.WriteLine(((IDerived)myClass).SomeProperty); // Error CS0229 Ambiguity between 'IBase1.SomeProperty' and 'IBase2.SomeProperty'
  }
}

Compliant Solution

public interface IDerived : IBase1, IBase2
{
  new string SomeProperty { get; set; }
}

public class MyClass : IDerived
{
  // Implements IBase1.SomeProperty, IBase2.SomeProperty and IDerived.SomeProperty
  public string SomeProperty { get; set; } = "Hello";

  public static void Main()
  {
    MyClass myClass = new MyClass();
    Console.WriteLine(myClass.SomeProperty); // Writes "Hello" as expected
    Console.WriteLine(((IBase1)myClass).SomeProperty); // Writes "Hello" as expected
    Console.WriteLine(((IBase2)myClass).SomeProperty); // Writes "Hello" as expected
    Console.WriteLine(((IDerived)myClass).SomeProperty); // Writes "Hello" as expected
  }
}

or

public interface IBase1
{
  string SomePropertyOne { get; set; }
}

public interface IBase2
{
  string SomePropertyTwo { get; set; }
}

public interface IDerived : IBase1, IBase2
{
}
csharpsquid:S3445

When rethrowing an exception, you should do it by simply calling throw; and not throw exc;, because the stack trace is reset with the second syntax, making debugging a lot harder.

Noncompliant Code Example

try
{}
catch(ExceptionType1 exc)
{
  Console.WriteLine(exc);
  throw exc; // Noncompliant; stacktrace is reset
}
catch (ExceptionType2 exc)
{
  throw new Exception("My custom message", exc);  // Compliant; stack trace preserved
}

Compliant Solution

try
{}
catch(ExceptionType1 exc)
{
  Console.WriteLine(exc);
  throw;
}
catch (ExceptionType2 exc)
{
  throw new Exception("My custom message", exc);
}
csharpsquid:S3447

The use of ref or out in combination with [Optional] is both confusing and contradictory. [Optional] indicates that the parameter doesn't have to be provided, while out and ref mean that the parameter will be used to return data to the caller (ref additionally indicates that the parameter may also be used to pass data into the method).

Thus, making it [Optional] to provide the parameter in which you will be passing back the method results doesn't make sense. In fact, the compiler will raise an error on such code. Unfortunately, it raises the error on method calls where the [Optional] parameter has been omitted, not the source of the problem, the method declaration.

Noncompliant Code Example

class MyClass
{
    public void DoStuff([Optional] ref int i) // Noncompliant
    {
        Console.WriteLine(i);
    }

    public static void Main()
    {
        new MyClass().DoStuff(); // This doesn't compile, CS7036 shows
    }
}

Compliant Solution

class MyClass
{
  public void DoStuff(ref int i)
  {
    Console.WriteLine(i);
  }

  public static void Main()
  {
    var i = 42;
    new MyClass().DoStuff(ref i);
  }
}
csharpsquid:S3449

Numbers can be shifted with the << and >> operators, but the right operand of the operation needs to be an int or a type that has an implicit conversion to int. However, with dynamic, the compiler's type checking is turned off, so you can pass anything to a shift operator and have it compile. And if the argument can't be converted to int at runtime, then a RuntimeBinderException will be raised.

Noncompliant Code Example

dynamic d = 5;
var x = d >> 5.4; // Noncompliant
x = d >> null; // Noncompliant
x <<= new object(); // Noncompliant
csharpsquid:S3450

There is no point in providing a default value for a parameter if callers are required to provide a value for it anyway. Thus, [DefaultParameterValue] should always be used in conjunction with [Optional].

Noncompliant Code Example

public void MyMethod([DefaultParameterValue(5)] int j) //Noncompliant, useless
{
  Console.WriteLine(j);
}

Compliant Solution

public void MyMethod(int j = 5)
{
  Console.WriteLine(j);
}

or

public void MyMethod([DefaultParameterValue(5)][Optional] int j)
{
  Console.WriteLine(j);
}
csharpsquid:S3451

The use of [DefaultValue] with [Optional] has no more effect than [Optional] alone. That's because [DefaultValue] doesn't actually do anything; it merely indicates the intent for the value. More than likely, [DefaultValue] was used in confusion instead of [DefaultParameterValue].

Noncompliant Code Example

class MyClass
{
    public void DoStuff([Optional][DefaultValue(4)]int i, int j = 5)  // Noncompliant
    {
        Console.WriteLine(i);
    }

    public static void Main()
    {
        new MyClass().DoStuff(); // prints 0
    }
}

Compliant Solution

class MyClass
{
    public void DoStuff([Optional][DefaultParameterValue(4)]int i, int j = 5)
    {
        Console.WriteLine(i);
    }

    public static void Main()
    {
        new MyClass().DoStuff(); // prints 4
    }
}
csharpsquid:S3453

A class with only private constructors can't be instantiated, thus, it seems to be pointless code.

Noncompliant Code Example

public class MyClass // Noncompliant
{
  private MyClass() { ... }
}

Compliant Solution

public class MyClass
{
  public MyClass() { ... }
}

Exceptions

Classes that themselves access their private constructors (singletons or smart enums) are ignored. Classes with only static members are also ignored because they are covered by Rule S1118.

csharpsquid:S3456

ToCharArray can be omitted when the operation on the array could have been done directly on the string, such as when iterating over the characters in a string, and when accessing a character in a string via an array index. In those cases, explicit ToCharArray calls should be omitted.

Noncompliant Code Example

string str = "some string";
foreach (var c in str.ToCharArray()) // Noncompliant
{
  // ...
}

Compliant Solution

string str = "some string";
foreach (var c in str)
{
  // ...
}
csharpsquid:S3458

Empty case clauses that fall through to the default are useless. Whether or not such a case is present, the default clause will be invoked. Such cases simply clutter the code, and should be removed.

Noncompliant Code Example

switch(ch)
{
  case 'a' :
    HandleA();
    break;
  case 'b' :
    HandleB();
    break;
  case 'c' :  // Noncompliant
  default:
    HandleTheRest();
    break;
}

Compliant Solution

switch(ch)
{
  case 'a' :
    HandleA();
    break;
  case 'b' :
    HandleB();
    break;
  default:
    HandleTheRest();
    break;
}
csharpsquid:S3459

Fields and auto-properties that are never assigned to hold the default values for their types. They are either pointless code or, more likely, mistakes.

Noncompliant Code Example

class MyClass
{
  private int field; // Noncompliant, shouldn't it be initialized? This way the value is always default(int), 0.
  private int Property { get; set; }  // Noncompliant
  public void Print()
  {
    Console.WriteLine(field); //Will always print 0
    Console.WriteLine(Property); //Will always print 0
  }
}

Compliant Solution

class MyClass
{
  private int field = 1;
  private int Property { get; set; } = 42;
  public void Print()
  {
    field++;
    Console.WriteLine(field);
    Console.WriteLine(Property);
  }
}
csharpsquid:S3464

Recursion is acceptable in methods, where you can break out of it. But with class types, you end up with code that will compile but not run if you try to instantiate the class.

Noncompliant Code Example

class C1<T>
{
}
class C2<T> : C1<C2<C2<T>>> // Noncompliant
{
}

...
var c2 = new C2<int>();
csharpsquid:S3466

Generally, writing the least code that will readably do the job is a good thing, so omitting default parameter values seems to make sense. Unfortunately, when you omit them from the base call in an override, you're not actually getting the job done thoroughly, because you're ignoring the value the caller passed in. The result will likely not be what the caller expected.

Noncompliant Code Example

public class BaseClass
{
    public virtual void MyMethod(int i = 1)
    {
        Console.WriteLine(i);
    }
}

public class DerivedClass : BaseClass
{
    public override void MyMethod(int i = 1)
    {
        // ...
        base.MyMethod(); // Noncompliant; caller's value is ignored
    }

    static int Main(string[] args)
    {
        DerivedClass dc = new DerivedClass();
        dc.MyMethod(12);  // prints 1
    }
}

Compliant Solution

public class BaseClass
{
    public virtual void MyMethod(int i = 1)
    {
        Console.WriteLine(i);
    }
}

public class DerivedClass : BaseClass
{
    public override void MyMethod(int i = 1)
    {
        // ...
        base.MyMethod(i);
    }

    static int Main(string[] args)
    {
        DerivedClass dc = new DerivedClass();
        dc.MyMethod(12);  // prints 12
    }
}
csharpsquid:S3532

The default clause should take appropriate action. Having an empty default is a waste of keystrokes.

Noncompliant Code Example

enum Fruit
{
  Apple,
  Orange,
  Banana
}

void PrintName(Fruit fruit)
{
  switch(fruit)
  {
    case Fruit.Apple:
      Console.WriteLine("apple");
      break;
    default:  //Noncompliant
      break;
  }
}

Compliant Solution

enum Fruit
{
  Apple,
  Orange,
  Banana
}

void PrintName(Fruit fruit)
{
  switch(fruit)
  {
    case Fruit.Apple:
      Console.WriteLine("apple");
      break;
    default:
      throw new NotSupportedException();
  }
}

or

void PrintName(Fruit fruit)
{
  switch(fruit)
  {
    case Fruit.Apple:
      Console.WriteLine("apple");
      break;
  }
}

Exceptions

default clauses containing only a comment are ignored with the assumption that they are empty on purpose and the comment documents why.

csharpsquid:S3597

The ServiceContract attribute specifies that a class or interface defines the communication contract of a Windows Communication Foundation (WCF) service. The service operations of this class or interface are defined by OperationContract attributes added to methods. It doesn't make sense to define a contract without any service operations; thus, in a ServiceContract class or interface at least one method should be annotated with OperationContract. Similarly, WCF only serves OperationContract methods that are defined inside ServiceContract classes or interfaces; thus, this rule also checks that ServiceContract is added to the containing type of OperationContract methods.

Noncompliant Code Example

[ServiceContract]
interface IMyService // Noncompliant
{
  int MyServiceMethod();
}

Compliant Solution

[ServiceContract]
interface IMyService
{
  [OperationContract]
  int MyServiceMethod();
}
csharpsquid:S3598

When declaring a Windows Communication Foundation (WCF) OperationContract method one-way, that service method won't return any result, not even an underlying empty confirmation message. These are fire-and-forget methods that are useful in event-like communication. Specifying a return type therefore does not make sense.

Noncompliant Code Example

[ServiceContract]
interface IMyService
{
  [OperationContract(IsOneWay = true)]
  int SomethingHappened(int parameter); // Noncompliant
}

Compliant Solution

[ServiceContract]
interface IMyService
{
  [OperationContract(IsOneWay = true)]
  void SomethingHappened(int parameter);
}

Exceptions

The rule doesn't report if OperationContractAttribute.AsyncPattern is set to true.

csharpsquid:S3600

Adding params to a method override has no effect. The compiler accepts it, but the callers won't be able to benefit from the added modifier.

Noncompliant Code Example

class Base
{
  public virtual void Method(int[] numbers)
  {
    ...
  }
}
class Derived : Base
{
  public override void Method(params int[] numbers) // Noncompliant, method can't be called with params syntax.
  {
    ...
  }
}

Compliant Solution

class Base
{
  public virtual void Method(int[] numbers)
  {
    ...
  }
}
class Derived : Base
{
  public override void Method(int[] numbers)
  {
    ...
  }
}
csharpsquid:S3604

Fields, properties and events can be initialized either inline or in the constructor. Initializing them inline and in the constructor at the same time is redundant; the inline initialization will be overridden.

Noncompliant Code Example

class Person
{
  int age = 42; // Noncompliant
  public Person(int age)
  {
    this.age = age;
  }
}

Compliant Solution

class Person
{
  int age;
  public Person(int age)
  {
    this.age = age;
  }
}

Exceptions

This rule doesn't report an issue if not all constructors initialize the field. If the field is initialized inline to its default value, then S3052 already reports an issue on the initialization.

csharpsquid:S3610

Calling GetType() on a nullable object returns the underlying value type. Thus, comparing the returned Type object to typeof(Nullable<SomeType>) doesn't make sense. The comparison either throws an exception or the result can be known at compile time.

Noncompliant Code Example

int? nullable = 42;
bool comparison = nullable.GetType() == typeof(Nullable<int>); // Noncompliant, always false
comparison = nullable.GetType() != typeof(Nullable<int>); // Noncompliant, always true

nullable = null;
comparison = nullable.GetType() != typeof(Nullable<int>); // Noncompliant, calling GetType on a null always throws an exception
csharpsquid:S3626

Jump statements, such as return, yield break, goto, and continue let you change the default flow of program execution, but jump statements that direct the control flow to the original direction are just a waste of keystrokes.

Noncompliant Code Example

void Foo()
{
  goto A; // Noncompliant
  A:
  while (condition1)
  {
    if (condition2)
    {
      continue; // Noncompliant
    }
    else
    {
      DoTheThing();
    }
  }
  return; // Noncompliant; this is a void method
}

Compliant Solution

void Foo()
{
  while (condition1)
  {
    if (!condition2)
    {
      DoTheThing();
    }
  }
}
csharpsquid:S3655

Nullable value types can hold either a value or null. The value held in the nullable type can be accessed with the Value property, but .Value throws an InvalidOperationException when the value is null. To avoid the exception, a nullable type should always be tested before .Value is accessed.

Noncompliant Code Example

int? nullable = null;
...
UseValue(nullable.Value); // Noncompliant

Compliant Solution

int? nullable = null;
...
if (nullable.HasValue)
{
  UseValue(nullable.Value);
}

or

int? nullable = null;
...
if (nullable != null)
{
  UseValue(nullable.Value);
}

See

csharpsquid:S3693

It may be a good idea to raise an exception in a constructor if you're unable to fully flesh the object in question, but not in an exception constructor. If you do, you'll interfere with the exception that was originally being thrown. Further, it is highly unlikely that an exception raised in the creation of an exception will be properly handled in the calling code, and the unexpected, unhandled exception will lead to program termination.

Noncompliant Code Example

class MyException: Exception
{
    public void MyException()
    {
         if (bad_thing)
         {
             throw new Exception("A bad thing happened");  // Noncompliant
          }
    }
}
csharpsquid:S3717

NotImplementedException is often used to mark methods which must be implemented for the overall functionality to be complete, but which the developer wants to implement later. That's as opposed to the NotSupportedException which is thrown by methods which are required by base classes or interfaces, but which are not appropriate to the current class.

This rule raises an exception when NotImplementedException is thrown.

Noncompliant Code Example

void doTheThing()
{
    throw new NotImplementedException();
}

Exceptions

Exceptions derived from NotImplementedException are ignored.

csharpsquid:S3869

Not surprisingly, the SafeHandle.DangerousGetHandle method is dangerous. That's because it may not return a valid handle. Using it can lead to leaks and vulnerabilities. While it is possible to use the method successfully, it's extremely difficult to do correctly, so the method should simply be avoided altogether.

Noncompliant Code Example

static void Main(string[] args)
{
    System.Reflection.FieldInfo fieldInfo = ...;
    SafeHandle handle = (SafeHandle)fieldInfo.GetValue(rKey);
    IntPtr dangerousHandle = handle.DangerousGetHandle();  // Noncompliant
}
csharpsquid:S3872

The name of a method should communicate what it does, and the names of its parameters should indicate how they're used. If a method and its parameter have the same name it is an indication that one of these rules of thumb has been broken, if not both. Even if by some trick of language that's not the case, it is still likely to confuse callers and maintainers.

Noncompliant Code Example

public void Login(string login)  // Noncompliant
{
  //...
}

Compliant Solution

public void Login(string userName)
{
  //...
}
csharpsquid:S3875

The use of == to compare to objects is expected to do a reference comparison. That is, it is expected to return true if and only if they are the same object instance. Overloading the operator to do anything else will inevitably lead to the introduction of bugs by callers. On the other hand, overloading it to do exactly that is pointless; that's what == does by default.

Noncompliant Code Example

public static bool operator== (MyType x, MyType y) // Noncompliant
{

Exceptions

  • Classes with overloaded operator + or operator - methods are ignored.
  • Classes that implement IComparable<T> or IEquatable<T> most probably behave as a value-type objects and so are ignored.
csharpsquid:S3876

Strings and integral types are typically used as indexers. When some other type is required, it typically indicates design problems, and potentially a situation where a method should be used instead.

Noncompliant Code Example

public int this[MyCustomClass index]  // Noncompliant
{
    // get and set accessors
}
csharpsquid:S3877

It is expected that some methods should be called with caution, but others, such as ToString, are expected to "just work". Throwing an exception from such a method is likely to break callers' code unexpectedly.

An issue is raised when an exception is thrown from any of the following:

  • Event accessors
  • Object.Equals
  • IEquatable.Equals
  • GetHashCode
  • ToString
  • static constructors
  • IDisposable.Dispose
  • operator ==, !=, <, >, <=, >=
  • implicit cast operators

Noncompliant Code Example

public override string ToString()
{
  if (string.IsNullOrEmpty(Name))
  {
    throw new ArgumentException("...");  // Noncompliant
  }
  //...

Exceptions

System.NotImplementedException and its derivatives are ignored.

System.InvalidOperationException, System.NotSupportedException, and System.ArgumentException and their derivatives are ignored in event accessors.

csharpsquid:S3880

Finalizers come with a performance cost due to the overhead of tracking the life cycle of objects. An empty one is consequently costly with no benefit or justification.

Noncompliant Code Example

public class Foo
{
    ~Foo() // Noncompliant
    {
    }
}
csharpsquid:S3881

The IDisposable interface is a mechanism to release unmanaged resources, if not implemented correctly this could result in resource leaks or more severe bugs.

This rule raises an issue when the recommended dispose pattern, as defined by Microsoft, is not adhered to. See the Compliant Solution section for examples.

Satisfying the rule's conditions will enable potential derived classes to correctly dispose the members of your class:

  • sealed classes are not checked.
  • If a base class implements IDisposable your class should not have IDisposable in the list of its interfaces. In such cases it is recommended to override the base class's protected virtual void Dispose(bool) method or its equivalent.
  • The class should not implement IDisposable explicitly, e.g. the Dispose() method should be public.
  • The class should contain protected virtual void Dispose(bool) method. This method allows the derived classes to correctly dispose the resources of this class.
  • The content of the Dispose() method should be invocation of Dispose(true) followed by GC.SuppressFinalize(this)
  • If the class has a finalizer, i.e. a destructor, the only code in its body should be a single invocation of Dispose(false).
  • If the class inherits from a class that implements IDisposable it must call the Dispose, or Dispose(bool) method of the base class from within its own implementation of Dispose or Dispose(bool), respectively. This ensures that all resources from the base class are properly released.

Noncompliant Code Example

public class Foo1 : IDisposable // Noncompliant - provide protected overridable implementation of Dispose(bool) on Foo or mark the type as sealed.
{
    public void Dispose() // Noncompliant - should contain only a call to Dispose(true) and then GC.SuppressFinalize(this)
    {
        // Cleanup
    }
}

public class Foo2 : IDisposable
{
    void IDisposable.Dispose() // Noncompliant - Dispose() should be public
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public virtual void Dispose() // Noncompliant - Dispose() should be sealed
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

public class Foo3 : IDisposable
{
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        // Cleanup
    }

    ~Foo3() // Noncompliant - Modify Foo.~Foo() so that it calls Dispose(false) and then returns.
    {
        // Cleanup
    }
}{code}

Compliant Solution

// Sealed class
public sealed class Foo1 : IDisposable
{
    public void Dispose()
    {
        // Cleanup
    }
}

// Simple implementation
public class Foo2 : IDisposable
{
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        // Cleanup
    }
}

// Implementation with a finalizer
public class Foo3 : IDisposable
{
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        // Cleanup
    }

    ~Foo3()
    {
        Dispose(false);
    }
}

// Base disposable class
public class Foo4 : DisposableBase
{
    protected override void Dispose(bool disposing)
    {
        // Cleanup
        // Do not forget to call base
        base.Dispose(disposing);
    }
}

See

Refer to

csharpsquid:S3885

The parameter to Assembly.Load includes the full specification of the dll to be loaded. Use another method, and you might end up with a dll other than the one you expected.

This rule raises an issue when Assembly.LoadFrom, Assembly.LoadFile, or Assembly.LoadWithPartialName is called.

Noncompliant Code Example

static void Main(string[] args)
{
    Assembly.LoadFrom(...); // Noncompliant
    Assembly.LoadFile(...); // Noncompliant
    Assembly.LoadWithPartialName(...); // Noncompliant + deprecated
}
csharpsquid:S3887

Using the readonly keyword on a field means that it can't be changed after initialization. However, when applied to collections or arrays, that's only partly true. readonly enforces that another instance can't be assigned to the field, but it cannot keep the contents from being updated. That means that in practice, the field value really can be changed, and the use of readonly on such a field is misleading, and you're likely to not be getting the behavior you expect.

This rule raises an issue when a non-private, readonly field is an array or collection.

Noncompliant Code Example

public class MyClass
{
  public readonly string[] strings;  // Noncompliant

  // ...

Compliant Solution

public class MyClass
{
  public string[] strings;

  // ...

or

public class MyClass
{
  private readonly string[] strings;

  // ...
csharpsquid:S3889

Thread.Suspend and Thread.Resume can give unpredictable results, and both methods have been deprecated. Indeed, if Thread.Suspend is not used very carefully, a thread can be suspended while holding a lock, thus leading to a deadlock. Other safer synchronization mechanisms should be used, such as Monitor, Mutex, and Semaphore.

Noncompliant Code Example

static void Main(string[] args)
{
  // ...
  Thread.CurrentThread.Suspend(); // Noncompliant
  Thread.CurrentThread.Resume(); // Noncompliant
}

See

csharpsquid:S3898

If you're using a struct, it is likely because you're interested in performance. But by failing to implement IEquatable<T> you're loosing performance when comparisons are made because without IEquatable<T>, boxing and reflection are used to make comparisons.

Noncompliant Code Example

struct MyStruct  // Noncompliant
{
  private int i;
  public int I
  {
    //...
  }
}

Compliant Solution

struct MyStruct : IEquatable<MyStruct>
{
  private int i;
  public int I
  {
    //...
  }

  public bool Equals(MyStruct other)
  {
    throw new NotImplementedException();
  }
}
csharpsquid:S3903

Types are declared in namespaces in order to prevent name collisions and as a way to organize them into the object hierarchy. Types that are defined outside any named namespace are in a global namespace that cannot be referenced in code.

Noncompliant Code Example

public class Foo // Noncompliant
{
}

public struct Bar // Noncompliant
{
}

Compliant Solution

namespace SomeSpace
{
    public class Foo
    {
    }

    public struct Bar
    {
    }
}
csharpsquid:S3904

If no AssemblyVersionAttribute is provided, the same default version will be used for every build. Since the version number is used by The .NET Framework to uniquely identify an assembly this can lead to broken dependencies.

Noncompliant Code Example

using System;
using System.Reflection;

[assembly: AssemblyTitle("MyAssembly")] // Noncompliant

namespace MyLibrary
{
}

Compliant Solution

using System;
using System.Reflection;

[assembly: AssemblyTitle("MyAssembly")]
[assembly: AssemblyVersionAttribute("1.2.125.0")]

namespace MyLibrary
{
}

See

Assembly Versioning (MSDN)

csharpsquid:S3906

Delegate event handlers (i.e. delegates used as type of an event) should have a very specific signature:

  • Return type void.
  • First argument of type System.Object and named 'sender'.
  • Second argument of type System.EventArgs (or any derived type) and is named 'e'.

This rule raises an issue whenever a delegate declaration doesn't match that signature.

Noncompliant Code Example

public delegate void AlarmEventHandler(object s);

public class Foo
{
    public event AlarmEventHandler AlarmEvent; // Noncompliant
}

Compliant Solution

public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);

public class Foo
{
    public event AlarmEventHandler AlarmEvent; // Compliant
}

See

Handling and Raising Events

csharpsquid:S3908

Since .Net Framework version 2.0 it is not necessary to declare a delegate that specifies a class derived from System.EventArgs. The System.EventHandler<TEventArgs> delegate mechanism should be used instead as it allows any class derived from EventArgs to be used with that handler.

This rule raises an issue when an old style delegate is used as an event handler.

Noncompliant Code Example

public class MyEventArgs : EventArgs
{
}

public delegate void MyEventHandler(object sender, MyEventArgs e); // Noncompliant

public class EventProducer
{
  public event MyEventHandler MyEvent;

  protected virtual void OnMyEvent(MyEventArgs e)
  {
    if (MyEvent != null)
    {
      MyEvent(e);
    }
  }
}

public class EventConsumer
{
  public EventConsumer(EventProducer producer)
  {
      producer.MyEvent += HandleEvent;
  }

  private void HandleEvent(object sender, MyEventArgs e)
  {
    // Do something...
  }
}

Compliant Solution

public class MyEventArgs : EventArgs
{
}

public class EventProducer
{
  public event EventHandler<MyEventArgs> MyEvent;

  protected virtual void OnMyEvent(MyEventArgs e)
  {
    if (MyEvent != null)
    {
      MyEvent(e);
    }
  }
}

public class EventConsumer
{
  public EventConsumer(EventProducer producer)
  {
      producer.MyEvent += HandleEvent;
  }

  private void HandleEvent(object sender, MyEventArgs e)
  {
    // Do something...
  }
}
csharpsquid:S3909

The NET Framework 2.0 introduced the generic interface System.Collections.Generic.IEnumerable<T> and it should be preferred over the older, non generic, interfaces.

This rule raises an issue when a public type implements System.Collections.IEnumerable.

Noncompliant Code Example

using System;
using System.Collections;

public class MyData
{
  public MyData()
  {
  }
}

public class MyList : CollectionBase // Noncompliant
{
  public void Add(MyData data)
  {
    InnerList.Add(data);
  }

  // ...
}

Compliant Solution

using System;
using System.Collections.ObjectModel;

public class MyData
{
  public MyData()
  {
  }
}

public class MyList : Collection<MyData>
{
  // Implementation...
}
csharpsquid:S3923

Having all branches in a switch or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a switch/if chain at all.

Noncompliant Code Example

if (b == 0)  // Noncompliant
{
    DoTheThing();
}
else
{
    DoTheThing();
}

int b = a > 12 ? 4 : 4;  // Noncompliant

switch (i) // Noncompliant
{
    case 1:
        DoSomething();
        break;
    case 2:
        DoSomething();
        break;
    case 3:
        DoSomething();
        break;
    default:
        DoSomething();
}

Exceptions

This rule does not apply to if chains without else-s, or to switch-es without default clauses.

if (b == 0)    //no issue, this could have been done on purpose to make the code more readable
{
    DoSomething();
}
else if (b == 1)
{
    DoSomething();
}
csharpsquid:S3925

The ISerializable interface is the mechanism to control the type serialization process. If not implemented correctly this could result in an invalid serialization and hard to detect bugs.

This rules raises an issue on types that implement ISerializable without following the serialization pattern recommended by Microsoft.

Specifically this rule checks for these problems:

  • The System.SerializableAttribute attribute is missing.
  • Non-serializable fields are not marked with the System.NonSerializedAttribute attribute.
  • There is no serialization constructor.
  • An unsealed type has a serialization constructor that is not protected.
  • A sealed type has a serialization constructor that is not private.
  • An unsealed type has a ISerializable.GetObjectData that is not both public and virtual.
  • A derived type has a serialization constructor that does not call the base constructor.
  • A derived type has a ISerializable.GetObjectData method that does not call the base method.
  • A derived type has serializable fields but the ISerializable.GetObjectData method is not overridden.

Noncompliant Code Example

public class Foo : ISerializable // Noncompliant the [Serializable] attribute is missing
{
}

or

public class Bar
{
}

[Serializable]
public class Foo : ISerializable // Noncompliant the serialization constructor is missing
{
    private readonly Bar bar; // Noncompliant the field is not marked with [NonSerialized]
}

Compliant Solution

public class Bar
{
}

[Serializable]
public class Foo : ISerializable
{
    [NonSerialized]
    private readonly Bar bar;

    public Foo()
    {
        // ...
    }

    protected Foo(SerializationInfo info, StreamingContext context)
    {
        // ...
    }

    public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        // ...
    }
}

[Serializable]
public sealed class SubFoo : Foo
{
    private int val;

    public SubFoo()
    {
        // ...
    }

    private SubFoo(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
        // ...
    }

    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        base.GetObjectData(info, context);
        // ...
    }
}

Exceptions

  • Classes in test projects are not checked.
csharpsquid:S3926

Fields marked with System.Runtime.Serialization.OptionalFieldAttribute are serialized just like any other field. But such fields are ignored on deserialization, and retain the default values associated with their types. Therefore, deserialization event handlers should be declared to set such fields during the deserialization process.

This rule raises when at least one field with the System.Runtime.Serialization.OptionalFieldAttribute attribute is declared but one (or both) of the following event handlers System.Runtime.Serialization.OnDeserializingAttribute or System.Runtime.Serialization.OnDeserializedAttribute are not present.

Noncompliant Code Example

[Serializable]
public class Foo
{
    [OptionalField(VersionAdded = 2)]
    int optionalField = 5;
}

Compliant Solution

[Serializable]
public class Foo
{
    [OptionalField(VersionAdded = 2)]
    int optionalField = 5;

    [OnDeserializing]
    void OnDeserializing(StreamingContext context)
    {
	    optionalField = 5;
    }

    [OnDeserialized]
    void OnDeserialized(StreamingContext context)
    {
        // Set optionalField if dependent on other deserialized values.
    }
}
csharpsquid:S3928

Some constructors of the ArgumentException, ArgumentNullException, ArgumentOutOfRangeException and DuplicateWaitObjectException classes must be fed with a valid parameter name. This rule raises an issue in two cases:

  • When this parameter name doesn't match any existing ones.
  • When a call is made to the default (parameterless) constructor

Noncompliant Code Example

public void Foo(Bar a, int[] b)
{
  throw new ArgumentException(); // Noncompliant
  throw new ArgumentException("My error message", "c"); // Noncompliant
  throw new ArgumentException("My error message", "c", innerException); // Noncompliant
  throw new ArgumentNullException("c"); // Noncompliant
  throw new ArgumentNullException("My error message", "c"); // Noncompliant
  throw new ArgumentOutOfRangeException("c");
  throw new ArgumentOutOfRangeException("c", "My error message"); // Noncompliant
  throw new ArgumentOutOfRangeException("c", b, "My error message"); // Noncompliant
}

Compliant Solution

public void Foo(Bar a, Bar b)
{
  throw new ArgumentException("My error message", "a");
  throw new ArgumentException("My error message", "b", innerException);
  throw new ArgumentNullException("a");
  throw new ArgumentNullException(nameOf(a));
  throw new ArgumentNullException("My error message", "a");
  throw new ArgumentOutOfRangeException("b");
  throw new ArgumentOutOfRangeException("b", "My error message");
  throw new ArgumentOutOfRangeException("b", b, "My error message");
}

Exceptions

The rule won't raise an issue if the parameter name is not a constant value (inline declaration, nameof() or const variable).

csharpsquid:S3956

System.Collections.Generic.List<T> is a generic collection that is designed for performance and not inheritance. For example, it does not contain virtual members that make it easier to change the behavior of an inherited class. That means that future attempts to expand the behavior will be spoiled because the extension points simply aren't there. Instead, one of the following generic collections should be used:

  • System.Collections.Generic.IEnumerable<T>
  • System.Collections.Generic.IReadOnlyCollection<T>
  • System.Collections.Generic.ICollection<TKey>
  • System.Collections.Generic.IReadOnlyList<T>
  • System.Collections.Generic.IList<TKey>
  • System.Collections.ObjectModel.Collection<T>
  • System.Collections.ObjectModel.ReadOnlyCollection<T>
  • System.Collections.ObjectModel.KeyedCollection<TKey, Titem>

This rule raises an issue every time a System.Collections.Generic.List<T> is exposed:

  • As an externally visible member.
  • As the return type of an externally visible method.
  • As a parameter type of an an externally visible method.

Noncompliant Code Example

namespace Foo
{
   public class Bar
   {
      public List<T> Method1(T arg) // Noncompliant
      {
           //...
      }
   }
}

Compliant Solution

namespace Foo
{
   public class Bar
   {
      public Collection<T> Method1(T arg)
      {
           //...
      }
   }
}
csharpsquid:S3962

The value of a static readonly field is computed at runtime while the value of a const field is calculated at compile time, which improves performance.

This rule raises an issue when a static readonly field is initialized with a value that is computable at compile time.

As specified by Microsoft, the list of types that can have a constant value are:

C# type .Net Fwk type
bool System.Boolean
byte System.Byte
sbyte System.SByte
char System.Char
decimal System.Decimal
double System.Double
float System.Single
int System.Int32
uint System.UInt32
long System.Int64
ulong System.UInt64
short System.Int16
ushort System.UInt16
string System.String

Noncompliant Code Example

namespace myLib
{
  public class Foo
  {
    static readonly int x = 1;  // Noncompliant
    static readonly int y = x + 4; // Noncompliant
    static readonly string s = "Bar";  // Noncompliant
  }
}

Compliant Solution

namespace myLib
{
  public class Foo
  {
    const int x = 1;
    const int y = x + 4;
    const string s = "Bar";
  }
}
csharpsquid:S3963

When a static constructor serves no other purpose that initializing static fields, it comes with an unnecessary performance cost because the compiler generates a check before each static method or instance constructor invocation.

Instead, inline initialization is highly recommended.

Noncompliant Code Example

namespace myLib
{
  public class Foo
  {
    static int i;
    static string s;

    static Foo() // Noncompliant
    {
      i = 3;
      ResourceManager sm =  new ResourceManager("strings", Assembly.GetExecutingAssembly());
      s = sm.GetString("mystring");
    }
  }
}

Compliant Solution

namespace myLib
{
  public class Foo
  {
    static int i =3;
    static string s = InitString();

    static string InitString()
    {
      ResourceManager sm = new ResourceManager("strings", Assembly.GetExecutingAssembly());
      return sm.GetString("mystring");
    }
  }
}
csharpsquid:S3966

A proper implementation of IDisposable.Dispose should allow for it to be called multiple times on the same object, however this is not guaranteed and could result in an exception being thrown.

It is best not to rely on this behaviour and therefore make sure an object is disposed only once on all execution paths. This is particularly true when dealing with nested using statements.

Noncompliant Code Example

using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
{
    using (StreamWriter writer = new StreamWriter(stream))  // Noncompliant: 'stream' will be disposed twice
    {
        // Use the writer object...
    }
}

Compliant Solution

Stream stream = null;
try
{
    stream = new FileStream("file.txt", FileMode.OpenOrCreate);
    using (StreamWriter writer = new StreamWriter(stream))
    {
        stream = null;
        // Use the writer object...
    }
}
finally
{
    if(stream != null)
        stream.Dispose();
}
csharpsquid:S3967

A jagged array is an array whose elements are arrays. It is recommended over a multidimensional array because the arrays that make up the elements can be of different sizes, which avoids wasting memory space.

Noncompliant Code Example

int [,] myArray =  // Noncompliant
    {
        {1,2,3,4},
        {5,6,7,0},
        {8,0,0,0},
        {9,0,0,0}
    };
// ...
myArray[1,1] = 0;

Compliant Solution

int[][] myArray =
    {
        new int[] {1,2,3,4},
        new int[] {5,6,7},
        new int[] {8},
        new int[] {9}
    };
// ...
myArray[1][1] = 0;
csharpsquid:S3971

GC.SuppressFinalize requests that the system not call the finalizer for the specified object. This should only be done when implementing Dispose as part of the Dispose Pattern.

This rule raises an issue when GC.SuppressFinalize is called outside that pattern.

csharpsquid:S3972

Code is clearest when each statement has its own line. Nonetheless, it is a common pattern to combine on the same line an if and its resulting then statement. However, when an if is placed on the same line as the closing } from a preceding else or else if, it is either an error - else is missing - or the invitation to a future error as maintainers fail to understand that the two statements are unconnected.

Noncompliant Code Example

if (condition1) {
  // ...
} if (condition2) {  // Noncompliant
  //...
}

Compliant Solution

if (condition1) {
  // ...
} else if (condition2) {
  //...
}

Or

if (condition1) {
  // ...
}

if (condition2) {
  //...
}
csharpsquid:S3973

In the absence of enclosing curly braces, the line immediately after a conditional is the one that is conditionally executed. By both convention and good practice, such lines are indented. In the absence of both curly braces and indentation the intent of the original programmer is entirely unclear and perhaps not actually what is executed. Additionally, such code is highly likely to be confusing to maintainers.

Noncompliant Code Example

if (condition)  // Noncompliant
DoTheThing();

DoTheOtherThing();
SomethingElseEntirely();

Foo();

Compliant Solution

if (condition)
  DoTheThing();

DoTheOtherThing();
SomethingElseEntirely();

Foo();
csharpsquid:S3981

The size of a collection and the length of an array are always greater than or equal to zero. So testing that a size or length is greater than or equal to zero doesn't make sense, since the result is always true. Similarly testing that it is less than zero will always return false. Perhaps the intent was to check the non-emptiness of the collection or array instead.

Noncompliant Code Example

if(collection.Count >= 0){...}

if(enumerable.Count() < 0){...}

if(array.Length >= 0){...}

bool result = array.Length >=0;

Compliant Solution

if (list.Any()) { ... }

if (list.Count > 0) { ... }

if (array.Length >= 42) { ... }
csharpsquid:S3990

Assemblies should conform with the Common Language Specification (CLS) in order to be usable across programming languages. To be compliant an assembly has to indicate it with System.CLSCompliantAttribute.

Compliant Solution

using System;

[assembly:CLSCompliant(true)]
namespace MyLibrary
{
}
csharpsquid:S3992

Assemblies should explicitly indicate whether they are meant to be COM visible or not. If the ComVisibleAttribute is not present, the default is to make the content of the assembly visible to COM clients.

Note that COM visibility can be overridden for individual types and members.

Noncompliant Code Example

using System;

namespace MyLibrary  // Noncompliant
{
}

Compliant Solution

using System;

[assembly: System.Runtime.InteropServices.ComVisible(false)]
namespace MyLibrary
{
}
csharpsquid:S3993

When defining custom attributes, System.AttributeUsageAttribute must be used to indicate where the attribute can be applied. This will determine its valid locations in the code.

Noncompliant Code Example

using System;

namespace MyLibrary
{

   public sealed class MyAttribute :Attribute // Noncompliant
   {
      string text;

      public MyAttribute(string myText)
      {
         text = myText;
      }
      public string Text
      {
         get
         {
            return text;
         }
      }
   }
}

Compliant Solution

using System;

namespace MyLibrary
{

   [AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate)]
   public sealed class MyAttribute :Attribute
   {
      string text;

      public MyAttribute(string myText)
      {
         text = myText;
      }
      public string Text
      {
         get
         {
            return text;
         }
      }
   }
}
csharpsquid:S3994

String representations of URIs or URLs are prone to parsing and encoding errors which can lead to vulnerabilities. The System.Uri class is a safe alternative and should be preferred. At minimum, an overload of the method taking a System.Uri as a parameter should be provided in each class that contains a method with an apparent Uri passed as a string.

This rule raises issues when a method has a string parameter with a name containing "uri", "Uri", "urn", "Urn", "url" or "Url", and the type doesn't declare a corresponding overload taking an System.Uri parameter instead.

Noncompliant Code Example

using System;

namespace MyLibrary
{
   public class MyClass
   {

      public void FetchResource(string uriString) { } // Noncompliant
   }
}

Compliant Solution

using System;

namespace MyLibrary
{
   public class MyClass
   {

      public void FetchResource(string uriString)
      {
          FetchResource(new Uri(uriString));
      }

      public void FetchResource(Uri uri) { }
   }
}
csharpsquid:S3995

String representations of URIs or URLs are prone to parsing and encoding errors which can lead to vulnerabilities. The System.Uri class is a safe alternative and should be preferred.

This rule raises an issue when a method has a string return type and its name contains "Uri", "Urn", or "Url" or begins with "uri", "urn", or "url".

Noncompliant Code Example

using System;

namespace MyLibrary
{
   public class MyClass
   {
      public string GetParentUri() // Noncompliant
      {
         return "http://www.mysite.com";
      }
   }
}

Compliant Solution

using System;

namespace MyLibrary
{
   public class MyClass
   {

      public Uri GetParentUri()
      {
         return new URI("http://www.mysite.com");
      }
   }
}
csharpsquid:S3996

String representations of URIs or URLs are prone to parsing and encoding errors which can lead to vulnerabilities. The System.Uri class is a safe alternative and should be preferred.

This rule raises an issue when a property is a string type and its name contains "uri", "Uri", "urn", "Urn", "url" or "Url".

Noncompliant Code Example

using System;

namespace MyLibrary
{
   public class MyClass
   {
      string myUri;

      public string MyUri // Noncompliant
      {
         get { return myURI; }
         set { myUri = value; }
      }
   }
}

Compliant Solution

using System;

namespace MyLibrary
{
   public class MyClass
   {
      Uri myUri;

      public Uri MyUri
      {
         get { return myURI; }
         set { myUri = value; }
      }
   }
}
csharpsquid:S3997

String representations of URIs or URLs are prone to parsing and encoding errors which can lead to vulnerabilities. The System.Uri class is a safe alternative and should be preferred.

This rule raises an issue when two overloads differ only by the string / Uri parameter and the string overload doesn't call the Uri overload. It is assumed that the string parameter represents a URI because of the exact match besides that parameter type. It stands to reason that the safer overload should be used.

Noncompliant Code Example

using System;

namespace MyLibrary
{
   public class MyClass
   {
      public void FetchResource(string uriString) // Noncompliant
      {
         // No calls to FetResource(Uri)
      }

      public void FetchResource(Uri uri) { }
   }
}

Compliant Solution

using System;

namespace MyLibrary
{
   public class MyClass
   {
      public void FetchResource(string uriString)
      {
          FetchResource(new Uri(uriString));
      }

      public void FetchResource(Uri uri) { }
   }
}
csharpsquid:S3998

A thread acquiring a lock on an object that can be accessed across application domain boundaries runs the risk of being blocked by another thread in a different application domain. Objects that can be accessed across application domain boundaries are said to have weak identity. Types with weak identity are:

  • MarshalByRefObject
  • ExecutionEngineException
  • OutOfMemoryException
  • StackOverflowException
  • String
  • MemberInfo
  • ParameterInfo
  • Thread

Noncompliant Code Example

using System;
using System.Threading;

namespace MyLibrary
{
  class Foo
  {
    string myString = "foo";

    void Bar()
    {
      lock(myString) { } // Noncompliant
    }
  }
}

Compliant Solution

using System;
using System.Threading;

namespace MyLibrary
{
  class Foo
  {
    string myString = "foo";
    private readonly Object thisLock = new Object();

    void Bar()
    {
      lock(thisLock) { } // Compliant
    }
  }
}
csharpsquid:S4000

The IntPtr and UIntPtr types are used to access unmanaged memory, usually in order to use C or C++ libraries. If such a pointer is not secured by making it private, internal or readonly, it can lead to a vulnerability allowing access to arbitrary locations.

Noncompliant Code Example

using System;

namespace MyLibrary
{
  public class MyClass
  {
    public IntPtr myPointer;  // Noncompliant
    protected UIntPtr myOtherPointer; // Noncompliant
  }
}

Compliant Solution

using System;

namespace MyLibrary
{
  public class MyClass
  {
    private IntPtr myPointer;
    protected readonly UIntPtr myOtherPointer;
  }
}
csharpsquid:S4002

This rule raises an issue when a disposable type contains fields of the following types and does not implement a finalizer:

  • System.IntPtr
  • System.UIntPtr
  • System.Runtime.InteropService.HandleRef

Noncompliant Code Example

using System;
using System.Runtime.InteropServices;

namespace MyLibrary
{
  public class Foo : IDisposable // Noncompliant: Doesn't have a finalizer
  {
    private IntPtr myResource;
    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
      if (!disposed)
      {
        // Dispose of resources held by this instance.
        FreeResource(myResource);
        disposed = true;

        // Suppress finalization of this disposed instance.
        if (disposing)
        {
          GC.SuppressFinalize(this);
        }
      }
    }

    public void Dispose() {
      Dispose(true);
    }
  }
}

Compliant Solution

using System;
using System.Runtime.InteropServices;

namespace MyLibrary
{
  public class Foo : IDisposable
  {
    private IntPtr myResource;
    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
      if (!disposed)
      {
        // Dispose of resources held by this instance.
        FreeResource(myResource);
        disposed = true;

        // Suppress finalization of this disposed instance.
        if (disposing)
        {
          GC.SuppressFinalize(this);
        }
      }
    }

    ~Foo()
    {
      Dispose(false);
    }
  }
}

See

  • Related: S3881 - "IDisposable" should be implemented correctly
csharpsquid:S4004

A writable collection property can be replaced by a completely different collection. Making it readonly prevents that while still allowing individual members to be set. If you want to allow the replacement of the whole collection the recommended pattern is to implement a method to remove all the elements (e.g. System.Collections.List<T>.Clear) and a method to populate the collection (e.g. System.Collections.List<T>.AddRange).

This rule raises an issue when an externally visible writable property is of a type that implements System.Collections.ICollection or System.Collections.Generic.ICollection<T>.

Noncompliant Code Example

using System;
using System.Collections;

namespace MyLibrary
{
  public class Foo
  {
    List<string> strings;

    public List<string> SomeStrings
    {
      get { return strings; }
      set { strings = value; } // Noncompliant
    }
  }
}

Compliant Solution

using System;
using System.Collections;

namespace MyLibrary
{
  public class Foo
  {
    List<string> strings;

    public readonly List<string> SomeStrings
    {
      get { return strings; }
    }
  }
}

Exceptions

This rule does not raise issues for string, Array and PermissionSet.

csharpsquid:S4005

String representations of URIs or URLs are prone to parsing and encoding errors which can lead to vulnerabilities. The System.Uri class is a safe alternative and should be preferred.

This rule raises an issue when a called method has a string parameter with a name containing "uri", "Uri", "urn", "Urn", "url" or "Url" and the declaring type contains a corresponding overload that takes a System.Uri as a parameter.

When there is a choice between two overloads that differ only regarding the representation of a URI, the user should choose the overload that takes a System.Uri argument.

Noncompliant Code Example

using System;

namespace MyLibrary
{
   public class Foo
   {
      public void FetchResource(string uriString) { }
      public void FetchResource(Uri uri) { }

      public string ReadResource(string uriString, string name, bool isLocal) { }
      public string ReadResource(Uri uri, string name, bool isLocal) { }

      public void Main() {
        FetchResource("http://www.mysite.com"); // Noncompliant
        ReadResource("http://www.mysite.com", "foo-resource", true); // Noncompliant
      }
   }
}

Compliant Solution

using System;

namespace MyLibrary
{
   public class Foo
   {
      public void FetchResource(string uriString) { }
      public void FetchResource(Uri uri) { }

      public string ReadResource(string uriString, string name, bool isLocal) { }
      public string ReadResource(Uri uri, string name, bool isLocal) { }

      public void Main() {
        FetchResource(new Uri("http://www.mysite.com"));
        ReadResource(new Uri("http://www.mysite.com"), "foo-resource", true);
      }
   }
}
csharpsquid:S4015

Changing an inherited member to private will not prevent access to the base class implementation.

This rule raises an issue when a private method in an unsealed type has a signature that is identical to a public method declared in a base type.

Noncompliant Code Example

using System;

namespace MyLibrary
{
  public class Foo
  {
    public void SomeMethod(int count) { }
  }
  public class Bar:Foo
  {
    private void SomeMethod(int count) { } // Noncompliant
  }
}

Compliant Solution

using System;

namespace MyLibrary
{
  public class Foo
  {
    public void SomeMethod(int count) { }
  }
  public sealed class Bar : Foo
  {
    private void SomeMethod(int count) { }
  }
}
csharpsquid:S4016

If an enum member's name contains the word "reserved" it implies it is not currently used and will be change in the future. However changing an enum member is a breaking change and can create significant problems. There is no need to reserve an enum member since a new member can be added in the future, and such an addition will usually not be a breaking change.

This rule raises an issue when the name of an enumeration member contains "reserved".

Noncompliant Code Example

using System;

namespace MyLibrary
{
  public enum Color
  {
        None,
        Red,
        Orange,
        Yellow,
        ReservedColor  // Noncompliant
    }
}
csharpsquid:S4017

A nested type is a type argument that is also a generic type. Calling a method with such a nested type argument requires complicated and confusing code. It should be avoided as much as possible.

Noncompliant Code Example

using System;
using System.Collections.Generic;

namespace MyLibrary
{
  public class Foo
  {
    public void DoSomething(ICollection<ICollection<int>> outerCollect) // Noncompliant
    {
    }
  }
}
csharpsquid:S4018

The best way to determine the type of a generic method is by inference based on the type of argument that is passed to the method. This is not possible when a parameter type is missing from the argument list.

Noncompliant Code Example

using System;

namespace MyLibrary
{
  public class Foo
  {
    public void MyMethod<T>()  // Noncompliant
    {
    }
  }
}

Compliant Solution

using System;

namespace MyLibrary
{
  public class Foo
  {
    public void MyMethod<T>(T param)
    {
    }
  }
}
csharpsquid:S4019

When a method in a derived class has the same name as a method in the base class but with a signature that only differs by types that are weakly derived (e.g. object vs string), the result is that the base method becomes hidden.

Noncompliant Code Example

using System;

namespace MyLibrary
{
  class Foo
  {
    internal void SomeMethod(string s1, string s2) { }
  }

  class Bar : Foo
  {
    internal void SomeMethod(string s1, object o2) { }  // Noncompliant
  }
}

Compliant Solution

using System;

namespace MyLibrary
{
  class Foo
  {
    internal void SomeMethod(string s1, string s2) { }
  }

  class Bar : Foo
  {
    internal void SomeOtherMethod(string s1, object o2) { }
  }
}
csharpsquid:S4022

By default the storage type of an enum is Int32. In most cases it is not necessary to change this. In particular you will not achieve any performance gain by using a smaller data type (e.g. Byte) and may limit future uses.

Noncompliant Code Example

using System;

namespace MyLibrary
{
    public enum Visibility : sbyte // Noncompliant
    {
        Visible = 0,
        Invisible = 1,
    }
}

Compliant Solution

using System;

namespace MyLibrary
{
    public enum Visibility
    {
        Visible = 0,
        Invisible = 1,
    }
}
csharpsquid:S4023

Empty interfaces are usually used as a marker or a way to identify groups of types. The preferred way to achieve this is to use custom attributes.

Noncompliant Code Example

using System;

namespace MyLibrary
{
   public interface MyInterface // Noncompliant
   {
   }
}

Compliant Solution

using System;

namespace MyLibrary
{
   public interface MyInterface
   {
      void Foo();
   }
}
csharpsquid:S4025

Having a field in a child class with a name that differs from a parent class' field only by capitalization is sure to cause confusion. Such child class fields should be renamed.

Noncompliant Code Example

public class Fruit
{
  protected string plantingSeason;
  //...
}

public class Raspberry : Fruit
{
  protected string plantingseason;  // Noncompliant
  // ...
}

Compliant Solution

public class Fruit
{
  protected string plantingSeason;
  //...
}

public class Raspberry : Fruit
{
  protected string whenToPlant;
  // ...
}

Or

public class Fruit
{
  protected string plantingSeason;
  //...
}

public class Raspberry : Fruit
{
  // field removed; parent field will be used instead
  // ...
}
csharpsquid:S4026

It is important to inform the ResourceManager of the language used to display the resources of the neutral culture for an assembly. This improves lookup performance for the first resource loaded.

This rule raises an issue when an assembly contains a ResX-based resource but does not have the System.Resources.NeutralResourcesLanguageAttribute applied to it.

Noncompliant Code Example

using System;

public class MyClass // Noncompliant
{
   public static void Main()
   {
      string[] cultures = { "de-DE", "en-us", "fr-FR" };
      Random rnd = new Random();
      int index = rnd.Next(0, cultures.Length);
      Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cultures[index]);

      ResourceManager rm = new ResourceManager("MyResources" ,
                                               typeof(MyClass).Assembly);
      string greeting = rm.GetString("Greeting");

      Console.Write("Enter your name: ");
      string name = Console.ReadLine();
      Console.WriteLine("{0} {1}!", greeting, name);
   }
}

Compliant Solution

using System;

[assembly:NeutralResourcesLanguageAttribute("en")]
public class MyClass
{
   public static void Main()
   {
      string[] cultures = { "de-DE", "en-us", "fr-FR" };
      Random rnd = new Random();
      int index = rnd.Next(0, cultures.Length);
      Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cultures[index]);

      ResourceManager rm = new ResourceManager("MyResources" ,
                                               typeof(MyClass).Assembly);
      string greeting = rm.GetString("Greeting");

      Console.Write("Enter your name: ");
      string name = Console.ReadLine();
      Console.WriteLine("{0} {1}!", greeting, name);
   }
}
csharpsquid:S4027

Exceptions types should provide the following constructors:

  • public MyException()
  • public MyException(string)
  • public MyException(string, Exception)
  • protected or private MyException(SerializationInfo, StreamingContext)

That fourth constructor should be protected in unsealed classes, and private in sealed classes.

Not having this full set of constructors can make it difficult to handle exceptions.

Noncompliant Code Example

using System;

namespace MyLibrary
{
  public class MyException // Noncompliant: several constructors are missing
  {
    public MyException()
    {
    }
  }
}

Compliant Solution

using System;
using System.Runtime.Serialization;

namespace MyLibrary
{
  public class MyException : Exception
  {
      public MyException()
      {
      }

      public MyException(string message)
          :base(message)
      {
      }

      public MyException(string message, Exception innerException)
          : base(message, innerException)
      {
      }

      protected MyException(SerializationInfo info, StreamingContext context)
          : base(info, context)
      {
      }
  }
}
csharpsquid:S4035

When a class implements the IEquatable<T> interface, it enters a contract that, in effect, states "I know how to compare two instances of type T or any type derived from T for equality.". However if that class is derived, it is very unlikely that the base class will know how to make a meaningful comparison. Therefore that implicit contract is now broken.

Alternatively IEqualityComparer<T> provides a safer interface and is used by collections or Equals could be made virtual.

This rule raises an issue when a unsealed, public or protected class implements IEquitable<T> and the Equals is not virtual.

Noncompliant Code Example

using System;

namespace MyLibrary
{
  class Base : IEquatable<Base> // Noncompliant
  {
    bool Equals(Base other)
    {
      if (other == null) { return false };
      // do comparison of base properties
    }

    override bool Equals(object other)  => Equals(other as Base);
  }

  class A : Base
  {
    bool Equals(A other)
    {
      if (other == null) { return false };
      // do comparison of A properties
      return base.Equals(other);
    }

    override bool Equals(object other)  => Equals(other as A);
  }

  class B : Base
  {
    bool Equals(B other)
    {
      if (other == null) { return false };
      // do comparison of B properties
     return base.Equals(other);
    }

    override bool Equals(object other)  => Equals(other as B);
  }

  static void Main() {
    A a = new A();
    B b = new B();

    Console.WriteLine(a.Equals(b)); // This calls the WRONG equals. This causes Base::Equals(Base)
    //  to be called which only compares the properties in Base and ignores the fact that
    // a and b are different types. In the working example A::Equals(Object) would have been
    // called and Equals would return false because it correctly recognizes that a and b are
    // different types. If a and b have the same base properties they will  be returned as equal.
  }
}

Compliant Solution

using System;

namespace MyLibrary
{
    public sealed class Foo : IEquatable<Foo>
    {
        public bool Equals(Foo other)
        {
            // Your code here
        }
    }
}

See

Inheritance and IEquatable do not mix

IEqualityComparer<T> Interface

csharpsquid:S4041

When a type name matches the name of a publicly defined namespace, for instance one in the .NET framework class library, it leads to confusion and makes the library that much harder to use.

This rule raises an issue when a name of a public type matches the name of a .NET Framework namespace, or a namespace of the project assembly, in a case-insensitive comparison.

Noncompliant Code Example

using System;

namespace MyLibrary
{
  public class Text   // Noncompliant: Collides with System.Text
  {
  }
}

Compliant Solution

using System;

namespace MyLibrary
{
  public class MyText
  {
  }
}
csharpsquid:S4047

When a reference parameter (keyword ref) is used, the passed argument type must exactly match the reference parameter type. This means that to be able to pass a derived type, it must be cast and assigned to a variable of the proper type. Use of generic methods eliminates that cumbersome down casting and should therefore be preferred.

This rule raises an issue when a method contains a ref parameter of type System.Object.

Noncompliant Code Example

using System;

namespace MyLibrary
{
  public class Foo
  {
    public void Bar(ref object o1, ref object o2) // Noncompliant
    {
    }
  }
}

Compliant Solution

using System;

namespace MyLibrary
{
  public class Foo
  {
    public void Bar<T>(ref T ref1, ref T ref2)
    {
    }
  }
}
csharpsquid:S4050

When implementing operator overloads, it is very important to make sure that all related operators and methods are consistent in their implementation.

The following guidelines should be followed:

  • When providing operator == you should also provide operator != and vice-versa.
  • When providing operator == you should also provide Equals(Object) and GetHashCode().
  • When providing operator + or operator - you should also provide operator ==, respecting previous guidelines.

This rule raises an issue when any of these guidelines are not followed on publicly-visible type (public, protected or protected internal).

Noncompliant Code Example

using System;

namespace MyLibrary
{
  public class Foo // Noncompliant
  {
    private int left;
    private int right;

    public Foo(int l, int r)
    {
      this.left = l;
      this.right = r;
    }

    public static Foo operator +(Foo a, Foo b)
    {
      return new Foo(a.left + b.left, a.right + b.right);
    }

    public static Foo operator -(Foo a, Foo b)
    {
      return new Foo(a.left - b.left, a.right - b.right);
    }
  }
}

Compliant Solution

using System;

namespace MyLibrary
{
  public class Foo
  {
    private int left;
    private int right;

    public Foo(int l, int r)
    {
      this.left = l;
      this.right = r;
    }

    public static Foo operator +(Foo a, Foo b)
    {
      return new Foo(a.left + b.left, a.right + b.right);
    }

    public static Foo operator -(Foo a, Foo b)
    {
      return new Foo(a.left - b.left, a.right - b.right);
    }

    public static bool operator ==(Foo a, Foo b)
    {
      return (a.left == b.left && a.right == b.right);
    }

    public static bool operator !=(Foo a, Foo b)
    {
      return !(a == b);
    }

    public override bool Equals(Object obj)
    {
      Foo a = obj as Foo;
      if (a == null)
        return false;
      return this == a;
    }

    public override int GetHashCode()
    {
       return (this.left * 10) + this.right;
    }
  }
}
csharpsquid:S4052

With the advent of .NET framework version 2, certain practices have become obsolete.

In particular, exceptions should now extend System.Exception instead of System.ApplicationException. Similarly, generic collections should be used instead of the older, non-generic, ones. Finally when creating an XML view, you should not extend System.Xml.XmlDocument.

This rule raises an issue when an externally visible type extends one of these types:

  • System.ApplicationException
  • System.Xml.XmlDocument
  • System.Collections.CollectionBase
  • System.Collections.DictionaryBase
  • System.Collections.Queue
  • System.Collections.ReadOnlyCollectionBase
  • System.Collections.SortedList
  • System.Collections.Stack

Noncompliant Code Example

using System;
using System.Collections;

namespace MyLibrary
{
  public class MyCollection : CollectionBase  // Noncompliant
  {
  }
}

Compliant Solution

using System;
using System.Collections;

namespace MyLibrary
{
  public class MyCollection : Collection<T>
  {
  }
}
csharpsquid:S4055

String literals embedded in the source code will not be localized properly.

This rule raises an issue when a literal string is passed as a parameter or property and one or more of the following cases is true:

  • The LocalizableAttribute attribute of the parameter or property is set to true.
  • The parameter or property name contains "Text", "Message", or "Caption".
  • The name of the string parameter that is passed to a Console.Write or Console.WriteLine method is either "value" or "format".

Noncompliant Code Example

using System;
using System.Globalization;
using System.Reflection;
using System.Windows.Forms;

[assembly: NeutralResourcesLanguageAttribute("en-US")]
namespace MyLibrary
{
    public class Foo
    {
        public void SetHour(int hour)
        {
            if (hour < 0 || hour > 23)
            {
                MessageBox.Show("The valid range is 0 - 23."); // Noncompliant
            }
        }
    }
}

Compliant Solution

using System;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Windows.Forms;



[assembly: NeutralResourcesLanguageAttribute("en-US")]
namespace MyLibrary
{
    public class Foo
    {
        ResourceManager rm;
        public Foo()
        {
            rm = new ResourceManager("en-US", Assembly.GetExecutingAssembly());
        }

        public void SetHour(int hour)
        {
            if (hour < 0 || hour > 23)
            {
                MessageBox.Show(
                rm.GetString("OutOfRangeMessage", CultureInfo.CurrentUICulture));
            }
        }
    }
}
csharpsquid:S4056

When a System.Globalization.CultureInfo or IFormatProvider object is not supplied, the default value that is supplied by the overloaded member might not have the effect that you want in all locales.

You should supply culture-specific information according to the following guidelines:

  • If the value will be displayed to the user, use the current culture. See CultureInfo.CurrentCulture.
  • If the value will be stored and accessed by software (persisted to a file or database), use the invariant culture. See CultureInfo.InvariantCulture.
  • If you do not know the destination of the value, have the data consumer or provider specify the culture.

This rule raises an issue when a method or constructor calls one or more members that have overloads that accept a System.IFormatProvider parameter, and the method or constructor does not call the overload that takes the IFormatProvider parameter. This rule ignores calls to .NET Framework methods that are documented as ignoring the IFormatProvider parameter as well as the following methods:

  • Activator.CreateInstance
  • ResourceManager.GetObject
  • ResourceManager.GetString

Noncompliant Code Example

using System;

namespace MyLibrary
{
    public class Foo
    {
        public void Bar(String string1)
        {
            if(string.Compare(string1, string2, false) == 0) // Noncompliant
            {
                Console.WriteLine(string3.ToLower()); // Noncompliant
            }
        }
    }
}

Compliant Solution

using System;
using System.Globalization;

namespace MyLibrary
{
    public class Foo
    {
        public void Bar(String string1, String string2, String string3)
        {
            if(string.Compare(string1, string2, false,
                              CultureInfo.InvariantCulture) == 0)
            {
                Console.WriteLine(string3.ToLower(CultureInfo.CurrentCulture));
            }
        }
    }
}

Exceptions

This rule will not raise an issue when the overload is marked as obsolete.

csharpsquid:S4057

When you create a DataTable or DataSet, you should set the locale explicitly. By default, the locale for these types is the current culture. For data that is stored in a database or file and is shared globally, the locale should ordinarily be set to the invariant culture (CultureInfo.InvariantCulture).

This rule raises an issue when System.Data.DataTable or System.Data.DataSet instances are created without explicitly setting the locale property (DataTable.Locale or DataSet.Locale).

Noncompliant Code Example

using System;
using System.Data;

namespace MyLibrary
{
    public class Foo
    {
        public DataTable CreateTable()
        {
            DataTable table = new DataTable("Customers"); // Noncompliant table.Locale not set
            DataColumn key = table.Columns.Add("ID", typeof(Int32));

            key.AllowDBNull = false;
            key.Unique = true;
            table.Columns.Add("LastName", typeof(String));
            table.Columns.Add("FirstName", typeof(String));
            return table;
        }
    }
}

Compliant Solution

using System;
using System.Data;
using System.Globalization;

namespace MyLibrary
{
    public class Foo
    {
        public DataTable CreateTable()
        {
            DataTable table = new DataTable("Customers");
            table.Locale = CultureInfo.InvariantCulture;
            DataColumn key = table.Columns.Add("ID", typeof(Int32));

            key.AllowDBNull = false;
            key.Unique = true;
            table.Columns.Add("LastName", typeof(String));
            table.Columns.Add("FirstName", typeof(String));
            return table;
        }
    }
}
csharpsquid:S4058

Many string operations, the Compare and Equals methods in particular, provide an overload that accepts a StringComparison enumeration value as a parameter. Calling these overloads and explicitly providing this parameter makes your code clearer and easier to maintain.

This rule raises an issue when a string comparison operation doesn't use the overload that takes a StringComparison parameter.

Noncompliant Code Example

using System;

namespace MyLibrary
{
  public class Foo
  {
    public bool HaveSameNames(string name1, string name2)
    {
      return string.Compare(name1, name2) == 0; // Noncompliant
    }
  }
}

Compliant Solution

using System;

namespace MyLibrary
{
  public class Foo
  {
    public bool HaveSameNames(string name1, string name2)
    {
      return string.Compare(name1, name2, StringComparison.OrdinalIgnoreCase) == 0;
    }
  }
}
csharpsquid:S4059

Properties and Get method should have names that makes them clearly distinguishable.

This rule raises an issue when the name of a public or protected member starts with 'Get' and otherwise matches the name of a public or protected property.

Noncompliant Code Example

using System;

namespace MyLibrary
{
    public class Foo
    {
        public DateTime Date
        {
            get { return DateTime.Today; }
        }

        public string GetDate() // Noncompliant
        {
            return this.Date.ToString();
        }
    }
}

Compliant Solution

using System;

namespace MyLibrary
{
    public class Foo
    {
        public DateTime Date
        {
            get { return DateTime.Today; }
        }

        public string GetDateAsString()
        {
            return this.Date.ToString();
        }
    }
}
csharpsquid:S4060

The .NET framework class library provides methods for retrieving custom attributes. Sealing the attribute eliminates the search through the inheritance hierarchy, and can improve performance.

This rule raises an issue when a public type inherits from System.Attribute, is not abstract, and is not sealed.

Noncompliant Code Example

using System;

namespace MyLibrary
{
    [AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct)]
    public class MyAttribute: Attribute // Noncompliant
    {
        private string nameValue;
        public MyAttribute(string name)
        {
            nameValue = name;
        }

        public string Name
        {
            get
            {
                return nameValue;
            }
        }
    }
}

Compliant Solution

using System;

namespace MyLibrary
{
    [AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct)]
    public sealed class MyAttribute: Attribute
    {
        private string nameValue;
        public MyAttribute(string name)
        {
            nameValue = name;
        }

        public string Name
        {
            get
            {
                return nameValue;
            }
        }
    }
}
csharpsquid:S4061

A method using the VarArgs calling convention is not Common Language Specification (CLS) compliant and might not be accessible across programming languages, while the params keyword works the same way and is CLS compliant.

This rule raises an issue when a public or protected type contains a public or protected method that uses the VarArgs calling convention.

Noncompliant Code Example

using System;

namespace MyLibrary
{
    public class Foo
    {
        public void Bar(__arglist) // Noncompliant
        {
            ArgIterator argumentIterator = new ArgIterator(__arglist);
            for(int i = 0; i < argumentIterator.GetRemainingCount(); i++)
            {
                Console.WriteLine(
                    __refvalue(argumentIterator.GetNextArg(), string));
            }
        }
    }
}

Compliant Solution

using System;

[assembly: CLSCompliant(true)]
namespace MyLibrary
{
    public class Foo
    {
        public void Bar(params string[] wordList)
        {
            for(int i = 0; i < wordList.Length; i++)
            {
                Console.WriteLine(wordList[i]);
            }
        }
    }
}

Exceptions

Interop methods using VarArgs calling convention do not raise an issue.

[DllImport("msvcrt40.dll")]
public static extern int printf(string format, __arglist); // Compliant
csharpsquid:S4070

This rule raises an issue when an externally visible enumeration is marked with FlagsAttribute and one, or more, of its values is not a power of 2 or a combination of the other defined values.

Noncompliant Code Example

using System;

namespace MyLibrary
{
    [FlagsAttribute]
    public enum Color // Noncompliant, Orange is neither a power of two, nor a combination of any of the defined values
    {
        None    = 0,
        Red     = 1,
        Orange  = 3,
        Yellow  = 4
    }
}

Compliant Solution

using System;

namespace MyLibrary
{
    public enum Color // Compliant - no FlagsAttribute attribute
    {
        None = 0,
        Red = 1,
        Orange = 3,
        Yellow = 4
    }

    [FlagsAttribute]
    public enum Days
    {
        None = 0,
        Monday = 1,
        Tuesday = 2,
        Wednesday = 4,
        Thursday = 8,
        Friday = 16,
        All = Monday| Tuesday | Wednesday | Thursday | Friday    // Compliant - combination of other values
    }
}
csharpsquid:S4142

There are valid cases for passing a variable multiple times into the same method call, but usually doing so is a mistake, and something else was intended for one of the arguments.

Noncompliant Code Example

if (Compare(point.X, point.X) != 0) // Noncompliant
{
  //...
}

if (DoSomething(GetNextValue(), GetNextValue()))  // Noncompliant
{
  // ...
}

Compliant Solution

if (Compare(point.X, point.Y) != 0)
{
  //...
}

var v1 = GetNextValue();
var v2 = GetNextValue();
if (DoSomething(v1, v2))
{
  // ...
}

Deprecated

This rule is deprecated, and will eventually be removed.

csharpsquid:S4144

When two methods have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, one implementation should invoke the other.

Noncompliant Code Example

private const string CODE = "bounteous";
private int callCount = 0;

public string GetCode()
{
  callCount++;
  return CODE;
}

public string GetName()  // Noncompliant
{
  callCount++;
  return CODE;
}

Compliant Solution

private const string CODE = "bounteous";
private int callCount = 0;

public string GetCode()
{
  callCount++;
  return CODE;
}

public string GetName()
{
  return GetCode();
}

Exceptions

Empty methods, methods with only one line of code and methods with the same name (overload) are ignored.

csharpsquid:S4158

When a collection is empty it makes no sense to access or iterate it. Doing so anyway is surely an error; either population was accidentally omitted or the developer doesn't understand the situation.

This rule raises an issue when any use is made of an empty collection other than the following ignored calls: Add, AddRange, Equals, GetHashCode.

Noncompliant Code Example

var strings = new List<string>();

strings.Remove("bar");  // Noncompliant

if (strings.Contains("foo")) {}  // Noncompliant

foreach (var str in strings) {}  // Noncompliant
csharpsquid:S4159

In the Attributed Programming Model, the ExportAttribute declares that a part "exports", or provides to the composition container, an object that fulfills a particular contract. During composition, parts with imports that have matching contracts will have those dependencies filled by the exported object.

If the type doesn't implement the interface it is exporting there will be an issue at runtime (either a cast exception or just a container not filled with the exported type) leading to unexpected behaviors/crashes.

The rule raises an issue when a class doesn't implement or inherit the type declared in the ExportAttribute.

Noncompliant Code Example

[Export(typeof(ISomeType))]
public class SomeType // Noncompliant; doesn't implement 'ISomeType'.
{
}

Compliant Solution

[Export(typeof(ISomeType))]
public class SomeType : ISomeType
{
}
csharpsquid:S4200

Native methods are functions that reside in libraries outside the virtual machine. Being able to call them is useful for interoperability with applications and libraries written in other programming languages, in particular when performing platform-specific operations. However doing so comes with extra risks since it means stepping out of the security model of the virtual machine. It is therefore highly recommended to take extra steps, like input validation, when invoking native methods. This is best done by making the native method private and by providing a wrapper that performs these extra steps and verifications.

This rule raises an issue when a native method is declared public or its wrapper is too trivial.

Noncompliant Code Example

using System;
using System.Runtime.InteropServices;

namespace MyLibrary
{
  class Foo
  {
    [DllImport("mynativelib")]
    extern public static void Bar(string s, int x); // Noncompliant
  }
}

Compliant Solution

using System;
using System.Runtime.InteropServices;

namespace MyLibrary
{
  class Foo
  {
    [DllImport("mynativelib")]
    extern private static void Bar(string s, int x);

    public void BarWrapper(string s, int x)
    {
      if (s != null && x >= 0  && x < s.Length)
      {
        bar(s, x);
      }
    }
  }
}
csharpsquid:S4210

When an assembly uses Windows Forms (classes and interfaces from the System.Windows.Forms namespace) its entry point should be marked with the STAThreadAttribute to indicate that the threading model should be "Single-Threaded Apartment" (STA) which is the only one supported by Windows Forms.

This rule raises an issue when the entry point (static void Main method) of an assembly using Windows Forms is not marked as STA.

Noncompliant Code Example

using System;
using System.Windows.Forms;

namespace MyLibrary
{
    public class MyForm: Form
    {
        public MyForm()
        {
            this.Text = "Hello World!";
        }

        public static void Main()  // Noncompliant
        {
            var form = new MyForm();
            Application.Run(form);
        }
    }
}

Compliant Solution

using System;
using System.Windows.Forms;

namespace MyLibrary
{
    public class MyForm: Form
    {
        public MyForm()
        {
            this.Text = "Hello World!";
        }

        [STAThread]
        public static void Main()
        {
            var form = new MyForm();
            Application.Run(form);
        }
    }
}
csharpsquid:S4214

Methods marked with the System.Runtime.InteropServices.DllImportAttribute attribute use Platform Invocation Services to access unmanaged code and should not be exposed. Keeping them private or internal makes sure that their access is controlled and properly managed.

This rule raises an issue when a method declared with DllImport is public or protected.

Noncompliant Code Example

using System;
using System.Runtime.InteropServices;

namespace MyLibrary
{
    public class Foo
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        public static extern bool RemoveDirectory(string name);  // Noncompliant
    }
}

Compliant Solution

using System;
using System.Runtime.InteropServices;

namespace MyLibrary
{
    public class Foo
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        private static extern bool RemoveDirectory(string name);
    }
}
csharpsquid:S4220

When raising an event, two arguments are expected by the EventHandler delegate: Sender and event-data. There are three guidelines regarding these parameters:

  • Do not pass null as the sender when raising a non-static event.
  • Do pass null as the sender when raising a static event.
  • Do not pass null as the event-data. If no data should be passed, then EventArgs.Empty should be used.

This rule raises an issue when any of these guidelines is not met.

Noncompliant Code Example

using System;

namespace MyLibrary
{
  class Foo
  {
    public event EventHandler ThresholdReached;

    protected virtual void OnThresholdReached(EventArgs e)
    {
        ThresholdReached?.Invoke(null, e); // Noncompliant
    }
  }
}

Compliant Solution

using System;

namespace MyLibrary
{
  class Foo
  {
    public event EventHandler ThresholdReached;

    protected virtual void OnThresholdReached(EventArgs e)
    {
        ThresholdReached?.Invoke(this, e);
    }
  }
}
csharpsquid:S4225

Creating an extension method that extends object is not recommended because it makes the method available on every type. Extensions should be applied at the most specialized level possible, and that is very unlikely to be object.

Noncompliant Code Example

using System;

namespace MyLibrary
{
    public static class MyExtensions
    {
        public static void Foo(this object o)  //Noncompliant
        {
            // ...
        }
    }
}
csharpsquid:S4261

According to the Task-based Asynchronous Pattern (TAP), methods returning either a System.Threading.Tasks.Task or a System.Threading.Tasks.Task<TResult> are considered "asynchronous". Such methods should use the Async suffix. Conversely methods which do not return such Tasks should not have an "Async" suffix in their names.

Noncompliant Code Example

using System;
using  System.Threading.Tasks;

namespace myLibrary
{

  public class Foo
  {
    public Task Read(byte [] buffer, int offset, int count, // Noncompliant
                                CancellationToken cancellationToken)
  }
}

Compliant Solution

using System;
using  System.Threading.Tasks;

namespace myLibrary
{

  public class Foo
  {
    public Task ReadAsync(byte [] buffer, int offset, int count, CancellationToken cancellationToken)
  }
}

Exceptions

This rule doesn't raise an issue when the method is an override or part of the implementation of an interface since it can not be renamed.

See

csharpsquid:S4275

Properties provide a way to enforce encapsulation by providing public, protected or internal methods that give controlled access to private fields. However in classes with multiple fields it is not unusual that cut and paste is used to quickly create the needed properties, which can result in the wrong field being accessed by a getter or setter.

This rule raises an issue in any of these cases:

  • A setter does not update the field with the corresponding name.
  • A getter does not access the field with the corresponding name.

For simple properties it is better to use auto-implemented properties (C# 3.0 or later).

Noncompliant Code Example

class A
{
    private int x;
    private int y;

    public int X
    {
        get { return x; }
        set { x = value; }
    }

    public int Y
    {
        get { return x; }  // Noncompliant: field 'y' is not used in the return value
        set { x = value; } // Noncompliant: field 'y' is not updated
    }
}

Compliant Solution

class A
{
    private int x;
    private int y;

    public int X
    {
        get { return x; }
        set { x = value; }
    }

    public int Y
    {
        get { return y; }
        set { y = value; }
    }
}
csharpsquid:S4277

Marking a class with PartCreationPolicy(CreationPolicy.Shared), which is part of Managed Extensibility Framework (MEF), means that a single, shared instance of the exported object will be created. Therefore it doesn't make sense to create new instances using the constructor and it will most likely result in unexpected behaviours.

This rule raises an issue when a constructor of a class marked shared with a PartCreationPolicyAttribute is invoked.

Noncompliant Code Example

[Export(typeof(IFooBar))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class FooBar : IFooBar
{
}

public class Program
{
    public static void Main()
    {
        var fooBar = new FooBar(); // Noncompliant;
    }
}

Compliant Solution

[Export(typeof(IFooBar))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class FooBar : IFooBar
{
}

public class Program
{
    public static void Main()
    {
        var fooBar = serviceProvider.GetService<IFooBar>();
    }
}
csharpsquid:S4428

The PartCreationPolicyAttribute attribute, which is part of the Managed Extensibility Framework (MEF), is used to specify how the exported object will be created. Therefore it doesn't make sense not to export this a class with this attribute using the ExportAttribute attribute.

This rule raises an issue when a class is marked as shared with a PartCreationPolicyAttribute but lacks a ExportAttribute.

Noncompliant Code Example

[PartCreationPolicy(CreationPolicy.Any)] // Noncompliant
public class FooBar : IFooBar
{
}

Compliant Solution

[Export(typeof(IFooBar))]
[PartCreationPolicy(CreationPolicy.Any)]
public class FooBar : IFooBar
{
}
csharpsquid:S4456

Because of the way yield methods are rewritten by the compiler (they become lazily evaluated state machines) any exceptions thrown during the parameters check will happen only when the collection is iterated over. That could happen far away from the source of the buggy code.

Therefore it is recommended to split the method into two: an outer method handling the validation (no longer lazy) and an inner (lazy) method to handle the iteration.

This rule raises an issue when a method throws any exception derived from ArgumentException and contains the yield keyword.

Noncompliant Code Example

public static IEnumerable<TSource> TakeWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) // Noncompliant
{
    if (source == null) { throw new ArgumentNullException(nameof(source)); }
    if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); }

    foreach (var element in source)
    {
        if (!predicate(element)) { break; }
        yield return element;
    }
}

Compliant Solution

public static IEnumerable<TSource> TakeWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null) { throw new ArgumentNullException(nameof(source)); }
    if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); }
    return TakeWhileIterator<TSource>(source, predicate);
}

private static IEnumerable<TSource> TakeWhileIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    foreach (TSource element in source)
    {
        if (!predicate(element)) break;
        yield return element;
    }
}
csharpsquid:S4457

Because of the way async/await methods are rewritten by the compiler, any exceptions thrown during the parameters check will happen only when the task is observed. That could happen far away from the source of the buggy code or never happen for fire-and-forget tasks.

Therefore it is recommended to split the method into two: an outer method handling the parameter checks (without being async/await) and an inner method to handle the iterator block with the async/await pattern.

This rule raises an issue when an async method throws any exception derived from ArgumentException and contains await keyword.

Noncompliant Code Example

public static async Task SkipLinesAsync(this TextReader reader, int linesToSkip) // Noncompliant
{
    if (reader == null) { throw new ArgumentNullException(nameof(reader)); }
    if (linesToSkip < 0) { throw new ArgumentOutOfRangeException(nameof(linesToSkip)); }

    for (var i = 0; i < linesToSkip; ++i)
    {
        var line = await reader.ReadLineAsync().ConfigureAwait(false);
        if (line == null) { break; }
    }
}

Compliant Solution

public static Task SkipLinesAsync(this TextReader reader, int linesToSkip)
{
    if (reader == null) { throw new ArgumentNullException(nameof(reader)); }
    if (linesToSkip < 0) { throw new ArgumentOutOfRangeException(nameof(linesToSkip)); }

    return reader.SkipLinesInternalAsync(linesToSkip);
}

private static async Task SkipLinesInternalAsync(this TextReader reader, int linesToSkip)
{
    for (var i = 0; i < linesToSkip; ++i)
    {
        var line = await reader.ReadLineAsync().ConfigureAwait(false);
        if (line == null) { break; }
    }
}
csharpsquid:S4462

Making blocking calls to async methods transforms something that was intended to be asynchronous into a synchronous block. Doing so can cause deadlocks and unexpected blocking of context threads.

According to the MSDN documentation:

The root cause of this deadlock is due to the way await handles contexts. By default, when an incomplete Task is awaited, the current ā€œcontextā€ is captured and used to resume the method when the Task completes. This ā€œcontextā€ is the current SynchronizationContext unless it’s null, in which case it’s the current TaskScheduler. GUI and ASP.NET applications have a SynchronizationContext that permits only one chunk of code to run at a time. When the await completes, it attempts to execute the remainder of the async method within the captured context. But that context already has a thread in it, which is (synchronously) waiting for the async method to complete. They’re each waiting for the other, causing a deadlock.

To Do This … Instead of This … Use This
Retrieve the result of a background task Task.Wait, Task.Result or Task.GetAwaiter.GetResult await
Wait for any task to complete Task.WaitAny await Task.WhenAny
Retrieve the results of multiple tasks Task.WaitAll await Task.WhenAll
Wait a period of time Thread.Sleep await Task.Delay

Noncompliant Code Example

public static class DeadlockDemo
{
    private static async Task DelayAsync()
    {
        await Task.Delay(1000);
    }

    // This method causes a deadlock when called in a GUI or ASP.NET context.
    public static void Test()
    {
        // Start the delay.
        var delayTask = DelayAsync();
        // Wait for the delay to complete.
        delayTask.Wait(); // Noncompliant
    }
}

Compliant Solution

public static class DeadlockDemo
{
    private static async Task DelayAsync()
    {
        await Task.Delay(1000);
    }

    public static async Task TestAsync()
    {
        // Start the delay.
        var delayTask = DelayAsync();
        // Wait for the delay to complete.
        await delayTask;
    }
}

Exceptions

  • Main methods of Console Applications are not subject to this deadlock issue and so are ignored by this rule.
  • Thread.Sleep is also ignored when it is used in a non-async method.
  • Calls chained after Task.Run or Task.Factory.StartNew are ignored because they don't suffer from this deadlock issue

See

csharpsquid:S4581

When the syntax new Guid() (i.e. parameterless instantiation) is used, it must be that one of three things is wanted:

  1. An empty GUID, in which case Guid.Empty is clearer.
  2. A randomly-generated GUID, in which case Guid.NewGuid() should be used.
  3. A new GUID with a specific initialization, in which case the initialization parameter is missing.

This rule raises an issue when a parameterless instantiation of the Guid struct is found.

Noncompliant Code Example

public void Foo()
{
    var g = new Guid(); // Noncompliant - what's the intent?
}

Compliant Solution

public void Foo(byte[] bytes)
{
    var g1 = Guid.Empty;
    var g2 = Guid.NewGuid();
    var g3 = new Guid(bytes);
}
csharpsquid:S4586

Returning null from a non-async Task/Task<T> method will cause a NullReferenceException at runtime. This problem can be avoided by returning Task.FromResult<T>(null) instead.

Noncompliant Code Example

public Task<object> GetFooAsync()
{
    return null; // Noncompliant
}

Compliant Solution

public Task<object> GetFooAsync()
{
    return Task.FromResult<object>(null);
}
css:S1128

Having the import of the same file twice, makes one of them useless. Leaving them in reduces the code's readability, since their presence can be confusing.

Noncompliant Code Example

@import 'a.css';
@import 'a.css'; // Noncompliant

@import url("a.css");
@import url("a.css"); // Noncompliant

Exceptions

This rule ignores @import in less files.

css:S4647

An invalid color definition will by default be interpreted as black, which is likely to have unintended impacts on the expected look and feel of the website.

This rule raises an issue when a color definition (color, background-color) is not valid. The color definition is considered valid when it is made of hexadecimal characters:

- longhand: 6 or 8 characters (when alpha is defined)

- shorthand variant: 3 or 4 characters (when alpha is defined)

Noncompliant Code Example

a {
 color: #3c; /* Noncompliant; shorthand should be made of 3 characters */
}
div {
  background-color: #3cb371a; /* Noncompliant; alpha should have 2 characters */
}

Compliant Solution

a {
 color: #3cc;
}
div {
  background-color: #3cb371ac;
}

See

css:S4648

Having duplicated font names doesn't help to read the font declaration and may be an indicator the author of the line was not sure how to configure it. This rule raises an issue when font or font-family properties contain a duplicated font name. This rule ignores $sass, @less, and var(--custom-property) variable syntaxes.

Noncompliant Code Example

a {
  font-family: 'Georgia', Georgia, serif; /* Noncompliant; 'Georgia' is duplicated */
}

Compliant Solution

a {
  font-family: Georgia, serif;
}
css:S4649

If none of the font names defined in a font or font-family declaration are available on the browser of the user, the browser will display the text using its default font. It's recommended to always define a generic font family for each declaration of font or font-family to get a less degraded situation than relying on the default browser font. All browsers should implement a list of generic font matching these families: Serif, Sans-serif, cursive, fantasy, Monospace.

Noncompliant Code Example

a {
  font-family: Helvetica, Arial, Verdana, Tahoma; /* Noncompliant; there is no generic font family in the list */
}

Compliant Solution

a {
  font-family: Helvetica, Arial, Verdana, Tahoma, sans-serif;
}

See

css:S4650

calc is a CSS3 function that provides the possibility to do simple math in CSS (add, subtract, divide, multiply). Without spaces around operators, calc will have no effect.

More precisely, before an operator, there must be a single whitespace or a newline plus indentation. After an operator, there must be a single whitespace or a newline.

Noncompliant Code Example

#div1 {
    position: absolute;
    width: calc(100%- 100px); /* Noncompliant; no space after the % sign */
}

Compliant Solution

#div1 {
    position: absolute;
    width: calc(100% - 100px);
}
css:S4651

linear-gradient was standardized with CSS3. Before that, it was possible to use different non-standard values to define the gradient's direction. Because these values are not standard, they are not supported in all browsers and therefore they should no longer be used in order to get the expected gradient in the latest browser versions that support CSS3.

This rule raises an issue when the first parameter of a linear-gradient is not a valid <side-or-corner> or angle.

Noncompliant Code Example

.foo {
  background: linear-gradient(top, #fff, #000);
}

.bar {
  background: linear-gradient(45, #fff, #000);
}

Compliant Solution

.foo {
  background: linear-gradient(to top, #fff, #000);
}

.bar {
  background: linear-gradient(45deg, #fff, #000);
}

See

css:S4652

According to the W3C specifications:

A string cannot directly contain a newline. To include a newline in a string, use an escape representing the line feed character in ISO-10646 (U+000A), such as "\A" or "\00000a".

[...]

It is possible to break strings over several lines, for aesthetic or other reasons, but in such a case the newline itself has to be escaped with a backslash (\).

Noncompliant Code Example

a {
  content: "first
    second";
}

Compliant Solution

a {
  content: "first\Asecond";
}

See

css:S4653

The W3C specifications define the units that can be used with lengths. A unit that is not part of the list of supported ones is likely to be a typo and will be seen as a UI bug by the user.

This rule raises an issue each time a unit is not officially supported.

Noncompliant Code Example

a {
  width: 10pixels; /* Noncompliant; "pixels" is not a valid unit */
}

Compliant Solution

a {
  width: 10px;
}

See

css:S4654

The W3C specifications define the valid CSS properties. Only the official and browser-specific properties should be used to get the expected impact in the final rendering.

This rule ignores:

- $sass, @less, and var(--custom-property) variable syntaxes.

- vendor-prefixed properties (e.g., -moz-align-self, -webkit-align-self).

Noncompliant Code Example

a {
  colour: blue; /* Noncompliant; colour is not part of the specifications */
}

Compliant Solution

a {
  color: blue;
}
css:S4656

CSS allows duplicate property names but only the last instance of a duplicated name determines the actual value that will be used for it. Therefore, changing values of other occurrences of a duplicated name will have no effect and may cause misunderstandings and bugs.

This rule ignores $sass, @less, and var(--custom-property) variable syntaxes.

Noncompliant Code Example

a {
  color: pink;
  background: orange;
  color: orange
}

Compliant Solution

a {
  color: pink;
  background: orange
}
css:S4657

A shorthand property defined after a longhand property will completely override the value defined in the longhand property making the longhand one useless. The code should be refactored to consider the longhand property or to remove it completely.

Noncompliant Code Example

a {
  padding-left: 10px;
  padding: 20px; /* Noncompliant; padding is overriding padding-left making it useless */
}

Compliant Solution

a {
  padding: 10px; /* Compliant; padding is defining a general behaviour and padding-left, just after, is precising the left case */
  padding-left: 20px;
}

See

css:S4658

Leftover empty blocks are usually introduced by mistake. They are useless and prevent readability of the code. They should be removed or completed with real code.

Noncompliant Code Example

a { }

Compliant Solution

a { color: pink; }
css:S4659

The W3C specifications define the valid pseudo-class selectors. Only the official and browser-specific pseudo-class selectors should be used to get the expected impact in the final rendering.

Noncompliant Code Example

a:hoverr { /* Noncompliant; there is a typo on the word "hover" */
...
}

Compliant Solution

a:hover {
...
}
css:S4660

The W3C specifications define the valid pseudo-element selectors. Only the official and browser-specific pseudo-element selectors should be used to get the expected impact in the final rendering.

Noncompliant Code Example

a::beforre { /* Noncompliant; there is a typo on the word "before" */
...
}

Compliant Solution

a::before {
...
}
css:S4661

The W3C specifications define the valid media features. Only the official and browser-specific media features should be used to get the expected impact in the final rendering.

Noncompliant Code Example

@media screen and (unknown: 1000px) { .. }

Compliant Solution

@media screen and (width: 1000px) { .. }

See

css:S4663

An empty multi-line comment is likely to be a mistake and doesn't help to improve the readability of the code. For these reasons, it should be removed.

Noncompliant Code Example

/* */

/*

 */
css:S4664

Order of instructions in CSS is important: instructions with equal specificity that occur later in the file take the priority. But when a selector with a higher specificity (e.g. p a { color: green;}) comes before the selector it overrides (e.g.: a { color: green;}), the priority is given to the first one. Even if it works properly, this is harder to anticipate the behaviour of the stylesheet while reading as it goes against the principle that the last instruction takes the priority.

Noncompliant Code Example

p a {
  color: green;
}

a {
  color: blue;
}

Compliant Solution

a {
  color: blue;
}

p a {
  color: green;
}
css:S4666

Duplication of selectors might indicate a copy-paste mistake. The rule detects the following kinds of duplications:

  • within a list of selectors in a single rule set
  • for duplicated selectors in different rule sets within a single stylesheet.

Noncompliant Code Example

.foo, .bar, .foo { ... }  /* Noncompliant */

.class1 { ... }
.class1 { ... }  /* Noncompliant */

Compliant Solution

.foo, .bar { ... }

.class1 { ... }
.class2 { ... }
css:S4667

This rule raises an issue when a CSS file is empty (ie: containing only spaces).

css:S4668

The W3C specifications say comments should be defined using /* ... */. The use of // is not supported on all browsers and can lead to unexpected results.

Noncompliant Code Example

// some comment
a { color: pink; }

Compliant Solution

/* some comment */
a { color: pink; }

Exceptions

This rule ignores single line comments in less and scss files.

flex:ActionScript2

Usage of statements, operators and keywords specific to ActionScript 2 does not allow to migrate to ActionScript 3. This includes "intrinsic" keyword, set variable statement and following list of operators:

  • <> (inequality) - use != instead
  • add (concatenation (strings)) - use + instead
  • eq (equality (strings)) - use == instead
  • ne (not equal (strings)) - use != instead
  • lt (less than (strings)) - use < instead
  • le (less than or equal to (strings)) - use <= instead
  • gt (greater than (strings)) - use > instead
  • ge (greater than or equal to (strings)) - use >= instead
  • and (logical and) - use && instead
  • or (logical or) - use || instead
  • not (logical not) - use ! instead

Noncompliant Code Example

if (true != false) { // Compliant
}

if (true <> false) { // Noncompliant
}

set("varName", value); // Noncompliant
varName = value; // Compliant
flex:ClassComplexity

The cyclomatic complexity of a class should not exceed a defined threshold. Complex code can perform poorly and will in any case be difficult to understand and therefore to maintain.

Deprecated

This rule is deprecated, and will eventually be removed.

flex:FunctionComplexity

The Cyclomatic Complexity of functions should not exceed a defined threshold. Complex code may perform poorly and can be difficult to test thoroughly.

flex:LineLength

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

flex:OneStatementPerLine

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

if(someCondition) doSomething();

Compliant Solution

if(someCondition) {
  doSomething();
}
flex:ParsingError

When the Flex parser fails, it is possible to record the failure as a violation on the file. This way, not only it is possible to track the number of files that do not parse but also to easily find out why they do not parse.

flex:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression: ^[a-z][a-zA-Z0-9]*$

function DoSomething(){...}

Compliant Solution

function doSomething(){...}
flex:S101

Shared coding conventions allow teams to collaborate effectively. This rule allows to check that all class names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression ^[A-Z][a-zA-Z0-9]*$:

public class myClass {...}

Compliant Solution

public class MyClass {...}
flex:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if (condition1) {
  if (condition2) {             // NonCompliant
    ...
  }
}

Compliant Solution

if (condition1 && condition2) {
  ...
}
flex:S1068

If a private field is declared but not used in the program, it can be considered dead code and should therefore be removed. This will improve maintainability because developers will not wonder what the variable is used for.

Noncompliant Code Example

public class MyClass {
  private var foo:int = 4;                       //foo is unused

  public function compute(a:int):int{
    return a * 4;
  }
}

Compliant Solution

public class MyClass {

  public function compute(a:int):int{
    return a * 4;
  }
}
flex:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

Noncompliant Code Example

With a maximum number of 4 parameters:

public function addData(p1 : int, p2 : int, p3 : int, p4 : int, p5 : int): void  {
...
}

Compliant Solution

public function addData(p1 : int, p2 : int, p3 : int, p4 : int): void  {
...
}
flex:S108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

for (var i:int = 0; i < 42; i++){}  // Noncompliant

try {                               // Noncompliant
} catch (error)
{
    ...
}

Compliant Solution

for (var i:int = 0; i < 42; i++);

for (var i:int = 0; i < 42; i++) {
  trace(i);
}

Exceptions

When a block contains a comment, this block is not considered to be empty.

flex:S1125

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

Noncompliant Code Example

if (booleanMethod() == true) { /* ... */ }
if (booleanMethod() == false) { /* ... */ }
if (booleanMethod() || false) { /* ... */ }
doSomething(!false);
doSomething(booleanMethod() == true);

booleanVariable = booleanMethod() ? true : false;
booleanVariable = booleanMethod() ? true : exp;
booleanVariable = booleanMethod() ? false : exp;
booleanVariable = booleanMethod() ? exp : true;
booleanVariable = booleanMethod() ? exp : false;

Compliant Solution

if (booleanMethod()) { /* ... */ }
if (!booleanMethod()) { /* ... */ }
if (booleanMethod()) { /* ... */ }
doSomething(true);
doSomething(booleanMethod());

booleanVariable = booleanMethod();
booleanVariable = booleanMethod() || exp;
booleanVariable = !booleanMethod() && exp;
booleanVariable = !booleanMethod() || exp;
booleanVariable = booleanMethod() && exp;
flex:S1142

Having too many return statements in a function increases the function's essential complexity because the flow of execution is broken each time a return statement is encountered. This makes it harder to read and understand the logic of the function.

Noncompliant Code Example

With the default threshold of 3:

function myFunction():boolean { // Noncompliant as there are 4 return statements
  if (condition1) {
    return true;
  } else {
    if (condition2) {
      return false;
    } else {
      return true;
    }
  }
  return false;
}
flex:S1144

Private functions that are never executed are dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.

Noncompliant Code Example

public class Foo
{
  private function Foo(){}   //Compliant, private empty constructor intentionally used to prevent any direct instantiation of a class.
  public static function doSomething():void
  {
    var foo:Foo = new Foo();
    ...
  }
  private function unusedPrivateFunction():void {...}
}

Compliant Solution

public class Foo
{
  private function Foo(){}   //Compliant, private empty constructor intentionally used to prevent any direct instantiation of a class.
  public static function doSomething():void
  {
    var foo:Foo = new Foo();
    ...
  }
}
flex:S115

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all constant names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$:

public static const first:String = "first";

Compliant Solution

public static const FIRST:String = "first";
flex:S1151

The switch statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the case clause should be extracted into a dedicated method.

Noncompliant Code Example

With the default threshold of 5:

switch (myVariable) {
  case 0:       // Noncompliant - 6 lines till next case or default case
    trace("");
    trace("");
    trace("");
    trace("");
    break;
  case 1:
  ...
}

Compliant Solution

switch (myVariable) {
  case 0:
    printSomething()
    break;
  case 1:
  ...
}
...
private function printSomething() {
  trace("");
  trace("");
  trace("");
  trace("");
}
flex:S116

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that field names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[_a-z][a-zA-Z0-9]*$:

class MyClass {
  public var my_field:int;
}

Compliant Solution

public class MyClass {
   public var myField:int;
}
flex:S117

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a local variable or function parameter name does not match the provided regular expression.

Noncompliant Code Example

With the default regular expression ^[_a-z][a-zA-Z0-9]*$:

public function doSomething(my_param:int):void
{
  var LOCAL:int;
  ...
}

Compliant Solution

public function doSomething(myParam):void
{
  var local;
  ...
}
flex:S1170

Making a public constant just const as opposed to static const leads to duplicating its value for every instance of the class, uselessly increasing the amount of memory required to execute the application.

Noncompliant Code Example

public class Myclass
{
  public const THRESHOLD:int = 3;
}

Compliant Solution

public class Myclass
{
  public static const THRESHOLD:int = 3;
}
flex:S1176

Try to imagine using the standard Flex API without ASDoc. It would be a nightmare, because ASDoc is the only way to understand of the contract of the API.

Documenting an API with ASDoc increases the productivity of the developers use it.

Noncompliant Code Example

public class MyClass {
  public var myLabel:String;

  public function myMethod(param1:String):Boolean {...}
}

Compliant Solution

/**
 * my doc
 */
public class MyClass {
  /**
   * my doc
   */
  public var myLabel:String;

  /**
   * my doc
   * @param param1 my doc
   * @return my doc
   */
  public function myMethod(param1:String):Boolean {...}
}

Exceptions

Classes or class elements with an ASDoc @private comment are ignored by this rule.

/**
 * @private  // This class and all its elements are ignored
 */
public class MyClass {  // Compliant

  public var myLabel:String;   // Compliant
}

public class AnotherClass {  // Noncompliant; class not @private and not documented

  /**
   * @private
   */
  public var name:String;  // Compliant
}
flex:S1185

Overriding a method just to call the same method from the super class without performing any other actions is useless and misleading.

Noncompliant Code Example

override public function doSomething() : void
{
  super.doSomething();
}

override public function isLegal(action:Action) : Boolean
{
  return super.isLegal(action);
}

Compliant Solution

override public function doSomething() : void
{
  super.doSomething();                             // Compliant - not simply forwarding the call
  doSomethingElse();
}

override public function isLegal(action:Action) : Boolean
{
  return super.isLegal(new Action(...));   // Compliant - not simply forwarding the call
}

[Deprecated(replacement="isAuthorized")]
override public function isLegal(action:Action) : Boolean
{
  return super.isLegal(action);   // Compliant as there is a metadata
}
flex:S1186

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

  • 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 NotSupportedException should be thrown.
  • The method is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.

Noncompliant Code Example

public override function doSomething():void {
}

public function doSomethingElse():void {
}

Compliant Solution

public override function doSomething():void {
  throw new IllegalOperationError("doSomething cannot be performed because ...");
}

public function doSomethingElse():void {
  //This method is empty because ...
}
flex:S120

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all package names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z]+(\.[a-z][a-z0-9]*)*$:

package org.Example {  // Noncompliant
...
}

Compliant Solution

package org.example {
...
}
flex:S1312

Loggers should be:

  • private: not accessible outside of their parent classes. If another class needs to log something, it should instantiate its own logger.
  • static: not dependent on an instance of a class (an object). When logging something, contextual information can of course be provided in the messages but the logger should be created at class level to prevent creating a logger along with each object.
  • const: created once and only once per class.

Noncompliant Code Example

With the default regular expression LOG(?:GER)?:

public const logger:ILogger = LogUtil.getLogger(MyClass);

Compliant Solution

private static const LOG:ILogger = LogUtil.getLogger(MyClass);
flex:S134

Nested if, for, while, do while and switch statements is a key ingredient 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:

  if (condition1) {                  // Compliant - depth = 1
    /* ... */
    if (condition2) {                // Compliant - depth = 2
      /* ... */
      for(int i = 0; i < 10; i++) {  // Compliant - depth = 3, not exceeding the limit
        /* ... */
        if (condition4) {            // Noncompliant - depth = 4
          if (condition5) {          // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
            /* ... */
          }
          return;
        }
      }
    }
  }
flex:S138

A function that grows too large tends to aggregate too many responsibilities.

Such functions inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions which focus on well-defined tasks.

Those smaller functions will not only be easier to understand, but also probably easier to test.

flex:S1434

Creating a new variable with the type "Object" means that it may be used to store any kind of object. This feature may be required in some specific contexts, but it leaves the compiler unable to do any kind of type checking, and is therefore a hazardous practice.

Noncompliant Code Example

var obj:Object = new String(); // Noncompliant; Object used explicitly
var foo = new Object(); // Noncompliant; Object used explicitly
var bar = {name:String, age:int};  // Noncompliant; Object implicitly created

Compliant Solution

var obj:String = new String();
var foo:IPortfolio = new Portfolio();
class Person {
  public var name:String;
  public var age:int;
}
var bar:Person = new Person();
flex:S1435

According to the ActionScript language reference, the star type:

Specifies that a property is untyped. Use of the asterisk symbol for a type annotation is equivalent to using no type annotation. Expressions that read from untyped properties are considered untyped expressions. Use of untyped expressions or properties is recommended in the following circumstances:

  • When you want to defer type checking to runtime. You can use an untyped property or expression to circumvent compile-time type checking in strict mode. Note, however, that runtime type checking of assignment statements occurs whether you use strict mode or not.
  • When you want to store the value undefined in a property. Unlike previous versions of ActionScript, the value undefined is not a member of the Object data type. You must use an untyped property to store the value undefined.

But deferring type checking to runtime can highly impact the robustness of the application because the compiler is unable to assist the developer.

Noncompliant Code Example

var obj:*;  // Noncompliant
var foo:* = new Something();  // Noncompliant

Compliant Solution

var obj:Something;
var foo:Something = new Something();
flex:S1438

In Flex, the semicolon is optional as a statement separator, but omitting semicolons can be confusing.

Noncompliant Code Example

function fun() {
  return   // Noncompliant
       5   // Noncompliant
}
print(fun());  // prints "undefined", not "5"

Compliant Solution

function fun() {
  return 5;
}
print(fun());
flex:S1439

Any statement or block of statements can be identified by a label, but those labels should be used only on while, do-while and for statements. Using labels in any other context leads to unstructured, confusing code.

Noncompliant Code Example

myLabel:if (i % 2 == 0) {  // Noncompliant
  if (i == 12) {
    print("12");
    break myLabel;
  }
  print("Odd number, but not 12");
}

Compliant Solution

myLabel:for (i = 0; i < 10; i++) {   // Compliant
  print("Loop");
  break myLabel;
}
flex:S1440

The == and != operators do type coercion before comparing values. This is bad because it can mask type errors. For example, it evaluates ' \t\r\n' == 0 as true.

It is best to always use the side-effect-less === and !== operators instead.

Noncompliant Code Example

if (var == 'howdy') {...} // Noncompliant

Compliant Solution

if (var === 'howdy') {...}
flex:S1445

Even though this is syntactically correct, the void return type should not be used in the signature of a constructor. Indeed some developers might be confused by this syntax, believing that the constructor is in fact a standard function.

Noncompliant Code Example

public class Foo
{
  public function Foo() : void
  {...}
}

Compliant Solution

public class Foo
{
  public function Foo()
  {...}
}
flex:S1446

A dynamic class defines an object that can be altered at run time by adding or changing properties and methods. This extremely powerful mechanism should be used very carefully, and only in very limited use cases.

Indeed, by definition dynamic classes make refactoring difficult and prevent the compiler from raising potential errors at compile time.

Noncompliant Code Example

dynamic public class DynamicFoo
{...}

Compliant Solution

public class Foo  //Note that the class has been renamed to avoid confusion
{...}
flex:S1447

In ActionScript 3, constructor code is always interpreted rather than compiled by the JIT at runtime, which is why the body of a constructor should be as lightweight as possible. As soon as a constructor contains branches ("if", "for", "switch", ...) an issue is logged.

Noncompliant Code Example

public class Foo
{
  public function Foo()
  {
    if (condition) {  // Noncompliant
      // ...
    }
  }
}

Compliant Solution

public class Foo
{
  public function Foo()
  {
    init()
  }

  private function init():void
  {
    if (condition) {
      // ...
    }
  }
}
flex:S1448

A class that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor the class into smaller ones which focus on well defined topics.

flex:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
flex:S1454

Using several "--" or "++" unary operators in the same arithmetic expression can quickly make the expression unreadable.

Noncompliant Code Example

var j:int = foo++ - --bar;

Compliant Solution

bar--;
var j:int = foo++ - bar;
flex:S1455

Declaring the package and class together has been deprecated since ActionScript 3. The package definition should be declared outside of the class definition even if the old syntax is still supported.

Noncompliant Code Example

class P.A {...}

Compliant Solution

package P {
    class A {...}
}
flex:S1462

Using plain string event names in even listeners is an anti-pattern; if the event is renamed, the application can start behaving unexpectedly. A constant variable should be used instead.

Noncompliant Code Example

import flash.display.Sprite;
import flash.events.MouseEvent;

class ChildSprite extends Sprite
{
    public function ChildSprite()
    {
        ...
        addEventListener("CustomEvent", clickHandler);   // Noncompliant
    }
}

function clickHandler(event:CustomEvent):void
{
    trace("clickHandler detected an event of type: " + event.type);
    trace("the this keyword refers to: " + this);
}

Compliant Solution

import flash.display.Sprite;
import flash.events.MouseEvent;

class ChildSprite extends Sprite
{
   public const CUSTOM_EVENT:String = "CustomEvent";

    public function ChildSprite()
    {
        ...
        addEventListener(CUSTOM_EVENT, clickHandler);
    }
}

function clickHandler(event:CustomEvent):void
{
    trace("clickHandler detected an event of type: " + event.type);
    trace("the this keyword refers to: " + this);
}
flex:S1463

According to the Flex documentation :

In an ActionScript file, when you define component events or other aspects of a component that affect more than a single property, you add the metadata tag outside the class definition so that the metadata is bound to the entire class, as the following example shows:

// Add the [Event] metadata tag outside of the class file.
[Event(name="enableChange", type="flash.events.Event")]
public class ModalText extends TextArea {

    ...

    // Define class properties/methods
    private var _enableTA:Boolean;

    // Add the [Inspectable] metadata tag before the individual property.
    [Inspectable(defaultValue="false")]
    public function set enableTA(val:Boolean):void {
        _enableTA = val;
        this.enabled = val;

        // Define event object, initialize it, then dispatch it.
        var eventObj:Event = new Event("enableChange");
        dispatchEvent(eventObj);
    }
}

In this example, the "enableChange" event must be considered part of the API. Therefore, it should be strongly typed.

Noncompliant Code Example

[Event(name="enableChange")]
public class ModalText extends TextArea {...}

Compliant Solution

[Event(name="enableChange", type="flash.events.Event")]
public class ModalText extends TextArea {...}
flex:S1464

The "ManagedEvents" metadata tag allows you to flag an event as being managed. By definition this "ManagedEvents" metadata tag should be used in pair with an "Event" metadata tag.

Noncompliant Code Example

[Event(name="message", type="my.package.MyEvemt")]
[ManagedEvents("mes")]       //This "mes" event is not defined with the "Event" metadata tag
public class MyClass {...}

Compliant Solution

[Event(name="message", type="my.package.MyEvemt")]
[ManagedEvents("message")]
public class MyClass {...}
flex:S1465

A LocalConnection object is used to invoke a method in another LocalConnection object, either within a single SWF file or between multiple SWF files. This kind of local connection should be authorized only when the origin (domain) of the other Flex applications is perfectly defined.

Noncompliant Code Example

localConnection.allowDomain("*");

Compliant Solution

localConnection.allowDomain("www.myDomain.com");
flex:S1466

The Security.exactSettings value should remain set at the default value of true. Setting this value to false could make the SWF vulnerable to cross-domain attacks.

Noncompliant Code Example

Security.exactSettings = false;
flex:S1467

A listener can be attached to an object only after it has been constructed. So dispatching an event in a constructor is useless and error prone.

Noncompliant Code Example

public class MyClass
{
  public function MyClass()
  {
    dispatchEvent( new Event( "uselessEvent" ) );
  }
}
flex:S1468

Calling Security.allowDomain("*") lets any domain cross-script into the domain of this SWF and exercise its functionality.

Noncompliant Code Example

Security.allowDomain("*");

Compliant Solution

Security.allowDomain("www.myDomain.com");
flex:S1469

Quoted from the Flex documentation :

When you define an Array variable in ActionScript, you specify Array as the data type of the variable. However, you cannot specify the data type of the elements of the Array.

To allow the Flex MXML compiler to perform type checking on Array elements, you can use the [ArrayElementType] metadata tag to specify the allowed data type of the Array elements.

Noncompliant Code Example

public var newStringProperty:Array;
public var newNumberProperty:Array;

Compliant Solution

[ArrayElementType("String")]
public var newStringProperty:Array;

[ArrayElementType("Number")]
public var newNumberProperty:Array;
flex:S1470

Overriding Event.clone() is a required part of the API contract:

You are required to override the Event.clone() method in your Event subclass. The clone() method returns a cloned copy of the event object by setting the type property and any new properties in the clone. Typically, you define the clone() method to return an event instance created with the new operator.

Noncompliant Code Example

public class MyEvent extends Event {...}

Compliant Solution

public class MyEvent extends Event
{
...
  override public function clone():Event {
    return new MyEvent(...);
  }
...
}
flex:S1481

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

public function numberOfMinutes(hours:int):int
{
  var seconds:int = 0;  // seconds is never used
  return hours * 60;
}

Compliant Solution

public function numberOfMinutes(hours:int):int
{
  return hours * 60;
}
flex:S1784

Access modifiers define which classes can access properties, variables, methods, and other classes. If an access modifier is not specified, the access level defaults to internal, which grants access to all classes in the same package. This may be what is intended, but it should be specified explicitly to avoid confusion.

Available access modifiers are:

  • internal - access allowed within the same package
  • private - access allowed only within the same class
  • protected - access allowed to the class and its child classes
  • public - unfettered access by all

Noncompliant Code Example

function checkResources():Boolean {
  ...
  return true;
}

Compliant Solution

public function checkResources():Boolean {
  ...
  return true;
}
flex:S1820

A class that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain, and having a lot of fields is an indication that a class has grown too large.

Above a specific threshold, it is strongly advised to refactor the class into smaller ones which focus on well defined topics.

flex:S1821

Nested switch structures are difficult to understand because you can easily confuse the cases of an inner switch as belonging to an outer statement. Therefore nested switch statements should be avoided.

Specifically, you should structure your code to avoid the need for nested switch statements, but if you cannot, then consider moving the inner switch to another function.

Noncompliant Code Example

public function func(foo:Number, bar:Number):void
{
  switch (foo)
  {
    case 1:
      // do something
      break;
    case 2:
      switch (bar)  // Noncompliant
      {
        case 89:  // It's easy to lose sight of what's being tested; is it foo or bar?
          // ...
          break;
        case 90:
          // ...
          break;
      }
      break;
    case 3:
      // do something
      break;
    default:
      break;
  }
}

Compliant Solution


public function func(foo:Number, bar:Number):void
{
  switch (foo)
  {
    case 1:
      // ...
      break;
    case 2:
      handleBar(bar);
      break;
    case 3:
      // ...
      break;
    default:
      break;
  }
}

public function handleBar(bar:Number):void
{
  switch (bar)
  {
    case 89:
      // ...
      break;
    case 90:
      // ...
      break;
  }
}
flex:S1950

Having multiple cases in a switch with the same condition is confusing at best. At worst, it's a bug that is likely to induce further bugs as the code is maintained.

If the first case ends with a break, the second case will never be executed, rendering it dead code. Worse there is the risk in this situation that future maintenance will be done on the dead case, rather than on the one that's actually used.

On the other hand, if the first case does not end with a break, both cases will be executed, but future maintainers may not notice that.

Noncompliant Code Example

switch(i) {
  case 1:
    //...
    break;
  case 5:
    //...
    break;
  case 3:
    //...
    break;
  case 1:  // Noncompliant
    //...
    break;
}

Compliant Solution

switch(i) {
  case 1:
    //...
    break;
  case 5:
    //...
    break;
  case 3:
    //...
    break;
}
flex:S1952

It can be expensive to instantiate a new object, and doing so inside a loop is typically an error. Instead, create the object once, before the loop.

Noncompliant Code Example

for (var i:int = 0; i < 10; i++) {
  var temp:MyObj = new MyObject();  // Noncompliant
  //...
}

Compliant Solution

var temp:MyObj = new MyObject();
for (var i:int = 0; i < 10; i++) {
  //...
}
flex:S1982

The onEnterFrame event handler is continually invoked at the frame rate of the SWF file, regardless of which individual movie frame it is set for. Having too many onEnterFrame handlers can seriously degrade performance.

If the use of this event handler cannot be avoided entirely, then it should be created as close to its use as possible, and then destroyed as soon as possible afterward.

Noncompliant Code Example

movieClip.onEnterFrame = function () {   // Noncompliant
   // ...
}
flex:WithStatement

Never use with statements, since they decrease readability. When you do not specify a variable's scope, you do not always know where you are setting properties, so your code can be confusing.

Noncompliant Code Example

with (foo) { // Noncompliant
  return x;  // is it a property of foo or local variable ?
}

Compliant Solution

return foo.x;
go:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression: ^[a-zA-Z0-9]+$:

func execute_all() {
...
}

Compliant Solution

func executeAll() {
...
}
go:S103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

go:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

go:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if condition1 {
	if condition2 {
		fmt.Println("Hello World")
	}
}

Compliant Solution

if condition1 && condition2 {
	fmt.Println("Hello World")
}
go:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

Noncompliant Code Example

With a maximum number of 4 parameters:

func foo(p1 int, p2 int, p3 int, p4 int, p5 int) { // Noncompliant
  // ...
}

Compliant Solution

func foo(p1 int, p2 int, p3 int, p4 int) {
  // ...
}
go:S108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

func compute(a int, b int) {
	sum := a + b
	if  sum > 0 { } // Noncompliant; empty on purpose or missing piece of code?
	fmt.Println("Result:", sum)
}

Compliant Solution

func compute(a int, b int) {
	sum := a + b
	if  sum > 0 {
		fmt.Println("Positive result")
	}
	fmt.Println("Result:", sum)
}

Exceptions

When a block contains a comment, this block is not considered to be empty. for and select statements with empty blocks are ignored as well.

go:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

func foo(a bool, y int) int {
  x := (y / 2 + 1)   //Compliant even if the parenthesis are ignored by the compiler

  if a && ((x+y > 0)) {  // Noncompliant
    //...
  }

  return ((x + 1))  // Noncompliant
}

Compliant Solution

func foo(a bool, y int) int {
  x := (y / 2 + 1)

  if a && (x+y > 0) {
    //...
  }

  return (x + 1)
}
go:S1116

Empty statements, i.e. ;, are usually introduced by mistake, for example because:

  • It was meant to be replaced by an actual statement, but this was forgotten.
  • There was a typo which lead the semicolon to be doubled, i.e. ;;.

Noncompliant Code Example

func doSomething() {
  ;                                                       // Noncompliant
}

func doSomethingElse() {
  fmt.Println("doSomethingElse");;     // Noncompliant - double useless ;
  ...
}

Compliant Solution

func doSomething() {
}

func doSomethingElse() {
  fmt.Println("doSomethingElse")
  ...
}

See

  • MISRA C:2004, 14.3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment provided that the first character following the null statement is a white-space character.
  • MISRA C++:2008, 6-2-3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment, provided that the first character following the null statement is a white-space character.
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • CERT, MSC51-J. - Do not place a semicolon immediately following an if, for, or while condition
  • CERT, EXP15-C. - Do not place a semicolon on the same line as an if, for, or while statement
go:S1125

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

Noncompliant Code Example

if boolFunc() == true {
    // ...
}

flag := x && true

Compliant Solution

if boolFunc() {
    // ...
}

flag := x
go:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

func foo() {
  // FIXME
}

See

go:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

func foo() {
  // TODO
}

See

go:S1145

if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.

There are three possible causes for the presence of such code:

  • An if statement was changed during debugging and that debug code has been committed.
  • Some value was left unset.
  • Some logic is not doing what the programmer thought it did.

In any of these cases, unconditional if statements should be removed.

Noncompliant Code Example

if true {
	doSomething()
}

if false {
	doSomething()
}

Compliant Solution

doSomething();
...

See

  • MITRE, CWE-489 - Leftover Debug Code
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
go:S1151

The switch statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the case clause should be extracted into a dedicated method.

Noncompliant Code Example

With the default threshold of 5:

func foo(tag int) {
	switch tag {
	case 0:
		methodCall1()
		methodCall2()
		methodCall3()
		methodCall4()
                methodCall5()
                methodCall6()
	case 1:
		bar()
	}
}

Compliant Solution

func foo(tag int) {
	switch tag {
	case 0:
		executeAll()
	case 1:
		bar()
	}
}

func executeAll() {
	methodCall1()
	methodCall2()
	methodCall3()
	methodCall4()
        methodCall5()
        methodCall6()
}
go:S1172

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

Noncompliant Code Example

func compute(start int) { // Noncompliant; start is not used
	sum := 0
	for i := 0; i < 10; i++ {
		sum += i
	}
	fmt.Println("Result:", sum)
}

Compliant Solution

func compute() {
	sum := 0
	for i := 0; i < 10; i++ {
		sum += i
	}
	fmt.Println("Result:", sum)
}

See

  • MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions.
  • MISRA C:2012, 2.7 - There should be no unused parameters in functions
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
go:S1186

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

  • 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.

Noncompliant Code Example

func doNothing() { // Noncompliant
}

Compliant Solution

func doNothing() {
  // Do nothing because of X and Y.
}
go:S1192

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

With the default threshold of 3:

func run() {
	prepare("This should be a constant")  // Noncompliant; 'foo' is duplicated 3 times
	execute("This should be a constant")
	release("This should be a constant")
}

Compliant Solution

const ACTION = "This should be a constant"

func run() {
	prepare(ACTION)
	execute(ACTION)
	release(ACTION)
}

Exceptions

To prevent generating some false-positives, literals having less than 5 characters are excluded.

go:S126

This rule applies whenever an if statement is followed by one or more else if statements; the final else if should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch statement.

Noncompliant Code Example

if x == 0 {
	doSomething()
} else if x == 1 {
	doSomethingElse()
}

Compliant Solution

if x == 0 {
	doSomething()
} else if x == 1 {
	doSomethingElse()
} else {
	return errors.New("unsupported int")
}

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
go:S1313

Hardcoding an IP address into source code is a bad idea for several reasons:

  • a recompile is required if the address changes
  • it forces the same address to be used in every environment (dev, sys, qa, prod)
  • it places the responsibility of setting the value to use in production on the shoulders of the developer
  • it allows attackers to decompile the code and thereby discover a potentially sensitive address

Noncompliant Code Example

var (
  ip   = "127.0.0.1"
  port = 3333
)

SocketClient(ip, port)

Compliant Solution

config, err := ReadConfig("properties.ini")

ip := config["ip"]
port := config["ip"]

SocketClient(ip, port)

See

go:S1314

Integer literals starting with a zero are octal rather than decimal values. While using octal values is fully supported, most developers do not have experience with them. They may not recognize octal values as such, mistaking them instead for decimal values.

Noncompliant Code Example

func printTen() {
	myNumber := 010 // Noncompliant. myNumber will hold 8, not 10 - was this really expected?
	fmt.Println(myNumber)
}

Compliant Solution

func printTen() {
	myNumber := 10
	fmt.Println(myNumber)
}

See

  • MISRA C:2004, 7.1 - Octal constants (other than zero) and octal escape sequences shall not be used.
  • MISRA C++:2008, 2-13-2 - Octal constants (other than zero) and octal escape sequences (other than "\0") shall not be used
  • MISRA C:2012, 7.1 - Octal constants shall not be used
  • CERT, DCL18-C. - Do not begin integer constants with 0 when specifying a decimal value
  • CERT, DCL50-J. - Use visually distinct identifiers
go:S134

Nested if, for, while, switch, 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:

if condition1 { // Compliant - depth = 1
	/* ... */
	if condition2 { // Compliant - depth = 2
		/* ... */
		for i := 1; i <= 10; i++ { // Compliant - depth = 3, not exceeding the limit
			/* ... */
			if condition4 { // Noncompliant - depth = 4
				if condition5 { // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
					/* ... */
				}
				return
			}
		}
	}
}
go:S138

A function that grows too large tends to aggregate too many responsibilities.

Such functions inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions which focus on well-defined tasks.

Those smaller functions will not only be easier to understand, but also probably easier to test.

go:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
go:S1479

When switch statements have large sets of case clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

go:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

func (user *User) rename(name string) {
  name = name  // Noncompliant
}

Compliant Solution

func (user *User) rename(name string) {
  user.name = name
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
go:S1751

A loop with at most one iteration is equivalent to the use of an if statement to conditionally execute one piece of code. No developer expects to find such a use of a loop statement. If the initial intention of the author was really to conditionally execute one piece of code, an if statement should be used instead.

At worst that was not the initial intention of the author and so the body of the loop should be fixed to use the nested return, break or throw statements in a more appropriate way.

Noncompliant Code Example

for i := 0; i < 10; i++ { // noncompliant, loop only executes once
	fmt.Println(i)
	break
}

Compliant Solution

for i := 0; i < 10; i++ {
	fmt.Println(i)
}
go:S1763

Jump statements (return, break, continue, goto) and throw expressions move control flow out of the current code block. So any unlabelled statements that come after a jump are dead code.

Noncompliant Code Example

func add(x, y int) int {
	return x + y // Noncompliant
	z := x + y // dead code
}

Compliant Solution

func add(x, y int) int {
	return x + y // Compliant
}

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code
  • MISRA C++:2008, 0-1-9 - There shall be no dead code
  • MISRA C:2012, 2.1 - A project shall not contain unreachable code
  • MISRA C:2012, 2.2 - There shall be no dead code
  • MITRE, CWE-561 - Dead Code
  • CERT, MSC56-J. - Detect and remove superfluous code and values
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
go:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Noncompliant Code Example

func main() {
  v1 := (true && false) && (true && false) // Noncompliant
}

Compliant Solution

func main() {
  v1 := (true && false) // Compliant
}

Exceptions

This rule ignores *, +, << and =.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
go:S1821

Nested switch structures are difficult to understand because you can easily confuse the cases of an inner switch as belonging to an outer statement. Therefore nested switch statements should be avoided.

Specifically, you should structure your code to avoid the need for nested switch statements, but if you cannot, then consider moving the inner switch to another function.

Noncompliant Code Example

func foo(x,y int) {
	switch x {
	case 0:
		switch y { // Noncompliant; nested switch
		// ...
		}
	case 1:
		// ...
	default:
		// ...
	}
}

Compliant Solution

func foo(x,y int) {
	switch x {
	case 0:
		bar(y)
	case 1:
		// ...
	default:
		// ...
	}
}

func bar(y int) {
	switch y {
	// ...
	}
}
go:S1862

A chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

Noncompliant Code Example

func example(condition1, condition2 bool) {
  if condition1 {
  } else if condition1 { // Noncompliant
  }
}
func SwitchWithMultipleConditions(param int) {
  switch param {
  case 1, 2, 3:
    fmt.Println(">1")
  case 3, 4, 5: // Noncompliant; 3 is duplicated
    fmt.Println("<1")
  }
}

Compliant Solution

func example(condition1, condition2 bool) {
  if condition1 {
  } else if condition2 { // Compliant
  }
}
func SwitchWithMultipleConditions(param int) {
  switch param {
  case 1, 2, 3:
    fmt.Println(">1")
  case 4, 5: // Compliant
    fmt.Println("<1")
  }
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
go:S1871

Having two cases in a switch statement or two branches in an if chain 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 chain they should be combined, or for a switch, one should fall through to the other.

Noncompliant Code Example

switch i {
case 1:
	doFirstThing()
	doSomething()
case 2:
	doSomethingElse()
case 3: // Noncompliant; duplicates case 1's implementation
	doFirstThing()
	doSomething()
default:
	doTheRest()
}

if a >= 0 && a < 10 {
	doFirstThing()
	doSomething()
} else if a >= 10 && a < 20 {
	doSomethingElse()
} else if a >= 20 && a < 50 {
	doFirstThing()
	doSomething() // Noncompliant; duplicates first condition
} else {
	doTheRest()
}

Exceptions

Blocks in an if chain or case blocks that contain a single line of code are ignored.

if a == 1 {
  doSomething()  //no issue, usually this is done on purpose to increase the readability
} else if a == 2 {
  doSomethingElse()
} else {
  doSomething()
}
go:S1994

It can be extremely confusing when a for condition tests a variable which is not updated inside the for post statement.

Noncompliant Code Example

for i := 1; i <= 10; j++ { // Noncompliant
	// ...
}

Compliant Solution

for i := 1; i <= 10; i++ {
	// ...
}
go:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

Noncompliant Code Example

func connect()  {
  user := "root"
  myPassword := "supersecret" // Noncompliant

  url := "login=" + user + "&passwd=" + myPassword
}

Compliant Solution

func connect()  {
  user := getEncryptedUser()
  myPassword := getEncryptedPass() // Compliant

  url := "login=" + user + "&passwd=" + myPassword
}

See

go:S2757

The use of operators pairs ( =+, =- or =! ) where the reversed, single operator was meant (+=, -= or !=) will compile and run, but not produce the expected results.

This rule raises an issue when =+, =-, or =! is used without any spacing between the two operators and when there is at least one whitespace character after.

Noncompliant Code Example

var target, num = -5, 3

target =- num  // Noncompliant; target = -3. Is that really what's meant?
target =+ num // Noncompliant; target = 3

Compliant Solution

var target, num = -5, 3

target = -num  // Compliant; intent to assign inverse value of num is clear
target += num
go:S2761

The needless repetition of an operator is usually a typo. There is no reason to write !!!i when !i will do.

On the other hand, the repetition of increment and decrement operators may have been done on purpose, but doing so obfuscates the meaning, and should be simplified.

This rule raises an issue for sequences of: !, ^, -, and +.

Noncompliant Code Example

  var a int = 1
  var flag bool = true

  var a1 int = ^^^a // Noncompliant
  var flag2 bool  = !!!flag  // Noncompliant

Compliant Solution

  var a int = 1
  var flag bool = true

  var a1 int = ^a
  var flag2 bool  = !flag
go:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

go:S3923

Having all branches in a switch or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a switch/if chain at all.

Noncompliant Code Example

if b == 0 {  // Noncompliant
  doOneMoreThing()
} else {
  doOneMoreThing()
}

switch i {  // Noncompliant
  case 1:
    doSomething()
  case 2:
    doSomething()
  case 3:
    doSomething()
  default:
    doSomething()
}

Exceptions

This rule does not apply to if chains without else-s, or to switch-es without default clauses.

if b == 0 {    //no issue, this could have been done on purpose to make the code more readable
  doSomething()
} else if b == 1 {
  doSomething()
}
go:S3981

The size of a collection and the length of an array are always greater than or equal to zero. So testing that a size or length is greater than or equal to zero doesn't make sense, since the result is always true. Similarly testing that it is less than zero will always return false. Perhaps the intent was to check the non-emptiness of the collection or array instead.

Noncompliant Code Example

if len(myArr) >= 0 { ... }

if len(myArr) < 0 { ... }

var result = len(myArr) >= 0

Compliant Solution

if len(myArr) > 0 { ... }

if len(myArr) < 42 { ... }
go:S4144

When two functions have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, one implementation should invoke the other.

Noncompliant Code Example

func fun1() (x, y int) {
  a, b := 1, 2
  b, a = a, b
  return a, b
}

func fun2() (x, y int) {  // Noncompliant; fun1 and fun2 have identical implementations
  a, b := 1, 2
  b, a = a, b
  return a, b
}

Compliant Solution

func fun1() (x, y int) {
  a, b := 1, 2
  b, a = a, b
  return a, b
}

func fun2() (x, y int) {  // Compliant
  return fun1()
}

Exceptions

Functions with fewer than 2 statements are ignored.

go:S4524

switch can contain a default clause for various reasons: to handle unexpected values, to show that all the cases were properly considered.

For readability purpose, to help a developer to quickly find the default behavior of a switch statement, it is recommended to put the default clause at the beginning or the end of the switch statement. This rule raises an issue if the default clause is not the first or the last one of the switch's cases.

Noncompliant Code Example

switch tag {
case 0, 1, 2, 3:
	foo()
default:  // Noncompliant; default case should be the first or last one
	qix()
case 4, 5, 6, 7:
	bar()
}

Compliant Solution

switch tag {
default:
	qix() // Compliant; default is the first one
case 0, 1, 2, 3:
	foo()
case 4, 5, 6, 7:
	bar()
}
switch tag {
case 0, 1, 2, 3:
	foo()
case 4, 5, 6, 7:
	bar()
default:
	qix() // Compliant; default is the last one
}

See

  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
javascript:ArrayAndObjectConstructors

Array literals should always be preferred to Array constructors.

Array constructors are error-prone due to the way their arguments are interpreted. If more than one argument is used, the array length will be equal to the number of arguments. However, using a single argument will have one of three consequences:

  • If the argument is a number and it is a natural number the length will be equal to the value of the argument.
let arr = new Array(3); // [empty Ɨ 3]
  • If the argument is a number, but not a natural number an exception will be thrown.
let arr = new Array(3.14);  // RangeError: Invalid array length
  • Otherwise the array will have one element with the argument as its value.
let arr = new Array("3");  // ["3"]

Note that even if you set the length of an array, it will be empty. That is, it will have the number of elements you declared, but they won't contain anything, so no callbacks will be applied to the array elements.

For these reasons, if someone changes the code to pass 1 argument instead of 2 arguments, the array might not have the expected length. To avoid these kinds of weird cases, always use the more readable array literal initialization format.

Noncompliant Code Example

let myArray = new Array(x1, x2, x3);   // Noncompliant. Results in 3-element array.
let emptyArray = new Array();          // Noncompliant. Results in 0-element array.

let unstableArray = new Array(n);      // Noncompliant. Variable in results.

let arr = new Array(3); // Noncompliant; empty array of length 3
arr.foreach((x) => alert("Hello " + x)); // callback is not executed because there's nothing in arr
let anotherArr = arr.map(() => 42); // anotherArr is also empty because callback didn't execute

Compliant Solution

let myArray = [x1, x2, x3];
let emptyArray = [];

// if "n" is the only array element
let unstableArray = [n];
// or,  if "n" is the array length (since ES 2015)
let unstableArray = Array.from({length: n});

let arr = ["Elena", "Mike", "Sarah"];
arr.foreach((x) => alert("Hello " + x));
let anotherArr = arr.map(() => 42);  // anotherArr now holds 42 in each element
javascript:BitwiseOperators

The bitwise operators &, | can be mistaken for the boolean operators && and ||.

This rule raises an issue when & or | is used in a boolean context.

Noncompliant Code Example

if (a & b) { ... } // Noncompliant; & used in error

Compliant Solution

if (a && b) { ... }

Exceptions

When a file contains other bitwise operations, (^, <<, >>>, >>, ~, &=, ^=, |=, <<=, >>=, >>>= and & or | used with a numeric literal as the right operand) all issues in the file are ignored, because it is evidence that bitwise operations are truly intended in the file.

javascript:BoundOrAssignedEvalOrArguments

eval is used to evaluate a string as JavaScript code, and arguments is used to access function arguments through indexed properties. As a consequence, eval and arguments should not be bound or assigned, because doing so would overwrite the original definitions of those two reserved words.

What's more, using either of those two names to assign or bind will generate an error in JavaScript strict mode code.

Noncompliant Code Example

eval = 17; // Noncompliant
arguments++; // Noncompliant
++eval; // Noncompliant
var obj = { set p(arguments) { } }; // Noncompliant
var eval; // Noncompliant
try { } catch (arguments) { } // Noncompliant
function x(eval) { } // Noncompliant
function arguments() { } // Noncompliant
var y = function eval() { }; // Noncompliant
var f = new Function("arguments", "return 17;"); // Noncompliant

function fun() {
  if (arguments.length == 0) { // Compliant
    // do something
  }
}

Compliant Solution

result = 17;
args++;
++result;
var obj = { set p(arg) { } };
var result;
try { } catch (args) { }
function x(arg) { }
function args() { }
var y = function fun() { };
var f = new Function("args", "return 17;");

function fun() {
  if (arguments.length == 0) {
    // do something
  }
}

Deprecated

This rule is deprecated; use S2137 instead.

javascript:ConditionalComment

Internet Explorer offers a way to change the JavaScript code at runtime using conditional comments (activated by a @cc_on statement found in a comment). Using this preprocessing feature decreases readability and maintainability, and can hinder automated tools. What's more, it is specific to Internet Explorer and won't work for other browsers.

Most of the time, using those conditional comments can be easily avoided with some refactoring - using modern cross-browsers JavaScript frameworks and libraries.

Noncompliant Code Example

/*@cc_on
  @if (@_jscript_version >= 5.5)
    document.write("You are using IE5.5 or newer");
  @else
    document.write("You are using IE5 or older");
  @end
  @*/
javascript:ConditionalOperator

While the ternary operator is pleasingly compact, its use can make code more difficult to read. It should therefore be avoided in favor of the more verbose if/else structure.

Noncompliant Code Example

function foo(a) {
  var b = (a === 'A') ? 'is A' : 'is not A'; // Noncompliant
  // ...
}

Compliant Solution

function foo(a) {
  var b;
  if (a === 'A') {
    b = 'is A';
  }
  else {
    b = 'is not A';
  }
  // ...
}
javascript:ConstructorFunctionsForSideEffects

There is no good reason to create a new object to not do anything with it. Most of the time, this is due to a missing piece of code and so could lead to an unexpected behavior in production.

If it was done on purpose because the constructor has side-effects, then that side-effect code should be moved into a separate method and called directly.

Noncompliant Code Example

new MyConstructor(); // Non-Compliant

Compliant Solution

var something = new MyConstructor();  // Compliant
javascript:DuplicateFunctionArgument

Function arguments should all have different names to prevent any ambiguity. Indeed, if arguments have the same name, the last duplicated argument hides all the previous arguments with the same name (those previous arguments remain available through arguments[i], so they're not completely inaccessible).

This hiding makes no sense, reduces understandability and maintainability, and obviously can be error prone. Furthermore, in strict mode, declaring arguments with the same name produces an error.

Noncompliant Code Example

function compute(a, a, c) { // Noncompliant
}

Compliant Solution

function compute(a, b, c) { // Compliant
}
javascript:DuplicatePropertyName

JavaScript allows duplicate property names in classes and object literals, but only the last instance of a duplicated name determines the actual value that will be used for it. Therefore, changing values of other occurrences of a duplicated name will have no effect and may cause misunderstandings and bugs.

Defining a class with a duplicated constructor will generate an error.

Before ECMAScript 2015, using duplicate names will generate an error in JavaScript strict mode code.

Noncompliant Code Example

var data = {
  "key": "value",
  "1": "value",
  "key": "value", // Noncompliant - duplicate of "key"
  'key': "value", // Noncompliant - duplicate of "key"
  key: "value", // Noncompliant - duplicate of "key"
  \u006bey: "value", // Noncompliant - duplicate of "key"
  "\u006bey": "value", // Noncompliant - duplicate of "key"
  "\x6bey": "value", // Noncompliant - duplicate of "key"
  1: "value" // Noncompliant - duplicate of "1"
}

Compliant Solution

var data = {
  "key": "value",
  "1": "value",
  "key2": "value",
  'key3': "value",
  key4: "value",
  \u006bey5: "value",
  "\u006bey6": "value",
  "\x6bey7": "value",
  1b: "value"
}
javascript:EmptyBlock

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

for (var i = 0; i < length; i++) {}  // Empty on purpose or missing piece of code ?

Exceptions

When a block contains a comment, this block is not considered to be empty. Moreover catch blocks are ignored.

javascript:EqEqEq

The == and != operators do type coercion before comparing values. This is bad because it can mask type errors. For example, it evaluates ' \t\r\n' == 0 as true.

It is best to always use the side-effect-less === and !== operators instead.

Noncompliant Code Example

if (var == 'howdy') {...} // Noncompliant

Compliant Solution

if (var === 'howdy') {...}

Exceptions

Even if testing the equality of a variable against null doesn't do exactly what most JavaScript developers believe, usage of == or != is tolerated in such context. In the following case, if foo hasn't been initialized, its default value is not null but undefined. Nevertheless undefined == null, so JavaScript developers get the expected behavior.

if(foo == null) {...}
javascript:ExcessiveParameterList

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

Noncompliant Code Example

With a maximum number of 4 parameters:

function doSomething(param1, param2, param3, param4, param5) {
...
}

Compliant Solution

function doSomething(param1, param2, param3, param4) {
...
}
javascript:ForIn

The for...in statement allows you to loop through the names of all of the properties of an object. The list of properties includes all those properties that were inherited through the prototype chain. This has the side effect of serving up functions when the interest is in data properties. Programs that don't take this into account can fail.

Therefore, the body of every for...in statement should be wrapped in an if statement that filters which properties are acted upon. It can select for a particular type or range of values, or it can exclude functions, or it can exclude properties from the prototype.

Noncompliant Code Example

for (name in object) {
    doSomething(name);  // Noncompliant
}

Compliant Solution

for (name in object) {
  if (object.hasOwnProperty(name)) {
    doSomething(name);
  }
}

Exceptions

Loops used to clone objects are ignored.

for (prop in obj) {
  a[prop] = obj[prop];  // Compliant by exception
}
javascript:FunctionComplexity

The Cyclomatic Complexity of functions should not exceed a defined threshold. Complex code may perform poorly and can be difficult to test thoroughly.

javascript:FunctionDeclarationsWithinBlocks

While most script engines support function declarations within blocks, it is not part of ECMAScript 5 and below, and from browser to browser the implementations are inconsistent with each other. ECMAScript 5 and below only allow function declarations in the root statement list of a script or function. If you are targeting browsers that don't support ECMAScript 6, use a variable initialized with a function expression to define a function within a block :

Noncompliant Code Example

if (x) {
  function foo() {}
}

Compliant Solution

if (x) {
  var foo = function() {}
}
javascript:FunctionDefinitionInsideLoop

Defining a function inside of a loop can yield unexpected results. Such a function keeps references to the variables which are defined in outer scopes. All function instances created inside the loop therefore see the same values for these variables, which is probably not expected.

Noncompliant Code Example

var funs = [];
for (var i = 0; i < 13; i++) {
  funs[i] = function() { // Non-Compliant
    return i;
  };
}
console.log(funs[0]()); // 13 instead of 0
console.log(funs[1]()); // 13 instead of 1
console.log(funs[2]()); // 13 instead of 2
console.log(funs[3]()); // 13 instead of 3
...
javascript:FutureReservedWords

The following words may be used as keywords in future evolutions of the language, so using them as identifiers should be avoided to allow an easier adoption of those potential future versions:

  • await
  • class
  • const
  • enum
  • export
  • extends
  • implements
  • import
  • interface
  • let
  • package
  • private
  • protected
  • public
  • static
  • super
  • yield

Use of these words as identifiers would produce an error in JavaScript strict mode code.

Noncompliant Code Example

var package = document.getElementsByName("foo"); // Noncompliant
var someData = { package: true };                 // Compliant, as it is not used as an identifier here

Compliant Solution

var elements = document.getElementsByName("foo"); // Compliant
javascript:HtmlComments

HTML-style comments are not part of EcmaScript specification, and should not be used.

Noncompliant Code Example

<!-- Noncompliant -->

Compliant Solution

// Compliant
/* Compliant */
javascript:LabelPlacement

Any statement or block of statements can be identified by a label, but those labels should be used only on while, do-while and for statements. Using labels in any other context leads to unstructured, confusing code.

Noncompliant Code Example

myLabel:if (i % 2 == 0) {  // Noncompliant
  if (i == 12) {
    print("12");
    break myLabel;
  }
  print("Odd number, but not 12");
}

Compliant Solution

myLabel:for (i = 0; i < 10; i++) {   // Compliant
  print("Loop");
  break myLabel;
}
javascript:LineLength

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

javascript:MissingNewlineAtEndOfFile

Some tools work better when files end with an empty line.

This rule simply generates an issue if it is missing.

For example, a Git diff looks like this if the empty line is missing at the end of the file:

+class Test {
+}
\ No newline at end of file
javascript:MultilineStringLiterals

Continuing a string across a linebreak is supported in most script engines, but it is not a part of ECMAScript. Additionally, the whitespace at the beginning of each line can't be safely stripped at compile time, and any whitespace after the slash will result in tricky errors.

Noncompliant Code Example

var myString = 'A rather long string of English text, an error message \
                actually that just keeps going and going -- an error \
                message to make the Energizer bunny blush (right through \
                those Schwarzenegger shades)! Where was I? Oh yes, \
                you\'ve got an error and all the extraneous whitespace is \
                just gravy.  Have a nice day.';  // Noncompliant

Compliant Solution

var myString = 'A rather long string of English text, an error message ' +
    'actually that just keeps going and going -- an error ' +
    'message to make the Energizer bunny blush (right through ' +
    'those Schwarzenegger shades)! Where was I? Oh yes, ' +
    'you\'ve got an error and all the extraneous whitespace is ' +
    'just gravy.  Have a nice day.';
javascript:NamedFunctionExpression

While named function expressions might be useful for debugging purposes, some browsers do not support them correctly (for example Internet Explorer 8).

Noncompliant Code Example

f = function fun(){}; // Noncompliant;  named function expression

Compliant Solution

fun = function(){}; // Compliant; function expression

Exceptions

ECMAScript 6 generator functions are excluded from this rule.

function* f() {} // Compliant; generator function.
javascript:OneStatementPerLine

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

foo(); bar(); // Noncompliant

Compliant Solution

foo();
bar();

Exceptions

Anonymous functions containing a single statement are ignored. Control flow statements with a single nested statement are ignored as well.

onEvent(function() { doSomething(); });               // Compliant
onEvent(function(p) { doSomething(); return p % 2; }); // Noncompliant

if (condition) doSomething();                         // Compliant
if (condition) { doSomething(); }                     // Compliant
javascript:Parentheses

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

let x = (y / 2 + 1);   //Compliant even if those parenthesis are useless for the compiler

if (a && ((x+y > 0))) {  // Noncompliant
  //...
}

return ((x + 1));  // Noncompliant

Compliant Solution

let x = (y / 2 + 1);

if (a && (x+y > 0)) {
  //...
}

return (x + 1);
javascript:ParsingError

When the JavaScript parser fails, it is possible to record the failure as a violation on the file. This way, not only it is possible to track the number of files that do not parse but also to easily find out why they do not parse.

javascript:PrimitiveWrappers

The use of wrapper objects for primitive types is gratuitous, confusing and dangerous. If you use a wrapper object constructor for type conversion, just remove the new keyword, and you'll get a primitive value automatically. If you use a wrapper object as a way to add properties to a primitive, you should re-think the design. Such uses are considered bad practice, and should be refactored.

Noncompliant Code Example

let x = new Number("0");
if (x) {
  alert('hi');  // Shows 'hi'.
}

Compliant Solution

let x = Number("0");
if (x) {
  alert('hi');
}

Exceptions

Cases when argument of primitive type constructor is a literal of the same type are ignored, except new Boolean(false).

let booleanObject = new Boolean(true);
let numberObject = new Number(0);
let stringObject = new String('');
javascript:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

function DoSomething(){...}  // Noncompliant

Compliant Solution

function doSomething(){...}
javascript:S101

Shared coding conventions allow teams to collaborate effectively. This rule allows to check that all class names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression ^[A-Z][a-zA-Z0-9]*$:

class my_class {...}

Compliant Solution

class MyClass {...}
javascript:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

javascript:S1067

The complexity of an expression is defined by the number of &&, || and condition ? ifTrue : ifFalse operators it contains.

A single expression's complexity should not become too high to keep the code readable.

javascript:S1105

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when an open curly brace is not placed at the end of a line of code.

Noncompliant Code Example

if (condition)
{                                                      //Noncompliant
  doSomething();
}

Compliant Solution

if (condition) {                                   //Compliant
  doSomething();
}

Exceptions

Object literals appearing as arguments can start on their own line.

functionWithObject(
   {                                                 //Compliant
        g: "someValue"
   }
);
javascript:S1119

Labels are not commonly used, and many developers do not understand how they work. Moreover, their usage makes the control flow harder to follow, which reduces the code's readability.

Noncompliant Code Example

myLabel: {
  let x = doSomething();
  if (x > 0) {
    break myLabel;
  }
  doSomethingElse();
}

Compliant Solution

let x = doSomething();
if (x <= 0) {
  doSomethingElse();
}

Exceptions

Labeled loops are ignored.

javascript:S1128

There's no reason to import modules you don't use; and every reason not to: doing so needlessly increases the load.

Finally, importing a module twice is pointless and confusing.

Noncompliant Code Example

import A from 'a';      // Noncompliant, A isn't used
import { B1 } from 'b';

console.log("My first JavaScript...");

import { B1 } from 'b'; // Noncompliant, already imported

console.log(B1);

Compliant Solution

import { B1 } from 'b';

console.log("My first JavaScript...");

console.log(B1);
javascript:S1154

Doing an operation on a string without using the result of the operation is useless and is certainly due to a misunderstanding.

Noncompliant Code Example

var str = "..."
str.toUpperCase(); // Noncompliant

Compliant Solution

var str = "..."
str = str.toUpperCase();

See

Deprecated

This rule is deprecated; use S2201 instead.

javascript:S1186

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

  • 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 in languages where that mechanism is available.
  • The method is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.

Noncompliant Code Example

function foo() {
}

var foo = () => {};

Compliant Solution

function foo() {
    // This is intentional
}

var foo = () => {
    do_something();
};
javascript:S138

A function that grows too large tends to aggregate too many responsibilities.

Such functions inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions which focus on well-defined tasks.

Those smaller functions will not only be easier to understand, but also probably easier to test.

Exceptions

This function ignores Immediately Invoked Function Expressions (IIFE), which are functions that are created and invoked without ever being assigned a name.

(function () { // Ignored by this rule

  function open() {  // Classic function declaration; not ignored
    // ...
  }

  function read() {
    // ...
  }

  function readlines() {
    // ...
  }
})();
javascript:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
javascript:S1472

Because semicolons at the ends of statements are optional, starting function call arguments on a separate line makes the code confusing. It could lead to errors and most likely will lead to questions for maintainers.

What was the initial intent of the developer?

  1. Define a function and then execute some unrelated code inside a closure ?
  2. Pass the second function as a parameter to the first one ?

The first option will be the one chosen by the JavaScript interpreter.

By extension, and to improve readability, any kind of function call argument should not start on new line.

Noncompliant Code Example

var fn = function () {
  //...
}

(function () { // Noncompliant
  //...
})();

Compliant Solution

Either

// define a function
var fn = function () {
  //...
}; // <-- semicolon added

// then execute some code inside a closure
(function () {
  //...
})();

Or

var fn = function () {
  //...
}(function () { // <-- start function call arguments on same line
  //...
})();
javascript:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

function setName(name) {
    name = name;
}

Compliant Solution

function setName(name) {
    this.name = name;
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
javascript:S1697

When either the equality operator in a test for null or undefined, or the logical operator that follows it is reversed, the code has the appearance of safely null-testing the object before dereferencing it. Unfortunately the effect is just the opposite - the object is null-tested and then dereferenced only if it is null/undefined, leading to a guaranteed TypeError.

Noncompliant Code Example

if (str == null && str.length == 0) {
  console.log("String is empty");
}

if (str == undefined && str.length == 0) {
  console.log("String is empty");
}

if (str != null || str.length > 0) {
  console.log("String is not empty");
}

if (str != undefined || str.length > 0) {
  console.log("String is not empty");
}

Compliant Solution

if (str != null && str.length == 0) {
  console.log("String is empty");
}

if (str != undefined && str.length == 0) {
  console.log("String is empty");
}

if (str == null || str.length > 0) {
  console.log("String is not empty");
}

if (str == undefined || str.length > 0) {
  console.log("String is not empty");
}

Deprecated

This rule is deprecated; use S2259 instead.

javascript:S1751

Having an unconditional break, return or throw in a loop renders it useless; the loop will only execute once and the loop structure itself is simply wasted keystrokes.

Having an unconditional continue in a loop is itself wasted keystrokes.

For these reasons, unconditional jump statements should never be used except for the final return in a function or method.

Noncompliant Code Example

for (i = 0; i < 10; i++) {
  console.log("i is " + i);
  break;  // loop only executes once
}

for (i = 0; i < 10; i++) {
  console.log("i is " + i);
  continue;  // this is meaningless; the loop would continue anyway
}

for (i = 0; i < 10; i++) {
  console.log("i is " + i);
  return;  // loop only executes once
}

Compliant Solution

for (i = 0; i < 10; i++) {
  console.log("i is " + i);
}

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code.
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code.
  • MISRA C++:2008, 0-1-9 - There shall be no dead code.
  • MISRA C:2012, 2.2 - There shall be no dead code
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
javascript:S1788

The ability to define default values for function parameters can make a function easier to use. Default parameter values allow callers to specify as many or as few arguments as they want while getting the same functionality and minimizing boilerplate, wrapper code.

But all function parameters with default values should be declared after the function parameters without default values. Otherwise, it makes it impossible for callers to take advantage of defaults; they must re-specify the defaulted values or pass undefined in order to "get to" the non-default parameters.

Noncompliant Code Example

function multiply(a = 1, b) {  // Noncompliant
  return a*b;
}

var x = multiply(42);  // returns NaN as b is undefined

Compliant Solution

function multiply(b, a = 1) {
  return a*b;
}

var x = multiply(42);  // returns 42 as expected
javascript:S1994

It can be extremely confusing when a for loop's counter is incremented outside of its increment clause. In such cases, the increment should be moved to the loop's increment clause if at all possible.

Noncompliant Code Example

for (i = 0; i < 10; j++) { // Noncompliant
  // ...
  i++;
}

Compliant Solution

for (i = 0; i < 10; i++, j++) {
  // ...
}

Or

for (i = 0; i < 10; i++) {
  // ...
  j++;
}
javascript:S2123

A value that is incremented or decremented and then not stored is at best wasted code and at worst a bug.

Noncompliant Code Example

let i = 0;
i = i++; // Noncompliant; i is still zero

Compliant Solution

let i = 0;
i++;
javascript:S2137

JavaScript has special identifiers that, while not reserved, still should not be used as identifiers. They include:

  • eval - evaluates a string as JavaScript code
  • arguments - used to access function arguments through indexed properties.
  • undefined - returned for values and properties that have not yet been assigned
  • NaN - Not a Number; returned when math functions fail.
  • Infinity - when a number exceeds the upper limit of the floating point numbers

These words should not be bound or assigned, because doing so would overwrite the original definitions of these identifiers. What's more, assigning or binding some of these names will generate an error in JavaScript strict mode code.

Noncompliant Code Example

eval = 17; // Noncompliant
arguments++; // Noncompliant
++eval; // Noncompliant
var obj = { set p(arguments) { } }; // Noncompliant
var eval; // Noncompliant
try { } catch (arguments) { } // Noncompliant
function x(eval) { } // Noncompliant
function arguments() { } // Noncompliant
var y = function eval() { }; // Noncompliant
var f = new Function("arguments", "return 17;"); // Noncompliant

function fun() {
  if (arguments.length == 0) { // Compliant
    // do something
  }
}

Compliant Solution

result = 17;
args++;
++result;
var obj = { set p(arg) { } };
var result;
try { } catch (args) { }
function x(arg) { }
function args() { }
var y = function fun() { };
var f = new Function("args", "return 17;");

function fun() {
  if (arguments.length == 0) {
    // do something
  }
}
javascript:S2138

undefined is the value you get for variables and properties which have not yet been created. Use the same value to reset an existing variable and you lose the ability to distinguish between a variable that exists but has no value and a variable that does not yet exist. Instead, null should be used, allowing you to tell the difference between a property that has been reset and one that was never created.

Noncompliant Code Example

var myObject = {};

// ...
myObject.fname = undefined;  // Noncompliant
// ...

if (myObject.lname == undefined) {
  // property not yet created
}
if (myObject.fname == undefined) {
  // no real way of knowing the true state of myObject.fname
}

Compliant Solution

var myObject = {};

// ...
myObject.fname = null;
// ...

if (myObject.lname == undefined) {
  // property not yet created
}
if (myObject.fname == undefined) {
  // no real way of knowing the true state of myObject.fname
}
javascript:S2189

An infinite loop is one that will never end while the program is running, i.e., you have to kill the program to get out of the loop. Whether it is by meeting the loop's end condition or via a break, every loop should have an end condition.

Known Limitations

  • False positives: when yield is used - Issue #674.
  • False positives: when an exception is raised by a function invoked within the loop.
  • False negatives: when a loop condition is based on an element of an array or object.

Noncompliant Code Example

for (;;) {  // Noncompliant; end condition omitted
  // ...
}

var j = 0;
while (true) { // Noncompliant; constant end condition
  j++;
}

var k;
var b = true;
while (b) { // Noncompliant; constant end condition
  k++;
}

Compliant Solution


while (true) { // break will potentially allow leaving the loop
  if (someCondition) {
    break;
  }
}

var k;
var b = true;
while (b) {
  k++;
  b = k < 10;
}

outer:
while(true) {
  while(true) {
    break outer;
  }
}

See

javascript:S2208

On the principle that clearer code is better code, you should explicitly import the things you want to use in a module. Using import * imports everything in the module, and runs the risk of confusing maintainers. Similarly, export * from "module"; imports and then re-exports everything in the module, and runs the risk of confusing not just maintainers but also users of the module.

Noncompliant Code Example

import * as Imported from "aModule";  // Noncompliant
javascript:S2234

When the names of arguments in a function call match the names of the function parameters, it contributes to clearer, more readable code. However, when the names match, but are passed in a different order than the function parameters, it indicates a mistake in the parameter order which will likely lead to unexpected results.

Noncompliant Code Example

function divide(divisor, dividend) {
  return divisor/dividend;
}

function doTheThing() {
  var divisor = 15;
  var dividend = 5;

  var result = divide(dividend, divisor);  // Noncompliant; operation succeeds, but result is unexpected
  //...
}

Compliant Solution

function divide(divisor, dividend) {
  return divisor/dividend;
}

function doTheThing() {
  var divisor = 15;
  var dividend = 5;

  var result = divide(divisor, dividend);
  //...
}
javascript:S2251

A for loop with a stop condition that can never be reached, such as one with a counter that moves in the wrong direction, will run infinitely. While there are occasions when an infinite loop is intended, the convention is to construct such loops as while loops. More typically, an infinite for loop is a bug.

Noncompliant Code Example

for (var i = 0; i < strings.length; i--) { // Noncompliant;
  //...
}

Compliant Solution

for (var i = 0; i < strings.length; i++) {
  //...
}

See

javascript:S2310

Loop counters should not be modified in the body of the loop. However other loop control variables representing logical values may be modified in the loop, for example a flag to indicate that something has been completed, which is then tested in the for statement.

Noncompliant Code Example

var names = [ "Jack", "Jim", "", "John" ];
for (var i = 0; i < names.length; i++) {
  if (!names[i]) {
    i = names.length;                                 // Non-Compliant
  } else {
    console.log(names[i]);
  }
}

Compliant Solution

var names = [ "Jack", "Jim", "", "John" ];
for (var name of names) {
  if (!name) {
    break;                                 // Compliant
  } else {
    console.log(name);
  }
}
javascript:S2376

When an object is created with a setter for a property but without a getter for that property, the property is inaccessible and is thus useless.

This rule also enforces the reverse situation (getter but no setter).

Noncompliant Code Example

var obj = {
    set foo(value) {
        this.fooval = value;
    }
};

Compliant Solution

var obj = {
    set foo(value) {
        this.fooval = value;
    },
    get foo() {
        return this.fooval;
    }
};

or

var obj = {
    setFoo(value) {    // a standard method, not a setter
        this.fooval = value;
    }
};
javascript:S2392

A variable that is declared at function scope, but only used inside a single block should be declared in that block, and variables that are declared inside a block but used outside of it (which is possible with a var-style declaration) should be declared outside the block.

Noncompliant Code Example

function doSomething(a, b) {
  var i;  // Noncompliant; should be declared in if-block
  if (a > b) {
    i = a;
    console.log(i);
    var x = a - b;  // Noncompliant; should be declared outside if-block
  }

  if (a > 4) {
   console.log(x);
  }

  return a+b;
}

Compliant Solution

function doSomething(a, b) {
  var x = a - b;

  if (a > b) {
    var i = a;
    console.log(i);
  }

  if (a > 4) {
   console.log(x);
  }

  return a+b;
}
javascript:S2424

Overriding an object changes its behavior and could potentially impact all code using that object. Overriding standard, built-in objects could therefore have broad, potentially catastrophic effects on previously-working code.

This rule detects overrides of the following native objects:

  • Fundamental objects - Object, Function, Boolean, Symbol, Error, EvalError, InternalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError
  • Numbers and dates - Number, Math, Date
  • Text processing - String, RegExp
  • Indexed collections - Array, Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Unit16Array, Int32Array, Uint32Array, Float32Array, Float64Array
  • Keyed collections - Map, Set, WeakMap, WeakSet
  • Structured data - ArrayBuffer, DataView, JSON
  • Control abstraction objects - Promise
  • Reflection - Reflect, Proxy
  • Internationalization - Intl
  • Non-standard objects - Generator, Iterator, ParallelArray, StopIteration
javascript:S2427

The parseInt function has two versions, one that takes a base value as a second argument, and one that does not. Unfortunately using the single-arg version can result in unexpected results on older browsers.

Noncompliant Code Example

parseInt("010");  // Noncompliant; pre-2013 browsers may return 8

Compliant Solution

parseInt("010", 10);
javascript:S2432

Functions declared with the set keyword will automatically return the values they were passed. Thus any value explicitly returned from a setter will be ignored, and explicitly returning a value is an error.

Noncompliant Code Example

var person = {
  // ...
  set name(name) {
    this.name = name;
    return 42;  // Noncompliant
  }
}

Compliant Solution

var person = {
  // ...
  set name(name) {
    this.name = name;
  }
}
javascript:S2508

When using the Backbone.js framework, the names of model attributes should not contain spaces. This is because the Events object accepts space-delimited lists of events, so an attributes with spaces in the names could be misinterpreted.

Noncompliant Code Example

Person = Backbone.Model.extend({
        defaults: {
            'first name': 'Bob',      // Noncompliant
            'birth date': new Date()  // Noncompliant
        },
    });

Compliant Solution

Person = Backbone.Model.extend({
        defaults: {
            firstName: 'Bob',
            birthDate: new Date()
        },
    });
javascript:S2549

According to the Backbone.js docs

The changed property is the internal hash containing all the attributes that have changed since the last set. Please do not update changed directly since its state is internally maintained by set. A copy of changed can be acquired from changedAttributes.

The changed property is involved in decisions about whether or not a collection should be resorted when it is updated. If you modify it manually, you can break the resorting of the collection.

Noncompliant Code Example

myModel.changed = { myProperty: 1 }; // Non-compliant
javascript:S2550

When using the Backbone.js framework with model defaults that contain arrays or objects, defaults should be defined as a function rather than an object. This is because objects and arrays are passed by reference in JavaScript. So a defaults object that contains arrays or objects is going to set the default value of every instance to point to the same shared object or array.

Use a function instead and a fresh copy of the object or array will be peeled off for each instance.

Noncompliant Code Example

var Person = Backbone.Model.extend({
    defaults: {  // Noncompliant; every instance of Person will share the same instance of favoriteColors
        favoriteColors: ["blue","purple","raspberry"]
    }
});

Compliant Solution

var Person = Backbone.Model.extend({
    defaults: function() {
      return {
        favoriteColors: ["blue","purple","raspberry"]
      };
    }
});
javascript:S2685

Both arguments.caller and arguments.callee make quite a few optimizations impossible so they were deprecated in latest versions of JavaScript. In fact, EcmaScript 5 forbids the use of both in strict mode, according to the docs:

Arguments objects for strict mode functions define non-configurable accessor properties named "caller" and "callee" which throw a TypeError exception on access.

The same restriction applies to the function's caller and arguments properties in strict mode.

Noncompliant Code Example

function whoCalled() {
   if (arguments.caller == null)   //Noncompliant
      console.log('I was called from the global scope.');
   else
      console.log(arguments.caller + ' called me!');  // Noncompliant

  console.log(whoCalled.caller);  // Noncompliant
  console.log(whoCalled.arguments);  // Noncompliant
}
javascript:S2688

NaN is not equal to anything, even itself. Testing for equality or inequality against NaN will yield predictable results, but probably not the ones you want.

Instead, the best way to see whether a variable is equal to NaN is to use Number.isNaN(), since ES2015, or (perhaps counter-intuitively) to compare it to itself. Since NaN !== NaN, when a !== a, you know it must equal NaN.

Noncompliant Code Example

var a = NaN;

if (a === NaN) {  // Noncompliant; always false
  console.log("a is not a number");  // this is dead code
}
if (a !== NaN) { // Noncompliant; always true
  console.log("a is not NaN"); // this statement is not necessarily true
}

Compliant Solution

if (Number.isNaN(a)) {
  console.log("a is not a number");
}
if (!Number.isNaN(a)) {
  console.log("a is not NaN");
}

See

javascript:S2703

JavaScript variable scope can be particularly difficult to understand and get right. The situation gets even worse when you consider the accidental creation of global variables, which is what happens when you declare a variable inside a function or the for clause of a for-loop without using the let, const or var keywords.

let and const were introduced in ECMAScript 2015, and are now the preferred keywords for variable declaration.

Noncompliant Code Example

function f(){
  i = 1;         // Noncompliant; i is global

  for (j = 0; j < array.length; j++) {  // Noncompliant; j is global now too
    // ...
  }
}

Compliant Solution

function f(){
  var i = 1;

  for (let j = 0; j < array.length; j++) {
    // ...
  }
}
javascript:S2713

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all variables names that are used to store/cache jQuery objects match a provided regular expression.

javascript:S2714

Using element type in class selectors is slower than using only the class selector.

Noncompliant Code Example

var $products = $("div.products");    // Noncompliant - slow

Compliant Solution

var $products = $(".products");    // Compliant - fast
javascript:S2715

The use of find allows document.getElementById() to be used for the top-level selection, and saves the jQuery Sizzle engine for where it's really needed. That makes the query faster, and your application more responsive.

From the jQuery documentation:

Beginning your selector with an ID is always best.

The .find() approach is faster because the first selection is handled without going through the Sizzle selector engine – ID-only selections are handled using document.getElementById(), which is extremely fast because it is native to the browser.

Noncompliant Code Example

var $productIds = $("#products div.id"); // Noncompliant - a nested query for Sizzle selector engine

Compliant Solution

var $productIds = $("#products").find("div.id"); // Compliant - #products is already selected by document.getElementById() so only div.id needs to go through Sizzle selector engine
javascript:S2716

Element selections that could be matched anywhere in the document can be very slow. That's why use of the universal selector, *, should be limited; it explicitly specifies that the match could be anywhere.

Noncompliant Code Example

$( ".buttons > *" );  // Noncompliant; extremely expensive

Compliant Solution

$( ".buttons" ).children(); // Compliant
javascript:S2757

The use of operators pairs (=+, =- or =!) where the reversed, single operator was meant (+=, -= or !=) will compile and run, but not produce the expected results.

This rule raises an issue when =+, =- and =! are used without any space between the two operators and when there is at least one whitespace after.

Noncompliant Code Example

let target =-5;
let num = 3;

target =- num;  // Noncompliant; target = -3. Is that really what's meant?
target =+ num; // Noncompliant; target = 3

Compliant Solution

let target = -5;
let num = 3;

target = -num;  // Compliant; intent to assign inverse value of num is clear
target += num;
javascript:S2762

jQuery doesn't cache elements for you. If you've made a selection that you might need to make again, you should save the selection in a variable rather than making the selection repeatedly.

Noncompliant Code Example

With the default threshold of 2

$( "p" ).hide();
$( "p" ).show();  // Noncompliant

Compliant Solution

var paragraph = $( "p" );

paragraph.hide();
paragraph.show();

Exceptions

Stored selections are not updated when the DOM changes. Since variables may need to updated this rule ignores selections that are repeated during an assignment.

var paragraph = $("p");

// ...

paragraph = $("p");
javascript:S2769

Once you've made a selection, you typically want to know whether it actually found anything. Since selectors always return an object (the set of selected DOM elements), the best way to see whether your selection found anything is to test the returned object's .length property.

Noncompliant Code Example

if ( $( "div.foo" ) ) {  // Noncompliant
  // this code always runs, even when the selector didn't match any elements
  // ...
}

Compliant Solution

// Testing whether a selection contains elements.
if ( $( "div.foo" ).length > 0) {
  // this code only runs if elements were found
  //  ...
}
javascript:S2770

Deprecation is a warning that a method has been superseded, and will eventually be removed. The deprecation period allows you to make a smooth transition away from the aging, soon-to-be-retired technology.

This rule raises an issue when any of the following methods is used:

  • .andSelf()
  • .context
  • .die()
  • .error()
  • jQuery.boxModel
  • jQuery.browser
  • jQuery.sub()
  • jQuery.support
  • .live()
  • .load()
  • .selector
  • .size()
  • .toggle()
  • .unload()
javascript:S2814

This rule checks that a declaration doesn't use a name that is already in use. Indeed, it is possible to use the same symbol multiple times as either a variable or a function, but doing so is likely to confuse maintainers. Further it's possible that such reassignments are made in error, with the developer not realizing that the value of the variable is overwritten by the new assignment.

This rule also applies to function parameters.

Noncompliant Code Example

var a = 'foo';
function a() {}   // Noncompliant
console.log(a);   // prints "foo"

function myFunc(arg) {
  var arg = "event"; // Noncompliant, argument value is lost
}

fun(); // prints "bar"

function fun() {
  console.log("foo");
}

fun(); // prints "bar"

function fun() {  // Noncompliant
  console.log("bar");
}

fun(); // prints "bar"

Compliant Solution

var a = 'foo';
function otherName() {}
console.log(a);

function myFunc(arg) {
  var newName = "event";
}

fun(); // prints "foo"

function fun() {
  print("foo");
}

fun(); // prints "foo"

function printBar() {
  print("bar");
}

printBar(); // prints "bar"
javascript:S2870

The delete operator can be used to remove a property from any object. Arrays are objects, so the delete operator can be used here too, but if it is, a hole will be left in the array because the indexes/keys won't be shifted to reflect the deletion.

The proper method for removing an element at a certain index would be:

  • Array.prototype.splice - add/remove elements from the array
  • Array.prototype.pop - add/remove elements from the end of the array
  • Array.prototype.shift - add/remove elements from the beginning of the array

Noncompliant Code Example

var myArray = ['a', 'b', 'c', 'd'];

delete myArray[2];  // Noncompliant. myArray => ['a', 'b', undefined, 'd']
console.log(myArray[2]); // expected value was 'd' but output is undefined

Compliant Solution

var myArray = ['a', 'b', 'c', 'd'];

// removes 1 element from index 2
removed = myArray.splice(2, 1);  // myArray => ['a', 'b', 'd']
console.log(myArray[2]); // outputs 'd'
javascript:S2873

The fact that JavaScript is not a strongly typed language allows developers a lot of freedom, but that freedom can be dangerous if you go too far with it.

Specifically, it is syntactically acceptable to invoke any expression as though its value were a function. But a TypeError may be raised if you do.

Noncompliant Code Example

foo = 1;
foo();   // Noncompliant; TypeError

foo = undefined;
foo();  // Noncompliant; TypeError
javascript:S2898

While :<element_type> and [type="<element_type>"] can both be used in jQuery to select elements by their type, [type="<element_type>"] is far faster because it can take advantage of the native DOM querySelectorAll() method in modern browsers.

This rule raises an issue when following selectors are used:

  • :checkbox
  • :file
  • :image
  • :password
  • :radio
  • :reset
  • :text

Noncompliant Code Example

var input = $( "form input:radio" ); // Noncompliant

Compliant Solution

var input = $( "form input[type=radio]" ); // Compliant
javascript:S2990

When the keyword this is used outside of an object, it refers to the global this object, which is the same thing as the window object in a standard web page. Such uses could be confusing to maintainers. Instead, simply drop the this, or replace it with window; it will have the same effect and be more readable.

Noncompliant Code Example

this.foo = 1;   // Noncompliant
console.log(this.foo); // Noncompliant

function MyObj() {
  this.foo = 1; // Compliant
}

MyObj.func1 = function() {
  if (this.foo == 1) { // Compliant
    // ...
  }
}

Compliant Solution

foo = 1;
console.log(foo);

function MyObj() {
  this.foo = 1;
}

MyObj.func1 = function() {
  if (this.foo == 1) {
    // ...
  }
}
javascript:S2999

The new keyword should only be used with objects that define a constructor function. Use it with anything else, and you'll get a TypeError because there won't be a constructor function for the new keyword to invoke.

Noncompliant Code Example

function MyClass() {
  this.foo = 'bar';
}

var someClass = 1;

var obj1 = new someClass;    // Noncompliant;
var obj2 = new MyClass();    // Noncompliant if considerJSDoc parameter set to true. Compliant when considerJSDoc=false

Compliant Solution

/**
 * @constructor
 */
function MyClass() {
  this.foo = 'bar';
}

var someClass = function(){
  this.prop = 1;
}

var obj1 = new someClass;  // Compliant
var obj2 = new MyClass();  // Compliant regardless of considerJSDoc value
javascript:S3001

The semantics of the delete operator are a bit tricky, and it can only be reliably used to remove properties from objects. Pass anything else to it, and you may or may not get the desired result.

Noncompliant Code Example

var x  = 1;
delete x;       // Noncompliant

function foo(){
..
}

delete foo;  // Noncompliant

Compliant Solution

var obj = {
  x:1,
  foo: function(){
  ...
  }
};
delete obj.x;
delete obj.foo;

javascript:S3002

The unary operators + and - can be used to convert some value types to numeric values. But not every value can be converted to a Number type; use it with an object, and result will be NaN (Not A Number). This can be confusing to maintainers.

Noncompliant Code Example

var obj = {x : 1};
doSomethingWithNumber(+obj);    // Noncompliant

function foo(){
  return 1;
}
doSomethingWithNumber(-foo);    // Noncompliant

Compliant Solution

var obj = {x : 1};
doSomethingWithNumber(+obj.x);

function foo(){
  return 1;
}
doSomethingWithNumber(-foo());

var str = '42';
doSomethingWithNumber(+str);

Exceptions

Unary + and - can be used with objects corresponding to primitive types, and + can be used with Date.

var b = new Boolean(true);
doSomethingWithNumber(-b);  // Compliant
var timestamp = +new Date();  // Compliant
javascript:S3003

The use of comparison operators (<, <=, >=, >) with strings is not likely to yield the expected results. Make sure the intention was to compare strings and not numbers.

Noncompliant Code Example

var appleNumber = "123";
var orangeNumber = "45";
if (appleNumber < orangeNumber) {  // Noncompliant, this condition is true
  alert("There are more oranges");
}

Compliant Solution

var appleNumber = "123";
var orangeNumber = "45";
if (Number(appleNumber) < Number(orangeNumber)) {
  alert("There are more oranges");
}
javascript:S3317

By convention, a file that exports only one class, function, or constant should be named for that class, function or constant. Anything else may confuse maintainers.

Noncompliant Code Example

// file path: myclass.js  -- Noncompliant
class MyClass {
  // ...
}
export default MyClass;

Compliant Solution

// file path: MyClass.js
class MyClass {
  // ...
}
export default MyClass;
javascript:S3353

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

function seek(input) {
  let target = 32;  // Noncompliant
  for (let i of input) {
    if (i == target) {
      return true;
    }
  }
  return false;
}

Compliant Solution

function seek(input) {
  const target = 32;
  for (let i of input) {
    if (i == target) {
      return true;
    }
  }
  return false;
}
javascript:S3403

Comparing dissimilar types using the strict equality operators === and !== will always return the same value, respectively false and true, because no type conversion is done before the comparison. Thus, such comparisons can only be bugs.

Noncompliant Code Example

var a = 8;
var b = "8";

if (a === b) {  // Noncompliant; always false
  // ...
}

Compliant Solution

var a = 8;
var b = "8";

if (a == b) {
  // ...
}

or

var a = 8;
var b = "8";

if (a === Number(b)) {
  // ...
}
javascript:S3498

When an already-defined variable is given the same name within a new object, object-shorthand syntax is preferred as being more compact. Similarly, object-shorthand is also preferred for the definition of functions in object literals.

Noncompliant Code Example

let a = 1;

let myObj = {
  a : a,  // Noncompliant
  fun: function () {  // Noncompliant
    //...
  }
}

Compliant Solution

let a = 1;

let myObj = {
  a,
  fun () {
    //...
  }
}
javascript:S3499

Grouping all the shorthand declarations together in an object makes the declaration as a whole more readable. This rule accepts shorthand declarations grouped at either the beginning or end of an object.

Noncompliant Code Example

let obj1 = {
  foo,
  a: 1,
  color,  // Noncompliant
  b: 2,
  judyGarland  // Noncompliant
}

Compliant Solution

let obj1 = {
  foo,
  color,
  judyGarland,
  a: 1,
  b: 2
}

or

let obj1 = {
  a: 1,
  b: 2,
  foo,
  color,
  judyGarland
}
javascript:S3500

Variables declared with const cannot be modified. Unfortunately, attempts to do so don't always raise an error; in a non-ES2015 environment, such an attempt might simply be ignored.

Noncompliant Code Example

const pi = "yes, please";
pi = 3.14;  // Noncompliant
javascript:S3504

ECMAScript 2015 introduced the let and const keywords for block-scope variable declaration. Using const creates a read-only (constant) variable.

The distinction between the variable types created by var and by let is significant, and a switch to let will help alleviate many of the variable scope issues which have caused confusion in the past.

Because these new keywords create more precise variable types, they are preferred in environments that support ECMAScript 2015. However, some refactoring may be required by the switch from var to let, and you should be aware that they raise SyntaxErrors in pre-ECMAScript 2015 environments.

This rule raises an issue when var is used instead of const or let.

Noncompliant Code Example

var color = "blue";
var size = 4;

Compliant Solution

const color = "blue";
let size = 4;
javascript:S3509

The assignment of default parameter values is generally intended to help the caller. But when a default assignment causes side effects, the caller may not be aware of the extra changes or may not fully understand their implications. I.e. default assignments with side effects may end up hurting the caller, and for that reason, they should be avoided.

Noncompliant Code Example

var count = 0;

function go(i = count++) {  // Noncompliant
  console.log(i);
}

go();  // outputs 0
go(7); // outputs 7
go();  // outputs 1
javascript:S3512

ECMAScript 2015 added the ability to use template literals instead of concatenation. Since their use is clearer and more concise, they are preferred in environments that support ECMAScript 2015.

This rule raises an issue when a string is created from the result of two or more concatenations.

Noncompliant Code Example

function sayHello(name) {
  console.log("hello " + name);  // ignored
}

function madLib(verb, noun) {
  console.log("I really " + verb + " one or two " + noun);  // Noncompliant
}

Compliant Solution

function sayHello(name) {
  console.log(`hello ${name}`);  // no issue raised before, but this is better
}

function madLib(verb, noun) {
  console.log(`I really ${verb} one or two ${noun}`);
}
javascript:S3513

The magic of JavaScript is that you can pass arguments to functions that don't declare parameters, and on the other side, you can use those passed-in arguments inside the no-args function.

But just because you can, that does't mean you should. The expectation and use of arguments inside functions that don't explicitly declare them is confusing to callers. No one should ever have to read and fully understand a function to be able to use it competently.

If you don't want to name arguments explicitly, use the ... syntax to specify that an a variable number of arguments is expected. Then inside the function, you'll be dealing with a first-class array, rather than an array-like structure.

Noncompliant Code Example

function concatenate() {
  let args = Array.prototype.slice.call(arguments);  // Noncompliant
  return args.join(', ');
}

function doSomething(isTrue) {
  var args = Array.prototype.slice.call(arguments, 1); // Noncompliant
  if (!isTrue) {
    for (var arg of args) {
      ...
    }
  }
}

Compliant Solution

function concatenate(...args) {
  return args.join(', ');
}

function doSomething(isTrue, ...values) {
  if (!isTrue) {
    for (var value of values) {
      ...
    }
  }
}
javascript:S3514

ECMAScript 2015 introduced the ability to extract and assign multiple data points from an object or array simultaneously. This is called "destructuring", and it allows you to condense boilerplate code so you can concentrate on logic.

This rule raises an issue when multiple pieces of data are extracted out of the same object or array and assigned to variables.

Noncompliant Code Example

function foo (obj1, obj2, array) {
  var a = obj1.a;  // Noncompliant
  var b = obj1.b;

  var name = obj2.name;  // ignored; there's only one extraction-and-assignment

  var zero = array[0];  // Noncompliant
  var one = array[1];
}

Compliant Solution

function foo (obj1, obj2, array) {
  var {a, b} = obj1;

  var {name} = obj2;  // this syntax works because var name and property name are the same

  var [zero, one] = array;
}
javascript:S3516

When a function is designed to return an invariant value, it may be poor design, but it shouldn't adversely affect the outcome of your program. However, when it happens on all paths through the logic, it is likely a mistake.

This rule raises an issue when a function contains several return statements that all return the same value.

Noncompliant Code Example

function foo(a) {  // Noncompliant
  let b = 12;
  if (a) {
    return b;
  }
  return b;
}
javascript:S3524

Shared coding conventions allow teams to collaborate effectively. This rule raises an issue when the use of parentheses with an arrow function does not conform to the configured requirements.

Noncompliant Code Example

With the configured defaults forbidding parentheses

var foo = (a) => { /* ... */ };  // Noncompliant; remove parens from arg
var bar = (a, b) => { return 0; };  // Noncompliant; remove curly braces from body

Compliant Solution

var foo = a => { /* ... */ };
var bar = (a, b) => 0;
javascript:S3525

Originally JavaScript didn't support classes, and class-like behavior had to be kludged using things like prototype assignments for "class" functions. Fortunately, ECMAScript 2015 added classes, so any lingering prototype uses should be converted to true classes. The new syntax is more expressive and clearer, especially to those with experience in other languages.

Specifically, with ES2015, you should simply declare a class and define its methods inside the class declaration.

Noncompliant Code Example

function MyNonClass(initializerArgs = []) {
  this._values = [...initializerArgs];
}

MyNonClass.prototype.doSomething = function () {  // Noncompliant
  // ...
}

Compliant Solution

class MyClass {
  constructor(initializerArgs = []) {
    this._values = [...initializerArgs];
  }

  doSomething() {
    //...
  }
}
javascript:S3531

A generator without a yield statement is at best confusing, and at worst a bug in your code, since the iterator produced by your code will always be empty.

Noncompliant Code Example

function* myGen(a, b) {  // Noncompliant
  let answer = 0;
  answer += a * b;
}

Compliant Solution

function* myGen(a, b) {
  let answer = 0;
  while (answer < 42) {
    answer += a * b;
    yield answer;
  }
}
javascript:S3533

Before ECMAScript 2015, module management had to be ad-hoc or provided by 3rd-party libraries such as Node.js, Webpack, or RequireJS. Fortunately, ES2015, provides language-standard mechanisms for module management, import and export, and older usages should be converted.

Noncompliant Code Example

// circle.js
exports.area = function (r) {
  return PI * r * r;
};

// foo.js
define(["./cart", "./horse"], function(cart, horse) {  // Noncompliant
  // ...
});

// bar.js
const circle = require('./circle.js');  // Noncompliant

Compliant Solution

// circle.js
let area = function (r) {
  return PI * r * r;
}
export default area;

// foo.js
import cart from "./cart.js";
import horse from "./horse.js";

// bar.js
import circle from "./circle.js"
javascript:S3579

Associative arrays allow you to store values in an array with either numeric or named indexes. But creating and populating an object is just as easy as an array, and more reliable if you need named members.

Noncompliant Code Example

let arr = [];
arr[0] = 'a';
arr['name'] = 'bob';  // Noncompliant
arr[1] = 'foo';

Compliant Solution

let obj = {
  name: 'bob',
  arr: ['a', 'foo']
};
javascript:S3616

The comma operator (,) evaluates its operands, from left to right, and returns the second one. That's useful in some situations, but just wrong in a switch case. You may think you're compactly handling multiple values in the case, but only the last one in the comma-list will ever be handled. The rest will fall through to the default.

Similarly the logical OR operator (||) will not work in a switch case, only the first argument will be considered at execution time.

Noncompliant Code Example

switch a {
  case 1,2:  // Noncompliant; only 2 is ever handled by this case
    doTheThing(a);
  case 3 || 4: // Noncompliant; only '3' is handled
    doThatThing(a);
  case 5:
    doTheOtherThing(a);
  default:
    console.log("Neener, neener!");  // this happens when a==1 or a == 4
}

Compliant Solution

switch a {
  case 1:
  case 2:
    doTheThing(a);
  case 3:
  case 4:
    doThatThing(a);
  case 5:
    doTheOtherThing(a);
  default:
    console.log("Neener, neener!");
}
javascript:S3686

Constructor functions, which create new object instances, must only be called with new. Non-constructor functions must not. Mixing these two usages could lead to unexpected results at runtime.

Noncompliant Code Example

function getNum() {
  return 5;
}

function Num(numeric, alphabetic) {
  this.numeric = numeric;
  this.alphabetic = alphabetic;
}

var myFirstNum = getNum();
var my2ndNum = new getNum();  // Noncompliant. An empty object is returned, NOT 5

var myNumObj1 = new Num();
var myNumObj2 = Num();  // Noncompliant. undefined is returned, NOT an object
javascript:S3723

Modern browsers ignore unneeded, trailing commas, so there are no negatives to having them unless you're supporting an IE 8 application. Since they make adding new properties simpler, their use is preferred. This rule raises an issue when the last item in an object declaration or array declaration does not end with a trailing comma and does not lie on the same line as the closing curly brace or bracket.

Noncompliant Code Example

var joe = {
  fname: "Joe",
  lname: "Smith"      // Noncompliant
};

Compliant Solution

var joe = {
  fname: "Joe",
  lname: "Smith",    // OK
};

var joe = {
  fname: "Joe",
  lname: "Smith"};   // OK
javascript:S3735

The void operator evaluates its argument and unconditionally returns undefined. It can be useful in pre-ECMAScript 5 environments, where undefined could be reassigned, but generally, its use makes code harder to understand.

Noncompliant Code Example

void (function() {
   ...
}());

Compliant Solution

(function() {
   ...
}());

Exceptions

No issue is raised when void 0 is used in place of undefined.

if (parameter === void 0) {...}
javascript:S3757

The result of an expression with an arithmetic operator /, *, %, ++, --, -, +=, -=, *=, /=, %=, + or unary operator +, - when at least one operand is Object or Undefined will be always a NaN (Not a Number).

Noncompliant Code Example

x = [1, 2];
var y = x / 4;  //Noncompliant

Exceptions

  • Date operands: they are implicitly converted to numbers.
  • The binary + operator with Object operand (concatenation).
javascript:S3758

In a Zen-like manner, NaN isn't equal to anything, even itself. So comparisons (>, <, >=, <=) where one operand is NaN or evaluates to NaN always return false. Specifically, undefined and objects that cannot be converted to numbers evaluate to NaN when used in numerical comparisons.

This rule raises an issue when there is at least one path through the code where one of the operands to a comparison is NaN, undefined or an Object which cannot be converted to a number.

Noncompliant Code Example

var x;  // x is currently "undefined"
if (someCondition()) {
  x = 42;
}

if (42 > x) {  // Noncompliant; "x" might still be "undefined"
  doSomething();
}

var obj = {prop: 42};
if (obj > 24) { // Noncompliant
  doSomething();
}

Compliant Solution

var x;
if (someCondition()) {
  x = 42;
} else {
  x = foo();
}

if (42 > x) {
  doSomething();
}

var obj = {prop: 42};
if (obj.prop > 24) {
  doSomething();
}
javascript:S3759

Reading a non-existent property on an object always returns undefined. Doing so is usually an error; either in the name of the property or the type of the variable being accessed.

If an attempt is made to access properties of a primitive, the primitive is automatically encased in a primitive-wrapper object for the operation. But being "promoted" to an object doesn't mean that the primitive will actually have properties to access. The wrapper object still won't have the non-existent property and undefined will be returned instead.

This rule raises an issue when an attempt is made to access properties of a primitive. Thus this rule should only be activated when you don't use monkey patching for standard objects, like Number, Boolean and String.

Noncompliant Code Example

x = 42;
y = x.length;   // Noncompliant, Number type doesn't have "length" property

Exceptions

The Ember framework introduces a few extensions to String. Since it is a widely used package, the following String properties will not trigger this rule even though they are not built-in:

  • camelize
  • capitalize
  • classify
  • dasherize
  • decamelize
  • fmt
  • loc
  • underscore
  • w
javascript:S3760

Expressions with arithmetic (/, *, %, ++, --, -, -=, *=, /=, %=, +=, +), unary (-), or comparison operators (>, <, >=, <=) where one, or both, of the operands is a String, Boolean or Date value rely on implicit conversions. Both the maintainability and reliability levels of such a piece of code are questionable.

Noncompliant Code Example

str = "80";
quarter = str / 4; // Noncompliant

if (str < 10) { // Noncompliant
   // ...
}

Compliant Solution

str = "80";
parsedStr = parseInt(str);
quarter = parsedStr / 4;

if (parsedStr < 10) {
  // ...
}

Exceptions

  • Expressions using the binary + operator with at least one String operand are ignored because the + operator will perform a concatenation in that case.
  • Comparisons where both operands are strings are ignored because a lexicographical comparison is performed in that case.
javascript:S3782

The types of the arguments to built-in functions are specified in the JavaScript language specifications. Calls to these functions should conform to the documented types, otherwise the result will most likely not be what was expected (e.g.: the call would always return false).

Noncompliant Code Example

const isTooSmall = Math.abs(x < 0.0042);

Compliant Solution

const isTooSmall = Math.abs(x) < 0.0042;
javascript:S3785

The in operator tests whether the specified property is in the specified object.

If the right operand is a of primitive type (i.e., not an object) the in operator raises a TypeError.

Noncompliant Code Example

var x = "Foo";
"length" in x; // Noncompliant: TypeError
0 in x;        // Noncompliant: TypeError

Compliant Solution

var x = new String("Foo");
"length" in x;    // true
0 in x;           // true
"foobar" in x;    // false
javascript:S3786

Template strings allow developers to embed variables or expressions in strings using template literals, instead of string concatenation. This is done by using expressions like ${variable} in a string between two back-ticks (`). However, when used in a regular string literal (between double or single quotes) the template will not be evaluated and will be used as a literal, which is probably not what was intended.

Noncompliant Code Example

console.log("Today is ${date}"); // Noncompliant

Compliant Solution

console.log(`Today is ${date}`);
javascript:S3796

Arrays in JavaScript have several methods for filtering, mapping or folding that require a callback. Not having a return statement in such a callback function is most likely a mistake.

This rule applies for the following methods of an array:

  • Array.from
  • Array.prototype.every
  • Array.prototype.filter
  • Array.prototype.find
  • Array.prototype.findIndex
  • Array.prototype.map
  • Array.prototype.reduce
  • Array.prototype.reduceRight
  • Array.prototype.some
  • Array.prototype.sort

Noncompliant Code Example

var merged = arr.reduce(function(a, b) {
  a.concat(b);
}); // Noncompliant: No return statement

Compliant Solution

var merged = arr.reduce(function(a, b) {
  return a.concat(b);
});
javascript:S3798

Any variable or function declared in the global scope implicitly becomes attached to the global object (the window object in a browser environment). To make it explicit this variable or function should be a property of window. When it is meant to be used just locally, it should be declared with the const or let keywords (since ECMAScript 2015) or within an Immediately-Invoked Function Expression (IIFE).

This rule should not be activated when modules are used.

Noncompliant Code Example

var myVar = 42;       // Noncompliant
function myFunc() { } // Noncompliant

Compliant Solution

window.myVar = 42;
window.myFunc = function() { };

or

let myVar = 42;
let myFunc = function() { }

or

// IIFE
(function() {
  var myVar = 42;
  function myFunc() { }
})();
javascript:S3799

Destructuring is a convenient way of extracting multiple values from data stored in (possibly nested) objects and arrays. However, it is possible to create an empty pattern that has no effect. When empty curly braces or brackets are used to the right of a property name most of the time the intent was to use a default value instead.

This rule raises an issue when empty destructuring pattern is used.

Noncompliant Code Example

var {a: {}, b} = myObj; // Noncompliant
function foo({first: [], second}) { // Noncompliant
  // ...
}

Compliant Solution

var {a = {}, b} = myObj;
function foo({first = [], second}) {
  // ...
}
javascript:S3800

Unlike strongly typed languages, JavaScript does not enforce a return type on a function. This means that different paths through a function can return different types of values, which can be very confusing to the user and significantly harder to maintain.

Noncompliant Code Example

function foo(a) {  // Noncompliant
  if (a === 1) {
    return true;
  }
  return 3;
}

Compliant Solution

function foo(a) {
  if (a === 1) {
    return true;
  }
  return false;
}
javascript:S3801

Unlike strongly typed languages, JavaScript does not enforce a return type on a function. This means that different paths through a function can return different types of values, which can be very confusing to the user and significantly harder to maintain.

In particular a function, in JavaScript, will return undefined in any of the following cases:

  • It exits without a return statement.
  • It executes a return with no value.

This rule verifies that return values are either always or never specified for each path through a function.

Noncompliant Code Example

function foo(a) { // Noncompliant, function exits without "return"
  if (a == 1) {
    return true;
  }
}

Compliant Solution

function foo(a) {
  if (a == 1) {
    return true;
  }
  return false;
}
javascript:S3827

When a non-existent variable is referenced a ReferenceError is raised.

Due to the dynamic nature of JavaScript this can happen in a number of scenarios:

  • When typo was made in a symbol's name.
  • When using variable declared with let or const before declaration (unlike var-declarations, they are not hoisted to the top of the scope).
  • Due to confusion with scopes of let- and const-declarations (they have block scope, unlike var-declarations, having function scope).
  • When accessing a property in the wrong scope (e.g. forgetting to specify this.).

This rule does not raise issues on global variables which are defined with sonar.javascript.globals and sonar.javascript.environments properties.

Noncompliant Code Example

var john = {
  firstName: "john",
  show: function() { console.log(firstName); } // Noncompliant: firstName is not defined
}
john.show();

Compliant Solution

var john = {
  firstName: "john",
  show: function() { console.log(this.firstName); }
}
john.show();
javascript:S3828

The yield keyword is used in a generator function to return an IteratorResult to the caller. It has no other purpose, and if found outside such a function will raise a ReferenceError because it is then treated as an identifier.

Noncompliant Code Example

function foo() {
  for (var i = 0; i < 5; i++) {
    yield i * 2;
  }
}

Compliant Solution

function * foo() {
  for (var i = 0; i < 5; i++) {
    yield i * 2;
  }
}
javascript:S3834

Symbol is a primitive type introduced in ECMAScript2015. Its instances are mainly used as unique property keys.

An instance can only be created by using Symbol as a function. Using Symbol with the new operator will raise a TypeError.

Noncompliant Code Example

const sym = new Symbol("foo");   // Noncompliant

Compliant Solution

const sym = Symbol("foo");
javascript:S3854

There are situations where super() must be invoked and situations where super() cannot be invoked.

The basic rule is: a constructor in a non-derived class cannot invoke super(); a constructor in a derived class must invoke super().

Furthermore:

- super() must be invoked before the this and super keywords can be used.

- super() must be invoked with the same number of arguments as the base class' constructor.

- super() can only be invoked in a constructor - not in any other method.

- super() cannot be invoked multiple times in the same constructor.

Known Limitations

  • False negatives: some issues are not raised if the base class is not defined in the same file as the current class.

Noncompliant Code Example

class Animal {
  constructor() {
    super();         // Noncompliant, super() cannot be invoked in a base class
  }

  doSomething() {
  }
}

class Dog extends Animal {
  constructor(name) {
    this.name = name;
    super.doSomething();
    super();         // Noncompliant, super() must be invoked before "this" or "super" is used
  }

  doSomething() {
    super();         // Noncompliant, super() cannot be invoked outside of a constructor
  }
}

class Labrador extends Dog {
  constructor(name) {
    super();         // Noncompliant, super() must be invoked with one argument
  }
}

class GermanShepherd extends Dog {
  constructor(name) {
  }                  // Noncompliant, super() must be invoked in constructor of derived class
}

class FilaBrasileiro extends Dog {
  constructor(name) {
    super(name);
    super(name);    // Noncompliant, super() can only be invoked once
  }
}

Compliant Solution

class Animal {
  constructor() {
  }

  doSomething() {
  }
}

class Dog extends Animal {
  constructor(name) {
    super();
    this.name = name;
    super.doSomething();
  }

  doSomething() {
  }
}

class Labrador extends Dog {
  constructor(name) {
    super(name);
  }
}

class GermanShepherd extends Dog {
  constructor(name) {
    super(name);
  }
}

class FilaBrasileiro extends Dog {
  constructor(name) {
    super(name);
  }
}
javascript:S3863

Multiple imports from the same module should be merged together to improve readability.

Noncompliant Code Example

import { B1 } from 'b';
import { B2 } from 'b'; // Noncompliant

Compliant Solution

import { B1, B2 } from 'b';
javascript:S3972

Code is clearest when each statement has its own line. Nonetheless, it is a common pattern to combine on the same line an if and its resulting then statement. However, when an if is placed on the same line as the closing } from a preceding else or else if, it is either an error - else is missing - or the invitation to a future error as maintainers fail to understand that the two statements are unconnected.

Noncompliant Code Example

if (condition1) {
  // ...
} if (condition2) {  // Noncompliant
  //...
}

Compliant Solution

if (condition1) {
  // ...
} else if (condition2) {
  //...
}

Or

if (condition1) {
  // ...
}

if (condition2) {
  //...
}
javascript:S3973

In the absence of enclosing curly braces, the line immediately after a conditional is the one that is conditionally executed. By both convention and good practice, such lines are indented. In the absence of both curly braces and indentation the intent of the original programmer is entirely unclear and perhaps not actually what is executed. Additionally, such code is highly likely to be confusing to maintainers.

Noncompliant Code Example

if (condition)  // Noncompliant
doTheThing();

doTheOtherThing();
somethingElseEntirely();

foo();

Compliant Solution

if (condition)
  doTheThing();

doTheOtherThing();
somethingElseEntirely();

foo();
javascript:S3981

The size of a collection and the length of an array are always greater than or equal to zero. So testing that a size or length is greater than or equal to zero doesn't make sense, since the result is always true. Similarly testing that it is less than zero will always return false. Perhaps the intent was to check the non-emptiness of the collection or array instead.

Noncompliant Code Example

if (someSet.size >= 0) {...} // Noncompliant

if (someMap.size < 0) {...} // Noncompliant

const result = someArray.length >= 0;  // Noncompliant

Compliant Solution

if (someSet.size > 0) {...}

if (someMap.size == 0) {...}

const result = someArray.length > 0;
javascript:S4030

When a collection is populated but its contents are never used, then it is surely some kind of mistake. Either refactoring has rendered the collection moot, or an access is missing.

This rule raises an issue when no methods are called on a collection other than those that add or remove values.

Noncompliant Code Example

function getLength(a, b, c) {
  const strings = [];  // Noncompliant
  strings.push(a);
  strings.push(b);
  strings.push(c);

  return a.length + b.length + c.length;
}

Compliant Solution

function getLength(a, b, c) {
  return a.length + b.length + c.length;
}
javascript:S4043

Many of JavaScript's Array methods return an altered version of the array while leaving the source array intact. reverse and sort do not fall into this category. Instead, they alter the source array in addition to returning the altered version, which is likely not what was intended.

This rule raises an issue when the return values of these methods are assigned, which could lead maintainers to overlook the fact that the original value is altered.

Noncompliant Code Example

var b = a.reverse(); // Noncompliant
var d = c.sort(); // Noncompliant

Compliant Solution

var b = [...a].reverse();  // de-structure and create a new array, so reverse doesn't impact 'a'
a.reverse();

c.sort(); // this sorts array in place
javascript:S4165

The transitive property says that if a == b and b == c, then a == c. In such cases, there's no point in assigning a to c or vice versa because they're already equivalent.

This rule raises an issue when an assignment is useless because the assigned-to variable already holds the value on all execution paths.

Noncompliant Code Example

a = b;
c = a;
b = c; // Noncompliant: c and b are already the same

Compliant Solution

a = b;
c = a;
javascript:Semicolon

In JavaScript, the semicolon (;) is optional as a statement separator, but omitting semicolons can be confusing, and lead to unexpected results because a semicolon is implicitly inserted at the end of each line.

Noncompliant Code Example

function fun() {
  return  // Noncompliant. ';' implicitly inserted at end of line
       5   // Noncompliant. ';' implicitly inserted at end of line
}
print(fun());  // prints "undefined", not "5"

Compliant Solution

function fun() {
  return 5;
}
print(fun());
javascript:SingleQuote

For consistency single-quotes (') are preferred to double-quotes ("). This is helpful when creating strings that include HTML.

Noncompliant Code Example

var firstParameter = "something";

Compliant Solution

var firstParameter = 'something';

Exceptions

JSX code and strings that contain quotes are ignored.

let heSaid = "Then he said 'What?'."  // ignored
let sheSaid = '"Whatever!" she replied.'  // ignored
javascript:StrictMode

Even though it may be a good practice to enforce JavaScript strict mode, doing so could result in unexpected behaviors on browsers that do not support it yet. Using this feature should therefore be done with caution and with full knowledge of the potential consequences on browsers that do not support it.

Noncompliant Code Example

function strict() {
  'use strict';
}
javascript:TabCharacter

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

javascript:TooManyBreakOrContinueInLoop

Restricting the number of break and continue statements in a loop is done in the interest of good structured programming.

One break and continue statement is acceptable in a loop, since it facilitates optimal coding. If there is more than one, the code should be refactored to increase readability.

Noncompliant Code Example

for (var i = 1; i <= 10; i++) {  // Noncompliant - 2 continue - one might be tempted to add some logic in between
  if (i % 2 == 0) {
    continue;
  }

  if (i % 3 == 0) {
    continue;
  }

  alert("i = " + i);
}
javascript:TrailingComment

This rule verifies that single-line comments are not located at the ends of lines of code. The main idea behind this rule is that in order to be really readable, trailing comments would have to be properly written and formatted (correct alignment, no interference with the visual structure of the code, not too long to be visible) but most often, automatic code formatters would not handle this correctly: the code would end up less readable. Comments are far better placed on the previous empty line of code, where they will always be visible and properly formatted.

Noncompliant Code Example

var a1 = b + c; // This is a trailing comment that can be very very long

Compliant Solution

// This very long comment is better placed before the line of code
var a2 = b + c;
javascript:TrailingWhitespace

Trailing whitespaces are simply useless and should not stay in code. They may generate noise when comparing different versions of the same file.

If you encounter issues from this rule, this probably means that you are not using an automated code formatter - which you should if you have the opportunity to do so.

Noncompliant Code Example

// The following string will error if there is a whitespace after '\'
var str = "Hello \
World";
javascript:UnusedVariable

If a local variable or a local function 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 or function is used for.

Noncompliant Code Example

function numberOfMinutes(hours) {
  var seconds = 0;   // seconds is never used
  return hours * 60;
}

Compliant Solution

function numberOfMinutes(hours) {
  return hours * 60;
}
javascript:VariableDeclarationAfterUsage

Variables declared with var have the special property that regardless of where they're declared in a function they "float" to the top of the function and are available for use even before they're declared. That makes scoping confusing, especially for new coders. To keep confusion to a minimum, var declarations should happen before the variables they declare are used for the first time.

Noncompliant Code Example

var x = 1;

function fun(){
  alert(x); // Noncompliant as x is declared later in the same scope
  if(something) {
    var x = 42; // Declaration in function scope (not block scope!) shadows global variable
  }
}

fun(); // Unexpectedly alerts "undefined" instead of "1"

Compliant Solution

var x = 1;

function fun() {
  print(x);
  if (something) {
    x = 42;
  }
}

fun(); // Print "1"
javascript:WithStatement

The use of the with keyword produces an error in JavaScript strict mode code. However, that's not the worst that can be said against with.

Using with allows a short-hand access to an object's properties - assuming they're already set. But use with to access some property not already set in the object, and suddenly you're catapulted out of the object scope and into the global scope, creating or overwriting variables there. Since the effects of with are entirely dependent on the object passed to it, with can be dangerously unpredictable, and should never be used.

Noncompliant Code Example

var x = 'a';

var foo = {
  y: 1
}

with (foo) {  // Noncompliant
  y = 4;  // updates foo.x
  x = 3;  // does NOT add a foo.x property; updates x var in outer scope
}
print(foo.x + " " + x); // shows: undefined 3

Compliant Solution

var x = 'a';

var foo = {
  y: 1
}

foo.y = 4;
foo.x = 3;

print(foo.x + " " + x); // shows: 3 a
kotlin:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

kotlin:S101

Shared coding conventions allow teams to collaborate effectively. This rule allows to check that all class names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression ^[A-Z][a-zA-Z0-9]*$:

class my_class {...}

Compliant Solution

class MyClass {...}
kotlin:S103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

kotlin:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

kotlin:S105

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

kotlin:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if (file != null) {
  if (file.isFile() || file.isDirectory()) {
    /* ... */
  }
}

Compliant Solution

if (file != null && isFileOrDirectory(file)) {
  /* ... */
}
fun isFileOrDirectory(file: File): Boolean {
    return file.isFile() || file.isDirectory();
}
kotlin:S1067

The complexity of an expression is defined by the number of &&, || and condition ? ifTrue : ifFalse operators it contains.

A single expression's complexity should not become too high to keep the code readable.

Noncompliant Code Example

With the default threshold value of 3:

if (((condition1 && condition2) || (condition3 && condition4)) && condition5) { ... }

Compliant Solution

if ((myFirstCondition() || mySecondCondition()) && myLastCondition()) { ... }
kotlin:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

kotlin:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

val x = (y / 2 + 1)  // Compliant even if the parentheses are ignored by the compiler

if (a && ((x + y > 0))) {  // Noncompliant
  //...
}

return ((x + 1))  // Noncompliant

Compliant Solution

val x = (y / 2 + 1)

if (a && (x + y > 0)) {
  //...
}

return (x + 1)
kotlin:S1144

private methods that are never executed are dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.

kotlin:S117

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a local variable or function parameter name does not match the provided regular expression.

kotlin:S1172

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

See

  • MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions.
  • MISRA C:2012, 2.7 - There should be no unused parameters in functions
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
kotlin:S1186

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

  • 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 function is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.
kotlin:S1192

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

With the default threshold of 3:

class A {
    fun run() {
        prepare("string literal")    // Noncompliant - "string literal" is duplicated 3 times
        execute("string literal")
        release("string literal")
    }

    fun method() {
        println("'")                 // Compliant - literal "'" has less than 5 characters and is excluded
        println("'")
        println("'")
    }
}

Compliant Solution

class A {
    companion object {
        const val CONSTANT = "string literal"
    }

    fun run() {
        prepare(CONSTANT)    // Compliant
        execute(CONSTANT)
        release(CONSTANT)
    }
}

Exceptions

To prevent generating some false-positives, literals having 5 or less characters are excluded as well as literals containing only letters, digits and '_'.

kotlin:S122

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

foo(); bar();

Compliant Solution

foo();
bar();
kotlin:S125

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
kotlin:S126

This rule applies whenever an if statement is followed by one or more else if statements; the final else if should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch statement.

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
kotlin:S134

Nested if, for, while, when, and try statements are key ingredients for making what's known as "Spaghetti code".

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

kotlin:S138

A function that grows too large tends to aggregate too many responsibilities.

Such functions inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions which focus on well-defined tasks.

Those smaller functions will not only be easier to understand, but also probably easier to test.

kotlin:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
kotlin:S1479

When when statements have a large number of clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

kotlin:S1481

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.

kotlin:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

fun doSomething() {
    var name = ""
    // ...
    name = name
}

Compliant Solution

fun doSomething() {
    var name = ""
    // ...
    this.name = name
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
kotlin:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Exceptions

This rule ignores *, +, and =.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
kotlin:S1821

Nested when structures are difficult to understand because you can easily confuse the cases of an inner when as belonging to an outer statement. Therefore nested when statements should be avoided.

Specifically, you should structure your code to avoid the need for nested when statements, but if you cannot, then consider moving the inner when to another function.

Noncompliant Code Example

fun foo(n: Int, m: Int) {
  when (n) {
    0 ->
      when (m) {  // Noncompliant; nested when
        // ...
      }
    1 -> print("1")
    else -> print("2")
  }
}

Compliant Solution

fun foo(n: Int, m: Int) {
  when (n) {
    0 -> bar(m)
    1 -> print("1")
    else -> print("2")
  }
}

fun bar(m: Int){
  when(m) {
    // ...
  }
}
kotlin:S1862

A chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
kotlin:S1940

It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.

Noncompliant Code Example

if (!(a == 2)) { ... }  // Noncompliant
val b = !(i < 10)  // Noncompliant

Compliant Solution

if (a != 2) { ... }
val b = (i >= 10)
objc:ClassComplexity

The cyclomatic complexity of a class should not exceed a defined threshold. Complex code can perform poorly and will in any case be difficult to understand and therefore to maintain.

Deprecated

This rule is deprecated, and will eventually be removed.

objc:CommentMixedStyles

Use either the // ... or /* ... */ comment syntax, but be consistent and do not mix them within the same file.

Noncompliant Code Example

/* Noncompliant; both comment syntaxes are used in the same file */
// Foo
/* Bar */

Compliant Solution

// Compliant; uniform comment syntax
// Foo
// Bar

See

  • CERT, MSC55-J. - Use comments consistently and in a readable fashion
objc:EmptyCompoundStatement

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

void foo()
{
  int x;
  if (x == 42)
  {                     /* Noncompliant */
    /* do nothing */
  }
  else
  {
    printf("x != 42");
  }
}

void bar()
{                       /* Compliant - functions are not nested blocks */
}

Compliant Solution

void foo()
{
  int x;
  if (x != 42)
  {                     /* Compliant */
    printf("x != 42");
  }
}

/* ... */

Exceptions

When a block contains a comment, this block is not considered to be empty.

objc:FileComplexity

Most of the time, a very complex file breaks the Single Responsibility Principle and should be re-factored into several different files.

Deprecated

This rule is deprecated, and will eventually be removed.

objc:FileLoc

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

objc:FunctionComplexity

The Cyclomatic Complexity of functions should not exceed a defined threshold. Complex code may perform poorly and can be difficult to test thoroughly.

objc:LineLength

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

objc:NonReentrantFunction

A function is called reentrant if it can be interrupted in the middle of its execution and then safely called again ("re-entered") before its previous invocations complete execution.

It is especially important that multi-threaded applications do not call the same non-reentrant function from different threads.

This rule will trigger an issue each time a function in the configurable list is invoked.

Noncompliant Code Example

Given a function that includes localtime:

#include <stdio.h>
#include <time.h>

void print_date_and_time(struct tm *time_ptr)
{
  printf(
    "Current date and time: %d/%02d/%02d %02d:%02d:%02d\n",
    time_ptr->tm_year + 1900,
    time_ptr->tm_mon,
    time_ptr->tm_mday,
    time_ptr->tm_hour,
    time_ptr->tm_min,
    time_ptr->tm_sec);
}

void print_unix_epoch_date_and_time()
{
  time_t unix_epoch_time = (time_t)0;
  struct tm *local_time_ptr = localtime(&unix_epoch_time); // Noncompliant, call to the non-reentrant localtime() function
  print_date_and_time(local_time_ptr);
}

int main(int argc, char* argv[])
{
  time_t current_time;
  struct tm *local_time_ptr;

  time(&current_time);

  local_time_ptr = localtime(&current_time); // Noncompliant, call to the non-reentrant localtime() function

  // As expected, this will print: Current date and time: 1970/00/01 01:00:00
  print_unix_epoch_date_and_time();

  // This will actually also print Current date and time: 1970/00/01 01:00:00
  // Indeed, localtime() is non-reentrant, and always returns the same pointer
  print_date_and_time(local_time_ptr);

  return 0;
}

Compliant Solution

#include <stdio.h>
#include <time.h>

void print_date_and_time(struct tm *time_ptr)
{
  printf(
    "Current date and time: %d/%02d/%02d %02d:%02d:%02d\n",
    time_ptr->tm_year + 1900,
    time_ptr->tm_mon,
    time_ptr->tm_mday,
    time_ptr->tm_hour,
    time_ptr->tm_min,
    time_ptr->tm_sec);
}

void print_unix_epoch_date_and_time()
{
  time_t unix_epoch_time = (time_t)0;
  struct tm local_time;
  localtime_r(&unix_epoch_time, &local_time); // Compliant
  print_date_and_time(&local_time);
}

int main(int argc, char* argv[])
{
  time_t current_time;
  struct tm local_time;

  time(&current_time);

  localtime_r(&current_time, &local_time); // Compliant

  // As expected, this will print: Current date and time: 1970/00/01 01:00:00
  print_unix_epoch_date_and_time();

  // As expected, this will print the current date and time, as expected
  print_date_and_time(&local_time);

  return 0;
}
objc:OneStatementPerLine

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

foo(); bar(); // Noncompliant

Compliant Solution

foo();
bar();

Exceptions

Control flow statements with a single nested statement are ignored.

if (condition) doSomething();       // Compliant
while (condition) doSomething();    // Compliant

case or default statements containing a single statement and followed by break are ignored.

switch (foo) {
  case  0: doSomething(); break;    // Compliant
  default: doSomething(); break;    // Compliant
}

Statements enclosed in curly braces on the same line are ignored.

auto lambda = [](int x) { doSomething(x); return x; }; // Compliant
objc:ParsingError

When the parser fails, it is possible to record the failure as an issue on the file. This way, not only is it possible to track the number of files that do not parse but also to easily find out why they do not parse.

objc:PPBackslashNotLastCharacter

The standard mentions that the line continuation character (\) should be immediately followed by a newline or be the very last character of the file in order for the lines to be joined.

Several compilers relax this requirement by allowing whitespace after the \ character, but this is not portable because other compilers may not do the same.

Compliant Solution

// There should be no whitespace after the '\'
#define FOO BAR \
            BAZ
objc:PPDirectiveIndentation

Indenting preprocessor directives reduces the code readability, because it make preprocessor directives harder to spot.

Noncompliant Code Example

void optimal()
{
  #if INTEL             /* Noncompliant - hard to spot */
  specificIntelStuff();
  #endif                /* Noncompliant - hard to spot */
}

Compliant Solution

void optimal()
{
#if INTEL               /* Compliant */
  specificIntelStuff();
#endif                  /* Compliant */
}
objc:PPErrorDirectiveReached

This rule creates a issue whenever an #error preprocessor directive is reached during the project's analysis. In most cases, this indicates that the preprocessor was badly configured. Some predefined macros or library include paths might be required to fix the configuration.

Noncompliant Code Example

#error This is an error
objc:PPMacroName

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all macro names match a provided regular expression.

Noncompliant Code Example

#define foo // Noncompliant

Compliant Solution

#define FOO
objc:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression: [a-z][a-zA-Z0-9]*:

void DoSomething (void);

Compliant Solution

void doSomething (void);
objc:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if (condition1) {
  if (condition2) {             // NonCompliant
    /* ... */
  }
}

Compliant Solution

if (condition1 && condition2) { // Compliant
  /* ... */
}
objc:S1067

The complexity of an expression is defined by the number of &&, || and condition ? ifTrue : ifFalse operators it contains.

A single expression's complexity should not become too high to keep the code readable.

Noncompliant Code Example

With the default threshold value 3.

if (((condition1 && condition2) || (condition3 && condition4)) && condition5) { ... }

Compliant Solution

if ((myFirstCondition() || mySecondCondition()) && myLastCondition()) { ... }
objc:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

Noncompliant Code Example

With a maximum number of 4 parameters:

void doSomething(int param1, int param2, int param3, int param4, int param5) {
  ...
}

Compliant Solution

void doSomething(int param1, int param2, int param3, int param4) {
  ...
}
objc:S110

Inheritance is certainly one of the most valuable concepts in object-oriented programming. It's a way to compartmentalize and reuse code by creating collections of attributes and behaviors called classes which can be based on previously created classes. But abusing this concept by creating a deep inheritance tree can lead to very complex and unmaintainable source code. Most of the time a too deep inheritance tree is due to bad object oriented design which has led to systematically use 'inheritance' when for instance 'composition' would suit better.

objc:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

int x = (y / 2 + 1);   //Compliant even if the parenthesis are ignored by the compiler

if (a && ((x+y > 0))) {  // Noncompliant
  //...
}

return ((x + 1));  // Noncompliant

Compliant Solution

int x = (y / 2 + 1);

if (a && (x+y > 0)) {
  //...
}

return (x + 1);

Exceptions

When the result of an assignment is used as a condition, clang raises a warning to make sure the purpose was not to use == in place of =. Adding some parentheses around the assignment is a common way to silence this clang warning. So, no issue is raised in such case.

if ((x = 7)) {} // Compliant
objc:S1123

The deprecated attribute can be applied with or without explanations, but marking something deprecated without including advice as to why it's deprecated or on what to use instead will lead maintainers to waste time trying to figure those things out - every single time the warning is encountered.

Noncompliant Code Example

[[deprecated]] // Noncompliant
void foo1();

__attribute__((deprecated)) // Noncompliant
void foo2();

__declspec(deprecated) // Noncompliant
void foo3();

Compliant Solution

[[deprecated("use 'bar' instead")]]
void foo1();

__attribute__((deprecated("use 'bar' instead")))
void foo2();

__declspec(deprecated("use 'bar' instead"))
void foo3();
objc:S113

Some tools work better when files end with an empty line.

This rule simply generates an issue if it is missing.

For example, a Git diff looks like this if the empty line is missing at the end of the file:

+class Test {
+}
\ No newline at end of file
objc:S1131

Trailing whitespaces are simply useless and should not stay in code. They may generate noise when comparing different versions of the same file.

If you encounter issues from this rule, this probably means that you are not using an automated code formatter - which you should if you have the opportunity to do so.

objc:S1133

This rule is meant to be used as a way to track code which is marked as being deprecated. Deprecated code should eventually be removed.

Noncompliant Code Example

// C++14 attribute
[[deprecated]] // Noncompliant
void fun();

// GNU attribute
__attribute__((deprecated)) // Noncompliant
void fun();

// Microsoft attribute
__declspec(deprecated) // Noncompliant
void fun();
objc:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

int divide(int numerator, int denominator) {
  return numerator / denominator;              // FIXME denominator value might be  0
}

See

objc:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

void foo() {
  // TODO
}

See

objc:S1142

Having too many return statements in a function increases the function's essential complexity because the flow of execution is broken each time a return statement is encountered. This makes it harder to read and understand the logic of the function.

Noncompliant Code Example

With the default threshold of 3:

int fun() {
  if (condition1) {
    return 1;
  } else {
    if (condition2) {
      return 0;
    } else {
      return 1;
    }
  }
  return 0;
}
objc:S1151

The switch statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of case clause should be extracted in a dedicated function.

Noncompliant Code Example

With the default threshold of 5:

switch (myVariable) {
  case 0: // 6 lines till next case
    methodCall1("");
    methodCall2("");
    methodCall3("");
    methodCall4("");
    break;
  case 1:
  // ...
}

Compliant Solution

switch (myVariable) {
  case 0:
    doSomething();
    break;
  case 1:
  // ...
}
// ...
void doSomething(){
    methodCall1("");
    methodCall2("");
    methodCall3("");
    methodCall4("");
}
objc:S116

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that field names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

class MyClass {
  int my_field;
};

Compliant Solution

class MyClass {
  int myField;
};
objc:S1163

Throwing an exception from within a finally block will mask any exception which was previously thrown in the try or catch block, and the masked's exception message and stack trace will be lost.

Noncompliant Code Example

void openResource() {
  @throw [NSException exceptionWithName:@"FileNotFoundException" reason:@"File Not Found on System" userInfo:nil];
}

void fun() {
  @try {
    openResource();
  }
  @finally {
    closeResource();
    @throw ... ; // Noncompliant - will mask previous exception
  }
}

Compliant Solution

void openResource() {
  @throw [NSException exceptionWithName:@"FileNotFoundException" reason:@"File Not Found on System" userInfo:nil];
}

void fun() {
  @try {
    openResource();
  }
  @finally {
    closeResource();
  }
}

See

  • CERT, ERR05-J. - Do not let checked exceptions escape from a finally block
objc:S117

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a local variable or function parameter name does not match the provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

void doSomething(int my_param) {
  int LOCAL;
  ...
}

Compliant Solution

void doSomething(int myParam) {
  int local;
  ...
}

Exceptions

Loop counters and const variables are ignored by this rule.

objc:S1186

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

  • 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 in languages where that mechanism is available.
  • The method is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.

Noncompliant Code Example

void fun(int p1) {
}

Compliant Solution

void fun(int p1) {
  int a = doSomething(p1);
  int threshold = 42;
  if (a > threshold) {
    // ...
  }
}

or

void fun(int p1) {
  // Intentionally unimplemented...
}

Exceptions

This rule doesn't raise an issue for empty class constructors or destructors. For instance this is the only way to define user-defined default constructors.

objc:S1198

In 1978, Brian Kernighan and Dennis Ritchie published the first edition of The C Programming Language. This book, known to C programmers as "K&R", served for many years as an informal specification of the language. The version of C that it describes is commonly referred to as K&R C.

The K&R function definition syntax introduced in the book was later deprecated in the ANSI C and ISO C standards. Even though the K&R syntax is still supported in the ISO C11 standard, it's not in ISO C++ standard versions and is not considered readable by most C/C++ developers today.

Noncompliant Code Example

int foo(a, b)   // Noncompliant K&R C syntax
  int a;
  char* b;
{
}

Compliant Solution

int foo(int a, char* b) { // Compliant
}
objc:S1199

Nested code blocks can be used to create a new scope and restrict the visibility of the variables defined inside it. Using this feature in a method typically indicates that the method has too many responsibilities, and should be refactored into smaller methods.

Noncompliant Code Example

public void evaluate(int operator) {
  switch (operator) {
    /* ... */
    case ADD: {                                // Noncompliant - nested code block '{' ... '}'
        int a = stack.pop();
        int b = stack.pop();
        int result = a + b;
        stack.push(result);
        break;
      }
    /* ... */
  }
}

Compliant Solution

public void evaluate(int operator) {
  switch (operator) {
    /* ... */
    case ADD:                                  // Compliant
      evaluateAdd();
      break;
    /* ... */
  }
}

private void evaluateAdd() {
  int a = stack.pop();
  int b = stack.pop();
  int result = a + b;
  stack.push(result);
}
objc:S1227

break; is an unstructured control flow statement which makes code harder to read.

Ideally, every loop should have a single termination condition.

Noncompliant Code Example

for (element = list.first; element != null; element = element->next) { // First termination condition
  if (!matches(element->value)) {                                      // Second termination condition
    break; // Noncompliant
  }

  /* ... */
}

Compliant Solution

// Compliant
for (element = list.first; element != null && matches(element->value); element = element->next) {
  /* ... */
}
objc:S1259

Function pointer syntax can be hard on the eyes, particularly when one function is used as a parameter to another. Providing and using a typedef instead can make code easier to read, and should be preferred.

Noncompliant Code Example

extern void (*signal(int, void(*)(int)))(int);

Compliant Solution

typedef void (*SignalHandler)(int signum);
extern SignalHandler signal(int signum, SignalHandler handler);
objc:S1264

When only the condition expression is defined in a for loop, and the initialization and increment expressions are missing, a while loop should be used instead to increase readability.

Noncompliant Code Example

for (;condition;) { /*...*/ }

Compliant Solution

while (condition) { /*...*/ }
objc:S1291

Any issue to quality rule can be deactivated with the NOSONAR marker. This marker is pretty useful to exclude false-positive results but it can also be used abusively to hide real quality flaws.

This rule raises an issue when NOSONAR is used.

objc:S134

Nested if, for, do, while, switch and try statements is a key ingredient 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:

  if (condition1) {                  // Compliant; depth = 1
    /* ... */
    if (condition2) {                // Compliant; depth = 2
      /* ... */
      for(int i = 0; i < 10; i++) {  // Compliant; depth = 3, not exceeding the limit
        /* ... */
        if (condition4) {            // Noncompliant; depth = 4
          if (condition5) {          // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
            /* ... */
          }
          return;
        }
      }
    }
  }

Exceptions

Each use of a macro containing control flow statements is counted as one nesting level, even if the macro contains more than one control flow statement.

  #define FOREACH(V,ARR) if(ARR!=nullptr) for(int V=0; V<(sizeof(ARR)/sizeof(ARR[0])); V++)

  if (condition1) {       // Compliant; depth = 1
    if (condition2) {     // Compliant; depth = 2
      FOREACH(i, arr) {     // Compliant; depth = 3 (not 4)
        if (condition3) {   // Noncompliant; depth = 4
          /* ... */
        }
      }
    }
  }
objc:S138

A function that grows too large tends to aggregate too many responsibilities.

Such functions inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions which focus on well-defined tasks.

Those smaller functions will not only be easier to understand, but also probably easier to test.

objc:S139

This rule verifies that single-line comments are not located at the ends of lines of code. The main idea behind this rule is that in order to be really readable, trailing comments would have to be properly written and formatted (correct alignment, no interference with the visual structure of the code, not too long to be visible) but most often, automatic code formatters would not handle this correctly: the code would end up less readable. Comments are far better placed on the previous empty line of code, where they will always be visible and properly formatted.

Noncompliant Code Example

a = b + c;   // This is a trailing comment that could be very very long

Compliant Solution

// This very long comment is better placed before the line of code
a = b + c;
objc:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
objc:S1479

When switch statements have large sets of case clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

objc:S1578

Shared coding conventions allow teams to collaborate effectively. For that reason, file names should conform to a defined standard. This rule raises an issue when the names of analyzed files don't match the provided regular expression.

See

objc:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

void setValue(int value) {
  value = value;
}

Compliant Solution

void setValue(int value) {
  this->value = value;
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
objc:S1705

Postfix increment and decrement typically involves making a copy of the object being incremented or decremented, whereas its prefix form does not. Therefore the prefix form is usually the more efficient form, and should be preferred.

Noncompliant Code Example

void myFunc(int lim)
{
  int i;
  for (i = 0; i < lim; i++)
  {
    // do something
  }
}

Compliant Solution

void myFunc(int lim)
{
  int i;
  for (i = 0; i < lim; ++i)
  {
    // do something
  }
}
objc:S1707

TODO and FIXME comments are typically intended to be short-lived; they are placeholders and reminders that programmers leave for themselves. Unfortunately, even with the best of intentions, those comments are not always acted on and removed in a timely manner. Thus, they can become mysterious, lingering cruft in a code base, reducing both readability and understand-ability.

This rule flags all FIXME and TODO comments that do not have an attribution matching the specified regular expression immediately after the FIXME or TODO. Ideally, such comments will also contain information about what needs to be fixed or done, but this rule does not enforce that.

Noncompliant Code Example

Using the default regular expression: [ ]*\([ _a-zA-Z0-9@.]+\):

// TODO

Compliant Solution

// TODO(ganncamp) per the business partners, more checks needed
objc:S1762

Using "#pragma warning (default: ...)" resets the warning in question to its default settings, which may not be what the compiler was initially invoked with. Typically, this usage is seen after a warning is turned off, in preparation for code that is known to cause warnings. Instead, the warning's current state should be saved, and then restored after the code in question.

Noncompliant Code Example

#pragma warning (disable: TheWarning)
#include problem_code.h
#pragma warning (default: TheWarning)

Compliant Solution

#pragma warning (push)
#include problem_code.h
#pragma warning (pop)

See

objc:S1768

Because the value in a variable of an unsigned type can never be less than zero, testing to see if it is negative is a useless operation which can only confuse future readers of the code.

Noncompliant Code Example

unsigned int i = 0; // the lowest value this var can have
...
if (i >= 0) { // Noncompliant
  do_x(i);
}

Compliant Solution

unsigned int i = 0;
...
do_x(i);
objc:S1772

The result of the comparison is the same, regardless of whether the constant is on the left or right-hand side. But following this convention will help pinpoint the occasional error where = (assignment) is substituted for == (comparison).

If the constant is on the right-hand side of the expression in such cases, the code will still compile and run - just not as expected. If the constant is on the left-hand side, the error will be caught at the first attempt to compile.

Noncompliant Code Example

if ( var == constant )
if ( pointer == NULL )

Compliant Solution

if ( constant == var )
if ( NULL == pointer )
objc:S1774

While the ternary operator is pleasingly compact, its use can make code more difficult to read. It should therefore be avoided in favor of the more verbose if/else structure.

Noncompliant Code Example

printf("%s", (i>10?"yes":"no"));

Compliant Solution

if (i > 10) {
  printf("yes");
} else {
  printf("no");
}
objc:S1820

A structure, such as a struct, union or class that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain, and having a lot of fields is an indication that a structure has grown too large.

Above a specific threshold, it is strongly advised to refactor the structure into smaller ones that focus on well defined topics.

objc:S1821

Nested switch structures are difficult to understand because you can easily confuse the cases of an inner switch as belonging to an outer statement. Therefore nested switch statements should be avoided.

Specifically, you should structure your code to avoid the need for nested switch statements, but if you cannot, then consider moving the inner switch to another function.

Noncompliant Code Example

void func(int n, int m) {

  switch (n) {
    case 1:
      // ...
    case 2:
      // ...
    case 3:
      switch (m) {  // Noncompliant
    case 4:  // Bad indentation makes this particularly hard to read properly
      // ...
    case 5:
      // ...
    case 6:
      // ...
    }
    case 4:
      // ...
    default:
      // ...
  }
}

Compliant Solution

void func(int n, int m) {

  switch (n) {
    case 1:
      // ...
    case 2:
      // ...
    case 3:
      int m2 = handle_m(m);
    case 4:
      // ...
    default:
      // ...
  }
}
objc:S1862

A chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

Noncompliant Code Example

if (param == 1)
  openWindow();
else if (param == 2)
  closeWindow();
else if (param == 1)  // Noncompliant
  moveWindowToTheBackground();

Compliant Solution

if (param == 1)
  openWindow();
else if (param == 2)
  closeWindow();
else if (param == 3)
  moveWindowToTheBackground();

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
objc:S1874

Code annotated as deprecated should not be used since it will be removed sooner or later.

Noncompliant Code Example

// C++14 attribute
[[deprecated]]
void fun();

// GNU attribute
__attribute__((deprecated))
void fun();

// Microsoft attribute
__declspec(deprecated)
void fun();

void example() {
  fun(); // Noncompliant
}

See

objc:S1986

Shared coding conventions allow teams to collaborate efficiently. This rule checks that curly braces are omitted from interfaces with no instance variables.

Using curly braces in such a situation means that the reader of the code must pause to find the close curly brace before understanding that there are no variables. On the other hand, omitting the curly braces is a quick, clear indicator that there are no variables.

Noncompliant Code Example

@interface Foo : NSObject { // Noncompliant
}

-(void) doSomething;

@end

Compliant Solution

@interface Foo : NSObject

-(void) doSomething;

@end
objc:S2123

A value that is incremented or decremented and then not stored is at best wasted code and at worst a bug.

Noncompliant Code Example

int pickNumber() {
  int i = 0;
  int j = 0;

  i = i++; // Noncompliant; i is still zero

  return j++; // Noncompliant; 0 returned
}

Compliant Solution

int pickNumber() {
  int i = 0;
  int j = 0;

  i++;
  return ++j;
}
objc:S2234

When the names of parameters in a method call match the names of the method arguments, it contributes to clearer, more readable code. However, when the names match, but are passed in a different order than the method arguments, it indicates a mistake in the parameter order which will likely lead to unexpected results.

Noncompliant Code Example

int divide(int divisor, int dividend) {
  return divisor / dividend;
}

void doTheThing() {
  int divisor = 15;
  int dividend = 5;

  int result = divide(dividend, divisor);  // Noncompliant; operation succeeds, but result is unexpected
  //...
}

Compliant Solution

int divide(int divisor, int dividend) {
  return divisor / dividend;
}

public void doTheThing() {
  int divisor = 15;
  int dividend = 5;

  int result = divide(divisor, dividend);
  //...
}
objc:S2343

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all enumeration values match a provided regular expression.

Noncompliant Code Example

With default provided regular expression:

enum SomeEnumeration {
    some  // Non-Compliant
};

Compliant Solution

enum SomeEnumeration {
    SOME
};
objc:S2665

Although some compilers will allow it, the use of sizeof and alignof with arguments that have a void type is forbidden by both the C and C++ standards.

Noncompliant Code Example

void fun() {
  void* p;
  sizeof(*p);  // Noncompliant
  sizeof(void);  // Noncompliant
}
objc:S2668

It is possible to use the increment operator ++, to set the value of a bool(C++) or _Bool(C) variable to true. But this feature has been deprecated in C++ since the 1998 version of the standard, and even where allowed, is simply confusing.

Noncompliant Code Example

bool alive;
...
alive++;

Compliant Solution

bool alive;
...
alive = true;

See

  • ISO/IEC 14882:1998, 5.3.2
objc:S2681

Curly braces can be omitted from a one-line block, such as with an if statement or for loop, but doing so can be misleading and induce bugs.

This rule raises an issue when the whitespacing of the lines after a one line block indicates an intent to include those lines in the block, but the omission of curly braces means the lines will be unconditionally executed once.

Noncompliant Code Example

if (condition)
  firstActionInBlock();
  secondAction();  // Noncompliant; executed unconditionally
thirdAction();

if (condition) firstActionInBlock(); secondAction();  // Noncompliant; secondAction executed unconditionally

if (condition) firstActionInBlock();  // Noncompliant
  secondAction();  // Executed unconditionally

if (condition); secondAction();  // Noncompliant; secondAction executed unconditionally

String str = null;
for (int i = 0; i < array.length; i++)
  str = array[i];
  doTheThing(str);  // Noncompliant; executed only on last array element

Compliant Solution

if (condition) {
  firstActionInBlock();
  secondAction();
}
thirdAction();

String str = null;
for (int i = 0; i < array.length; i++) {
  str = array[i];
  doTheThing(str);
}

See

objc:S2738

A general catch block seems like an efficient way to handle multiple possible exceptions. Unfortunately, it traps all exception types, casting too broad a net, and perhaps mishandling extraordinary cases. Instead, specific exception sub-types should be caught.

Noncompliant Code Example

try {
  file.open("test.txt");
} catch (...) {  // Noncompliant
  // ...
}

Compliant Solution

try {
  file.open("test.txt");
} catch (std::ifstream::failure e) {
  // ...
}
objc:S2754

Empty declarations are cruft; they (may) compile, but they violate the language standards, don't contribute anything of value, and clutter up the program. Like cobwebs, they should be swept away.

Noncompliant Code Example

int;  // Noncompliant

See

  • ISO/IEC 9899:2011, 6.7p2
  • ISO/IEC 14882:2011, 7p3.
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
objc:S2757

The use of operators pairs (=+) where the reversed, single operator was meant (+=) will compile and run, but not produce the expected results.

This rule raises an issue when =+, =-, =!, =&, =*, +=+, and -=- are used without any space between the two operators and when there is at least one whitespace after.

Noncompliant Code Example

int target = -5;
int num = 3;

target =- num;  // Noncompliant; target = -3. Is that really what's meant?
target =+ num; // Noncompliant; target = 3

Compliant Solution

int target = -5;
int num = 3;

target = -num;  // Compliant; intent to assign inverse value of num is clear
target += num;
objc:S2761

The needless repetition of an operator is usually a typo. After all, why write !!!i when !i will do?

On the other hand, the repetition of increment and decrement operators may have been done on purpose, but doing so obfuscates the meaning, and should be simplified.

This rule raises an issue for sequences of: !, ~, -, and +, and in C++ for repetitions of the increment and decrement operators.

Noncompliant Code Example

int i = 1;

int j = - - -i;  // Noncompliant; just use -i
int k = ~~i;     // Noncompliant; same as i
int m = + +i;    // Noncompliant; operators are useless here

bool b = false;
bool c = !!!b;   // Noncompliant

Compliant Solution

int i =  1;

int j = -i;
int k =  i;
int m =  i;

bool b = false;
bool c = !b;

Exceptions

Boolean normalization !! is ignored.

objc:S2806

The real need for bit fields is narrow and highly specialized. Previously, they were used to save memory, but that's less a concern in modern systems than are the extra instructions required to interact with them. Today, they may be needed in direct hardware interaction, but since their behavior is platform-dependent, getting them right can be tricky, and since their use is increasingly rare these days, they're likely to confuse maintainers. For these reasons, it's simpler and more performant to use another field type instead of bit fields.

Noncompliant Code Example

unsigned int b1 : 3;  // Noncompliant
unsigned char b2 : 3;  // Noncompliant

Compliant Solution

unsigned int b1;
unsigned char b2;
objc:S3231

Redundant forward declarations simply clutter the code, and like any duplications, should be removed.

Noncompliant Code Example

struct S {
  // ...
};
// ...
struct S;  // Noncompliant

Compliant Solution

struct S {
  // ...
};
objc:S3358

Just because you can do something, doesn't mean you should, and that's the case with nested ternary operations. Nesting ternary operators results in the kind of code that may seem clear as day when you write it, but six months later will leave maintainers (or worse - future you) scratching their heads and cursing.

Instead, err on the side of clarity, and use another line to express the nested operation as a separate statement.

Noncompliant Code Example

int max(int p1, int p2, int p3) {
  return p1 > p2 ? (p1 > p3 ? p1 : p3) : (p2 > p3 ? p2 : p3); // Noncompliant
}

Compliant Solution

int max(int p1, int p2, int p3) {
  if (p1 > p2) {
    return p1 > p3 ? p1 : p3;
  } else {
    return p2 > p3 ? p2 : p3;
  }
}
objc:S3400

There's no point in forcing the overhead of a method call for a method that always returns the same constant value. Even worse, the fact that a method call must be made will likely mislead developers who call the method thinking that something more is done. Declare a constant instead.

This rule raises an issue if on methods that contain only one statement: the return of a constant value.

Noncompliant Code Example

int getBestNumber() {
  return 12;  // Noncompliant
}

Compliant Solution

static int bestNumber = 12;

Exceptions

override, final, virtual and overriding functions are ignored.

objc:S3458

Empty case clauses that fall through to the default are useless. Whether or not such a case is present, the default clause will be invoked. Such cases simply clutter the code, and should be removed.

Noncompliant Code Example

switch(ch)
{
  case 'a' :
    handleA();
    break;
  case 'b' :
    handleB();
    break;
  case 'c' :  // Noncompliant
  default:
    handleTheRest();
    break;
}

Compliant Solution

switch(ch)
{
  case 'a' :
    handleA();
    break;
  case 'b' :
    handleB();
    break;
  default:
    handleTheRest();
    break;
}
objc:S3485

It may seem cleaner to omit keywords from your method declarations, but this is one time you should err on the side of verbosity. Omitting keywords in a declaration necessarily means that they'll be omitted from calls too. What results is code that will be impenetrable to maintainers. That's why it's considered best practice to always use keywords. This applies both to Objective-C-style parameters without keywords, and to C-style parameter declarations, which are deprecated.

Noncompliant Code Example

@interface MyAction
- (void)sendAction:(int)anAction :(int)flag;  // Noncompliant
- (void)seekAction:(int)anAction, int flag;  // Noncompliant; hard on maintainers AND deprecated
@end

void test(MyAction* myAction) {
  [myAction sendAction:1 :1];
  [myAction sendAction:1 forAllCells:1]; // warning: 'MyAction' may not respond to 'sendAction:forAllCells:'
  [myAction seekAction:1 :1];
}

Compliant Solution

@interface MyAction
- (void)sendAction:(int)anAction forAllCells:(int)flag;
- (void)seekAction:(int)anAction forAllCells:(int)flag;
@end

void test(MyAction* myAction) {
  [myAction sendAction:1 forAllCells:1];
  [myAction seekAction:1 forAllCells:1];
}

See

objc:S3486

C-style definitions should not be made inside Objective-C structures such as @interfaces. Doing so appears to limit their scope to the interface, but in fact, it imposes no such restriction. Such symbols are available globally, and may result in future confusion. Instead, such definitions should be moved to the top level, to make it clear that they're globally available.

Noncompliant Code Example

@interface Example : NSObject
typedef int T; // Noncompliant - defines type, which is visible outside of @interface
void fun(); // Noncompliant - declares global function
@end

Compliant Solution

typedef int T;
void fun();

@interface Example : NSObject
@end
objc:S3491

By contract, chaining the 'Address of' operator & with the 'Indirection' operator * results in a return to the initial value. Thus, such combinations are confusing at best, and bugs at worst.

Noncompliant Code Example

int *ptr = ...;
int *result1 = &(*ptr); //Noncompliant
int *result2 = &*ptr; //Noncompliant

int value = 4;
int result3 = *(&value); //Noncompliant
int result4 = *&value; //Noncompliant

Compliant Solution

int *ptr = ...;
int *result1 = ptr;
int *result2 = ptr;

int value = 4;
int result3 = value;
int result4 = value;

Exceptions

No issue is raised when the * or & operators are overloaded or when both operators are not located in the same piece of code (one being generated by a macro expansion and the other one located in the main source code for instance).

objc:S3562

For completeness, a switch over the values of an enum must either address each value in the enum or contain a default case. switch statements that are not over enum must end with a default case.

Noncompliant Code Example

typedef enum {APPLE, GRAPE, KIWI} fruit;

void example(fruit f, int i) {
  switch (f) {  // Noncompliant; no case for KIWI
    case APPLE:
      //...
    case GRAPE:
      //...
    case 3: // Noncompliant; case value not in enum
      // ...
  }

  switch (i) { // Noncompliant; no default
    case 0:
      // ...
    case 1:
      // ...
  }
}

Compliant Solution

typedef enum {APPLE, GRAPE, KIWI} fruit;

void example(fruit f) {
  switch (f) {
    case APPLE:
      //...
    case GRAPE:
      //...
    default:
      // ...
  }

  switch (i) {
    case 0:
      // ...
    case 1:
      // ...
    default:
      // ...
  }
}

or

typedef enum {APPLE, GRAPE, KIWI} fruit;

void example(fruit f) {
  switch (f) {
    case APPLE:
      //...
    case GRAPE:
      //...
    case KIWI:
      //...
  }

  switch (i) {
    case 0:
    case 1:
      // ...
    default:
      // ...
  }
}

See also

objc:S3646

It is possible in the same statement, to declare a user-defined type (class, struct, union or enum) followed by variable declarations of this type. But mixing more than one concern in a single statement is confusing for maintainers.

This rule raises an issue when a variable is declared at the end of a user-defined type declaration statement.

Noncompliant Code Example

struct Container { int size; } container; // Noncompliant

Compliant Solution

struct Container { int size; };
Container container;
objc:S3687

Except for interactions with extern volatile variables provided by libraries, C/C++ programmers should consider volatile an esoteric feature that is best avoided. In most cases, it is used in an attempt to provide atomicity, memory ordering, or inter-thread synchronization, but volatile does not provide those guarantees. It is only really needed for the kind of low-level code found in kernels, i.e. using memory-mapped I/O registers to manipulate hardware directly.

According to the C standard:

volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation.

Only C11/C++11 "atomic types" are free from data races.

This rule raises an issue when a volatile type is declared.

Noncompliant Code Example

volatile int counter; // Noncompliant
User * volatile vpUser; // Noncompliant; pointer is volatile
User volatile * pvUser;  // Compliant; User instance is volatile, not the pointer

Compliant Solution

atomic_int counter;
std::atomic<User*> vpUser;
User volatile * pvUser;
objc:S3689

Redundant declaration specifiers should be removed or corrected. Typically, they represent bugs. A specifier modifies the type or pointer to its left. Only when it is at the far left does it apply to the right.

Noncompliant Code Example

const int const * v1a; // Noncompliant; both const specifiers apply to int
const int const * v1b; // Noncompliant
static static int v2;  // Noncompliant

Compliant Solution

const int *       v1a;  // pointer to a const int. same meaning as before but less confusing
int const * const v1b;  // const pointer to a const int
static int         v2;
objc:S3715

Proprietary compiler extensions can be handy, but they commit you to always using that compiler. This rule raises an issue when the following GNU extensions are used:

  • A array initializer without =, which has been obsolete since GCC 2.5
  • A structure member initializer with a colon, which has been obsolete since GCC 2.5.
  • Case ranges
  • Ternary operator with omitted second operand

Noncompliant Code Example

struct S {
  int f;
};

struct S s[] = {
  [0] { // Noncompliant
    f : 0 // Noncompliant
  }
};

int fun(int p) {
  switch (p) {
    case 0 ... 1: // Noncompliant
      do_the_thing();
      break;
    case 2:
      //...
  }

  return p ?: 0; // Noncompliant
}

Compliant Solution

struct S {
  int f;
};

struct S s[] = {
  [0] = {
    .f = 0
  }
};

int fun(int p) {
  switch (p) {
    case 0:
    case 1:
      do_the_thing();
      break;
    case 2:
      //...
  }

  return p ? p: 0;
}
objc:S3728

While in C, and derived languages, it is legal to concatenate two literals by putting them next to each other, this is only justified in a few cases. For instance if one is a macro or if the layout makes it clearer.

Noncompliant Code Example

  const char * v1 = "a""b";      // Noncompliant; same as "ab"
  const char * v2 = "a\n" "b\n"; // Noncompliant

Compliant Solution

  const char * v1 = "ab"
  const char * v2 = "a\n"
                    "b\n";

Exceptions

  const char * v3 = "a" /* comment */ "b";

  #define _s "b"
  const char * v4 = "a" _s; // concatenation with macro ignored
objc:S3729

While C syntax considers array subscripts ([]) as symmetrical, meaning that a[i] and i[a] are equivalent, the convention is to put the index in the brackets rather than the array name. Inverting the index and array name serves no purpose, and is very confusing.

Noncompliant Code Example

10[P1] = 0; // Noncompliant
dostuff(i[arr]); // Noncompliant

Compliant Solution

P1[10] = 0;
dostuff(arr[i]);
objc:S3730

#include_next is a gcc-specific language extension that alters the search path for the specified header file by starting the search from the header file directory after the one in which the directive was encountered. It also ignores the distinction between "file" and <file>. It is typically used when you have two (probably related) header files with the same name, although there is nothing in the extension to enforce or limit the use to same-name files.

Use of this extension can be tricky to get right, and is almost never justified. Instead, you should use an absolute path in the #include statement or rename one of the files.

Noncompliant Code Example

#include_next "foo.h" // Noncompliant

Compliant Solution

#include "/usr/local/include/foo.h"
objc:S3744

A macro definition should not be redefined without marking that intent specifically by un-defining it first.

Noncompliant Code Example

#define A 1
#define A 2

Compliant Solution

#define A 1
#undef A
#define A 2

Exceptions

If the redefinition has the same value as the original one. This is consistent with most C compilers warnings.

#define A 1
#define A 1
objc:S3806

The path provided here doesn't match the actual path on this file system (e.g. the case is different). While this may work on a particular environment, this is not portable and may fail on a different environment.

Noncompliant Code Example

#include "Foo.h" // Noncompliant, the file name is "foo.h"
objc:S3935

The GNU compiler extension that allows cases to be specified with ranges will only recognize ranges specified from a smaller value to a larger value. Flip the order and the range will evaluate as empty.

Noncompliant Code Example

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 5 ... 3: // Noncompliant
    //...
    break;

Compliant Solution

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 3 ... 5
    //...
    break;
objc:S3936

The GNU compiler extension that allows cases to be specified with ranges should only be used when a range is actually needed. Use it with the same number on both ends of the range, and you've either made a mistake because an actual range was intended, or you've used the syntax inappropriately in a way that is highly likely to confuse maintainers.

Noncompliant Code Example

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 3 ... 3: // Noncompliant
    //...
    break;
}

Compliant Solution

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 3:
    //...
    break;
}

or

switch (i) {
  case 0:
    //...
    break;
  case 1 ... 2:
    //...
    break;
  case 3 ... 5:
    //...
    break;
}
objc:S3972

Code is clearest when each statement has its own line. Nonetheless, it is a common pattern to combine on the same line an if and its resulting then statement. However, when an if is placed on the same line as the closing } from a preceding else or else if, it is either an error - else is missing - or the invitation to a future error as maintainers fail to understand that the two statements are unconnected.

Noncompliant Code Example

if (condition1) {
  // ...
} if (condition2) {  // Noncompliant
  //...
}

Compliant Solution

if (condition1) {
  // ...
} else if (condition2) {
  //...
}

Or

if (condition1) {
  // ...
}

if (condition2) {
  //...
}
objc:S4143

It is highly suspicious when a value is saved for a key or index and then unconditionally overwritten. Such replacements are likely in error.

Noncompliant Code Example

towns[i] = "London";
towns[i] = "Chicago";  // Noncompliant
objc:S4144

When two methods have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, one implementation should invoke the other.

This rule raises an exception when two methods implemented inside the class definition share the same implementation.

Noncompliant Code Example

class Point {
  int x;
  int y;

// .....

public:
  void setX(int v) {
    if (v >= 0 && v < MAX_X) {
      x = v;
      return;
    }
    error();
  }

  void setY(int v) {  // Noncompliant
    if (v >= 0 && v < MAX_X) {
      x = v;
      return;
    }
    error();
  }
};

Compliant Solution

class Point {
  int x;
  int y;

// .....

public:
 void setX(int v) {
    if (v >= 0 && v < MAX_X) {
      x = v;
      return;
    }
    error();
  }

  void setY(int v) {
    if (v >= 0 && v < MAX_X) {
      y = v;
      return;
    }
    error();
  }
};

Exceptions

Empty methods, methods with the same name (overload) and methods with only one statement are ignored.

objc:SizeofSizeof

A call to sizeof(sizeof(...)) is equivalent to sizeof(size_t), and indicates a misuse or misunderstanding of the sizeof construct.

Noncompliant Code Example

#include <string.h>

int main(int argc, char* argv[])
{
  char buffer[42];
  char buffer2[sizeof(sizeof(buffer))]; /* Noncompliant - a single sizeof() was intended */

  memcpy(buffer, "Hello, world!", strlen("Hello, world!")+1);
  memcpy(buffer2, buffer, sizeof(buffer)); /* Buffer overflow */

  return 0;
}

Compliant Solution

#include <string.h>

int main(int argc, char* argv[])
{
  char buffer[42];
  char buffer2[sizeof(buffer)]; /* Compliant */

  memcpy(buffer, "Hello, world!", strlen("Hello, world!")+1);
  memcpy(buffer2, buffer, sizeof(buffer));

  return 0;
}
objc:TabCharacter

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

php:NoSonar

Any issue to quality rule can be deactivated with the NOSONAR marker. This marker is pretty useful to exclude false-positive results but it can also be used abusively to hide real quality flaws.

This rule raises an issue when NOSONAR is used.

php:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression: ^[a-z][a-zA-Z0-9]*$:

function DoSomething(){...}

Compliant Solution

function doSomething(){...}

Exceptions

Methods with an @inheritdoc annotation, as well as magic methods (__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), __debugInfo()) are ignored.

function __construct(){...}
function __destruct(){...}

/**
 * {@inheritdoc}
 */
function myFunc(){...}
php:S103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

php:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

php:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if (condition1) {
  if (condition2) {
    ...
  }
}

Compliant Solution

if (condition1 && condition2) {
  ...
}
php:S1067

The complexity of an expression is defined by the number of &&, || and condition ? ifTrue : ifFalse operators it contains.

A single expression's complexity should not become too high to keep the code readable.

Noncompliant Code Example

With the default threshold value of 3

if ((($condition1 && $condition2) || ($condition3 && $condition4)) && $condition5) { ... }

Compliant Solution

if ( (my_first_condition() || my_second_condition()) && my_last_condition()) { ... }
php:S1068

If a private field is declared but not used in the program, it can be considered dead code and should therefore be removed. This will improve maintainability because developers will not wonder what the variable is used for.

Noncompliant Code Example

class MyClass {
  private $foo = 4;                       //foo is unused

  public function compute($a) {
    return $a * 4;
  }
}

Compliant Solution

class MyClass {

  public function compute($a) {
    return $a * 4;
  }
}
php:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

Noncompliant Code Example

With a maximum number of 4 parameters:

function doSomething($param1, $param2, $param3, $param4, $param5) {
...
}

Compliant Solution

function doSomething($param1, $param2, $param3, $param4) {
...
}
php:S108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

for ($i = 0; $i < 42; $i++){}  // Empty on purpose or missing piece of code ?

Exceptions

When a block contains a comment, this block is not considered to be empty.

php:S1106

Shared coding conventions make it possible to collaborate efficiently. This rule makes it mandatory to place the open curly brace at the beginning of a line.

Noncompliant Code Example

function myMethod() {  // Noncompliant
  if(something) {  // Noncompliant
    executeTask();
  } else {  //Noncompliant
    doSomethingElse();
  }
}

Compliant Solution

function myMethod()
{
  if(something)
  {
    executeTask();
  } else
  {
    doSomethingElse();
  }
}
php:S1109

Shared coding conventions make it possible for a team to efficiently collaborate. This rule makes it mandatory to place a close curly brace at the beginning of a line.

Noncompliant Code Example

if(condition) {
  doSomething();}

Compliant Solution

if(condition) {
  doSomething();
}

Exceptions

When blocks are inlined (open and close curly braces on the same line), no issue is triggered.

if(condition) {doSomething();}
php:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

$x = ($y / 2 + 1); // Compliant even if the parenthesis are ignored by the compiler

if ($a && (($x + $y > 0))) { // Noncompliant
  //...
}

return (($x + 1)); // Noncompliant

Compliant Solution

$x = ($y / 2 + 1);

if ($a && ($x + $y > 0)) {
  //...
}

return ($x + 1);
php:S1124

The PSR2 standard recommends listing modifiers in the following order to improve the readability of PHP source code:

  1. final or abstract
  2. public or protected or private
  3. static

Noncompliant Code Example

static protected $foo;
...
public static final function bar(){...}

Compliant Solution

protected static $foo;
...
final public static function bar(){...}
php:S1125

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

Noncompliant Code Example

if ($booleanVariable == true) { /* ... */ }
if ($booleanVariable != true) { /* ... */ }
if ($booleanVariable || false) { /* ... */ }
doSomething(!false);

$booleanVariable = condition ? true : exp;
$booleanVariable = condition ? false : exp;
$booleanVariable = condition ?  exp : true;
$booleanVariable = condition ?  exp : false;

Compliant Solution

if ($booleanVariable) { /* ... */ }
if (!$booleanVariable) { /* ... */ }
if ($booleanVariable) { /* ... */ }
doSomething(true);

$booleanVariable = condition || exp;
$booleanVariable = !condition && exp;
$booleanVariable = !condition ||  exp;
$booleanVariable = condition && exp;

Exceptions

The use of literal booleans in comparisons which use identity operators (=== and !==) are ignored.

php:S1126

Return of boolean literal statements wrapped into if-then-else ones should be simplified.

Noncompliant Code Example

if (expression) {
  return true;
} else {
  return false;
}

Compliant Solution

return expression;
php:S113

Some tools work better when files end with an empty line.

This rule simply generates an issue if it is missing.

For example, a Git diff looks like this if the empty line is missing at the end of the file:

+class Test {
+}
\ No newline at end of file
php:S1131

Trailing whitespaces are simply useless and should not stay in code. They may generate noise when comparing different versions of the same file.

If you encounter issues from this rule, this probably means that you are not using an automated code formatter - which you should if you have the opportunity to do so.

Exceptions

Lines containing only whitespaces.

php:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

function divide($numerator, $denominator) {
  return $numerator / $denominator;              // FIXME denominator value might be  0
}

See

php:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

function doSomething() {
  // TODO
}

See

php:S114

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all interface names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[A-Z][a-zA-Z0-9]*$:

interface myInterface {...} // Noncompliant

Compliant Solution

interface MyInterface {...}
php:S1142

Having too many return statements in a function increases the function's essential complexity because the flow of execution is broken each time a return statement is encountered. This makes it harder to read and understand the logic of the function.

Noncompliant Code Example

With the default threshold of 3:

function myFunction(){ // Noncompliant as there are 4 return statements
  if (condition1) {
    return true;
  } else {
    if (condition2) {
      return false;
    } else {
      return true;
    }
  }
  return false;
}
php:S1144

private methods that are never executed are dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.

Noncompliant Code Example

public class Foo
{
  private function Foo() {}   // Compliant, private empty constructor intentionally used to prevent any direct instantiation of a class.

  public static function doSomething()
  {
    $foo = new Foo();
    ...
  }

  private function unusedPrivateFunction() {  // Noncompliant
  }
}

Compliant Solution

public class Foo
{
  private function Foo(){}   // Compliant, private empty constructor intentionally used to prevent any direct instantiation of a class.

  public static function doSomething()
  {
    $foo = new Foo();
  }
}
php:S115

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all constant names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$:

define("const1", true);

class Foo {
    const const2 = "bar";
}

Compliant Solution

define("CONST1", true);

class Foo {
    const CONST2 = "bar";
}
php:S1151

The switch statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the case clause should be extracted into a dedicated method.

Noncompliant Code Example

With a threshold of 5:

switch ($var) {
  case 0:  // 6 lines till next case
    methodCall1();
    methodCall2();
    methodCall3();
    methodCall4();
    break;
  default:
    break;
}

Compliant Solution

switch ($var) {
  case 0:
    doSomething();
    break;
  default:
    break;
}

function doSomething(){
  methodCall1("");
  methodCall2("");
  methodCall3("");
  methodCall4("");
}
php:S1185

Overriding a method just to call the same method from the super class without performing any other actions is useless and misleading. The only time this is justified is in final overriding methods, where the effect is to lock in the parent class behavior. This rule ignores such overrides of equals, hashCode and toString.

Noncompliant Code Example

class Child extends Parent {

  public function func($n,$m) {
    parent::func($n$m);  // Noncompliant
  }
}

class Parent {
  public function func($n, $m) {
    // do something
  }
}

Compliant Solution

class Child extends Parent {

  public function func($n,$m) {
    parent::func($n$m);
    // do additional things...
  }
}

class Parent {
  public function func($n, $m) {
    // do something
  }
}

or

class Child extends Parent {
  // function eliminated
}

class Parent {
  public function func($n, $m) {
    // do something
  }
}
php:S1192

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

With the default threshold of 3:

function run() {
  prepare('action1');                              // Non-Compliant - 'action1' is duplicated 3 times
  execute('action1');
  release('action1');
}

Compliant Solution

ACTION_1 = 'action1';

function run() {
  prepare(ACTION_1);
  execute(ACTION_1);
  release(ACTION_1);
}

Exceptions

To prevent generating some false-positives, literals having less than 5 characters are excluded.

php:S1200

According to the Single Responsibility Principle, introduced by Robert C. Martin in his book "Principles of Object Oriented Design", a class should have only one responsibility:

If a class has more than one responsibility, then the responsibilities become coupled.

Changes to one responsibility may impair or inhibit the class' ability to meet the others.

This kind of coupling leads to fragile designs that break in unexpected ways when changed.

Classes which rely on many other classes tend to aggregate too many responsibilities and should be split into several smaller ones.

Nested classes dependencies are not counted as dependencies of the outer class.

Noncompliant Code Example

  class Foo {            // Noncompliant - Foo depends on too many classes: T1, T2, T3, T4, T5, T6 and T7
    /**
     * @var T1
     */
    public $a1;          // Foo is coupled to T1
    /**
     * @var T2
     */
    protected $a2;       // Foo is coupled to T2
    /**
     * @var T3
     */
    private $a3;         // Foo is coupled to T3

    /**
     * @param T5
     * @param T6
     *
     * @return T4
     */
    public function compute(T5 $a, $b) { // Foo is coupled to T4, T5 and T6
      $result = new T7();     // Foo is coupled to T7
      return $result;
  }
}
php:S122

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

if(someCondition) doSomething();

Compliant Solution

if(someCondition) {
  doSomething();
}

Exceptions

Anonymous functions containing a single statement are ignored.

$max_comparator = function ($v) { return $v > 2; };           // Compliant
$max_comparator = function ($v) { echo $v; return $v > 2; };  // Noncompliant
php:S1264

When only the condition expression is defined in a for loop, and the initialization and increment expressions are missing, a while loop should be used instead to increase readability.

Noncompliant Code Example

for (;condition;) { /*...*/ }

Compliant Solution

while (condition) { /*...*/ }
php:S1311

The cyclomatic complexity of a class should not exceed a defined threshold. Complex code can perform poorly and will in any case be difficult to understand and therefore to maintain.

Deprecated

This rule is deprecated, and will eventually be removed.

php:S134

Nested if, for, while, switch, 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:

  if (condition1) {                  // Compliant - depth = 1
    ...
    if (condition2) {                // Compliant - depth = 2
      ...
      for($ = 0; $i < 10; $i++) {  // Compliant - depth = 3, not exceeding the limit
        ...
        if (condition4) {            // Non-Compliant - depth = 4
          if (condition5) {          // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
            ...
          }
          return;
        }
      }
    }
  }
php:S138

A function that grows too large tends to aggregate too many responsibilities.

Such functions inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions which focus on well-defined tasks.

Those smaller functions will not only be easier to understand, but also probably easier to test.

php:S139

This rule verifies that single-line comments are not located at the ends of lines of code. The main idea behind this rule is that in order to be really readable, trailing comments would have to be properly written and formatted (correct alignment, no interference with the visual structure of the code, not too long to be visible) but most often, automatic code formatters would not handle this correctly: the code would end up less readable. Comments are far better placed on the previous empty line of code, where they will always be visible and properly formatted.

Noncompliant Code Example

$a = $b + $c; // This is a trailing comment that can be very very long

Compliant Solution

// This very long comment is better placed before the line of code
$a = $b + $c;
php:S1448

A class that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor the class into smaller ones which focus on well defined topics.

php:S1479

When switch statements have large sets of case clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

php:S1481

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

function numberOfMinutes($hours) {
  $seconds = 0;   // seconds is never used
  return hours * 60;
}

Compliant Solution

function numberOfMinutes($hours) {
  return hours * 60;
}
php:S1488

Declaring a variable only to immediately return or throw it is a bad practice.

Some developers argue that the practice improves code readability, because it enables them to explicitly name what is being returned. However, this variable is an internal implementation detail that is not exposed to the callers of the method. The method name should be sufficient for callers to know exactly what will be returned.

Noncompliant Code Example

function computeDurationInMilliseconds() {
  $duration = ((($hours * 60) + $minutes) * 60 + $seconds ) * 1000 ;
  return $duration;
}

Compliant Solution

function computeDurationInMilliseconds() {
  return ((($hours * 60) + $minutes) * 60 + $seconds ) * 1000;
}
php:S1536

Function arguments should all have different names to prevent any ambiguity. Indeed, if arguments have the same name, the last duplicated argument hides all the previous arguments with the same name. This hiding makes no sense, reduces understandability and maintainability, and obviously can be error prone.

Noncompliant Code Example

function compute($a, $a, $c) { // Noncompliant
}

Compliant Solution

function compute($a, $b, $c) { // Compliant
}
php:S1541

The Cyclomatic Complexity of functions should not exceed a defined threshold. Complex code may perform poorly and can be difficult to test thoroughly.

php:S1599

PHP's "variable variables" feature (dynamically-named variables) is temptingly powerful, but can lead to unmaintainable code.

Noncompliant Code Example

$var = 'foo';
$$var = 'bar';      //Noncompliant
$$$var = 'hello';  //Noncompliant

echo $foo; //will display 'bar'
echo $bar; //will display 'hello'
php:S1600

The following predefined variables are deprecated and should be replaced by the new versions:

Replace With
$HTTP_SERVER_VARS $_SERVER
$HTTP_GET_VARS $_GET
$HTTP_POST_VARS $_POST
$HTTP_POST_FILES $_FILES
$HTTP_SESSION_VARS $_SESSION
$HTTP_ENV_VARS $_ENV
$HTTP_COOKIE_VARS $_COOKIE
$php_errormsg error_get_last()

Noncompliant Code Example

echo 'Name parameter value: ' . $HTTP_GET_VARS["name"];

Compliant Solution

echo 'Name parameter value: ' . $_GET["name"];
php:S1603

In PHP 4, any function with the same name as the nesting class was considered a class constructor. In PHP 5, this mechanism has been deprecated and the "__construct" method name should be used instead. If both styles are present in the same class, PHP 5 will treat the function named "__construct" as the class constructor.

This rule rule raises an issue for each method with the same name as the enclosing class.

Noncompliant Code Example

class Foo {
  function Foo(){...}
}

Compliant Solution

class Foo {
  function __construct(){...}
}
php:S1605

In PHP 5 both the way to declare a constructor and the way to make a call to a parent constructor have evolved. When declaring constructors with the PHP5 __construct name, nested calls to parent constructors should also use the new __constructor name.

Noncompliant Code Example

class Foo extends Bar {
  function __construct() {
    parent::Bar();
  }
}

Compliant Solution

class Foo extends Bar {
  function __construct() {
    parent::__construct();
  }
}
php:S1697

When either the equality operator in a null test or the logical operator that follows it is reversed, the code has the appearance of safely null-testing the object before dereferencing it. Unfortunately the effect is just the opposite - the object is null-tested and then dereferenced only if it is null, leading to a guaranteed null pointer dereference.

Noncompliant Code Example

if ($obj == null && $obj->isOpen()) {
  echo "Object is open";
}

if ($obj != null || $obj->isOpen()) {
  echo "Object is not open";
}

Compliant Solution

if ($obj == null || $obj->isOpen()) {
  echo "Object is open";
}

if ($obj != null && !$obj->isOpen()) {
  echo "Object is not open";
}
php:S1757

Coding conventions allow teams to collaborate effectively. For maximum standardization and readability, PHP code should use the long <?php ?> tags or the short-echo <?= ?> tags; it should not use the other tag variations.

Noncompliant Code Example

<?
$foo = 1;
?>

Compliant Solution

<?php
$foo = 1;
?>
php:S1765

The PHP 4 method of declaring a variable, using the var keyword, was deprecated in early versions of PHP 5. Even though it's not considered deprecated in the most recent versions, it's nonetheless not best practice to use it. When var does appear, it is interpreted as a synonym for public and treated as such. Therefore public should be used instead.

From the PHP Manual:

The PHP 4 method of declaring a variable with the var keyword is still supported for compatibility reasons (as a synonym for the public keyword). In PHP 5 before 5.1.3, its usage would generate an E_STRICT warning.

Noncompliant Code Example

<?php
class Foo
{
    var $bar = 1;
}

Compliant Solution

<?php
class Foo
{
    public $bar = 1;
}
php:S1766

For better readability, do not put multiple property declarations in the same statement.

Noncompliant Code Example

<?php
class Foo
{
   private $bar = 1, $bar2 = 2;
}

Compliant Solution

<?php
class Foo
{
   private $bar1 = 1;
   private $bar2 = 2;
}
php:S1780

According to the PSR2 coding standard:

The closing ?> tag should be omitted from files containing only PHP.

According to the PHP manual:

in some cases omitting it is helpful when using include or require, so unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

php:S1781

Using indifferently lower or upper case for PHP keywords and constants "true", "false" and "null" can impact the readability of PHP source code.

Noncompliant Code Example

<?php ECHO 'Hello World'; ?>

Compliant Solution

<?php echo 'Hello World'; ?>
php:S1784

Class methods may be defined as public, private, or protected. Methods declared without any explicit visibility keyword are defined as public. To prevent any misunderstanding, this visibility should always be explicitly declared.

Noncompliant Code Example

function foo(){...}

Compliant Solution

public function foo(){...}
php:S1788

The ability to define default values for method arguments can make a method easier to use. Default argument values allow callers to specify as many or as few arguments as they want while getting the same functionality and minimizing boilerplate, wrapper code.

But all method arguments with default values should be declared after the method arguments without default values. Otherwise, it makes it impossible for callers to take advantage of defaults; they must re-specify the defaulted values in order to "get to" the non-default arguments.

Noncompliant Code Example

function makeyogurt($type = "acidophilus", $flavor){...}  // Noncompliant

makeyogurt("raspberry")}}  // Runtime error: Missing argument 2 in call to makeyogurt()

Compliant Solution

function makeyogurt($flavor, $type = "acidophilus", ){...}

makeyogurt("raspberry")}} // Works as expected
php:S1793

According to the PSR2 coding standard:

The keyword elseif SHOULD be used instead of else if so that all control keywords look like single words.

Noncompliant Code Example

if ($expr1) {
  ...
} else if ($expr2) {
  ...
} else {...}

Compliant Solution

if ($expr1) {
  ...
} elseif ($expr2) {
  ...
} else {...}
php:S1799

The exit(...) and die(...) statements should absolutely not be used in Web PHP pages as this might lead to a very bad user experience. In such case, the end user might have the feeling that the web site is down or has encountered a fatal error.

But of course PHP can also be used to develop command line application and in such case use of exit(...) or die(...) statement can be justified but must remain limited and not spread all over the application. We expect exceptions to be used to handle errors and those exceptions should be caught just before leaving the application to specify the exit code with help of exit(...) or die(...) statements.

Noncompliant Code Example

class Foo {
    public function bar($param)  {
        if ($param === 42) {
            exit(23);
        }
    }
}

Compliant Solution

class Foo {
    public function bar($param)  {
        if ($param === 42) {
            throw new Exception('Value 42 is not expected.');
        }
    }
}
php:S1808

Shared coding conventions make it possible for a team to collaborate efficiently. This rule raises issues for failures to comply with formatting standard. The default parameter values conform to the PSR2 standard.

Noncompliant Code Example

With the default PSR2 parameter values:

use FooClass;              // Noncompliant; the "use" declaration should be placed after the "namespace" declaration

namespace Vendor\Package;
use FooClass;              // Noncompliant; the "namespace" declaration should be followed by a blank line
$foo = 1;                  // Noncompliant; the "use" declaration should be followed by a blank line

class ClassA {             // Noncompliant; an open curly brace should be at the beginning of a new line for classes and functions
  function my_function(){  // Noncompliant; curly brace on wrong line
    if ($firstThing)       // Noncompliant; an open curly brace should be at the end of line for a control structure
    {
      ...
    }

    if ($secondThing)    { // Noncompliant; there should be exactly one space between the closing parenthesis and the opening curly brace
      ...
    }

    if($thirdThing) {      // Noncompliant; there should be exactly one space between the control structure keyword and the opening parenthesis
      ...
    }
    else {                 // Noncompliant; the close curly brace and the next "else" (or "catch" or "finally") keyword should be located on the same line
      ...
    }

    try{                   // Noncompliant; there should be exactly one space between the control structure keyword and the curly brace
      ...
    } catch (Exception $e) {
    }

    analyse( $fruit ) ;    // Noncompliant; there should not be any space after the opening parenthesis and before the closing parenthesis

    for ($i = 0;$i < 10;   $i++) { // Nomcompliant; there should be exactly one space after each ";" in the {{for}} statement
      ...
    }

    pressJuice($apply ,$orange);    // Noncompliant; the comma should be followed by one space and not preceded by any

    do_something ();       // Noncompliant; there should not be any space after the method name

    foreach ($fruits    as $fruit_key =>     $fruit) {  // Noncompliant; in the foreach statement there should be one space before and after "as" keyword and "=>" operator
      ...
    }
  }
}

class ClassB
extends ParentClass  // Noncompliant; the class name and the "extends" / "implements" keyword should be on the same line
{
  ...
}

class ClassC extends ParentClass implements \ArrayAccess, \Countable,
    \Serializable    // Noncompliant; the list of implemented interfaces should be correctly indented
{

  public function aVeryLongMethodName(ClassTypeHint $arg1, // Noncompliant; the arguments in a method declaration should be correctly indented
    &$arg2, array $arg3 = []) {

    $noArgs_longVars = function () use ($longVar1,         // Noncompliant; the arguments in a function declaration should be correctly indented
        $longerVar2,
        $muchLongerVar3
    ) {
      ...
    };

    $foo->bar($longArgument,    // Noncompliant; the arguments in a method call should be correctly indented
      $longerArgument,
      $muchLongerArgument);     // Noncompliant; the closing parenthesis should be placed on the next line

    $closureWithArgsAndVars = function($arg1, $arg2)use   ($var1, $var2) {  // Noncompliant; the closure declaration should be correctly spaced - see (5)
      ...
    };
  }
}

Compliant Solution

namespace Vendor\Package; // Compliant; the "namespace" declaration is followed by a blank line

use FooClass;             // Compliant; the "use" declaration is placed after the "namespace" declaration
                          // Compliant; the "use" declaration is followed by a blank line
$foo = 1;

class ClassA
{                         // Compliant; the open curly brace is at the beginning of a new line for the class
  function my_function()
  {                       // Compliant; the open curly brace is at the beginning of a new line for the function
    if ($firstThing) {    // Compliant; the open curly brace is at the end of line for the control structure
      ...
    }

    if ($secondThing) {   // Compliant; there is exactly one space between the closing parenthesis and the opening curly brace
      ...
    }

    if ($thirdThing) {    // Compliant; there is exactly one space between the control structure keyword and the opening parenthesis
      ...
    } else {              // Compliant; the close curly brace and the next "else" (or "catch" or "finally") keyword are located on the same line
      ...
    }

    try {                 // Compliant; there is exactly one space between the control structure keyword and the curly brace
      ...
    } catch (Exception $e) {
      ...
    }

    analyse($fruit);      // Compliant: there is no space after the opening parenthesis, nor before the closing parenthesis

    for ($i = 0; $i < 10; $i++) { // Compliant: there is exactly one space after each ";" in the {{for}} statement
      ...
    }

    pressJuice($apply, $orange);   // Compliant; the comma is followed by one space and is not preceded by any

    do_something();       // Compliant; there is no space after the method name

    foreach ($fruits as $fruit_key => $fruit) {  // Compliant; in the foreach statement there is one space before and after "as" keyword and "=>" operator
      ...
    }
  }
}

/* The idea here is to make it obvious at first glance that a class extends
 * some other classes and/or implements some interfaces. The names of
 * extended classes or implemented interfaces can be located on subsequent lines.
 */
class ClassB1 extends ParentClass // Compliant; the class name and the "extends" (or "implements") keyword are located on the same line
{
  ...
}

class ClassB2 extends             // Compliant; the class name and the "extends" (or "implements") keyword are located on the same line
ParentClass {
  ...
}

/* Lists of implements may be split across multiple lines, where each subsequent line
 * is indented once. When doing so, the first item in the list should be on the next line,
 * and there should be only one interface per line.
 */
class ClassC extends ParentClass implements
    \ArrayAccess,         // Compliant; the list of implemented interfaces is correctly indented
    \Countable,
    \Serializable
{
  /* Argument lists may be split across multiple lines, where each subsequent line
   * is indented once. When doing so, the first item in the list should be on the next line,
   * and there should be only one argument per line. Also, when the argument list is
   * split across multiple lines, the closing parenthesis and opening brace should be
   * placed together on their own line with one space between them.
   */
  public function aVeryLongMethodName(
    ClassTypeHint $arg1,  // Compliant; the arguments in a method/function declaration are correctly indented
      &$arg2,
      array $arg3 = []
    ) {
      $noArgs_longVars = function () use (
        $longVar1,        // Compliant; the arguments in a method/function declaration are correctly indented
        $longerVar2,
        $muchLongerVar3
      ) {
        ...
      };


    /* Argument lists may be split across multiple lines, where each subsequent line is
     * indented once. When doing so, the first item in the list should be on the next line,
     * and there should be only one argument per line.
     */
    $foo->bar(
      $longArgument,       // Compliant; the arguments in the method call are be correctly indented
      $longerArgument,
      $muchLongerArgument
    );                     // Compliant; the closing parenthesis is placed on a separate line

    /* Closures should be declared with a space after the "function" keyword,
     * and a space before and after the "use" keyword.
     */
    $closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) { // Compliant; the closure declaration is correctly spaced
      ...
    };
  }
}
php:S1820

A class that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain, and having a lot of fields is an indication that a class has grown too large.

Above a specific threshold, it is strongly advised to refactor the class into smaller ones which focus on well defined topics.

php:S1848

There is no good reason to create a new object to not do anything with it. Most of the time, this is due to a missing piece of code and so could lead to an unexpected behavior in production.

If it was done on purpose because the constructor has side-effects, then that side-effect code should be moved into a separate, static method and called directly.

Noncompliant Code Example

if ($x < 0) {
  new foo;  // Noncompliant
}

Compliant Solution

$var = NULL;
if ($x < 0) {
  $var = new foo;
}
php:S1871

Having two cases in a switch statement or two branches in an if chain 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 chain they should be combined, or for a switch, one should fall through to the other.

Noncompliant Code Example

switch ($i) {
  case 1:
    doFirst();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  case 3:  // Noncompliant; duplicates case 1's implementation
    doFirst();
    doSomething();
    break;
  default:
    doTheRest();
}

if ($a >= 0 && $a < 10) {
  doFirst();
  doTheThing();
}
else if ($a >= 10 && $a < 20) {
  doTheOtherThing();
}
else if ($a >= 20 && $a < 50) {
  doFirst();
  doTheThing();  // Noncompliant; duplicates first condition
}

Exceptions

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a switch statement that contain a single line of code with or without a following break.

if ($a >= 0 && $a < 10) {
  doTheThing();
}
else if ($a >= 10 && $a < 20) {
  doTheOtherThing();
}
else if ($a >= 20 && $a < 50) {
  doTheThing();  // no issue, usually this is done on purpose to increase the readability
}

But this exception does not apply to if chains without else-s, or to switch-es without default clauses when all branches have the same single line of code. In case of if chains with else-s, or of switch-es with default clauses, rule S3923 raises a bug.

if ($a >= 0 && $a < 10) {
  doTheThing();
}
else if ($a >= 20 && $a < 50) {
  doTheThing();   //Noncompliant; this might have been done on purpose but probably not
}
php:S1990

There is no need to use the final modifier inside a final class. Everything in it is final by default.

Noncompliant Code Example

final class MyClass {

  public final String getName() {  // Noncompliant
    return name;
  }
}

Compliant Solution

final class MyClass {

  public String getName() {  // Compliant
    return name;
  }
}
php:S1996

A file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. This is doubly true for a file with multiple top-level classes and interfaces. It is strongly advised to divide the file into one top-level class or interface per file.

php:S1998

Passing a reference to a function parameter means that any modifications the method makes to the parameter will be made to the original value as well, since references have the effect of pointing two variables at the same memory space. This feature can be difficult to use correctly, particularly if the callee is not expecting a reference, and the improper use of references in function calls can make code less efficient rather than more efficient.

Further, according to the PHP manual:

As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated... And as of PHP 5.4.0, call-time pass-by-reference was removed, so using it will raise a fatal error.

Noncompliant Code Example

myfun(&$name);  // Noncompliant

Compliant Solution

myfun($name);

See

  • MITRE, CWE-374 - Weakness Base Passing Mutable Objects to an Untrusted Method
php:S2000

Having characters before <?php can cause "Cannot modify header information" errors and similar problems with Ajax requests.

Noncompliant Code Example

test<?php  //Noncompliant
// ...

and

// Noncompliant; newline before opening tag
<?php
// ...

Compliant Solution

<?php
// ...
php:S2002

Just as pain is your body's way of telling you something is wrong, errors are PHP's way of telling you there's something you need to fix. Neither pain, nor PHP errors should be ignored.

Noncompliant Code Example

@doSomethingDangerous($password);  // Noncompliant; '@' silences errors from function call

Compliant Solution

doSomethingDangerous($password);
php:S2003

At root, require, require_once, include, and include_once all perform the same task of including one file in another. However, the way they perform that task differs, and they should not be used interchangeably.

require includes a file but generates a fatal error if an error occurs in the process.

include also includes a file, but generates only a warning if an error occurs.

Predictably, the difference between require and require_once is the same as the difference between include and include_once - the "_once" versions ensure that the specified file is only included once.

Because including the same file multiple times could have unpredictable results, the "once" versions are preferred.

Because include_once generates only warnings, it should be used only when the file is being included conditionally, i.e. when all possible error conditions have been checked beforehand.

Noncompliant Code Example

include 'code.php';  //Noncompliant; not a "_once" usage and not conditional
include $user.'_history.php'; // Noncompliant
require 'more_code.php';  // Noncompliant; not a "_once" usage

Compliant Solution

require_once 'code.php';
if (is_member($user)) {
  include_once $user.'_history.php';
}
require_once 'more_code.php';
php:S2004

Nesting functions can quickly turn your code into "spaghetti code". Such code is hard to read, refactor and therefore to maintain.

Noncompliant Code Example

With the default threshold of 3:

function f () {
  function f_inner () {
    function f_inner_inner() {
      function f_inner_inner_inner() { // Noncompliant
      }
    }
  }
}
php:S2005

There is no reason to concatenate literal strings. Doing so is an exercise in reducing code readability. Instead, the strings should be combined.

Noncompliant Code Example

$msg = "Hello " . "${name}" . "!";  // Noncompliant

Compliant Solution

$msg = "Hello ${name}!";
php:S2007

Defining and using global variables and global functions, when the convention dictates OOP can be confusing and difficult to use properly for multiple reasons:

  • You run the risk of name clashes.
  • Global functions must be stateless, or they can cause difficult-to-track bugs.
  • Global variables can be updated from anywhere and may no longer hold the value you expect.
  • It is difficult to properly test classes that use global functions.

Instead of being declared globally, such variables and functions should be moved into a class, potentially marked static, so they can be used without a class instance.

This rule checks that only object-oriented programming is used and that no functions or procedures are declared outside of a class.

Noncompliant Code Example

<?php

$name = "Bob"; // Noncompliant

function doSomething($arg) {   // Noncompliant
  //...
}

class MyClass {
    //...
}

Compliant Solution

<?php
class MyClass {

  public static $name = "Bob"; // Compliant

  public static function doSomething($arg) {              // Compliant
    //...
  }
  //...
}
php:S2010

PHP has two sets of logical operators: && / ||, and and / or. The difference between the sets is precedence. Because and / or have a lower precedence than almost any other operator, using them instead of && / || may not have the result you expect.

Noncompliant Code Example

$have_time = true;
$have_money = false;
$take_vacation = $have_time and $have_money;  // Noncompliant. $take_vacation == true.

Compliant Solution

$have_time = true;
$have_money = false;
$take_vacation = $have_time && $have_money;  // $take_vacation == false.
php:S2011

Global variables are a useful construct, but they should not be abused. Functions can access the global scope either through the global keyword or though the $GLOBALS array, but these practices considerably reduce the function's readability and reusability. Instead, the global variable should be passed as a parameter to the function.

Noncompliant Code Example

$myGlobalVariable;

function foo()
{
  global $myGlobalVariable; // Noncompliant
  $GLOBALS['myGlobalVariable']; // Noncompliant
  // ...
}

Compliant Solution

function foo($myStateVariable)
{
  // ...
}
php:S2014

$this refers to the current class instance. But static methods can be accessed without instantiating the class, and $this is not available to them. Using $this in a static context will result in a fatal error at runtime.

Noncompliant Code Example

class Clazz {
  $name=NULL;  // instance variable

  public static function foo(){
    if ($this->name != NULL) {
      // ...
    }
  }
}

Compliant Solution

class Clazz {
  $name=NULL;  // instance variable

  public static function foo($nameParam){
    if ($nameParam != NULL) {
      // ...
    }
  }
}
php:S2037

References in a class to static class members (fields or methods) can be made using either self::$var or static::$var (introduced in 5.3). The difference between the two is one of scope. Confusingly, in subclasses, the use of self:: references the original definition of the member, i.e. the superclass version, rather than any override at the subclass level. static::, on the other hand, references the class that was called at runtime.

Noncompliant Code Example

<?php

class Toy {

    public static function status() {
        self::getStatus();  // Noncompliant; will always print "Sticks are fun!" even when called from a subclass which overrides this method;
    }

    protected static function getStatus() {
        echo "Sticks are fun!";
    }
}

class Ball extends Toy {

    protected static function getStatus() {  // Doesn't actually get called
        echo "Balls are fun!";
    }
}

$myBall = new Ball();
$myBall::status();  // Prints "Sticks are fun!"

Compliant Solution

<?php

class Toy {

    public static function status() {
        static::getStatus();  // Compliant
    }

    protected static function getStatus() {
        echo "Sticks are fun!";
    }
}

class Ball extends Toy {

    protected static function getStatus() {
        echo "Balls are fun!";
    }
}

$myBall = new Ball();
$myBall::status();  // Prints "Balls are fun!"

Exceptions

No issue is raised when self is used on a constant field, a private field or a private method.

class A
{
    private static $somevar = "hello";
    const CONSTANT = 42;

    private static function foo()
    {
        $var = self::$somevar . self::CONSTANT;  // Should be OK
        self::foo();                               // Should be OK
    }
}
php:S2038

Shared coding conventions allow teams to collaborate effectively. Writing colors in upper case makes them stand out at such, thereby making the code easier to read.

This rule checks that hexadecimal color definitions are written in upper case.

Noncompliant Code Example

$white = '#ffffff';  // Noncompliant
$dkgray = '#006400';
$aqua = '#00ffff';  // Noncompliant

Compliant Solution

$white = '#FFFFFF';  // Compliant
$dkgray = '#006400';
$aqua = '#00FFFF';  // Compliant
php:S2041

echo can be called with or without parentheses, but it is best practice to leave parentheses off the call because using parentheses with multiple arguments will result in a parse error.

Noncompliant Code Example

echo("Hello");  // Noncompliant, but it works
echo("Hello", "World"); // Noncompliant. Parse error

Compliant Solution

echo "Hello";
echo "Hello","World!";
php:S2042

A class that grows too much tends to aggregate too many responsibilities, and inevitably becomes harder to understand and to maintain. Above a specific threshold, it is strongly advised to refactor the class into smaller ones which focus on well-defined topics.

php:S2043

Superglobal variables are predefined variables available in all scopes throughout a script. However, accessing them directly is considered bad practice. Instead, they should be accessed through an object or framework that handles sanitation and validation.

Noncompliant Code Example

$name = $_POST['name'];

Compliant Solution

$name = $this->params()->fromPost('name');
php:S2044

Both php_sapi_name() and the PHP_SAPI constant give the same value. But calling the method is less efficient that simply referencing the constant.

Noncompliant Code Example

if (php_sapi_name() == 'test') { ... }

Compliant Solution

if (PHP_SAPI == 'test') { ... }
php:S2047

Well-named functions can allow the users of your code to understand at a glance what to expect from the function - even before reading the documentation. Toward that end, methods returning a boolean property should have names that start with "is" or "has" rather than with "get".

Note that this rule will only apply to functions that are documented to return a boolean.

Noncompliant Code Example

/**
 * @return boolean
 */
public function getFoo() // Noncompliant
{
  return foo;
}

Compliant Solution

/**
 * @return boolean
 */
public function isFoo()
{
  return true;
}
php:S2050

Certain functions exist in PHP only as aliases of other functions. These aliases have been made available for backward compatibility, but should really be removed from code.

This rule looks for uses of the following aliases:

Alias Replacement
chop rtrim
close closedir
doubleval floatval
fputs fwrite
ini_alter ini_set
is_double is_float
is_integer is_int
is_long is_int
is_real is_float
is_writeable is_writable
join implode
key_exists array_key_exists
magic_quotes_runtime set_magic_quotes_runtime
pos current
show_source highlight_file
sizeof count
strchr strstr

Noncompliant Code Example

$arr=array("apple", "pear","banana");
echo sizeof($arr);  // Noncompliant

Compliant Solution

$arr=array("apple", "pear","banana");
echo count($arr);
php:S2123

A value that is incremented or decremented and then not stored is at best wasted code and at worst a bug.

Noncompliant Code Example

  $i = 0;
  $i = $i++; // Noncompliant; i is still zero

Compliant Solution

  $i = 0;
  $i++;
php:S2260

When the PHP parser fails, it is possible to record the failure as a violation on the file. This way, not only it is possible to track the number of files that do not parse but also to easily find out why they do not parse.

php:S2830

Dependency injection is a software design pattern in which one or more dependencies (or services) are injected, or passed by reference, into a dependent object (or client) and are made part of the client's state. The pattern separates the creation of a client's dependencies from its own behavior, which allows program designs to be loosely coupled and to follow the dependency inversion and single responsibility principles.

Noncompliant Code Example

class SomeClass {

  public function __construct() {
    $this->object = new SomeOtherClass();  // Noncompliant
  }
}

Compliant Solution

class SomeClass {

  public function __construct(SomeOtherClass $object) {
    $this->object = $object;
  }
}
php:S2918

ini_set changes the value of the given configuration option for the duration of the script's execution. While there may be a reason to do this, you should make sure that it's a very good reason indeed, because this is the sort of "magic" change which can cause severe teeth-gnashing and hair tearing when the script needs to be debugged.

For instance, if the user explicitly turns logging on for a script, but then the script itself uses ini_set('display_errors', 0); to turn logging back off, it is likely that every other aspect of the environment will be examined before, in desperation, the script is read to figure out where the logging is going.

Noncompliant Code Example

ini_set('display_errors', 0);  // Noncompliant
php:S3358

Just because you can do something, doesn't mean you should, and that's the case with nested ternary operations. Nesting ternary operators results in the kind of code that may seem clear as day when you write it, but six months later will leave maintainers (or worse - future you) scratching their heads and cursing.

Instead, err on the side of clarity, and use another line to express the nested operation as a separate statement.

Noncompliant Code Example

function get_title($gender, $is_married) {
  return $gender == "MALE" ? "Mr. " : ($is_married ? "Mrs. " : "Miss ");  // Noncompliant
}

Compliant Solution

function get_title($gender, $is_married) {
  if ($gender == "MALE") {
    return "Mr. ";
  }
  return $is_married ? "Mrs. " : "Miss ";
}
php:S3699

If a function does not return anything, it makes no sense to use its output. Specifically, passing it to another function, or assigning its "result" to a variable is probably a bug because such functions return nothing, which is probably not what was intended.

Noncompliant Code Example

$result = closedir($dir_handle); // Noncompliant, "closedir" does not return anything.

Compliant Solution

closedir($dir_handle);
php:S3801

Because it is dynamically typed, PHP does not enforce a return type on a function. This means that different paths through a function can return different types of values, which can be very confusing to the user and significantly harder to maintain.

In particular, it is consequently also possible to mix empty return statements (implicitly returning null) with some returning an expression. This rule verifies that all the return statements from a function are consistent.

Noncompliant Code Example

function foo($a) { // Noncompliant, function will return "true" or null
  if ($a == 1) {
    return true;
  }
  return;
}

Compliant Solution

function foo($a) {
  if ($a == 1) {
    return true;
  }
  return false;
}

or

function foo($a) {
  if ($a == 1) {
    return true;
  }
  return null;
}
php:S3923

Having all branches in a switch or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a switch/if chain at all.

Noncompliant Code Example

if ($b == 0) {  // Noncompliant
  doOneMoreThing();
} else {
  doOneMoreThing();
}

$b = $a > 12 ? 4 : 4;  // Noncompliant

switch ($i) {  // Noncompliant
  case 1:
    doSomething();
    break;
  case 2:
    doSomething();
    break;
  case 3:
    doSomething();
    break;
  default:
    doSomething();
}

Exceptions

This rule does not apply to if chains without else-s, or to switch-es without default clauses.

if($b == 0) {    //no issue, this could have been done on purpose to make the code more readable
  doSomething();
} elseif($b == 1) {
  doSomething();
}
php:S3972

Code is clearest when each statement has its own line. Nonetheless, it is a common pattern to combine on the same line an if and its resulting then statement. However, when an if is placed on the same line as the closing } from a preceding else or elseif, it is either an error - else is missing - or the invitation to a future error as maintainers fail to understand that the two statements are unconnected.

Noncompliant Code Example

if ($condition1) {
  // ...
} if ($condition2) {  // Noncompliant
  //...
}

Compliant Solution

if ($condition1) {
  // ...
} elseif ($condition2) {
  //...
}

Or

if ($condition1) {
  // ...
}

if ($condition2) {
  //...
}
php:S3973

In the absence of enclosing curly braces, the line immediately after a conditional is the one that is conditionally executed. By both convention and good practice, such lines are indented. In the absence of both curly braces and indentation the intent of the original programmer is entirely unclear and perhaps not actually what is executed. Additionally, such code is highly likely to be confusing to maintainers.

Noncompliant Code Example

if ($x > 0)  // Noncompliant
doTheThing();
doTheOtherThing();

foo();

Compliant Solution

if ($x > 0) {
  doTheThing();
  doTheOtherThing();
}

foo();

or

if ($x > 0)
    doTheThing();
doTheOtherThing();

foo();
php:S3981

The count of elements from an array or Countable object is always greater than or equal to zero. So testing that the count is greater than or equal to zero doesn't make sense, since the result is always true. Similarly testing that it is less than zero will always return false. Perhaps the intent was to check the non-emptiness of the object or array instead.

Noncompliant Code Example

if (count($arr) >= 0) { ... }

if (count($arr) < 0) { ... }

$result = count($arr) >= 0;

if (0 > count($arr)) { ... }

Compliant Solution

if (count($arr) != 0) { ... }

if (count($arr) > 0) { ... }
php:S4142

There are valid cases for passing a variable multiple times into the same method call, but usually doing so is a mistake, and something else was intended for one of the arguments.

Noncompliant Code Example

if (compare($a+$x, $a+$x) != 0) { // Noncompliant
  //...
}

if (compare(getValue($a), getValue($a)) != 0) { // Noncompliant
  // ...
}

Compliant Solution

if (compare($a+$y, $a+$x) != 0) {
  //...
}

$v1 = getValue($a);
$v2 = getValue($a);
if (compare($v1, $v2) != 0) {
  // ...
}

Deprecated

This rule is deprecated, and will eventually be removed.

php:S4144

When two methods have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, one implementation should invoke the other.

Noncompliant Code Example

class A {
    private const CODE = "bounteous";

    public function getCode() {
        doTheThing();
        return A::CODE;
    }

    public function getName() {  // Noncompliant
        doTheThing();
        return A::CODE;
    }
}

Compliant Solution

class A {
    private const CODE = "bounteous";

    public function getCode() {
        doTheThing();
        return A::CODE;
    }

    public function getName() {
        return $this->getCode();
    }
}

Exceptions

Methods that are not accessors (getters and setters), with fewer than 2 statements are ignored.

plsql:AnchoredTypeConstrainCheck

Anchored types, i.e. those specified using either %TYPE or %ROWTYPE, cannot be constrained. Trying to do so results in the exception PLS-00573: cannot constrain scale, precision, or range of an anchored type being raised.

Noncompliant Code Example

DECLARE
  foo DUAL.DUMMY%TYPE(42); -- Non-Compliant - raises PLS-00573
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  foo DUAL.DUMMY%TYPE; -- Compliant
BEGIN
  NULL;
END;
/
plsql:AvoidFetchBulkCollectIntoWithoutLimitCheck

A FETCH ... BULK COLLECT INTO without a LIMIT clause will load all the records returned by the cursor at once. This may lead to memory exhaustion. Instead, it is better to process the records in chunks using the LIMIT clause.

Noncompliant Code Example

SET SERVEROUTPUT ON

-- Fetches all records at once, requiring lots of memory
DECLARE
  TYPE largeTableRowArrayType IS TABLE OF largeTable%ROWTYPE;
  largeTableRowArray largeTableRowArrayType;
  CURSOR myCursor IS SELECT * FROM largeTable;
BEGIN
  OPEN myCursor;

  FETCH myCursor BULK COLLECT INTO largeTableRowArray; -- Non-compliant

  DBMS_OUTPUT.PUT_LINE('Alternative 1: ' || largeTableRowArray.COUNT || ' records');

  CLOSE myCursor;
END;
/

Compliant Solution

SET SERVEROUTPUT ON

-- fetches one chunk at a time, requiring constant memory
DECLARE
  TYPE largeTableRowArrayType IS TABLE OF largeTable%ROWTYPE;
  largeTableRowArray largeTableRowArrayType;
  CURSOR myCursor IS SELECT * FROM largeTable;
  counter PLS_INTEGER := 0;
BEGIN
  OPEN myCursor;

  LOOP
    FETCH myCursor BULK COLLECT INTO largeTableRowArray LIMIT 1000; -- Compliant

    counter := counter + largeTableRowArray.COUNT;

    EXIT WHEN myCursor%NOTFOUND;
  END LOOP;

  DBMS_OUTPUT.PUT_LINE('Alternative 1: ' || counter || ' records');

  CLOSE myCursor;
END;
/

DROP TABLE largeTable;
plsql:AvoidGroupByClauseCheck

Using GROUP BY in SQL SELECT statements should be avoided because it makes queries complex. Complex queries are generally not performant and are difficult to understand and therefore to maintain.

plsql:BackwardsGoto

Jumping back to a previous statement using GOTO is a way to reimplement loops, which PL/SQL already provides in much more readable forms.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  result PLS_INTEGER := 0;
  counter PLS_INTEGER := 1;
BEGIN
  <<loop>>
  result := result + counter;
  counter := counter + 1;

  IF counter <= 9 THEN
    GOTO loop;                    -- Noncompliant
  END IF;

  DBMS_OUTPUT.PUT_LINE('Sum from 1 to 9 is ' || result); -- Displays 1 + 2 + ... + 8 + 9 = 45
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  result PLS_INTEGER := 0;
BEGIN
  FOR counter IN 1 .. 9 LOOP
    result := result + counter;
  END LOOP;

  DBMS_OUTPUT.PUT_LINE('Sum from 1 to 9 is ' || result); -- Displays 1 + 2 + ... + 8 + 9 = 45
END;
/

See

  • MISRA C++:2008, 6-6-2 - The goto statement shall jump to a label declared later in the same function body
  • MISRA C:2012, 15.2 - The goto statement shall jump to a label declared later in the same function
plsql:BadRaiseApplicationErrorUsageCheck

RAISE_APPLICATION_ERROR may only be called with an error code from 20,000 to 20,999, which is the range reserved for application errors. When called with another value, Oracle raises the exception: ORA-21000: error number argument to raise_application_error of 0 is out of range.

Noncompliant Code Example

BEGIN
  RAISE_APPLICATION_ERROR(0, 'This is an application error'); -- Non-Compliant - raises ORA-21000
END;
/

Compliant Solution

BEGIN
  RAISE_APPLICATION_ERROR(-20000, 'This is an application error'); -- Compliant
END;
/
plsql:BlockMissingSemicolonCheck

Labeled blocks are useful to help maintainers match-up the beginning and ending of each section of code, especially when that code is badly indented. However, if used, those labels must appear on the same line as the "END" keyword in order to avoid confusion. Otherwise, the label might be misread by maintainers as a procedure call.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  PROCEDURE foo AS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('foo was called!');
  END;
BEGIN
  BEGIN
    NULL;
  END -- Semicolon was forgotten?

  foo; -- Noncompliant; looks like a procedure call, but is actually END block label

  <<myBlockLabel>>
  BEGIN
    NULL;
  END
  myBlockLabel; -- Noncompliant
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  PROCEDURE foo AS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('foo was called!');
  END;
BEGIN
  BEGIN
    NULL;
  END;

  foo; -- The method "foo" was actually meant to be called

  <<myBlockLabel>>
  BEGIN
    NULL;
  END myBlockLabel;
END;
/
plsql:BlockUnlabeledEndCheck

Labeled blocks are useful, especially when the code is badly indented, to match the begin and end of each block. This check detects labeled blocks which are missing an ending label.

Noncompliant Code Example

<<myBlockLabel1>>
BEGIN
  NULL;
END; -- Noncompliant; this labeled loop has no ending label
/

BEGIN
  NULL; -- Compliant; not a labeled block
END;
/

Compliant Solution

<<myBlockLabel2>>
BEGIN
  NULL;
END myBlockLabel2;
/

BEGIN
  NULL;
END;
/
plsql:BooleanLiteralComparisonCheck

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

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  foo BOOLEAN := TRUE;
BEGIN
  IF foo = FALSE THEN                     -- Noncompliant
    DBMS_OUTPUT.PUT_LINE('foo = false!');
  ELSIF foo = TRUE THEN                   -- Noncompliant
    DBMS_OUTPUT.PUT_LINE('foo = true!');
  END IF;
END;
/

Compliant Solution

DECLARE
  foo BOOLEAN := TRUE;
BEGIN
  IF NOT foo THEN                         -- Compliant
    DBMS_OUTPUT.PUT_LINE('foo = false!');
  ELSIF foo THEN                          -- Compliant
    DBMS_OUTPUT.PUT_LINE('foo = true!');
  END IF;
END;
/
plsql:CharVarchar

For fixed-length values, a CHAR field occupies the same amount of disk space as a VARCHAR2 field, but for variable-length values CHAR fields use more storage space and make searching more difficult by right-padding values with whitespaces. Therefore VARCHAR2 fields are preferred. Similarly, NCHAR should be replaced by NVARCHAR2.

Note that for 1-character fields, CHAR is naturally equivalent to VARCHAR2, but the latter is still preferred for consistency.

Noncompliant Code Example

DECLARE
  var1 CHAR; -- Noncompliant

  var2 CHAR(42); -- Noncompliant

  var3 NCHAR; -- Noncompliant

  var4 NCHAR(42); -- Noncompliant
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  var1 VARCHAR2(42);

  var2 VARCHAR2(42);

  var3 NVARCHAR2(42);

  var4 NVARCHAR2(42);
BEGIN
  NULL;
END;
/
plsql:ColumnsShouldBeAliasedCheck

Consistently using aliases for column names is useful for several reasons. The main one is that the code is independant from potential database modifications - when a column has been renamed to comply with standards for instance. Another reason is to remove ambiguity when querying several tables that may have equivalent column names.

Noncompliant Code Example

BEGIN
  SELECT
    emp.name, -- Noncompliant - should be aliased
    dpt.name -- Noncompliant - should be aliased
  INTO employeesArray
  FROM employee emp INNER JOIN department dpt
  ON emp.DepartmentID = dpt.ID;
END;
/

Compliant Solution

BEGIN
  SELECT
    emp.name employee_name, -- Compliant
    dpt.name departement_name -- Compliant
  INTO employeesArray
  FROM employee emp INNER JOIN department dpt
  ON emp.DepartmentID = dpt.ID;
END;
/
plsql:CompoundTriggerDefinesSingleTrigger

Compound triggers were introduced to ease the implementation of multiple triggers which need to work in cooperation.

Typically, a FOR EACH ROW trigger accumulates facts, and an AFTER STATEMENT trigger performs the actual changes.

The compound trigger can hold a state common to all the triggers it defines, thereby removing the need to use package variables. This approach is sometimes the only possible one, as when avoiding a mutating table ORA-04091 error, or it can be used to get better performance.

However, there is no point in defining a compound trigger which contains only a single trigger, since there is no state to be shared. In such cases, a simple trigger should be used instead.

Noncompliant Code Example

CREATE OR REPLACE TRIGGER my_trigger  -- Noncompliant; defines a single trigger
FOR INSERT ON my_table
COMPOUND TRIGGER

AFTER EACH ROW IS
BEGIN
  DBMS_OUTPUT.PUT_LINE('New row inserted!');
END AFTER EACH ROW;

END;
/

Compliant Solution

CREATE OR REPLACE TRIGGER my_trigger
  AFTER INSERT
  ON my_table
  FOR EACH ROW
BEGIN
  DBMS_OUTPUT.PUT_LINE('New row inserted!');
END;
/
plsql:ConstantDeclarationWithoutInitializationCheck

Constants must be immediately initialized at declaration. They cannot be reassigned any value after the declaration, as they are constant. This rule prevents PLS-00322 exceptions from being raised at runtime.

The following code snippet illustrates this rule:

Noncompliant Code Example

DECLARE
  foo CONSTANT PLS_INTEGER NULL; -- Noncompliant PLS-00322
  bar CONSTANT PLS_INTEGER NOT NULL; -- Noncompliant PLS-00322
  aa CONSTANT PLS_INTEGER; -- Noncompliant
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  foo CONSTANT PLS_INTEGER NULL :=42;
  bar CONSTANT PLS_INTEGER NOT NULL := 42;
  aa CONSTANT PLS_INTEGER := 42; -- Compliant
BEGIN
  NULL;
END;
/
plsql:CreateOrReplaceCheck

When creating a function, procedure, package, package body, type, type body, trigger or library, it is a good practice replace the existing one to avoid errors.

Noncompliant Code Example

CREATE FUNCTION my_function RETURN PLS_INTEGER AS -- Noncompliant
BEGIN
  RETURN 42;
END;
/

Compliant Solution

CREATE OR REPLACE FUNCTION my_function RETURN PLS_INTEGER AS -- Compliant, no error even if the function already exists
BEGIN
  RETURN 42;
END;
/
plsql:CrossJoinUsageCheck

A CROSS JOIN query will return all records where each row from the first table is combined with each row from the second table. This means that such a query returns the Cartesian product of the sets of rows from the joined tables, which is why it is also know as "Cartesian product query".

Such a query can return a huge amount of data, and therefore should be used only with great caution and only when really needed.

Noncompliant Code Example

BEGIN
  -- Standard ANSI syntax
  SELECT *
    INTO employeeArray
    FROM employee CROSS JOIN department; -- Noncompliant; explicit cross join
END;
/

BEGIN
  -- Old syntax
  SELECT *
    INTO employeeArray
    FROM employee, department; -- Noncompliant; also a cross join
END;
/
plsql:CustomExceptionInitCheck

Centralizing the definitions of custom exceptions comes with two major benefits:

  • The duplication of the exceptions declarations and PRAGMA EXCEPTION_INIT is avoided
  • The risk of associating multiple different exceptions to the same number is reduced

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  user_not_found EXCEPTION;
  PRAGMA EXCEPTION_INIT(user_not_found, -20000); -- Noncompliant, user_not_found is bound to -20000
BEGIN
  NULL;
END;
/

DECLARE
  user_not_found EXCEPTION;
  PRAGMA EXCEPTION_INIT(user_not_found, -20000); -- Noncompliant, user_not_found is again bound to -20000, duplication
BEGIN
  NULL;
END;
/

DECLARE
  wrong_password EXCEPTION;
  PRAGMA EXCEPTION_INIT(wrong_password, -20000); -- Noncompliant, wrong_password is bound to -20000, conflicting with user_not_found
BEGIN
  NULL;
END;
/

Compliant Solution

SET SERVEROUTPUT ON

CREATE PACKAGE exceptions AS
 user_not_found EXCEPTION;
 wrong_password EXCEPTION;

 PRAGMA EXCEPTION_INIT(user_not_found, -20000); -- Non-Compliant (flag as false-positive)
 PRAGMA EXCEPTION_INIT(wrong_password, -20001); -- Non-Compliant (flag as false-positive), conflicts are easier to avoid
END;
/

DROP PACKAGE exceptions;
plsql:DecodeFunctionUsageCheck

DECODE is an old function that has been replaced by the easier to understand and more common CASE. Unlike DECODE, CASE may also be used directly within PL/SQL.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  operand CHAR(1) := 'B';
  l_result PLS_INTEGER;
BEGIN
  -- Noncompliant
  SELECT DECODE(operand, 'A', 1
                       , 'B', 2
                       , 'C', 3
                       , 'D', 4
                       , 'E', 5
                       , 'F', 6
                       , 7)
  INTO l_result
  FROM dual;

  DBMS_OUTPUT.PUT_LINE('l_result = ' || l_result); -- 2
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  operand CHAR(1) := 'B';
  l_result PLS_INTEGER;
BEGIN

  l_result := CASE operand
                WHEN 'A' THEN 1
                WHEN 'B' THEN 2
                WHEN 'C' THEN 3
                WHEN 'D' THEN 4
                WHEN 'E' THEN 5
                WHEN 'F' THEN 6
                ELSE 7
              END;

  DBMS_OUTPUT.PUT_LINE('l_result = ' || l_result); -- 2
END;
/
plsql:ExecuteImmediateTrapExceptionsCheck

Since the purpose of the EXECUTE IMMEDIATE statement is to execute dynamic SQL queries - which by definition can contain unexpected errors - properly handling exceptions becomes critical. Therefore, care should be taken to trap all possible exceptions.

Noncompliant Code Example

DECLARE
  result      VARCHAR2(42);
  column      VARCHAR2(42);
BEGIN
  column := 'DUMMY_2';
  EXECUTE IMMEDIATE 'SELECT ' || column || ' FROM DUAL' INTO result; -- Non-Compliant
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  result      VARCHAR2(42);
  column      VARCHAR2(42);
BEGIN
  column := 'DUMMY_2';
  EXECUTE IMMEDIATE 'SELECT ' || column || ' FROM DUAL' INTO result; -- Compliant
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE ('Execute immediate error: ' || DBMS_UTILITY.FORMAT_ERROR_STACK);
END;
/
plsql:ExitInLoop

FOR and WHILE loops are structured control flow statements.

A FOR loop will iterate once for each element in the range, and the WHILE iterates for as long as a condition holds.

However, inserting an EXIT statement within the loop breaks this structure, reducing the code's readability and making it harder to debug.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  TYPE myCollectionType IS VARRAY(10) OF VARCHAR2(42);
  myCollection myCollectionType := myCollectionType('Foo', 'Bar', NULL, 'Baz', 'Qux');

  i PLS_INTEGER;
BEGIN
  i := 1;
  WHILE i <= myCollection.LAST LOOP
    EXIT WHEN myCollection(i) IS NULL; -- Noncompliant, breaks the structure of the WHILE

    DBMS_OUTPUT.PUT_LINE('Got: ' || myCollection(i));
    i := i + 1;
  END LOOP;

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  TYPE myCollectionType IS VARRAY(10) OF VARCHAR2(42);
  myCollection myCollectionType := myCollectionType('Foo', 'Bar', NULL, 'Baz', 'Qux');

  i PLS_INTEGER;
BEGIN
  i := 1;
  WHILE i <= myCollection.LAST AND myCollection(i) IS NOT NULL LOOP
    DBMS_OUTPUT.PUT_LINE('Got: ' || myCollection(i));
    i := i + 1;
  END LOOP;
END;
/

See

  • MISRA C:2004, 14.5 - The continue statement shall not be used.
plsql:FloatWithScaleUsageCheck

Float data types, such as FLOAT, DOUBLE PRECISION, and REAL cannot have a scale constraint. Trying to specify a scale results in the exception PLS-00510: Float cannot have scale being raised.

Noncompliant Code Example

DECLARE
  foo FLOAT(10, 3); -- Noncompliant - raises PLS-00510
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  foo FLOAT(10); -- Compliant
BEGIN
  NULL;
END;
/
plsql:ForallStatementShouldUseSaveExceptionsClause

When the FORALL statement is used without the SAVE EXCEPTIONS clause and an exception is raised by a DML query, the whole operation is rolled back and the exception goes unhandled. Instead of relying on this default behavior, it is better to always use the SAVE EXCEPTIONS clause and explicitly handle exceptions in a ORA-24381 handler.

Noncompliant Code Example

CREATE TABLE my_table(
  id NUMBER(10) NOT NULL
);

DECLARE
  TYPE my_table_id_type IS TABLE OF my_table.id%TYPE;
  my_table_ids my_table_id_type := my_table_id_type();
BEGIN
  FOR i IN 1 .. 10 LOOP
    my_table_ids.EXTEND;
    my_table_ids(my_table_ids.LAST) := i;
  END LOOP;

  -- Cause the failure
  my_table_ids(10) := NULL;

  FORALL i IN my_table_ids.FIRST .. my_table_ids.LAST  -- Noncompliant
    INSERT INTO my_table
    VALUES (my_table_ids(i));
END;
/

SELECT COUNT(*) FROM my_table;

DROP TABLE my_table;

Compliant Solution

-- ...

DECLARE
  TYPE my_table_id_type IS TABLE OF my_table.id%TYPE;
  my_table_ids my_table_id_type := my_table_id_type();

  bulk_errors EXCEPTION;
  PRAGMA EXCEPTION_INIT(bulk_errors, -24381);
BEGIN
  FOR i IN 1 .. 10 LOOP
    my_table_ids.EXTEND;
    my_table_ids(my_table_ids.LAST) := i;
  END LOOP;

  -- Cause the failure
  my_table_ids(10) := NULL;

  FORALL i IN my_table_ids.FIRST .. my_table_ids.LAST SAVE EXCEPTIONS
    INSERT INTO my_table
    VALUES (my_table_ids(i));
EXCEPTION
  WHEN bulk_errors THEN
    -- Explicitly rollback the whole transaction,
    -- or handle each exception individually by looping over SQL%BULK_EXCEPTIONS
    ROLLBACK;
END;
/

-- ...
plsql:ForLoopUsageCheck

The FOR loop at first seems like a convenient way of iterating over the elements of a collection, but doing so will raise a VALUE_ERROR exception if the collection is empty. Looping instead from 1 to COUNT doesn't work either if the collection is sparse; that leads to a ORA-01403: no data found error.

Instead, a WHILE loop should be used.

Noncompliant Code Example

DECLARE
  TYPE fooType IS TABLE OF VARCHAR2(42);
  foo fooType := new fooType('Strawberry', 'Apple', 'Banana');
BEGIN
  foo.DELETE(2);                                -- The collection is now sparse

  FOR i IN 1 .. foo.COUNT                       -- Noncompliant - leads to ORA-01403: no data found
  LOOP
    DBMS_OUTPUT.PUT_LINE(i || ' = ' || foo(i));
  END LOOP;
END;
/

Compliant Solution

DECLARE
  TYPE fooType IS TABLE OF VARCHAR2(42);
  foo fooType := new fooType('Strawberry', 'Apple', 'Banana');
  i PLS_INTEGER;
BEGIN
  foo.DELETE(2);                                -- The collection is now sparse

  i := foo.FIRST;

  WHILE (i IS NOT NULL)                         -- Compliant - works as expected
  LOOP
    DBMS_OUTPUT.PUT_LINE(i || ' = ' || foo(i));
    i := foo.NEXT(i);
  END LOOP;
END;
/
plsql:FormatErrorStackAndBacktraceUsedAlongside

Since Oracle 10g, DBMS_UTILITY.FORMAT_ERROR_BACKTRACE is available to get an exception's stack trace, i.e. files and lines that lead up to the exception. When combined with DBMS_UTILITY.FORMAT_ERROR_STACK, which contains the exception error code and message, developers are able quickly identify defects.

This rule verifies that whenever either is used in an exception handler, the other is used as well.

Noncompliant Code Example

BEGIN
  RAISE_APPLICATION_ERROR(-20000, 'This is an error example');
EXCEPTION
  WHEN OTHERS THEN  -- Noncompliant; only FORMAT_ERROR_STACK is used
    DBMS_OUTPUT.PUT(DBMS_UTILITY.FORMAT_ERROR_STACK);           -- "ORA-20000: This is an error example"
    DBMS_OUTPUT.PUT_LINE('');
END;
/

Compliant Solution

BEGIN
  RAISE_APPLICATION_ERROR(-20000, 'This is an error example');
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT(DBMS_UTILITY.FORMAT_ERROR_STACK);           -- "ORA-20000: This is an error example"
    DBMS_OUTPUT.PUT(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);       -- "ORA-06512: at line 2"
    DBMS_OUTPUT.PUT_LINE('');
END;
/
plsql:FullOuterJoinCheck

Full outer joins aren't in common use, and as a result many developers don't really understand them. Therefore, each use of this language feature should be reviewed.

Noncompliant Code Example

BEGIN
  SELECT *
  BULK COLLECT INTO result
  FROM DUAL d1
  FULL OUTER JOIN DUAL d2 ON d1.dummy != d2.dummy; -- Noncompliant
END;
/
plsql:FunctionLastStatementReturnCheck

Always having a RETURN as the last statement in a function is a good practice for two reasons:

  • It prevents the ORA-06503 PL/SQL: Function returned without value error.
  • It prevents unreachable code from being added after the RETURN.

Noncompliant Code Example

CREATE FUNCTION incorrectFunction1 RETURN PLS_INTEGER IS -- Non-Compliant
BEGIN
  RETURN 42;

   -- This is unreachable code
   NULL;
END;
/

DROP FUNCTION incorrectFunction1;

CREATE FUNCTION incorrectFunction2 RETURN PLS_INTEGER IS -- Non-Compliant
BEGIN
   NULL; -- This function was expected to return a PLS_INTEGER, but did not. Will lead to ORA-06503
END;
/

BEGIN
  DBMS_OUTPUT.PUT_LINE('Ret = ' || incorrectFunction2); -- ORA-06503 PL/SQL: Function returned without value
END;
/

DROP FUNCTION incorrectFunction2;

CREATE FUNCTION correctFunction RETURN PLS_INTEGER IS -- Compliant
BEGIN
  RETURN 42;
END;
/

DROP FUNCTION correctFunction;
plsql:GotoInLoopCheck

The use of GOTO in general is arguable. However, when used within loops, GOTO statements are even more evil, and they can often be replaced by other constructs.

Noncompliant Code Example

DECLARE
  i PLS_INTEGER := 0;
BEGIN
  LOOP
    IF i = 3 THEN
      GOTO loopEnd; -- Noncompliant
    END IF;

    DBMS_OUTPUT.PUT_LINE('i = ' || i);

    i := i + 1;
  END LOOP;

  <<loopEnd>>
  DBMS_OUTPUT.PUT_LINE('Loop end');
END;
/

Compliant Solution

DECLARE
  i PLS_INTEGER := 0;
BEGIN
  LOOP
    EXIT WHEN i = 3; -- Compliant

    DBMS_OUTPUT.PUT_LINE('i = ' || i);

    i := i + 1;
  END LOOP;

  DBMS_OUTPUT.PUT_LINE('Loop end');
END;
/
plsql:ImproperConstraintUsageCheck

Not every data type supports the RANGE or scale constraints. Using these constraints on incompatible types results in an PLS-00572: improper constraint form used exception being raised.

Noncompliant Code Example

DECLARE
  foo INTEGER RANGE 0 .. 42; -- Non-Compliant - raises PLS-00572 as NUMBER does not support the RANGE constraint
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  foo INTEGER; -- Compliant
BEGIN
  NULL;
END;
/
plsql:InItemsCountCheck

Oracle supports at most 1000 items in a SQL query's IN clause. When more items are given, the exception ORA-01795 maximum number of expressions in a list is 1000 is raised. Thus, IN clauses are not as scalable as joins.

Noncompliant Code Example

BEGIN
  SELECT *
  INTO result
  FROM my_table
  WHERE col1 IN (1, 2, 3, ..., 1001);       -- Noncompliant - raises ORA-01795
END;
/

Compliant Solution

BEGIN
  SELECT my_table.*
  INTO result
  FROM my_table
  JOIN new_in_table
  WHERE my_table.col1 = new_in_table.value; -- Compliant
END;
/
plsql:InitializeWithNullCheck

Explicit variable initializations with null values are superfluous, since unassigned variables are implicitly initialized to null.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  foo PLS_INTEGER := NULL; -- Noncompliant, the null assignation is superfluous
  bar VARCHAR2(100) := ''; -- Noncompliant, the null assignation is superfluous
  correctInitializedString VARCHAR2(100) := 'Hello world!';

BEGIN
  IF foo IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('foo is NULL');
  ELSE
    DBMS_OUTPUT.PUT_LINE('foo is NOT NULL');
  END IF;
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  foo PLS_INTEGER;
  bar VARCHAR2(100);
  correctInitializedString VARCHAR2(100) := 'Hello world!';

BEGIN
  IF foo IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('foo is NULL');
  ELSE
    DBMS_OUTPUT.PUT_LINE('foo is NOT NULL');
  END IF;
END;
/
plsql:InvalidConstrainCheck

Some types cannot be constrained, and attempting to do so results in the exception PLS-00566: type name "..." cannot be constrained being raised.

Noncompliant Code Example

DECLARE
  foo BLOB(42); -- Noncompliant - raises PLS-00566: type name "BLOB" cannot be constrained
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  foo BLOB;
BEGIN
  NULL;
END;
/
plsql:LabelStartEndMatchBlockCheck

Labeled blocks are useful, especially when the code is badly indented, to match the begin and end of each block. This rule verifies that block start and end labels match, when both are specified.

Noncompliant Code Example

BEGIN
  NULL;
END; -- Compliant, no labels at all
/

<<myBlockLabel1>>
BEGIN
  NULL;
END; -- Compliant, only starting label
/

BEGIN
  NULL;
END myBlockLabel2; -- Compliant, only ending label
/

<<myBlockLabel3>>
BEGIN
  NULL;
END myBlockLabel4; -- Noncompliant, labels mismatch
/

<<myBlockLabel6>>
<<myBlockLabel6>>
BEGIN
  NULL;
END myBlockLabel6; -- Noncompliant, several starting labels
/

Compliant Solution

BEGIN
  NULL;
END;
/

<<myBlockLabel1>>
BEGIN
  NULL;
END;
/

BEGIN
  NULL;
END myBlockLabel2;
/

<<myBlockLabel3>>
BEGIN
  NULL;
END myBlockLabel3;
/

<<myBlockLabel6>>
BEGIN
  NULL;
END myBlockLabel6;
/
plsql:LabelStartEndMatchLoopCheck

Labeled loops are useful, especially when the code is badly indented, to match the begin and end of each loop. This rule verifies that loop start and end labels match, when both are specified.

Noncompliant Code Example

BEGIN
  LOOP
    EXIT;
  END LOOP; -- Compliant, this loop has no label at all

  <<myLoopLabel1>>
  LOOP
    EXIT;
  END LOOP; -- Compliant, this loop only has a start label

  LOOP
    EXIT;
  END LOOP myLoopLabel2; -- Compliant, this loop only has an end label

  <<myLoopLabel4>>
  LOOP
    EXIT;
  END LOOP myLoopLabel5; -- Noncompliant, label mismatch

  <<myLoopLabel6>>
  <<myLoopLabel7>>
  LOOP
    EXIT;
  END LOOP myLoopLabel7; -- Noncompliant, several start labels mismatch
END;
/

Compliant Solution

BEGIN
  LOOP
    EXIT;
  END LOOP;

  <<myLoopLabel1>>
  LOOP
    EXIT;
  END LOOP;

  LOOP
    EXIT;
  END LOOP myLoopLabel2;

  <<myLoopLabel4>>
  LOOP
    EXIT;
  END LOOP myLoopLabel4;

  <<myLoopLabel7>>
  LOOP
    EXIT;
  END LOOP myLoopLabel7;
END;
/
plsql:LongCheck

The LONG and LONG RAW datatypes are deprecated and Oracle recommends to migrate them to the LOB datatypes CLOB, NCLOB or BLOB.

Noncompliant Code Example

CREATE TABLE images(
  data LONG RAW
);

Compliant Solution

CREATE TABLE images(
  data BLOB
);
plsql:LoopAvoidSimpleLoopCheck

Simple loops, of the form LOOP ... END LOOP, behave by default as infinite ones, since they do not have a loop condition. They can often be replaced by other, safer, loop constructs.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  i PLS_INTEGER;
BEGIN
  i := 1;
  LOOP -- Noncompliant, an infinite loop by default and therefore dangerous
    DBMS_OUTPUT.PUT_LINE('First loop i: ' || i);

    i := i + 1;
    EXIT WHEN i > 10;
  END LOOP;

END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  i PLS_INTEGER;
BEGIN
  FOR i IN 1..10 LOOP -- Compliant, much safer equivalent alternative
    DBMS_OUTPUT.PUT_LINE('Second loop i: ' || i);
  END LOOP;
END;
/
plsql:LoopHardcodedBoundsCheck

Hard-coding bounds in FOR loops is a bad practice, just as magic numbers in general are. Often, those magic bounds can be replaced by dynamic values. If that is not possible, replacing the literal number with a constant is still better.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  TYPE myCollectionType IS VARRAY(3) OF VARCHAR2(42);
  myCollection myCollectionType := myCollectionType('David', 'John', 'Richard');

BEGIN

  FOR i IN 2 .. 3 -- Noncompliant; magic numbers used for the loop bounds
  LOOP
    DBMS_OUTPUT.PUT_LINE('name = ' || myCollection(i));
  END LOOP;

  FOR i IN 2 .. myCollection.LAST -- Noncompliant, better but still magic
  LOOP
    DBMS_OUTPUT.PUT_LINE('name = ' || myCollection(i));
  END LOOP;

END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  TYPE myCollectionType IS VARRAY(3) OF VARCHAR2(42);
  myCollection myCollectionType := myCollectionType('David', 'John', 'Richard');

BEGIN
  FOR i IN myCollection.FIRST .. myCollection.LAST
  LOOP
    DBMS_OUTPUT.PUT_LINE('name = ' || myCollection(i));
  END LOOP;
END;
/
plsql:LoopMissingSemicolonCheck

Labeled loops are useful, especially when the code is badly indented, to match the begin and end of each loop. However, those labels, if used, must appear on the same line as the "END" keyword in order to avoid any confusion. Indeed, the label might otherwise be seen as a procedure call.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  PROCEDURE foo AS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('foo was called!');
  END;
BEGIN
  LOOP
    EXIT;
  END LOOP -- The semicolon was forgotten

  foo; -- Noncompliant, This is interpreted as a label of the previous FOR loop, not as a procedure call to foo!

END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  PROCEDURE foo AS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('foo was called!');
  END;
BEGIN

  <<myLoopLabel>>
  LOOP
    EXIT;
  END LOOP myLoopLabel;

  foo; -- Correctly interpreted as a procedure call to foo
END;
/
plsql:LoopUnlabeledEndCheck

Labeled loops are useful, especially when the code is badly indented, to match the begin and end of each loop. This rule raises an issue when the end of a labeled loop is unlabeled.

Noncompliant Code Example

BEGIN
  <<myLoopLabel1>>
  LOOP
    EXIT;
  END LOOP; -- Noncompliant; this labeled loop has no ending label

  LOOP
    EXIT;
  END LOOP; -- Compliant; not a labeled loop
END;
/

Compliant Solution

BEGIN
  <<myLoopLabel1>>
  LOOP
    EXIT;
  END LOOP myLoopLabel1;

  LOOP
    EXIT;
  END LOOP;
END;
/
plsql:LoopUnlabeledExitCheck

Labeled loops are useful, especially when the code is badly indented, to match the begin and end of each loop. Within a labeled loop, the code's maintainability is increased by explicitly providing the loop's label in every EXIT statement. Indeed, if a nested loop is added afterwards, it is clear which loop has to be exited.

Noncompliant Code Example

BEGIN
  <<myLoopLabel1>>
  LOOP
    EXIT; -- Noncompliant, the loop label is missing
  END LOOP myLoopLabel1;

  LOOP
    EXIT; -- Compliant, this EXIT is not in a labeled loop
  END LOOP;
END;
/

Compliant Solution

BEGIN
 <<myLoopLabel1>>
  LOOP
    EXIT myLoopLabel1;
  END LOOP myLoopLabel1;

  LOOP
    EXIT;
  END LOOP;
END;
/
plsql:LoopUseExitWhenCheck

The EXIT WHEN syntax can exit a loop depending on a condition. It should be preferred to the more verbose and error-prone IF ... THEN EXIT; END IF; syntax.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  i PLS_INTEGER;
BEGIN

  i := 0;
  LOOP
    IF i > 10 THEN -- Noncompliant
       EXIT;
    END IF;

    DBMS_OUTPUT.PUT_LINE('i = ' || i);
    i := i + 1;
  END LOOP;

END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  i PLS_INTEGER;
BEGIN

  i := 0;
  LOOP
    EXIT WHEN i > 10;

    DBMS_OUTPUT.PUT_LINE('i = ' || i);
    i := i + 1;
  END LOOP;
END;
/
plsql:MlslabelDatatypeUsageCheck

The deprecated MLSLABEL datatype is still supported only for backwards compatibility with Trusted Oracle, and since Oracle8, the only valid value it can hold is NULL. Thus, the usage of this type should be progressively removed.

Noncompliant Code Example

DECLARE
  foo MLSLABEL; -- Noncompliant
BEGIN
  NULL;
END;
/
plsql:NameReusedInInnerScope

Using the same name for multiple purposes reduces the understandability of the code and might eventually lead to bugs.

This rule verifies that no label is reused in an inner scope.

Noncompliant Code Example

<<foo>>
DECLARE
  a CONSTANT PLS_INTEGER := 0;
BEGIN
  <<foo>>                                  -- Noncompliant
  DECLARE
    b CONSTANT PLS_INTEGER := 42;
  BEGIN
    DBMS_OUTPUT.PUT_LINE('x = ' || foo.b); -- Confusing
  END;
END;
/

Compliant Solution

<<foo>>
DECLARE
  a CONSTANT PLS_INTEGER := 0;
BEGIN
  <<bar>>
  DECLARE
    b CONSTANT PLS_INTEGER := 42;
  BEGIN
    DBMS_OUTPUT.PUT_LINE('x = ' || bar.b);
  END;
END;
/
plsql:NaturalJoinUsageCheck

NATURAL JOIN is a type of equi-join which implicitly compares all identically-named columns of the two tables. While this a feature which may seem convenient at first, it becomes hard to maintain over time.

Consider an EMPLOYEE table with the columns FULL_NAME, and DEPT_ID, and a DEPARTMENT table with the columns DEPT_ID, and NAME. A natural join between those tables will join on the DEPT_ID column, which is the only identically-named column.

But, if a new NAME column is later added to the EMPLOYEE table, then the join will be done on both DEPT_ID and NAME. Natural joins make simple changes such as adding a column complicated and are therefore better avoided.

Noncompliant Code Example

BEGIN
  SELECT *
  INTO employeeArray
  FROM employee
  NATURAL JOIN departement; -- Non-Compliant, the join predicate is implicit
END;
/

Compliant Solution

BEGIN
  SELECT *
  INTO employeeArray
  FROM employee
  JOIN departement
  USING (dept_id);  -- Compliant, explicit join predicate
END;
/
plsql:NcharByteLengthUsageCheck

NCHAR and NVARCHAR2 lengths must be given in characters, not bytes. This is partly because a single character may occupy more than a single byte in memory. Specify the field length in bytes, and theoretically your value could overrun the field, but instead Oracle simply refuses to run the code. Specify it in characters, and Oracle will allocate the appropriate number of bytes to store the requested number of characters. Trying to specify the length semantics in bytes will result in the PLS-00639: NCHAR/NVARCHAR2 cannot be byte length semantics exception being raised.

Noncompliant Code Example

DECLARE
  foo NCHAR(42 BYTE); -- Noncompliant - raises PLS-00639
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  foo NCHAR(42);      -- Compliant
  bar NCHAR(42 CHAR); -- Also compliant, as an alternative
BEGIN
  NULL;
END;
/
plsql:Notfound

cursor%NOTFOUND is clearer and more readable than NOT cursor%FOUND, and is preferred.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  CURSOR c IS SELECT DUMMY FROM DUAL;
  x VARCHAR2(1);
BEGIN
  OPEN c;
  FETCH c INTO x;
  IF NOT c%FOUND THEN  -- Noncompliant
    DBMS_OUTPUT.PUT_LINE('uh?');
  ELSE
    DBMS_OUTPUT.PUT_LINE('all good: ' || x);
  END IF;
  CLOSE c;
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  CURSOR c IS SELECT DUMMY FROM DUAL;
  x VARCHAR2(1);
BEGIN
  OPEN c;
  FETCH c INTO x;
  IF c%NOTFOUND THEN
    DBMS_OUTPUT.PUT_LINE('uh?');
  ELSE
    DBMS_OUTPUT.PUT_LINE('all good: ' || x);
  END IF;
  CLOSE c;
END;
/
plsql:NotNullDeclarationWithoutInitializationCheck

Variables and fields declared as NOT NULL must be immediately initialized, since they cannot be implicitly initialized to NULL. This rule prevents PLS-00218 exceptions from being raised at runtime.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  test PLS_INTEGER; -- This variable is implicitly initialized to NULL

  foo PLS_INTEGER NOT NULL; -- Noncompliant PLS-00218 a variable declared NOT NULL must have an initialization assignment

  TYPE myType IS RECORD(
    foo PLS_INTEGER NOT NULL, -- Non-Compliant PLS-00218 a variable declared NOT NULL must have an initialization assignment
    bar PLS_INTEGER NULL
  );
BEGIN
  IF test IS NULL
    DBMS_OUTPUT.PUT_LINE('test is NULL');
  ELSE
    DBMS_OUTPUT.PUT_LINE('test is NOT NULL');
  END IF;
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  test PLS_INTEGER; -- This variable is implicitly initialized to NULL

  foo PLS_INTEGER NOT NULL := 42; -- Compliant

  TYPE myType IS RECORD(
    foo PLS_INTEGER NOT NULL := 42, -- Compliant
    bar PLS_INTEGER NULL
  );
BEGIN
  IF test IS NULL
    DBMS_OUTPUT.PUT_LINE('test is NULL');
  ELSE
    DBMS_OUTPUT.PUT_LINE('test is NOT NULL');
  END IF;
END;
/
plsql:NullComparison

In a Zen-like manner, "NULL" is never equal to anything, even itself. Therefore comparisons using equality operators will always return False, even when the value actually IS NULL.

For that reason, comparison operators should never be used to make comparisons with NULL; IS NULL and IS NOT NULL should be used instead. This extends as well to empty string (""), which is equivalent to NULL for some database engines.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  name VARCHAR2(42) := ''; /* This is equivalent to name := NULL; */
BEGIN
  IF name = '' THEN /* Noncompliant; equivalent to name = NULL & therefore always FALSE*/
    DBMS_OUTPUT.PUT_LINE('True'); /* Unreachable */
  ELSE
    DBMS_OUTPUT.PUT_LINE('False');
  END IF;
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  name VARCHAR2(42) := ''; /* This is equivalent to name := NULL; */
BEGIN
  IF name IS NULL THEN /* Compliant */
    DBMS_OUTPUT.PUT_LINE('True');
  ELSE
    DBMS_OUTPUT.PUT_LINE('False');
  END IF;
END;
/
plsql:OrderByColumnNumberCheck

Even though the ORDER BY clause supports using column numbers, doing so makes the code difficult to read and maintain. Therefore the use of column names is preferred.

Noncompliant Code Example

BEGIN
  SELECT col2, col3
  BULK COLLECT INTO result
  FROM my_table
  ORDER BY
    1 ASC;           -- Noncompliant - if col1 is added to the selected fields, this may break
END;
/

Compliant Solution

BEGIN
  SELECT col2, col3
  BULK COLLECT INTO result
  FROM my_table
  ORDER BY
    col2 ASC;
END;
/
plsql:OrderByExplicitAscCheck

ASC or DESC should be specified for every column of an ORDER BY clause to improve readability.

Noncompliant Code Example

BEGIN
  SELECT col1, col2, col3
  BULK COLLECT INTO result
  FROM my_table
  ORDER BY
    col1 ASC,
    col2,            -- Noncompliant - ASC or DESC should be specified
    col3 DESC;
END;
/

Compliant Solution

BEGIN
  SELECT col1, col2, col3
  BULK COLLECT INTO result
  FROM my_table
  ORDER BY
    col1 ASC,
    col2 ASC,
    col3 DESC;
END;
/
plsql:OverridePredefinedExceptionCheck

Naming custom exceptions the same as predefined ones, while technically acceptable, is not a good practice.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  no_data_found EXCEPTION; -- Noncompliant, overrides an Oracle predefined exception

  d VARCHAR2(1);
BEGIN
  SELECT dummy INTO d FROM DUAL WHERE dummy = 'Y'; -- Will raise STANDARD.NO_DATA_FOUND
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE('No data found!'); -- Won't be executed, as NO_DATA_FOUND was overriden, confusing!
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Unknown error!'); -- *Will* be executed
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  my_own_exception EXCEPTION; -- Compliant

  d VARCHAR2(1);
BEGIN
  SELECT dummy INTO d FROM DUAL WHERE dummy = 'Y';
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE('No data found!'); -- *Will* be executed
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Unknown error!');
END;
/
plsql:PipelinedFunctionsWithoutPipeRow

Pipelined functions offers the ability to create programmatically generated tables.

One of the benefits of such functions is that they reduce memory consumption as results are not all kept in memory before being returned.

Instead of relying on RETURN, PIPE ROW must be used to return the results, one row at a time.

Trying to return an expression from a pipelined function raises PLS-00633: RETURN statement in a pipelined function cannot contain an expression

Noncompliant Code Example

CREATE OR REPLACE TYPE myScalarType AS OBJECT
(
  dummy   VARCHAR2(42)
)
/
CREATE OR REPLACE TYPE myTableType AS TABLE OF myScalarType;
/

CREATE OR REPLACE FUNCTION foo RETURN myTableType PIPELINED AS  -- Noncompliant, should contain at least one PIPE ROW
  result myTableType := myTableType();
BEGIN
  FOR i IN 1 .. 3 LOOP
    result.EXTEND;
    result(i) := myScalarType('Dummy ' || i);
  END LOOP;

  RETURN result;  -- Noncompliant, will raise PLS-00633
END;
/

SELECT * FROM TABLE(foo());

DROP FUNCTION foo;
DROP TYPE myTableType;
DROP TYPE myScalarType;

Compliant Solution

-- ...

CREATE OR REPLACE FUNCTION foo RETURN myTableType PIPELINED AS
BEGIN
  FOR i IN 1 .. 3 LOOP
    PIPE ROW(myScalarType('Dummy ' || i));
  END LOOP;

  RETURN;
END;
/

-- ...
plsql:PlSql.CreateFunctionAndCreateProcedureDocumented

Each function and procedure should be documented with a comment either just before or right after the IS or AS keyword it to explain its goal and how it works.

Noncompliant Code Example

CREATE FUNCTION my_function RETURN PLS_INTEGER AS
BEGIN
  RETURN 42;
END;
/

CREATE PACKAGE my_package AS

PROCEDURE my_procedure;

FUNCTION my_function RETURN PLS_INTEGER;

END my_package;
/

Compliant Solution

CREATE FUNCTION my_function RETURN PLS_INTEGER AS
-- Computes the meaning of life
BEGIN
  RETURN 42;
END;
/

CREATE PACKAGE my_package AS

-- This is documentation
PROCEDURE my_procedure;

/*
  This is documentation
*/
FUNCTION my_function RETURN PLS_INTEGER;

END my_package;
/

Exceptions

Functions are procedures declared in package bodies, and anonymous PL/SQL blocks do not have to be documented.

DECLARE
  PROCEDURE helper_procedure AS
  BEGIN
    NULL;
  END;
BEGIN
  helper_procedure;
END;
/

CREATE PACKAGE my_package AS

-- This is documentation
PROCEDURE public_procedure;

END my_package;
/

CREATE PACKAGE BODY my_package AS

PROCEDURE helper_procedure AS
BEGIN
  NULL;
END;

PROCEDURE public_procedure AS
BEGIN
  helper_procedure;
END;

END my_package;
/
plsql:PlSql.FileComplexity

Most of the time, a very complex file breaks the Single Responsibility Principle and should be re-factored into several different files.

Deprecated

This rule is deprecated, and will eventually be removed.

plsql:PlSql.Goto

A GOTO statement is an unstructured change in the control flow. They should be avoided and replaced by structured constructs.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  i PLS_INTEGER := 42;
BEGIN
  IF i < 0 THEN
    GOTO negative; -- Noncompliant
  END IF;

  DBMS_OUTPUT.PUT_LINE('positive');
  goto cleanup; -- Noncompliant

  <<negative>>
  DBMS_OUTPUT.PUT_LINE('negative!');

  <<cleanup>>
  NULL;
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  i PLS_INTEGER := 42;
BEGIN
  IF i < 0 THEN
    DBMS_OUTPUT.PUT_LINE('negative!'); -- Compliant
  ELSE
    DBMS_OUTPUT.PUT_LINE('positive');
  END IF;
END;
/

See

  • MISRA C:2004, 14.4 - The goto statement shall not be used.
  • MISRA C:2012, 15.1 - The goto statement should not be used
plsql:PositionalAndNamedArgumentMixCheck

For better readability, and to prevent the PLS-00312: a positional parameter association may not follow a named association exception from being raised, do not mix named and positional argument invocations.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  PROCEDURE sub(op1 PLS_INTEGER, op2 PLS_INTEGER) AS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('Sub = ' || (op1 - op2));
  END;
BEGIN

  sub(10, op2 => 2); -- Noncompliant
  sub(op1 => 10, 2); -- Noncompliant - raises PLS-00312: a positional parameter association may not follow a named association

END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  PROCEDURE sub(op1 PLS_INTEGER, op2 PLS_INTEGER) AS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('Sub = ' || (op1 - op2));
  END;
BEGIN

  sub(10, 2); -- Compliant
  sub(op1 => 10, op2 => 2); -- Compliant

END;
/
plsql:QuotedIdentifiersCheck

Quoted identifiers are confusing to many programmers, as they look similar to string literals. Moreover, for maximum portability, identifiers should be self-descriptive and should not contain accents. Quoted identifiers can contain any character, which can be confusing.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  "x + y" PLS_INTEGER := 0; -- Noncompliant, quoted identifiers are confusing
  x PLS_INTEGER := 40;
  y PLS_INTEGER := 2;
  "hello" VARCHAR2(42) := 'world';  -- Noncompliant

BEGIN
  DBMS_OUTPUT.PUT_LINE("x + y"); -- Noncompliant, displays 0
  DBMS_OUTPUT.PUT_LINE("hello"); -- Noncompliant, confusing, displays "world" and not "hello"
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  my_int PLS_INTEGER := 0;
  x PLS_INTEGER := 40;
  y PLS_INTEGER := 2;
  greeting VARCHAR2(42) := 'hello';
BEGIN
  DBMS_OUTPUT.PUT_LINE(my_int);
  DBMS_OUTPUT.PUT_LINE(x + y); -- Compliant, displays 42

  DBMS_OUTPUT.PUT_LINE(greeting);
END;
/
plsql:ReliesOnClauseUsage

Since Oracle 11.2, RELIES_ON has been deprecated because the dependencies of result cache-enabled functions are automatically computed.

Noncompliant Code Example

CREATE OR REPLACE FUNCTION foo RETURN PLS_INTEGER RESULT_CACHE RELIES_ON(DUAL) AS -- Noncompliant
BEGIN
  RETURN 0;
END;
/

DROP FUNCTION foo;

Compliant Solution

CREATE OR REPLACE FUNCTION foo RETURN PLS_INTEGER RESULT_CACHE AS
BEGIN
  RETURN 0;
END;
/

DROP FUNCTION foo;
plsql:ResultCacheHintUsage

The result_cache Oracle hint can vastly improve performance, but it comes at the cost of extra memory consumption, so one should double-check that the gain in performance is significant, and avoid overusing this feature in general.

Noncompliant Code Example

SELECT /*+ result_cache */ * FROM DUAL;  -- Noncompliant
plsql:ReturnInInitializationSectionCheck

In a CREATE PACKAGE BODY, the purpose of the initialization section is to set the initial values of the package's global variables. It is therefore surprising to find a RETURN statement there, as all its following statements will be unreachable.

Noncompliant Code Example

SET SERVEROUTPUT ON

CREATE OR REPLACE PACKAGE foo AS
  FUNCTION getBar RETURN PLS_INTEGER;
  bar PLS_INTEGER;
END;
/

CREATE OR REPLACE PACKAGE BODY foo AS
  FUNCTION getBar RETURN PLS_INTEGER AS
  BEGIN
    RETURN bar; -- Compliant
  END;
BEGIN
  bar := 42;
  DBMS_OUTPUT.PUT_LINE('package loaded');
  RETURN; -- Noncompliant
  DBMS_OUTPUT.PUT_LINE('this is unreachable code');
END;
/

DROP PACKAGE BODY foo;

DROP PACKAGE foo;
plsql:ReturnInLoop

RETURN should not be used from within a FOR or WHILE loop. Doing so can quickly turn your code into "spaghetti code". Such code is hard to read, refactor and therefore to maintain.

Deprecated

This rule is deprecated, and will eventually be removed.

plsql:ReturnInProcedureCheck

Procedures, unlike functions, do not return values. The RETURN statement therefore, when used within a procedure, is used to prematurely end the procedure. However, having multiple exit points (i.e. more than the END of the procedure itself), increases the complexity of the procedure and makes it harder to understand and debug.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  PROCEDURE prcoedureWithReturn AS
  BEGIN
    RETURN; -- Noncompliant

    DBMS_OUTPUT.PUT_LINE('prcoedureWithReturn called'); -- This is actually unreachable
  END;
BEGIN
  prcoedureWithReturn;
END;
/

See

  • MISRA C:2004, 14.7 - A function shall have a single point of exit at the end of the function.
  • MISRA C++:2008, 6-6-5 - A function shall have a single point of exit at the end of the function
  • MISRA C:2012, 15.5 - A function should have a single point of exit at the end
plsql:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

IF something THEN
  IF something_else THEN
    -- ...
  END IF;
END IF;

Compliant Solution

IF something AND something_else THEN
  -- ...
END IF;
plsql:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

x := (y / 2 + 1); -- Compliant even if the parentheses are ignored
IF (x > 0) AND ((x+y > 0)) THEN -- Noncompliant
  -- ...
END IF;

Compliant Solution

x := (y / 2 + 1);
IF (x > 0) AND (x+y > 0) THEN
  -- ...
END IF;
plsql:S1126

Return of boolean literal statements wrapped into if-then-else ones should be simplified.

Noncompliant Code Example

IF expression THEN
  RETURN TRUE;
ELSE
  RETURN FALSE;
END IF;

Compliant Solution

RETURN expression;
plsql:S1479

CASE structures with a large set of WHEN clauses are difficult to understand and maintain, and should be refactored to include fewer WHEN clauses.

plsql:S1481

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.

plsql:S1614

Tables without primary keys are largely unusable in a relational database because they cannot be joined to. A primary key should be specified at table creation to guarantee that all its records have primary key values.

Noncompliant Code Example

CREATE TABLE employee
(
  employee_id INTEGER NOT NULL,
  first_name VARCHAR2(42) NOT NULL,
  last_name VARCHAR2(42) NOT NULL
);

Compliant Solution

CREATE TABLE employee
(
  employee_id INTEGER PRIMARY KEY,
  first_name VARCHAR2(42) NOT NULL,
  last_name VARCHAR2(42) NOT NULL
);
plsql:S3633

Queries with contradictory WHERE clauses will always return empty result sets. This is clearly a bug.

Noncompliant Code Example

SELECT *
FROM fruit
WHERE type='apple' AND type='orange'  -- Noncompliant
plsql:S3830

Frequent commits are widely understood to negatively impact performance. Thus, committing inside a loop (even when only executed conditionally once every n iterations) is highly likely to cause unwanted performance impacts.

Further, in general use COMMIT should only be used at the end of a transaction. Code that is not structured to have one transaction per loop iteration could yield unexpected results if COMMIT is nonetheless used inside the loop. Code that is structured to have one transaction per loop iteration should probably be reconsidered.

Note that when dealing with very large data sets, a COMMIT may be required every n iterations, but the goal should be to avoid COMMITs inside loops.

Noncompliant Code Example

FOR item IN itemlist
LOOP
  -- ...
  COMMIT;  -- Noncompliant
END LOOP;

Compliant Solution

FOR item IN itemlist
LOOP
  -- ...
END LOOP;
COMMIT;
plsql:S4062

Oracle's ROWNUM is a pseudo column that numbers the rows in a result set. Unfortunately, it numbers the rows in the set before ordering is applied. So combining the two in the same query won't get you the results you expect. Instead, you should move your selection and ordering into a subquery, and use ROWNUM only on the outer query.

Noncompliant Code Example

SELECT fname, lname, deptId
FROM employee
WHERE rownum <= 10
ORDER BY salary  -- Noncompliant

Compliant Solution

SELECT *
FROM ( SELECT fname, lname, deptId
    FROM employee
    ORDER BY salary
  )
WHERE rownum <= 10
plsql:SingleLineCommentsSyntaxCheck

The multi-line comment syntax /* ... */ should not be used for single line comments; the -- syntax is more appropriate.

Noncompliant Code Example

/*
 These comment lines are Compliant
 comment 1
 comment 2
*/

/*
 This comment is also Compliant
 */

/* This comment is Noncompliant */

Compliant Solution

/*
 These comment lines are Compliant
 comment 1
 comment 2
*/

/*
 This comment is also Compliant
 */

-- This comment is compliant
plsql:SizeConstraintMissingCheck

String data types, such as VARCHAR2 or NVARCHAR2 require a size constraint. Omitting the size results in the exception PLS-00215: String length constraints must be in range (1 .. 32767) being raised.

Noncompliant Code Example

DECLARE
  foo VARCHAR2; -- Noncompliant - raises PLS-00215
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  foo VARCHAR2(42); -- Compliant
BEGIN
  NULL;
END;
/
plsql:TriggerCommitRollbackCheck

Calling COMMIT or ROLLBACK from within a trigger will lead to an ORA-04092 exception, unless the trigger has its own autonomous transaction.

Noncompliant Code Example

SET SERVEROUTPUT ON

CREATE TABLE accounts(
  balance NUMBER
);

INSERT INTO accounts VALUES(0);

CREATE TABLE log(
  message VARCHAR2(100)
);

CREATE TRIGGER beforeLogger
  BEFORE UPDATE ON accounts
  FOR EACH ROW
BEGIN
  INSERT INTO log VALUES('Attempt to update the value from ' || :OLD.balance || ' to ' || :NEW.balance);
  COMMIT; -- Noncompliant, will fail with a ORA-04092
END;
/

-- We want to be able to log any attempt to update the "accounts" table
BEGIN
  UPDATE accounts SET balance = 100;
  ROLLBACK; -- Ultimately, this update is rolled back, however we still want to log it
END;
/

SELECT * FROM log;

DROP TRIGGER beforeLogger;

DROP TABLE log;

DROP TABLE accounts;

Compliant Solution

SET SERVEROUTPUT ON

CREATE TABLE accounts(
  balance NUMBER
);

INSERT INTO accounts VALUES(0);

CREATE TABLE log(
  message VARCHAR2(100)
);

CREATE TRIGGER beforeLogger
  BEFORE UPDATE ON accounts
  FOR EACH ROW
DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  INSERT INTO log VALUES('Attempt to update the value from ' || :OLD.balance || ' to ' || :NEW.balance);
  COMMIT; -- Compliant, commits the trigger's autonomous transaction, not the main one
END;
/

-- We want to be able to log any attempt to update the "accounts" table
BEGIN
  UPDATE accounts SET balance = 100;
  ROLLBACK; -- Ultimately, this update is rolled back, however we still want to log it
END;
/

SELECT * FROM log;

DROP TRIGGER beforeLogger;

DROP TABLE log;

DROP TABLE accounts;
plsql:TriggerOfConditionsCheck

The DML events clause of a trigger is not meant to be used with multiple OF conditions. When it is, only the last one will actually be taken into account, without any error message being produced. This can lead to counter-intuitive code.

Only the UPDATE event should have an OF condition, and there should be at most one occurence of it.

Noncompliant Code Example

CREATE OR REPLACE TRIGGER myTrigger
  BEFORE UPDATE OF firstName OR UPDATE OF lastName -- Noncompliant - will *only* be triggered on updates of lastName!
  ON myTable
  FOR EACH ROW
BEGIN
  NULL;
END;
/

Compliant Solution

CREATE OR REPLACE TRIGGER myTrigger
  BEFORE UPDATE OF firstName, lastName             -- Compliant - triggered on updates of firstName or/and lastName
  ON myTable
  FOR EACH ROW
BEGIN
  NULL;
END;
/
plsql:UseAsForColumnAliasesCheck

For better readability, column aliases should be used with the AS keyword. If it is missing, it could be misread as another column being selected.

Noncompliant Code Example

DECLARE
  result DUAL.dummy%TYPE;
BEGIN
  SELECT
    dummy d -- Non-Compliant - could be misread as selecting both "dummy" and a column "d"
  INTO
    result
  FROM
    DUAL;
END;
/

Compliant Solution

DECLARE
  result DUAL.dummy%TYPE;
BEGIN
  SELECT
    dummy AS d -- Compliant
  INTO
    result
  FROM
    DUAL;
END;
/
plsql:UseFetchBulkCollectIntoCheck

The FETCH ... INTO statement is inefficient when used in a loop (where many records are expected). It leads to many context-switches between the SQL and PL/SQL engines. Instead, the FETCH ... BULK COLLECT INTO statement will issue the SQL requests in bulk, minimizing context switches.

Noncompliant Code Example

SET SERVEROUTPUT ON

CREATE TABLE largeTable AS SELECT ROWNUM AS id FROM all_objects;

SET TIMING ON
DECLARE
  x PLS_INTEGER;
  CURSOR largeCursor IS SELECT ROWNUM FROM largeTable;
  largeTableRowId BINARY_INTEGER;
BEGIN
  OPEN largeCursor;

  x := 0;
  LOOP
    FETCH largeCursor INTO largeTableRowId; -- Noncompliant
    EXIT WHEN largeCursor%NOTFOUND;

    x := x + largeTableRowId;
  END LOOP;

  DBMS_OUTPUT.PUT_LINE('Sum of rownums using alternative 1: ' || x);

  CLOSE largeCursor;
END;
/
SET TIMING OFF

DECLARE
  r largeTable%ROWTYPE;
  CURSOR myCursor IS SELECT * FROM largeTable;
BEGIN
  OPEN myCursor;
  FETCH myCursor INTO r; -- Compliant, outside of a loop
  CLOSE myCursor;
END;
/

DROP TABLE largeTable;

Compliant Solution

SET SERVEROUTPUT ON

CREATE TABLE largeTable AS SELECT ROWNUM AS id FROM all_objects;

SET TIMING ON
DECLARE
  x PLS_INTEGER;
  CURSOR largeCursor IS SELECT * FROM largeTable;
  TYPE largeTableRowIdArrayType IS TABLE OF BINARY_INTEGER INDEX BY BINARY_INTEGER;
  largeTableRowIdArray largeTableRowIdArrayType;
BEGIN
  OPEN largeCursor;

  x := 0;
  LOOP
    FETCH largeCursor BULK COLLECT INTO largeTableRowIdArray LIMIT 1000; -- Compliant

    FOR i IN largeTableRowIdArray.FIRST .. largeTableRowIdArray.LAST LOOP
      x := x + largeTableRowIdArray(i);
    END LOOP;

    EXIT WHEN largeCursor%NOTFOUND;
  END LOOP;

  DBMS_OUTPUT.PUT_LINE('Sum of rownums using alternative 2: ' || x);

  CLOSE largeCursor;
END;
/
SET TIMING OFF

DECLARE
  r largeTable%ROWTYPE;
  CURSOR myCursor IS SELECT * FROM largeTable;
BEGIN
  OPEN myCursor;
  FETCH myCursor INTO r; -- Compliant, outside of a loop
  CLOSE myCursor;
END;
/

DROP TABLE largeTable;
plsql:UseForallStatementCheck

The performance of DML queries in loops can be improved by placing them in a FORALL statement. This way, queries will be sent in bulk, minimizing the number of context switches between PL/SQL and SQL.

Noncompliant Code Example

SET SERVEROUTPUT ON

CREATE TABLE largeTable(
  foo VARCHAR2(42)
);

BEGIN
  FOR i IN 1 .. 100000 LOOP
    INSERT INTO largeTable VALUES('bar' || i); -- Non-compliant
  END LOOP;
END;
/

SET TIMING ON
DECLARE
  TYPE largeTableRowArrayType IS TABLE OF largeTable%ROWTYPE;
  largeTableRowArray largeTableRowArrayType;
BEGIN
  SELECT * BULK COLLECT INTO largeTableRowArray FROM largeTable;

  EXECUTE IMMEDIATE 'TRUNCATE TABLE largeTable';
  FOR i IN largeTableRowArray.FIRST .. largeTableRowArray.LAST LOOP
    INSERT INTO largeTable (foo) VALUES (largeTableRowArray(i).foo); -- Non-compliant
  END LOOP;
END;
/
SET TIMING OFF

DROP TABLE largeTable;

Compliant Solution

SET SERVEROUTPUT ON

CREATE TABLE largeTable(
  foo VARCHAR2(42)
);

BEGIN
  FOR i IN 1 .. 100000 LOOP
    INSERT INTO largeTable VALUES('bar' || i); -- Non-compliant
  END LOOP;
END;
/

SET TIMING ON
DECLARE
  TYPE largeTableRowArrayType IS TABLE OF largeTable%ROWTYPE;
  largeTableRowArray largeTableRowArrayType;
BEGIN
  SELECT * BULK COLLECT INTO largeTableRowArray FROM largeTable;

  EXECUTE IMMEDIATE 'TRUNCATE TABLE largeTable';
  FORALL i IN largeTableRowArray.FIRST .. largeTableRowArray.LAST
    INSERT INTO largeTable (foo) VALUES (largeTableRowArray(i).foo); -- Compliant

  INSERT INTO largeTable (foo) VALUES ('baz'); -- Compliant, not in a loop
END;
/
SET TIMING OFF

DROP TABLE largeTable;
plsql:UseNativeSqlJoinsInsteadOfEmbeddedCursorLoopsCheck

SQL is an extremely powerful and hard to master language. It may be tempting to emulate SQL joins in PL/SQL using nested cursor loops, but those are not optimized by Oracle at all. In fact, they lead to numerous context switches between the SQL and PL/SQL engines, and those switches have a highly negative impact on performance. It is therefore much better to replace nested PL/SQL cursor loops with native SQL joins.

Noncompliant Code Example

SET SERVEROUTPUT ON

CREATE TABLE countriesTable(
  countryName VARCHAR2(42)
);

CREATE TABLE citiesTable(
  cityName VARCHAR2(42)
);

INSERT INTO countriesTable VALUES('India');
INSERT INTO countriesTable VALUES('Switzerland');
INSERT INTO countriesTable VALUES('United States');

INSERT INTO citiesTable VALUES('Berne');
INSERT INTO citiesTable VALUES('Delhi');
INSERT INTO citiesTable VALUES('Bangalore');
INSERT INTO citiesTable VALUES('New York');

BEGIN
  FOR countryRecord IN (SELECT countryName FROM countriesTable) LOOP
    FOR cityRecord IN (SELECT cityName FROM citiesTable) LOOP -- Non-Compliant
      DBMS_OUTPUT.PUT_LINE('Country: ' || countryRecord.countryName || ', City: ' || cityRecord.cityName);
    END LOOP;
  END LOOP;
END;
/

DROP TABLE citiesTable;

DROP TABLE countriesTable;

Compliant Solution

SET SERVEROUTPUT ON

CREATE TABLE countriesTable(
  countryName VARCHAR2(42)
);

CREATE TABLE citiesTable(
  cityName VARCHAR2(42)
);

INSERT INTO countriesTable VALUES('India');
INSERT INTO countriesTable VALUES('Switzerland');
INSERT INTO countriesTable VALUES('United States');

INSERT INTO citiesTable VALUES('Berne');
INSERT INTO citiesTable VALUES('Delhi');
INSERT INTO citiesTable VALUES('Bangalore');
INSERT INTO citiesTable VALUES('New York');

BEGIN
  FOR myRecord IN (SELECT * FROM countriesTable CROSS JOIN citiesTable) LOOP -- Compliant
    DBMS_OUTPUT.PUT_LINE('Country: ' || myRecord.countryName || ', City: ' || myRecord.cityName);
  END LOOP;
END;
/

DROP TABLE citiesTable;

DROP TABLE countriesTable;
plsql:VarcharUsageCheck

Currently, VARCHAR and VARCHAR2 are identical data types. But to prevent future changes in behavior, Oracle recommends the use of VARCHAR2.

Noncompliant Code Example

DECLARE
  var VARCHAR(42);  -- Noncompliant
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  var VARCHAR2(42);  -- Noncompliant
BEGIN
  NULL;
END;
/
plsql:VariableNotNullUsageCheck

Declaring a variable with the NOT NULL constraint incurs a small performance cost - while this constraint may not really be required. Using such a constraint should be avoided.

Noncompliant Code Example

DECLARE
  counter PLS_INTEGER NOT NULL := 0; -- Noncompliant
BEGIN
  NULL;
END;
/

Compliant Solution

DECLARE
  counter PLS_INTEGER := 0; -- Compliant
BEGIN
  NULL;
END;
/
plsql:VariableRedeclaration

At most one declaration of a variable in a given scope is allowed in PL/SQL. The PLS-00371 error will be raised at runtime when attempting to reference a variable declared more than once.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  foo VARCHAR2(42) := 'foo';
  foo VARCHAR2(42) := 'bar'; -- Non-Compliant
BEGIN
  DBMS_OUTPUT.PUT_LINE(foo); -- Raises PLS-00371: at most one declaration for 'FOO' is permitted
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  foo VARCHAR2(42) := 'foo';
  bar VARCHAR2(42) := 'bar'; -- Compliant
BEGIN
  DBMS_OUTPUT.PUT_LINE(foo);
END;
/
Pylint:C0102
Used when the name is listed in the black list (unauthorized names).

Pylint can be customized to help enforce coding guidelines that discourage or forbid use of certain names for variables, functions, etc. These names are specified with the bad-names option. This message is raised whenever a name is in the list of names defined with the bad-names option.

Pylint:C0103
Used when the name doesn't conform to naming rules associated to its type (constant, variable, class...).

This rule is deprecated, use S116, S117, S101, S100, S1542, S1578 instead.

Pylint:C0111
Used when a module, function, class or method has no docstring. Some special methods like __init__ doesn't necessary require a docstring.

This rule is deprecated, use S1720 instead.

Pylint:C0112
Used when a module, function, class or method has an empty docstring (it would be too easy ;).

This rule is deprecated, use S1720 instead.

Pylint:C0113
Used when a boolean expression contains an unneeded negation.
Pylint:C0121
Used when an expression is compared to singleton values like True, False or None.
Pylint:C0122
Used when the constant is placed on the left side of a comparison. It is usually clearer in intent to place it in the right hand side of the comparison.
Pylint:C0123
The idiomatic way to perform an explicit typecheck in Python is to use isinstance(x, Y) rather than type(x) == Y, type(x) is Y. Though there are unusual situations where these give different results.
Pylint:C0200
Emitted when code that iterates with range and len is encountered. Such code can be simplified by using the enumerate builtin.
Pylint:C0201
Emitted when the keys of a dictionary are iterated through the .keys() method. It is enough to just iterate through the dictionary itself, as in "for key in dictionary".
Pylint:C0202
Used when a class method has a first argument named differently than the value specified in valid-classmethod-first-arg option (default to "cls"), recommended to easily differentiate them from regular instance methods.
Pylint:C0203
Used when a metaclass method has a first argument named differently than the value specified in valid-classmethod-first-arg option (default to "cls"), recommended to easily differentiate them from regular instance methods.
Pylint:C0205
Used when a class __slots__ is a simple string, rather than an iterable.
Pylint:C0301
Used when a line is longer than a given number of characters.

This rule is deprecated, use LineLength instead.

Pylint:C0305
Used when there are trailing blank lines in a file.
Pylint:C0322
Used when one of the following operator (!= | <= | == | >= | < | > | = | \+= |-= | \*= | /= | %) is not preceded by a space.
Pylint:C0323
Used when one of the following operator (!= | <= | == | >= | < | > | = | \+= |-= | \*= | /= | %) is not followed by a space.
Pylint:C0324
Used when a comma (",") is not followed by a space.
Pylint:C0327
Used when there are mixed (LF and CRLF) newline signs in a file.
Pylint:C0328
Used when there is different newline than expected.
Pylint:C0330

Used when continued lines are badly indented.

This rule was added in Pylint 1.2.1.

Pylint:C0403
Used when a word in docstring cannot be checked by enchant.
Pylint:C0410
Used when import statement importing multiple modules is detected.
Pylint:C0411
Used when PEP8 import order is not respected (standard imports first, then third-party libraries, then local imports)
Pylint:C0412
Used when imports are not grouped by packages
Pylint:C0413
Used when code and imports are mixed
Pylint:C1801
Used when Pylint detects that len(sequence) is being used inside a condition to determine if a sequence is empty. Instead of comparing the length to 0, rely on the fact that empty sequences are false.
Pylint:E0001
Used when a syntax error is raised for a module.
Pylint:E0100
Used when the special class method __init__ is turned into a generator by a yield in its body.

The __init__() method is required to return nothing. Python 2.7 and 3.x raise a TypeError when __init__() is called and executes a yield statement. Pylint reports this error without depending on the actual invocation.

This rule is deprecated, use S2734 instead.

Pylint:E0101
Used when the special class method __init__ has an explicit return value.

The __init__() method is required to return nothing. Python raises a TypeError when __init__() is called and executes a return statement with a value other than None. Pylint reports this error without depending on the actual invocation.

This rule is deprecated, use S2734 instead.

Pylint:E0102
Used when a function / class / method is redefined.
Pylint:E0103
Used when break or continue keywords are used outside a loop.

This rule is deprecated, use S1716 instead.

Pylint:E0104
Used when a "return" statement is found outside a function or method.

This rule is deprecated, use S2711 instead.

Pylint:E0105
Used when a "yield" statement is found outside a function or method.

This rule is deprecated, use S2711 instead.

Pylint:E0108
Duplicate argument names in function definitions are syntax errors.

This rule was added in Pylint 0.28.0.

Pylint:E0109
Used when reversed() builtin didn't receive an argument.
Pylint:E0110
Used when an abstract class with `abc.ABCMeta` as metaclass has abstract methods and is instantiated.
Pylint:E0111
Used when the first argument to reversed() builtin isn't a sequence (does not implement __reversed__, nor __getitem__ and __len__

This rule was added in Pylint 1.2.0.

Pylint:E0116
Emitted when the `continue` keyword is found inside a finally clause, which is a SyntaxError.
Pylint:E0203
Used when an instance member is accessed before it's actually assigned.
Pylint:E0211
Used when a method which should have the bound instance as first argument has no argument defined.
Pylint:E0213
Used when a method has an attribute different the "self" as first argument. This is considered as an error since this is a so common convention that you shouldn't break it!
Pylint:E0221
Used when a class claims to implement an interface which is not a class.
Pylint:E0222
Used when a method declared in an interface is missing from a class implementing this interface.
Pylint:E0235
Used when the __exit__ special method, belonging to a context manager, does not accept 3 arguments (type, value, traceback).

This rule was added in Pylint 1.1.0.

This rule is deprecated, use S2733 instead.

Pylint:E0237
Used when assigning to an attribute not defined in the class slots.
Pylint:E0238
Used when an invalid __slots__ is found in class. Only a string, an iterable or a sequence is permitted.

This rule was added in Pylint 1.2.0.

Pylint:E0239
Used when a class inherits from something which is not a class.
Pylint:E0240
Used when a class has an inconsistent method resolution order.
Pylint:E0241
Used when a class has duplicate bases.
Pylint:E0302
Emitted when a special method was defined with an invalid number of parameters. If it has too few or too many, it might not work at all.
Pylint:E0401
Used when pylint has been unable to import a module.
Pylint:E0402
Used when a relative import tries to access too many levels in the current package.
Pylint:E0501
Used when some non-ASCII characters are detected but no encoding is specified, as stated in the PEP 263.
Pylint:E0502
Used when a known encoding is specified but the file doesn't seem to be actually in this encoding.
Pylint:E0503
Used when an encoding is specified, but it's unknown to Python.
Pylint:E0602
Used when an undefined variable is accessed.
Pylint:E0603
Used when an undefined variable name is referenced in __all__.
Pylint:E0604
Used when an invalid (non-string) object occurs in __all__.

This rule was added in Pylint 0.27.0.

Pylint:E0632
Used when there is an unbalanced tuple unpacking in assignment
Pylint:E0633
Used when something which is not a sequence is used in an unpack assignment
Pylint:E0702
Used when something which is neither a class, an instance or a string is raised (i.e. a 'TypeError' will be raised).
Pylint:E0704
Used when a bare raise is not used inside an except clause. This generates an error, since there are no active exceptions to be reraised. An exception to this rule is represented by a bare raise inside a finally clause, which might work, as long as an exception is raised inside the try block, but it is nevertheless a code smell that must not be relied upon.
Pylint:E0710
Used when a new style class which doesn't inherit from BaseException is raised.
Pylint:E0711
Used when NotImplemented is raised instead of NotImplementedError.
Pylint:E1001
Used when an old style class uses the __slots__ attribute. This message can't be emitted when using Python >= 3.0.
Pylint:E1002
Used when an old style class uses the super builtin. This message can't be emitted when using Python >= 3.0.
Pylint:E1003
Used when another argument than the current class is given as first argument of the super builtin.
Pylint:E1004
Used when the super builtin didn't receive an argument. This message can't be emitted when using Python >= 3.0.
Pylint:E1102
Used when an object being called has been inferred to a non callable object.
Pylint:E1103
Used when a variable is accessed for an nonexistent member, but Pylint was not able to interpret all possible types of this variable.
Pylint:E1120
Used when a function call passes too few arguments.
Pylint:E1121
Used when a function call passes too many positional arguments.
Pylint:E1122
Used when a function call passes the same keyword argument multiple times.
Pylint:E1123
Used when a function call passes a keyword argument that doesn't correspond to one of the function's parameter names.
Pylint:E1124
Used when a function call would result in assigning multiple values to a function parameter, one value from a positional argument and one from a keyword argument.
Pylint:E1126
Used when a sequence type is indexed with an invalid type. Valid types are ints, slices, and objects with an __index__ method.
Pylint:E1127
Used when a slice index is not an integer, None, or an object with an __index__ method.
Pylint:E1129
Used when an instance in a with statement doesn't implement the context manager protocol(__enter__/__exit__).
Pylint:E1131
Emitted when a binary arithmetic operation between two operands is not supported.
Pylint:E1132
Emitted when a function call got multiple values for a keyword.
Pylint:E1133
Used when a non-iterable value is used in place where iterable is expected
Pylint:E1134
Used when a non-mapping value is used in place where mapping is expected
Pylint:E1139
Emitted whenever we can detect that a class is using, as a metaclass, something which might be invalid for using as a metaclass.
Pylint:E1205
Used when a logging format string is given too many arguments.
Pylint:E1206
Used when a logging format string is given too few arguments.
Pylint:E1301
Used when a format string terminates before the end of a conversion specifier.
Pylint:E1302
Used when a format string contains both named (e.g. '%(foo)d') and unnamed (e.g. '%d') conversion specifiers. This is also used when a named conversion specifier contains * for the minimum field width and/or precision.
Pylint:E1303
Used when a format string that uses named conversion specifiers is used with an argument that is not a mapping.
Pylint:E1304
Used when a format string that uses named conversion specifiers is used with a dictionary that doesn't contain all the keys required by the format string.
Pylint:E1310
The argument to a str.{l,r}strip call contains a duplicate character.

This rule was added in Pylint 0.28.0.

Pylint:E1606
Used when "l" or "L" is used to mark a long integer. This will not work in Python 3, since `int` and `long` types have merged. This message can't be emitted when using Python >= 3.0.
Pylint:E1608
Used when encountering the old octal syntax, removed in Python 3. To use the new syntax, prepend 0o on the number. This message can't be emitted when using Python >= 3.0.
Pylint:E1609
Used when the import star syntax is used somewhere else than the module level. This message can't be emitted when using Python >= 3.0.
Pylint:E1610
Used when non-ascii bytes literals are found in a program. They are no longer supported in Python 3. This message can't be emitted when using Python >= 3.0.
Pylint:R0123
Used when comparing an object to a literal, which is usually what you do not want to do, since you can compare to a different literal than what was expected altogether.
Pylint:R0201
Used when a method doesn't use its bound instance, and so could be written as a function.

This rule is deprecated, use S2325 instead.

Pylint:R0202
Used when a class method is defined without using the decorator syntax.
Pylint:R0203
Used when a static method is defined without using the decorator syntax.
Pylint:R0401
Used when a cyclic import between two or more modules is detected.

While cyclic imports terminate and execute without surprises in most cases, the circular dependency often indicates a design issue in the code base.

Pylint:R0903
Used when class has too few public methods, so be sure it's really worth it.
Pylint:R0911
Used when a function or method has too many return statement, making it hard to follow.

This rule is deprecated, use S1142 instead.

Pylint:R0913
Used when a function or method takes too many arguments.

This rule is deprecated, use S107 instead.

Pylint:R0914
Used when a function or method has too many local variables.
Pylint:R0921
Used when an abstract class is not used as ancestor anywhere.
Pylint:R0922
Used when an abstract class is used less than X times as ancestor.
Pylint:R0923
Used when an interface class is not implemented anywhere.
Pylint:R1701
Used when multiple consecutive isinstance calls can be merged into one.
Pylint:R1702
Used when a function or a method has too many nested blocks. This makes the code less understandable and maintainable.
Pylint:R1703
Used when an if statement can be replaced with 'bool(test)'.
Pylint:R1704
Used when a local name is redefining an argument, which might suggest a potential error. This is taken in account only for a handful of name binding operations, such as for iteration, with statement assignment and exception handler assignment.
Pylint:R1705
Used in order to highlight an unnecessary block of code following an if containing a return statement. As such, it will warn when it encounters an else following a chain of ifs, all of them containing a return statement.
Pylint:R1706
Used when one of known pre-python 2.5 ternary syntax is used.
Pylint:R1709
Emitted when redundant pre-python 2.5 ternary syntax is used.
Pylint:R1710
According to PEP8, if any return statement returns an expression, any return statements where no value is returned should explicitly state this as return None, and an explicit return statement should be present at the end of the function (if reachable)
Pylint:W0101
Used when there is some code behind a "return" or "raise" statement, which will never be accessed.

This rule is deprecated, use S1763 instead.

Pylint:W0104
Used when a statement doesn't have (or at least seems to) any effect.
Pylint:W0105
Used when a string is used as a statement (which of course has no effect). This is a particular case of W0104 with its own message so you can easily disable it if you're using those strings as documentation, instead of comments.
Pylint:W0106
Used when an expression that is not a function call is assigned to nothing. Probably something else was intended.
Pylint:W0107
Used when a "pass" statement that can be avoided is encountered.

This rule is deprecated, use S2772 instead.

Pylint:W0108
Used when the body of a lambda expression is a function call on the same argument list as the lambda itself; such lambda expressions are in all but a few cases replaceable with the function being called in the body of the lambda.
Pylint:W0109
Used when a dictionary expression binds the same key multiple times.
Pylint:W0121
Used when the alternate raise syntax 'raise foo, bar' is used instead of 'raise foo(bar)'. This message can't be emitted when using Python >= 3.0.

This rule was added in Pylint 1.0.0.

Pylint:W0124
Emitted when a `with` statement component returns multiple values and uses name binding with `as` only for a part of those values, as in with ctx() as a, b. This can be misleading, since it's not clear if the context manager returns a tuple or if the node without a name binding is another context manager.
Pylint:W0125
Emitted when a conditional statement (If or ternary if) uses a constant value for its test. This might not be what the user intended to do.
Pylint:W0141
Used when a black listed builtin function is used (see the bad-function option). Usual black listed functions are the ones like map, or filter, where Python offers now some cleaner alternative like list comprehension.
Pylint:W0142
Used when a function or method is called using `*args` or `**kwargs` to dispatch arguments. This doesn't improve readability and should be used with care.
Pylint:W0150
Used when a break or a return statement is found inside the finally clause of a try...finally block: the exceptions raised in the try clause will be silently swallowed instead of being re-raised.
Pylint:W0199
A call of assert on a tuple will always evaluate to true if the tuple is not empty, and will always evaluate to false if it is. Did you mean 'assert x,y'?
Pylint:W0212
Used when a protected member (i.e. class member with a name beginning with an underscore) is access outside the class or a descendant of the class where it's defined.
Pylint:W0221
Used when a method has a different number of arguments than in the implemented interface or in an overridden method.
Pylint:W0223
Used when an abstract method (i.e. raise NotImplementedError) is not overridden in concrete class.
Pylint:W0231
Used when an ancestor class method has an __init__ method which is not called by a derived class.
Pylint:W0232
Used when a class has no __init__ method, neither its parent classes.
Pylint:W0233
Used when an __init__ method is called on a class which is not in the direct ancestors for the analysed class.
Pylint:W0234
Used when an __iter__ method returns something which is not an iterable (i.e. has no `next` method).

This rule was added in Pylint 1.1.0.

Pylint:W0235
Used whenever we can detect that an overridden method is useless, relying on super() delegation to do the same thing as another method from the MRO.
Pylint:W0311
Used when an unexpected number of indentation's tabulations or spaces has been found.
Pylint:W0312
Used when there are some mixed tabs and spaces in a module.

As indentation is part of Python's syntax, inconsistencies in its usage are usually considered a major issue.

Pylint:W0331
Used when the deprecated "<>" operator is used instead of "!=".

This rule is deprecated, use InequalityUsage instead.

Pylint:W0333
Used when the deprecated "``" (backtick) operator is used instead of the str() function.

This rule is deprecated, use BackticksUsage instead.

Pylint:W0402
Used a module marked as deprecated is imported.
Pylint:W0404
Used when a module is reimported multiple times.
Pylint:W0406
Used when a module is importing itself.
Pylint:W0410
Python 2.5 and greater require __future__ import to be the first non docstring statement in the module.
Pylint:W0511
Used when a warning note as FIXME or XXX is detected.
Pylint:W0601
Used when a variable is defined through the "global" statement but the variable is not defined in the module scope.
Pylint:W0602
Used when a variable is defined through the "global" statement but no assignment to this variable is done.
Pylint:W0611
Used when an imported module or variable is not used.
Pylint:W0612
Used when a variable is defined but not used.
Pylint:W0613
Used when a function or method argument is not used.
Pylint:W0621
Used when a variable's name hides a name defined in the outer scope.
Pylint:W0622
Used when a variable or function override a built-in.
Pylint:W0632
Used when there is an unbalanced tuple unpacking in assignment.

This rule was added in Pylint 1.1.0.

Pylint:W0633
Used when something which is not a sequence is used in an unpack assignment.

This rule was added in Pylint 1.1.0.

Pylint:W0640
A variable used in a closure is defined in a loop. This will result in all closures using the same value for the closed-over variable.
Pylint:W0701
Used when a string exception is raised.
Pylint:W0702
Used when an except clause doesn't specify exceptions type to catch.

Catching exceptions should be as precise as possible. The type of exceptions that can be raised should be known in advance. Using catch-all-constructs hides potential errors (including syntax ones), defeats the purpose of knowing the type of error that occurred, and prohibits the use of tailored responses.

Pylint:W0703
Used when an except catches a too general exception, possibly burying unrelated errors.

Catching exceptions should be as precise as possible. The type of exceptions that can be raised should be known in advance. Using a catch-all Exception instance defeats the purpose of knowing the type of error that occur-ed, and prohibits the use of tailored responses.

Pylint:W0704
Used when an except clause does nothing but "pass" and there is no "else" clause.
Pylint:W0705
Used when an except catches a type that was already caught by a previous handler.
Pylint:W0711
Used when the exception to catch is of the form "except A or B:". If intending to catch multiple, rewrite as "except (A, B):"
Pylint:W0715
Used when passing multiple arguments to an exception constructor, the first of them a string literal containing what appears to be placeholders intended for formatting
Pylint:W1111
Used when an assignment is done on a function call but the inferred function returns nothing but None.
Pylint:W1113
When defining a keyword argument before variable positional arguments, one can end up in having multiple values passed for the aforementioned parameter in case the method is called with keyword arguments.
Pylint:W1300
Used when a format string that uses named conversion specifiers is used with a dictionary whose keys are not all strings.
Pylint:W1301
Used when a format string that uses named conversion specifiers is used with a dictionary that contains keys not required by the format string.
Pylint:W1302
Used when a PEP 3101 format string is invalid. This message can't be emitted when using Python < 2.7.
Pylint:W1501
Python supports: r, w, a[, x] modes with b, +, and U (only with r) options. See http://docs.python.org/2/library/functions.html#open
Pylint:W1502
Using datetime.time in a boolean context can hide subtle bugs when the time they represent matches midnight UTC. This behaviour was fixed in Python 3.5. See http://bugs.python.org/issue13936 for reference. This message can't be emitted when using Python >= 3.5.
Pylint:W1503
The first argument of assertTrue and assertFalse is a condition. If a constant is passed as parameter, that condition will be always true. In this case a warning should be emitted.
Pylint:W1505
The method is marked as deprecated and will be removed in a future version of Python. Consider looking for an alternative in the documentation.
Pylint:W1506
The warning is emitted when a threading.Thread class is instantiated without the target function being passed. By default, the first parameter is the group param, not the target param.
Pylint:W1507
os.environ is not a dict object but proxy object, so shallow copy has still effects on original object. See https://bugs.python.org/issue15373 for reference.
python:ClassComplexity

The cyclomatic complexity of a class should not exceed a defined threshold. Complex code can perform poorly and will in any case be difficult to understand and therefore to maintain.

Deprecated

This rule is deprecated, and will eventually be removed.

python:FileComplexity

Most of the time, a very complex file breaks the Single Responsibility Principle and should be re-factored into several different files.

Deprecated

This rule is deprecated, and will eventually be removed.

python:FunctionComplexity

The Cyclomatic Complexity of functions should not exceed a defined threshold. Complex code may perform poorly and can be difficult to test thoroughly.

python:InequalityUsage

The forms <> and != are equivalent. But in Python 2.7.3 the <> form is considered obsolete.

Noncompliant Code Example

return a <> b # Noncompliant

Compliant Solution

return a != b
python:LineLength

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

python:LongIntegerWithLowercaseSuffixUsage

The long suffix should always be written in uppercase, i.e. 'L', as the lowercase 'l' can easily be confused with the digit one '1'.

Noncompliant Code Example

return 10l  // Noncompliant; easily confused with one zero one

Compliant Solution

return 10L
python:OneStatementPerLine

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

if (True): print("hello")

Compliant Solution

if (True):
    print("hello")
python:ParsingError

When the Python parser fails, it is possible to record the failure as a violation on the file. This way, not only it is possible to track the number of files that do not parse but also to easily find out why they do not parse.

python:PreIncrementDecrement

Python has no pre/post increment/decrement operator. For instance, x++ and x-- will fail to parse. More importantly, ++x and --x will do nothing. To increment a number, simply write x += 1.

Noncompliant Code Example

++x # Noncompliant

Compliant Solution

x += 1
python:PrintStatementUsage

The print statement was removed in Python 3.0. The built-in function should be used instead.

Noncompliant Code Example

print '1'  # Noncompliant

Compliant Solution

print('1')
python:S100

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all method names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression: ^[a-z_][a-z0-9_]{2,30}$

class MyClass:
    def MyMethod(a,b):
        ...

Compliant Solution

class MyClass:
    def my_method(a,b):
        ...
python:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

python:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if condition1:
    if condition2:
        # ...

Compliant Solution

if condition1 and condition2:
    # ...
python:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

Noncompliant Code Example

With a maximum number of 4 parameters:

def do_something(param1, param2, param3, param4, param5):
	...

Compliant Solution

def do_something(param1, param2, param3, param4):
	...
python:S108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

for i in range(3):
    pass

Exceptions

When a block contains a comment, this block is not considered to be empty.

python:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

return ((3))        # Noncompliant
return ((x + 1))    # Noncompliant
x = ((y / 2)) + 1   # Noncompliant

Compliant Solution

return 3
return (3)
return x + 1
return (x + 1)
x = y / 2 + 1
x = (y / 2) + 1
python:S113

Some tools such as Git work better when files end with an empty line. This rule simply generates an issue if it is missing.

For example, a Git diff looks like this if the empty line is missing at the end of the file:

<pre>

+class Test:

+ pass

\ No newline at end of file

</pre>

python:S1131

Trailing whitespaces are simply useless and should not stay in code. They may generate noise when comparing different versions of the same file.

If you encounter issues from this rule, this probably means that you are not using an automated code formatter - which you should if you have the opportunity to do so.

python:S1142

Having too many return statements in a function increases the function's essential complexity because the flow of execution is broken each time a return statement is encountered. This makes it harder to read and understand the logic of the function.

Noncompliant Code Example

With the default threshold of 3:

def fun():          # Noncompliant as there are 4 return statements
  if condition1:
    return True
  elif condition2:
    return False
  else:
    return True
  return False
}
python:S134

Nested if, for, while, try, and with 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

The following code snippet illustrates this rule with the default threshold of 3.

  if condition1:           # Compliant - depth = 1
    # ...
    if condition2:         # Compliant - depth = 2
      # ...
      for i in range(10):  # Compliant - depth = 3, not exceeding the limit
        # ...
        if condition4:     # Non-Compliant - depth = 4
          if condition5:   # Depth = 5, exceeding the limit, but issues are only reported on depth = 4
            # ...
python:S139

This rule verifies that single-line comments are not located at the ends of lines of code. The main idea behind this rule is that in order to be really readable, trailing comments would have to be properly written and formatted (correct alignment, no interference with the visual structure of the code, not too long to be visible) but most often, automatic code formatters would not handle this correctly: the code would end up less readable. Comments are far better placed on the previous empty line of code, where they will always be visible and properly formatted.

Noncompliant Code Example

a = b + c   # This is a trailing comment that can be very very long

Compliant Solution

# This very long comment is better placed before the line of code
a = b + c
python:S1542

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

With the default provided regular expression: ^[a-z_][a-z0-9_]{2,30}$

def MyFunction(a,b):
    ...

Compliant Solution

def my_function(a,b):
    ...
python:S1578

Shared coding conventions allow teams to collaborate effectively. For that reason, module names should conform to a defined standard.

See

python:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

name = name

Compliant Solution

name = other.name

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
python:S1700

It's confusing to have a class member with the same name (case differences aside) as its enclosing class. This is particularly so when you consider the common practice of naming a class instance for the class itself.

Best practice dictates that any field or member with the same name as the enclosing class be renamed to be more descriptive of the particular aspect of the class it represents or holds.

Noncompliant Code Example

class Foo:
  foo = ''

  def getFoo(self):
    ...

foo = Foo()
foo.getFoo() # what does this return?

Compliant Solution

class Foo:
  name = ''

  def getName(self):
    ...

foo = Foo()
foo.getName()
python:S1707

TODO and FIXME comments are typically intended to be short-lived; they are placeholders and reminders that programmers leave for themselves. Unfortunately, even with the best of intentions, those comments are not always acted on and removed in a timely manner. Thus, they can become mysterious, lingering cruft in a code base, reducing both readability and understand-ability.

This rule flags all FIXME and TODO comments that do not have an attribution matching the specified regular expression immediately after the FIXME or TODO. Ideally, such comments will also contain information about what needs to be fixed or done, but this rule does not enforce that.

Noncompliant Code Example

# TODO

Compliant Solution

# TODO(ganncamp) per the business partners, more checks needed
python:S1716

break and continue are unstructured control flow statements which make code harder to read. Additionally, more recent versions of Python raise a SyntaxError when modules containing break or continue outside of a loop are imported.

Therefore, these statements should not be used outside of loops.

Noncompliant Code Example

narg=len(sys.argv)
if narg == 1:
        print('@Usage: input_filename nelements nintervals')
        break

Compliant Solution

if narg == 1:
        print('@Usage: input_filename nelements nintervals')
        sys.exit()
python:S1717

Typically, backslashes are seen only as part of escape sequences. Therefore, the use of a backslash outside of a raw string or escape sequence looks suspiciously like a broken escape sequence.

Characters recognized as escape-able are: abfnrtvox\'"

Noncompliant Code Example

s = "Hello \world."
t = "Nice to \ meet you"
u = "Let's have \ lunch"

Compliant Solution

s = "Hello world."
t = "Nice to \\ meet you"
u = r"Let's have \ lunch"  // raw string
python:S1720

A string literal that is the first statement in a module, function, class, or method is a docstring. A docstring should document what a caller needs to know about the code. Information about what it does, what it returns, and what it requires are all valid candidates for documentation. Well written docstrings allow callers to use your code without having to first read it and understand its logic.

By convention, docstrings are enclosed in three sets of double-quotes.

Noncompliant Code Example

def my_function(a,b):

Compliant Solution

def my_function(a,b):
      """Do X"""
python:S1721

Parentheses are not required after the assert, del, elif, except, for, if, in, not, raise, return, while, and yield keywords, and using them unnecessarily impairs readability. They should therefore be omitted.

Noncompliant Code Example

x = 1
while (x < 10):
    print "x is now %d" % (x)
    x += 1

Compliant Solution

x = 1
while x < 10:
    print "x is now %d" % (x)
    x += 1
python:S1722

The new style of class creation, with the declaration of a parent class, created a unified object model in Python, so that the type of an instantiated class is equal to its class. In Python 2.2-2.7, this is not the case for old-style classes. In Python 3+ all classes are new-style classes. However, since the behavior can differ from 2.2+ to 3+, explicitly inheriting from object (if there is no better candidate) is recommended.

Noncompliant Code Example

class MyClass():
    pass

Compliant Solution

class MyClass(object):
    pass
python:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Noncompliant Code Example

if a == a: # Noncompliant
    work()

if  a != a: # Noncompliant
    work()

if  a == b and a == b: # Noncompliant
    work()

if a == b or a == b: # Noncompliant
    work()

j = 5 / 5 # Noncompliant
k = 5 - 5 # Noncompliant

Exceptions

The following are ignored:

  • The expression 1 << 1

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
python:S1845

Looking at the set of methods and fields in a class and finding two that differ only by capitalization is confusing to users of the class.

This situation may simply indicate poor naming. Method names should be action-oriented, and thus contain a verb, which is unlikely in the case where both a method and a field have the same name (with or without capitalization differences). However, renaming a public method could be disruptive to callers. Therefore renaming the member is the recommended action.

Noncompliant Code Example

class SomeClass:
    lookUp = false
    def lookup():       # Non-compliant; method name differs from field name only by capitalization
        pass

Compliant Solution

class SomeClass:
    lookUp = false
    def getLookUp():
        pass
python:S1862

A chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

Noncompliant Code Example

if param == 1:
  openWindow()
elif param == 2:
  closeWindow()
elif param == 1:            # Noncompliant
  moveWindowToTheBackground()

Compliant Solution

if param == 1:
  openWindow()
elif param == 2:
  closeWindow()
elif param == 3:
  moveWindowToTheBackground()

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
python:S2325

Class methods that don't access instance data can and should be static because they yield more performant code.

To implement a static method in Python one should use either @classmethod or @staticmethod. A class method receives the class as implicit first argument, just like an instance method receives the instance. A static method does not receive an implicit first argument.

Noncompliant Code Example

class Utilities:
    def do_the_thing(self, arg1, arg2, ...):  # Noncompliant
        #...

Compliant Solution

class Utilities:
    @classmethod
    def do_the_thing(cls, arg1, arg2, ...):
        #...

or

class Utilities:
    @staticmethod
    def do_the_thing(arg1, arg2, ...):
        #...

Exceptions

Methods which raise or may raise a NotImplementedError are ignored.

python:S2711

yield and return only make sense in the context of functions. Using them outside a function raises a SyntaxError. To break out of a loop, use break instead.

Noncompliant Code Example

class MyClass:
    while True:
        return False #Noncompliant
python:S2712

Functions that use yield are known as "generators", and generators cannot return values. Similarly, functions that use return cannot use yield. Doing so will cause a SyntaxError.

Noncompliant Code Example

def adder(n):
     num = 0
     while num < n:
         yield num
         num += 1
     return num  #Noncompliant
python:S2733

The __exit__ method is invoked with four arguments: self, type, value and traceback. Leave one of these out of the method declaration and the result will be a TypeError at runtime.

Noncompliant Code Example

class MyClass:
   def __enter__(self):
       pass
   def __exit__(self, exc_type, exc_val):  # Noncompliant
       pass
python:S2734

By contract, every Python function returns something, even if it's the None value, which can be returned implicitly by omitting the return statement, or explicitly.

The __init__ method is required to return None. A TypeError will be raised if the __init__ method either yields or returns any expression other than None. Returning some expression that evaluates to None will not raise an error, but is considered bad practice.

Noncompliant Code Example

class MyClass(object):
    def __init__(self):
        self.message = 'Hello'
        return self  # Noncompliant

Compliant Solution

class MyClass(object):
    def __init__(self):
        self.message = 'Hello'
python:S2772

The use of a pass statement where it's not required by the syntax is pure cruft and should be removed.

Noncompliant Code Example

    def __init__(self, log="", who="", date=0, files=[]):
        self.log = log
        self.files = files
        self.who = who
        self.date = date
        pass    # Noncompliant

    def lookup():
        pass    # Compliant; method can't be empty

Compliant Solution

    def __init__(self, log="", who="", date=0, files=[]):
        self.log = log
        self.files = files
        self.who = who
        self.date = date

    def lookup():
        pass
ruby:ParsingError

When the parser fails, it is possible to record the failure as an issue on the file. This way, not only is it possible to track the number of files that do not parse but also to easily find out why they do not parse.

ruby:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

ruby:S101

Shared coding conventions allow teams to collaborate effectively. This rule allows to check that all class names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression ^[A-Z][a-zA-Z0-9]*$:

class my_class
  ...
end

Compliant Solution

class MyClass
  ...
end
ruby:S103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

ruby:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

ruby:S105

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

ruby:S1067

The complexity of an expression is defined by the number of &&, || and condition ? ifTrue : ifFalse operators it contains.

A single expression's complexity should not become too high to keep the code readable.

Noncompliant Code Example

With the default threshold value of 3:

if ((condition1 && condition2) || (condition3 && condition4)) && condition5
  ...
end

Compliant Solution

if (myFirstCondition() || mySecondCondition()) && myLastCondition()
  ...
end
ruby:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

ruby:S108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

def compute(a, b)
  sum = a + b
  if  sum > 0 # Noncompliant; empty on purpose or missing piece of code?
  end
  puts "Result: #{sum}"
end

Compliant Solution

def compute(a, b)
  sum = a + b
  if  sum > 0
    puts "Positive result"
  end
  puts "Result: #{sum}"
end

Exceptions

When a block contains a comment, this block is not considered to be empty.

while and unless loops are also exception to the rule.

while @order.process_next; end # Compliant
ruby:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

x = (y / 2 + 1)  # Compliant even if the parenthesis are ignored by the compiler

if a && ((x+y > 0))  # Noncompliant
  # ...
end

return ((x + 1)) # Noncompliant

Compliant Solution

x = (y / 2 + 1)

if a && (x+y > 0)
  # ...
end

return (x + 1)
ruby:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

def divide(numerator, denominator)
  return numerator / denominator             # FIXME denominator value might be 0
end

See

ruby:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

def do_something()
   # TODO
end

See

ruby:S1145

if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.

There are three possible causes for the presence of such code:

  • An if statement was changed during debugging and that debug code has been committed.
  • Some value was left unset.
  • Some logic is not doing what the programmer thought it did.

In any of these cases, unconditional if statements should be removed.

Noncompliant Code Example

if true
  doSomething()
end
...
if false
  doSomethingElse()
end

Compliant Solution

doSomething()
...

See

  • MITRE, CWE-489 - Leftover Debug Code
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
ruby:S1151

The case statement should be used only to clearly define some new branches in the control flow. As soon as a when clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the case clause should be extracted into a dedicated function.

Noncompliant Code Example

With the threshold set at 5:

case myVariable
when 0 then # Noncompliant: 6 lines till next "when"
    methodCall1("")
    methodCall2("")
    methodCall3("")
    methodCall4("")
    methodCall5("")
    methodCall6("")
when 1
   # ...
end

Compliant Solution

case myVariable
when 0 then
  doSomething()
when 1
   # ...
end
...
def doSomething()
    methodCall1("")
    methodCall2("")
    methodCall3("")
    methodCall4("")
    methodCall5("")
    methodCall6("")
end
ruby:S117

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a function or block parameter name does not match the provided regular expression.

ruby:S1172

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

See

  • MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions.
  • MISRA C:2012, 2.7 - There should be no unused parameters in functions
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
ruby:S1186

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

  • 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.
ruby:S1192

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.

Exceptions

To prevent generating some false-positives, literals having less than 5 characters are excluded.

ruby:S122

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

if someCondition; puts "hello"; end

Compliant Solution

if someCondition
  puts "hello"
end
ruby:S126

This rule applies whenever an if statement is followed by one or more elsif statements; the final elsif should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final else clause in a case statement.

Noncompliant Code Example

if x == 0
  doSomething
elsif x == 1
  doSomethingElse
end

Compliant Solution

if x == 0
  doSomething
elsif x == 1
  doSomethingElse
else
  raise 'An error has occured'
end

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
ruby:S131

The requirement for a final else clause is defensive programming. The clause should either take appropriate action, or contain a suitable comment as to why no action is taken.

Noncompliant Code Example

case param
  when 1
    do_something()
  when 2
    do_something_else()
end

Compliant Solution

case param
  when 1
    do_something()
  when 2
    do_something_else()
  else
    handle_error('error_message')
end

See

  • MISRA C:2004, 15.0 - The MISRA C switch syntax shall be used.
  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-3 - A switch statement shall be a well-formed switch statement.
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.1 - All switch statements shall be well-formed
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
  • MITRE, CWE-478 - Missing Default Case in Switch Statement
  • CERT, MSC01-C. - Strive for logical completeness
ruby:S1314

Integer literals starting with a zero are octal rather than decimal values. While using octal values is fully supported, most developers do not have experience with them. They may not recognize octal values as such, mistaking them instead for decimal values.

Noncompliant Code Example

my_number = 023 # Noncompliant. my_number will hold 19, not 23 - was this really expected?

Compliant Solution

my_number = 23

Exceptions

This rule does not apply to values smaller than 8 and octal values having 3 digits, since 3 digits octal values are often used as file permission masks.

Example:

permission_mask = 0777
day_of_month = 03

See

  • MISRA C:2004, 7.1 - Octal constants (other than zero) and octal escape sequences shall not be used.
  • MISRA C++:2008, 2-13-2 - Octal constants (other than zero) and octal escape sequences (other than "\0") shall not be used
  • MISRA C:2012, 7.1 - Octal constants shall not be used
  • CERT, DCL18-C. - Do not begin integer constants with 0 when specifying a decimal value
  • CERT, DCL50-J. - Use visually distinct identifiers
ruby:S134

Nested if, for, while, until, case and begin...rescue statements are key ingredients for making what's known as "Spaghetti code".

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

ruby:S138

A function that grows too large tends to aggregate too many responsibilities.

Such functions inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions which focus on well-defined tasks.

Those smaller functions will not only be easier to understand, but also probably easier to test.

ruby:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

#
# SonarQube, open source software quality management tool.
# Copyright (C) 2008-2018 SonarSource
# mailto:contact AT sonarsource DOT com
#
# SonarQube is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 3 of the License, or (at your option) any later version.
#
# SonarQube is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#
ruby:S1479

When case statements have a large number of clauses, it is usually an attempt to map two sets of data. A real Hash structure would be more readable and maintainable, and should be used instead.

ruby:S1481

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.

ruby:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

def set_name(name)
  name = name
end

Compliant Solution

def set_name(name)
  @name = name
end

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
ruby:S1763

Jump statements (return, break and next) move control flow out of the current code block. So any statements that come after a jump are dead code.

Noncompliant Code Example

def foo(a)
  i = 10
  return a + i    # Noncompliant
  i += 1          # dead code
end

Compliant Solution

def foo(a)
  i = 10
  return a + i
end

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code
  • MISRA C++:2008, 0-1-9 - There shall be no dead code
  • MISRA C:2012, 2.1 - A project shall not contain unreachable code
  • MISRA C:2012, 2.2 - There shall be no dead code
  • MITRE, CWE-561 - Dead Code
  • CERT, MSC56-J. - Detect and remove superfluous code and values
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
ruby:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Exceptions

This rule ignores *, +, and =.

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
ruby:S1821

Nested case structures are difficult to understand because you can easily confuse the cases of an inner case as belonging to an outer statement. Therefore nested case statements should be avoided.

Specifically, you should structure your code to avoid the need for nested case statements, but if you cannot, then consider moving the inner case to another function.

Noncompliant Code Example

def foo(n, m)
  case n
  when 0
      case m  # Noncompliant; nested case
      when 0 then puts "0"
        # ...
      end
  when 1 then puts "1"
  else puts "2"
  end
end

Compliant Solution

def foo(n, m)
  case n
  when 0
    bar(m)
  when 1 then puts "1"
  else puts "2"
  end
end

def bar(m)
  case m
  when 0 then puts "0"
    # ...
  end
end
ruby:S1862

A case and a chain of if/elsif statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

For a case, the second when will never be executed, rendering it dead code. Worse there is the risk in this situation that future maintenance will be done on the dead case, rather than on the one that's actually used.

Noncompliant Code Example

if param == 1
  openWindow()
elsif param == 2
  closeWindow()
elsif param == 1  # Noncompliant
  moveWindowToTheBackground()
end

case i
  when 1
    # ...
  when 3
    # ...
  when 1  # Noncompliant
    # ...
  else
    # ...
end

Compliant Solution

if param == 1
  openWindow()
elsif param == 2
  closeWindow()
elsif param == 3
  moveWindowToTheBackground()
end

case i
  when 1
    # ...
  when 3
    # ...
  else
    # ...
end

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
ruby:S1871

Having two when clauses in a case statement or two branches in an if chain 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 chain they should be combined, or for a case, duplicates should be refactored.

Noncompliant Code Example

case i
  when 1
    doFirstThing()
    doSomething()
  when 2
    doSomethingDifferent()
  when 3 # Noncompliant; duplicates case 1's implementation
    doFirstThing()
    doSomething()
  else
    doTheRest()
end

if a >= 0 && a < 10
  doFirstThing()
  doTheThing()
elsif a >= 10 && a < 20
  doTheOtherThing()
elsif a >= 20 && a < 50
  doFirstThing()
  doTheThing()   # Noncompliant; duplicates first condition
else
  doTheRest()
end

Exceptions

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a case statement that contain a single line of code.

if a ==
  doSomething()  # no issue, usually this is done on purpose to increase the readability
elsif a == 2
  doSomethingElse()
else
  doSomething()
end

But this exception does not apply to if chains without else-s, or to case-es without else clauses when all branches have the same single line of code. In case of if chains with else-s, or of case-es with else clauses, rule S3923 raises a bug.

if a == 1
  doSomething()  # Noncompliant, this might have been done on purpose but probably not
elsif a == 2
  doSomething()
end
ruby:S1940

It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.

Noncompliant Code Example

if  !(a == 2)  # Noncompliant
  # ...
end

b = !(a < 10) # Noncompliant

Compliant Solution

if a != 2
  # ...
end
b = (a >= 10)
ruby:S2757

The use of operators pairs ( =+, =- or =! ) where the reversed, single operator was meant (+=, -= or !=) will compile and run, but not produce the expected results.

This rule raises an issue when =+, =-, or =! is used without any spacing between the two operators and when there is at least one whitespace character after.

Noncompliant Code Example

target = -5
num = 3

target =- num # Noncompliant; target = -3. Is that really what's meant?
target =+ num # Noncompliant; target = 3

Compliant Solution

target = -5
num = 3

target = -num # Compliant; intent to assign inverse value of num is clear
target += num
ruby:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

ruby:S3923

Having all branches in a case or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a case/if chain at all.

Noncompliant Code Example

if b == 0  # Noncompliant
  doOneMoreThing()
else
  doOneMoreThing()
end

b = a > 12 ? 4 : 4;  # Noncompliant

case i  # Noncompliant
  when 1
    doSomething()
  when 2
    doSomething()
  when 3
    doSomething()
  else
    doSomething()
end

Exceptions

This rule does not apply to if chains or case-es without else-s.

if b == 0 # no issue, this could have been done on purpose to make the code more readable
  doSomething()
elsif b == 1
  doSomething()
end
ruby:S4144

When two methods have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, one implementation should invoke the other.

Noncompliant Code Example

class Box
  def initialize(length, width, height)
    @length, @width, @height = length, width, height
  end

  def getVolume
    area = @length * @width
    return area * @height
  end

  def getArea                  # Noncompliant, implementation is identical to "getVolume"
    area = @length * @width
    return area * @height
  end
end

Compliant Solution

class Box
  def initialize(length, width, height)
    @length, @width, @height = length, width, height
  end

  def getVolume
    return getArea * @height
  end

  def getArea
    return @length * @width
  end
end

Exceptions

Methods with fewer than 2 statements are ignored.

ruby:S4663

An empty multi-line comment is likely to be a mistake and doesn't help to improve the readability of the code. For these reasons, it should be removed.

Noncompliant Code Example

=begin
=end

=begin


=end
squid:CallToDeprecatedMethod

Once deprecated, classes, and interfaces, and their members should be avoided, rather than used, inherited or extended. Deprecation is a warning that the class or interface has been superseded, and will eventually be removed. The deprecation period allows you to make a smooth transition away from the aging, soon-to-be-retired technology.

Noncompliant Code Example

/**
 * @deprecated  As of release 1.3, replaced by {@link #Fee}
 */
@Deprecated
public class Fum { ... }

public class Foo {
  /**
   * @deprecated  As of release 1.7, replaced by {@link #doTheThingBetter()}
   */
  @Deprecated
  public void doTheThing() { ... }

  public void doTheThingBetter() { ... }
}

public class Bar extends Foo {
  public void doTheThing() { ... } // Noncompliant; don't override a deprecated method or explicitly mark it as @Deprecated
}

public class Bar extends Fum {  // Noncompliant; Fum is deprecated

  public void myMethod() {
    Foo foo = new Foo();  // okay; the class isn't deprecated
    foo.doTheThing();  // Noncompliant; doTheThing method is deprecated
  }
}

See

squid:CallToFileDeleteOnExitMethod

Use of File.deleteOnExit() is not recommended for the following reasons:

  • The deletion occurs only in the case of a normal JVM shutdown but not when the JVM crashes or is killed.
  • For each file handler, the memory associated with the handler is released only at the end of the process.

Noncompliant Code Example

File file = new File("file.txt");
file.deleteOnExit();  // Noncompliant
squid:ClassCyclomaticComplexity

The Cyclomatic Complexity is measured by the number of && and || operators and if, while, do, for, ?:, catch, switch, case, return and throw statements in the body of a class plus one for each constructor, method, static initializer, or instance initializer in the class. The last return statement in method, if exists, is not taken into account.

Even when the Cyclomatic Complexity of a class is very high, this complexity might be well distributed among all methods. Nevertheless, most of the time, a very complex class is a class which breaks the Single Responsibility Principle and which should be re-factored to be split in several classes.

Deprecated

This rule is deprecated, and will eventually be removed.

squid:ClassVariableVisibilityCheck

Public class variable fields do not respect the encapsulation principle and has three main disadvantages:

  • Additional behavior such as validation cannot be added.
  • The internal representation is exposed, and cannot be changed afterwards.
  • Member values are subject to change from anywhere in the code and may not meet the programmer's assumptions.

By using private attributes and accessor methods (set and get), unauthorized modifications are prevented.

Noncompliant Code Example

public class MyClass {

  public static final int SOME_CONSTANT = 0;     // Compliant - constants are not checked

  public String firstName;                       // Noncompliant

}

Compliant Solution

public class MyClass {

  public static final int SOME_CONSTANT = 0;     // Compliant - constants are not checked

  private String firstName;                      // Compliant

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

}

Exceptions

Because they are not modifiable, this rule ignores public final fields.

See

squid:EmptyFile

Files with no lines of code clutter a project and should be removed.

Noncompliant Code Example

//package org.foo;
//
//public class Bar {}
squid:LabelsShouldNotBeUsedCheck

Labels are not commonly used in Java, and many developers do not understand how they work. Moreover, their usage makes the control flow harder to follow, which reduces the code's readability.

Noncompliant Code Example

int matrix[][] = {
  {1, 2, 3},
  {4, 5, 6},
  {7, 8, 9}
};

outer: for (int row = 0; row < matrix.length; row++) {   // Non-Compliant
  for (int col = 0; col < matrix[row].length; col++) {
    if (col == row) {
      continue outer;
    }
    System.out.println(matrix[row][col]);                // Prints the elements under the diagonal, i.e. 4, 7 and 8
  }
}

Compliant Solution

for (int row = 1; row < matrix.length; row++) {          // Compliant
  for (int col = 0; col < row; col++) {
    System.out.println(matrix[row][col]);                // Also prints 4, 7 and 8
  }
}
squid:LeftCurlyBraceStartLineCheck

Shared coding conventions make it possible to collaborate efficiently. This rule makes it mandatory to place the open curly brace at the beginning of a line.

Noncompliant Code Example

public void myMethod {  // Noncompliant
  if(something) {  // Noncompliant
    executeTask();
  } else {  // Noncompliant
    doSomethingElse();
  }
}

Compliant Solution

public void myMethod
{
  if(something)
  {
    executeTask();
  } else
  {
    doSomethingElse();
  }
}
squid:MethodCyclomaticComplexity

The cyclomatic complexity of methods should not exceed a defined threshold.

Complex code can perform poorly and will in any case be difficult to understand and therefore to maintain.

Exceptions

While having a large number of fields in a class may indicate that it should be split, this rule nonetheless ignores high complexity in equals and hashCode methods.

squid:MissingDeprecatedCheck

Deprecation should be marked with both the @Deprecated annotation and @deprecated Javadoc tag. The annotation enables tools such as IDEs to warn about referencing deprecated elements, and the tag can be used to explain when it was deprecated, why, and how references should be refactored.

Further, Java 9 adds two additional arguments to the annotation:

  • since allows you to describe when the deprecation took place
  • forRemoval, indicates whether the deprecated element will be removed at some future date

If your compile level is Java 9 or higher, you should be using one or both of these arguments.

Noncompliant Code Example

class MyClass {

  @Deprecated
  public void foo1() {
  }

  /**
    * @deprecated
    */
  public void foo2() {    // Noncompliant
  }

}

Compliant Solution

class MyClass {

  /**
    * @deprecated (when, why, refactoring advice...)
    */
  @Deprecated
  public void foo1() {
  }

  /**
    * Java >= 9
    * @deprecated (when, why, refactoring advice...)
    */
  @Deprecated(since="5.1")
  public void foo2() {
  }

  /**
    * Java >= 9
    * @deprecated (when, why, refactoring advice...)
    */
  @Deprecated(since="4.2", forRemoval=true)
  public void foo3() {
  }

}

Exceptions

The members and methods of a deprecated class or interface are ignored by this rule. The classes and interfaces themselves are still subject to it.

/**
 * @deprecated (when, why, etc...)
 */
@Deprecated
class Qix  {

  public void foo() {} // Compliant; class is deprecated

}

/**
 * @deprecated (when, why, etc...)
 */
@Deprecated
interface Plop {

  void bar();

}
squid:ObjectFinalizeOverridenCallsSuperFinalizeCheck

Overriding the Object.finalize() method must be done with caution to dispose some system resources.

Calling the super.finalize() at the end of this method implementation is highly recommended in case parent implementations must also dispose some system resources.

Noncompliant Code Example

protected void finalize() {   // Noncompliant; no call to super.finalize();
  releaseSomeResources();
}

protected void finalize() {
  super.finalize();  // Noncompliant; this call should come last
  releaseSomeResources();
}

Compliant Solution

protected void finalize() {
  releaseSomeResources();
  super.finalize();
}

See

squid:ParsingError

When the Java parser fails, it is possible to record the failure as a violation on the file. This way, not only it is possible to track the number of files that do not parse but also to easily find out why they do not parse.

squid:RightCurlyBraceSameLineAsNextBlockCheck

Shared coding conventions make it possible for a team to collaborate efficiently.

This rule makes it mandatory to place closing curly braces on the same line as the next else, catch or finally keywords.

Noncompliant Code Example

public void myMethod() {
  if(something) {
    executeTask();
  } else if (somethingElse) {
    doSomethingElse();
  }
  else {                               // Noncompliant
     generateError();
  }

  try {
    generateOrder();
  } catch (Exception e) {
    log(e);
  }
  finally {                            // Noncompliant
    closeConnection();
  }
}

Compliant Solution

public void myMethod() {
  if(something) {
    executeTask();
  } else if (somethingElse) {
    doSomethingElse();
  } else {
     generateError();
  }

  try {
    generateOrder();
  } catch (Exception e) {
    log(e);
  } finally {
    closeConnection();
  }
}
squid:S00104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

squid:S00108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

for (int i = 0; i < 42; i++){}  // Empty on purpose or missing piece of code ?

Exceptions

When a block contains a comment, this block is not considered to be empty unless it is a synchronized block. synchronized blocks are still considered empty even with comments because they can still affect program flow.

squid:S00112

Using such generic exceptions as Error, RuntimeException, Throwable, and Exception prevents calling methods from handling true, system-generated exceptions differently than application-generated errors.

Noncompliant Code Example

public void foo(String bar) throws Throwable {  // Noncompliant
  throw new RuntimeException("My Message");     // Noncompliant
}

Compliant Solution

public void foo(String bar) {
  throw new MyOwnRuntimeException("My Message");
}

Exceptions

Generic exceptions in the signatures of overriding methods are ignored, because overriding method has to follow signature of the throw declaration in the superclass. The issue will be raised on superclass declaration of the method (or won't be raised at all if superclass is not part of the analysis).

@Override
public void myMethod() throws Exception {...}

Generic exceptions are also ignored in the signatures of methods that make calls to methods that throw generic exceptions.

public void myOtherMethod throws Exception {
  doTheThing();  // this method throws Exception
}

See

squid:S00113

Some tools work better when files end with an empty line.

This rule simply generates an issue if it is missing.

For example, a Git diff looks like this if the empty line is missing at the end of the file:

+class Test {
+}
\ No newline at end of file
squid:S00118

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all abstract class names match a provided regular expression. If a non-abstract class match the regular expression, an issue is raised to suggest to either make it abstract or to rename it.

Noncompliant Code Example

With the default regular expression: ^Abstract[A-Z][a-zA-Z0-9]*$:

abstract class MyClass { // Noncompliant
}

class AbstractLikeClass { // Noncompliant
}

Compliant Solution

abstract class MyAbstractClass {
}

class LikeClass {
}
squid:S106

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

  • The user must be able to easily retrieve the logs
  • The format of all logged message must be uniform to allow the user to easily read the log
  • Logged data must actually be recorded
  • Sensitive data must only be logged securely

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

System.out.println("My Message");  // Noncompliant

Compliant Solution

logger.log("My Message");

See

squid:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if (file != null) {
  if (file.isFile() || file.isDirectory()) {
    /* ... */
  }
}

Compliant Solution

if (file != null && isFileOrDirectory(file)) {
  /* ... */
}

private static boolean isFileOrDirectory(File file) {
  return file.isFile() || file.isDirectory();
}
squid:S1067

The complexity of an expression is defined by the number of &&, || and condition ? ifTrue : ifFalse operators it contains.

A single expression's complexity should not become too high to keep the code readable.

Noncompliant Code Example

With the default threshold value of 3:

if (((condition1 && condition2) || (condition3 && condition4)) && condition5) { ... }

Compliant Solution

if ( (myFirstCondition() || mySecondCondition()) && myLastCondition()) { ... }
squid:S1068

If a private field is declared but not used in the program, it can be considered dead code and should therefore be removed. This will improve maintainability because developers will not wonder what the variable is used for.

Note that this rule does not take reflection into account, which means that issues will be raised on private fields that are only accessed using the reflection API.

Noncompliant Code Example

public class MyClass {
  private int foo = 42;

  public int compute(int a) {
    return a * 42;
  }

}

Compliant Solution

public class MyClass {
  public int compute(int a) {
    return a * 42;
  }
}

Exceptions

The Java serialization runtime associates with each serializable class a version number, called serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization.

A serializable class can declare its own serialVersionUID explicitly by declaring a field named serialVersionUID that must be static, final, and of type long. By definition those serialVersionUID fields should not be reported by this rule:

public class MyClass implements java.io.Serializable {
  private static final long serialVersionUID = 42L;
}

Moreover, this rule doesn't raise any issue on annotated fields.

squid:S1075

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.

Noncompliant Code Example

public class Foo {
  public Collection<User> listUsers() {
    File userList = new File("/home/mylogin/Dev/users.txt"); // Non-Compliant
    Collection<User> users = parse(userList);
    return users;
  }
}

Compliant Solution

public class Foo {
  // Configuration is a class that returns customizable properties: it can be mocked to be injected during tests.
  private Configuration config;
  public Foo(Configuration myConfig) {
    this.config = myConfig;
  }
  public Collection<User> listUsers() {
    // Find here the way to get the correct folder, in this case using the Configuration object
    String listingFolder = config.getProperty("myApplication.listingFolder");
    // and use this parameter instead of the hard coded path
    File userList = new File(listingFolder, "users.txt"); // Compliant
    Collection<User> users = parse(userList);
    return users;
  }
}

See

squid:S109

A magic number is a number that comes out of nowhere, and is directly used in a statement. Magic numbers are often used, for instance to limit the number of iterations of a loops, to test the value of a property, etc.

Using magic numbers may seem obvious and straightforward when you're writing a piece of code, but they are much less obvious and straightforward at debugging time.

That is why magic numbers must be demystified by first being assigned to clearly named variables before being used.

-1, 0 and 1 are not considered magic numbers.

Noncompliant Code Example

public static void doSomething() {
	for(int i = 0; i < 4; i++){                 // Noncompliant, 4 is a magic number
		...
	}
}

Compliant Solution

public static final int NUMBER_OF_CYCLES = 4;
public static void doSomething() {
  for(int i = 0; i < NUMBER_OF_CYCLES ; i++){
    ...
  }
}

Exceptions

This rule ignores hashCode methods.

squid:S1125

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

Noncompliant Code Example

if (booleanMethod() == true) { /* ... */ }
if (booleanMethod() == false) { /* ... */ }
if (booleanMethod() || false) { /* ... */ }
doSomething(!false);
doSomething(booleanMethod() == true);

booleanVariable = booleanMethod() ? true : false;
booleanVariable = booleanMethod() ? true : exp;
booleanVariable = booleanMethod() ? false : exp;
booleanVariable = booleanMethod() ? exp : true;
booleanVariable = booleanMethod() ? exp : false;

Compliant Solution

if (booleanMethod()) { /* ... */ }
if (!booleanMethod()) { /* ... */ }
if (booleanMethod()) { /* ... */ }
doSomething(true);
doSomething(booleanMethod());

booleanVariable = booleanMethod();
booleanVariable = booleanMethod() || exp;
booleanVariable = !booleanMethod() && exp;
booleanVariable = !booleanMethod() || exp;
booleanVariable = booleanMethod() && exp;
squid:S1132

It is preferable to place string literals on the left-hand side of an equals() or equalsIgnoreCase() method call.

This prevents null pointer exceptions from being raised, as a string literal can never be null by definition.

Noncompliant Code Example

String myString = null;

System.out.println("Equal? " + myString.equals("foo"));                        // Noncompliant; will raise a NPE
System.out.println("Equal? " + (myString != null && myString.equals("foo")));  // Noncompliant; null check could be removed

Compliant Solution

System.out.println("Equal?" + "foo".equals(myString));                         // properly deals with the null case
squid:S1133

This rule is meant to be used as a way to track code which is marked as being deprecated. Deprecated code should eventually be removed.

Noncompliant Code Example

class Foo {
  /**
   * @deprecated
   */
  public void foo() {    // Noncompliant
  }

  @Deprecated            // Noncompliant
  public void bar() {
  }

  public void baz() {    // Compliant
  }
}
squid:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

int divide(int numerator, int denominator) {
  return numerator / denominator;              // FIXME denominator value might be  0
}

See

squid:S1142

Having too many return statements in a method increases the method's essential complexity because the flow of execution is broken each time a return statement is encountered. This makes it harder to read and understand the logic of the method.

Noncompliant Code Example

With the default threshold of 3:

public boolean myMethod() { // Noncompliant; there are 4 return statements
  if (condition1) {
    return true;
  } else {
    if (condition2) {
      return false;
    } else {
      return true;
    }
  }
  return false;
}
squid:S1147

Calling System.exit(int status) or Rutime.getRuntime().exit(int status) calls the shutdown hooks and shuts downs the entire Java virtual machine. Calling Runtime.getRuntime().halt(int) does an immediate shutdown, without calling the shutdown hooks, and skipping finalization.

Each of these methods should be used with extreme care, and only when the intent is to stop the whole Java process. For instance, none of them should be called from applications running in a J2EE container.

Noncompliant Code Example

System.exit(0);
Runtime.getRuntime().exit(0);
Runtime.getRuntime().halt(0);

Exceptions

These methods are ignored inside main.

See

squid:S1149

Early classes of the Java API, such as Vector, Hashtable and StringBuffer, were synchronized to make them thread-safe. Unfortunately, synchronization has a big negative impact on performance, even when using these collections from a single thread.

It is better to use their new unsynchronized replacements:

  • ArrayList or LinkedList instead of Vector
  • Deque instead of Stack
  • HashMap instead of Hashtable
  • StringBuilder instead of StringBuffer

Noncompliant Code Example

Vector cats = new Vector();

Compliant Solution

ArrayList cats = new ArrayList();

Exceptions

Use of those synchronized classes is ignored in the signatures of overriding methods.

@Override
public Vector getCats() {...}
squid:S1150

From the official Oracle Javadoc:

NOTE: The functionality of this Enumeration interface is duplicated by the Iterator interface. In addition, Iterator adds an optional remove operation, and has shorter method names. New implementations should consider using Iterator in preference to Enumeration.

Noncompliant Code Example

public class MyClass implements Enumeration {  // Non-Compliant
  /* ... */
}

Compliant Solution

public class MyClass implements Iterator {     // Compliant
  /* ... */
}
squid:S1151

The switch statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the case clause should be extracted into a dedicated method.

Noncompliant Code Example

With the default threshold of 5:

switch (myVariable) {
  case 0: // Noncompliant: 6 lines till next case
    methodCall1("");
    methodCall2("");
    methodCall3("");
    methodCall4("");
    break;
  case 1:
  ...
}

Compliant Solution

switch (myVariable) {
  case 0:
    doSomething()
    break;
  case 1:
  ...
}
...
private void doSomething(){
    methodCall1("");
    methodCall2("");
    methodCall3("");
    methodCall4("");
}
squid:S1153

Appending String.valueOf() to a String decreases the code readability.

The argument passed to String.valueOf() should be directly appended instead.

Noncompliant Code Example

public void display(int i){
  System.out.println("Output is " + String.valueOf(i));    // Noncompliant
}

Compliant Solution

public void display(int i){
  System.out.println("Output is " + i);                    // Compliant
}
squid:S1155

Using Collection.size() to test for emptiness works, but using Collection.isEmpty() makes the code more readable and can be more performant. The time complexity of any isEmpty() method implementation should be O(1) whereas some implementations of size() can be O(n).

Noncompliant Code Example

if (myCollection.size() == 0) {  // Noncompliant
  /* ... */
}

Compliant Solution

if (myCollection.isEmpty()) {
  /* ... */
}
squid:S1157

Using toLowerCase() or toUpperCase() to make case insensitive comparisons is inefficient because it requires the creation of temporary, intermediate String objects.

Noncompliant Code Example

boolean result1 = foo.toUpperCase().equals(bar);             // Noncompliant
boolean result2 = foo.equals(bar.toUpperCase());             // Noncompliant
boolean result3 = foo.toLowerCase().equals(bar.LowerCase()); // Noncompliant

Compliant Solution

boolean result = foo.equalsIgnoreCase(bar);                  // Compliant
squid:S1158

Creating temporary primitive wrapper objects only for String conversion or the use of the compareTo method is inefficient.

Instead, the static toString() or compare method of the primitive wrapper class should be used.

Noncompliant Code Example

new Integer(myInteger).toString();  // Noncompliant

Compliant Solution

Integer.toString(myInteger);        // Compliant
squid:S1160

Using checked exceptions forces method callers to deal with errors, either by propagating them or by handling them. Throwing exceptions makes them fully part of the API of the method.

But to keep the complexity for callers reasonable, methods should not throw more than one kind of checked exception.

Noncompliant Code Example

public void delete() throws IOException, SQLException {      // Noncompliant
  /* ... */
}

Compliant Solution

public void delete() throws SomeApplicationLevelException {
  /* ... */
}

Exceptions

Overriding methods are not checked by this rule and are allowed to throw several checked exceptions.

squid:S1162

The purpose of checked exceptions is to ensure that errors will be dealt with, either by propagating them or by handling them, but some believe that checked exceptions negatively impact the readability of source code, by spreading this error handling/propagation logic everywhere.

This rule verifies that no method throws a new checked exception.

Noncompliant Code Example

public void myMethod1() throws CheckedException {
  ...
  throw new CheckedException(message);   // Noncompliant
  ...
  throw new IllegalArgumentException(message); // Compliant; IllegalArgumentException is unchecked
}

public void myMethod2() throws CheckedException {  // Compliant; propagation allowed
  myMethod1();
}
squid:S1163

Throwing an exception from within a finally block will mask any exception which was previously thrown in the try or catch block, and the masked's exception message and stack trace will be lost.

Noncompliant Code Example

try {
  /* some work which end up throwing an exception */
  throw new IllegalArgumentException();
} finally {
  /* clean up */
  throw new RuntimeException();       // Noncompliant; masks the IllegalArgumentException
}

Compliant Solution

try {
  /* some work which end up throwing an exception */
  throw new IllegalArgumentException();
} finally {
  /* clean up */
}

See

  • CERT, ERR05-J. - Do not let checked exceptions escape from a finally block
squid:S1165

Exceptions are meant to represent the application's state at the point at which an error occurred.

Making all fields in an Exception class final ensures that this state:

  • Will be fully defined at the same time the Exception is instantiated.
  • Won't be updated or corrupted by a questionable error handler.

This will enable developers to quickly understand what went wrong.

Noncompliant Code Example

public class MyException extends Exception {

  private int status;                               // Noncompliant

  public MyException(String message) {
    super(message);
  }

  public int getStatus() {
    return status;
  }

  public void setStatus(int status) {
    this.status = status;
  }

}

Compliant Solution

public class MyException extends Exception {

  private final int status;

  public MyException(String message, int status) {
    super(message);
    this.status = status;
  }

  public int getStatus() {
    return status;
  }

}
squid:S1168

Returning null instead of an actual array or collection forces callers of the method to explicitly test for nullity, making them more complex and less readable.

Moreover, in many cases, null is used as a synonym for empty.

Noncompliant Code Example

public static List<Result> getResults() {
  return null;                             // Noncompliant
}

public static Result[] getResults() {
  return null;                             // Noncompliant
}

public static void main(String[] args) {
  Result[] results = getResults();

  if (results != null) {                   // Nullity test required to prevent NPE
    for (Result result: results) {
      /* ... */
    }
  }
}

Compliant Solution

public static List<Result> getResults() {
  return Collections.emptyList();          // Compliant
}

public static Result[] getResults() {
  return new Result[0];
}

public static void main(String[] args) {
  for (Result result: getResults()) {
    /* ... */
  }
}

See

  • CERT, MSC19-C. - For functions that return an array, prefer returning an empty array over a null value
  • CERT, MET55-J. - Return an empty array or collection instead of a null value for methods that return an array or collection
squid:S1170

Making a public constant just final as opposed to static final leads to duplicating its value for every instance of the class, uselessly increasing the amount of memory required to execute the application.

Further, when a non-public, final field isn't also static, it implies that different instances can have different values. However, initializing a non-static final field in its declaration forces every instance to have the same value. So such fields should either be made static or initialized in the constructor.

Noncompliant Code Example

public class Myclass {
  public final int THRESHOLD = 3;
}

Compliant Solution

public class Myclass {
  public static final int THRESHOLD = 3;    // Compliant
}

Exceptions

No issues are reported on final fields of inner classes whose type is not a primitive or a String. Indeed according to the Java specification:

An inner class is a nested class that is not explicitly or implicitly declared static. Inner classes may not declare static initializers (§8.7) or member interfaces. Inner classes may not declare static members, unless they are compile-time constant fields (§15.28).

squid:S1171

Non-static initializers are rarely used, and can be confusing for most developers because they only run when new class instances are created. When possible, non-static initializers should be refactored into standard constructors or field initializers.

Noncompliant Code Example

class MyClass {
  private static final Map<String, String> MY_MAP = new HashMap<String, String>() {

    // Noncompliant - HashMap should be extended only to add behavior, not for initialization
    {
      put("a", "b");
    }

  };
}

Compliant Solution

class MyClass {
  private static final Map<String, String> MY_MAP = new HashMap<String, String>();

  static {
    MY_MAP.put("a", "b");
  }
}

or using Guava:

class MyClass {
  // Compliant
  private static final Map<String, String> MY_MAP = ImmutableMap.of("a", "b");
}
squid:S1174

The contract of the Object.finalize() method is clear: only the Garbage Collector is supposed to call this method.

Making this method public is misleading, because it implies that any caller can use it.

Noncompliant Code Example

public class MyClass {

  @Override
  public void finalize() {    // Noncompliant
    /* ... */
  }
}

See

squid:S1175

Object.finalize() is called by the Garbage Collector at some point after the object becomes unreferenced.

In general, overloading Object.finalize() is a bad idea because:

  • The overload may not be called by the Garbage Collector.
  • Users are not expected to call Object.finalize() and will get confused.

But beyond that it's a terrible idea to name a method "finalize" if it doesn't actually override Object.finalize().

Noncompliant Code Example

public int finalize(int someParameter) {        // Noncompliant
  /* ... */
}

Compliant Solution

public int someBetterName(int someParameter) {  // Compliant
  /* ... */
}
squid:S1182

Cloneable is the marker Interface that indicates that clone() may be called on an object. Overriding clone() without implementing Cloneable can be useful if you want to control how subclasses clone themselves, but otherwise, it's probably a mistake.

The usual convention for Object.clone() according to Oracle's Javadoc is:

  1. x.clone() != x
  2. x.clone().getClass() == x.getClass()
  3. x.clone().equals\(x\)

Obtaining the object that will be returned by calling super.clone() helps to satisfy those invariants:

  1. super.clone() returns a new object instance
  2. super.clone() returns an object of the same type as the one clone() was called on
  3. Object.clone() performs a shallow copy of the object's state

Noncompliant Code Example

class BaseClass {  // Noncompliant; should implement Cloneable
  @Override
  public Object clone() throws CloneNotSupportedException {    // Noncompliant; should return the super.clone() instance
    return new BaseClass();
  }
}

class DerivedClass extends BaseClass implements Cloneable {
  /* Does not override clone() */

  public void sayHello() {
    System.out.println("Hello, world!");
  }
}

class Application {
  public static void main(String[] args) throws Exception {
    DerivedClass instance = new DerivedClass();
    ((DerivedClass) instance.clone()).sayHello();              // Throws a ClassCastException because invariant #2 is violated
  }
}

Compliant Solution

class BaseClass implements Cloneable {
  @Override
  public Object clone() throws CloneNotSupportedException {    // Compliant
    return super.clone();
  }
}

class DerivedClass extends BaseClass implements Cloneable {
  /* Does not override clone() */

  public void sayHello() {
    System.out.println("Hello, world!");
  }
}

class Application {
  public static void main(String[] args) throws Exception {
    DerivedClass instance = new DerivedClass();
    ((DerivedClass) instance.clone()).sayHello();              // Displays "Hello, world!" as expected. Invariant #2 is satisfied
  }
}

See

squid:S1185

Overriding a method just to call the same method from the super class without performing any other actions is useless and misleading. The only time this is justified is in final overriding methods, where the effect is to lock in the parent class behavior. This rule ignores such overrides of equals, hashCode and toString.

Noncompliant Code Example

public void doSomething() {
  super.doSomething();
}

@Override
public boolean isLegal(Action action) {
  return super.isLegal(action);
}

Compliant Solution

@Override
public boolean isLegal(Action action) {         // Compliant - not simply forwarding the call
  return super.isLegal(new Action(/* ... */));
}

@Id
@Override
public int getId() {                            // Compliant - there is annotation different from @Override
  return super.getId();
}
squid:S1186

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

  • 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 UnsupportedOperationException should be thrown.
  • The method is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.

Noncompliant Code Example

public void doSomething() {
}

public void doSomethingElse() {
}

Compliant Solution

@Override
public void doSomething() {
  // Do nothing because of X and Y.
}

@Override
public void doSomethingElse() {
  throw new UnsupportedOperationException();
}

Exceptions

Default (no-argument) constructors are ignored when there are other constructors in the class, as are empty methods in abstract classes.

public abstract class Animal {
  void speak() {  // default implementation ignored
  }
}
squid:S1188

Anonymous classes and lambdas (with Java 8) are a very convenient and compact way to inject a behavior without having to create a dedicated class. But those anonymous inner classes and lambdas should be used only if the behavior to be injected can be defined in a few lines of code, otherwise the source code can quickly become unreadable.

squid:S1190

Through Java's evolution keywords have been added. While code that uses those words as identifiers may be compilable under older versions of Java, it will not be under modern versions.

Following keywords are marked as invalid identifiers

Keyword Added
_ 9
enum 5.0

assert and strictfp are another example of valid identifiers which became keywords in later versions, however as documented in SONARJAVA-285, it is not easily possible to support parsing of the code for such old versions, therefore they are not supported by this rule.

Noncompliant Code Example

public void doSomething() {
  int enum = 42;            // Noncompliant
  String _ = "";   // Noncompliant
}

Compliant Solution

public void doSomething() {
  int magic = 42;
}
squid:S1191

Classes in the sun.* or com.sun.* packages are considered implementation details, and are not part of the Java API.

They can cause problems when moving to new versions of Java because there is no backwards compatibility guarantee. Similarly, they can cause problems when moving to a different Java vendor, such as OpenJDK.

Such classes are almost always wrapped by Java API classes that should be used instead.

Noncompliant Code Example

import com.sun.jna.Native;     // Noncompliant
import sun.misc.BASE64Encoder; // Noncompliant
squid:S1193

Multiple catch blocks of the appropriate type should be used instead of catching a general exception, and then testing on the type.

Noncompliant Code Example

try {
  /* ... */
} catch (Exception e) {
  if(e instanceof IOException) { /* ... */ }         // Noncompliant
  if(e instanceof NullPointerException{ /* ... */ }  // Noncompliant
}

Compliant Solution

try {
  /* ... */
} catch (IOException e) { /* ... */ }                // Compliant
} catch (NullPointerException e) { /* ... */ }       // Compliant

See

  • CERT, ERR51-J. - Prefer user-defined exceptions over more general exception types
squid:S1194

java.lang.Error and its subclasses represent abnormal conditions, such as OutOfMemoryError, which should only be encountered by the Java Virtual Machine.

Noncompliant Code Example

public class MyException extends Error { /* ... */ }       // Noncompliant

Compliant Solution

public class MyException extends Exception { /* ... */ }   // Compliant
squid:S1199

Nested code blocks can be used to create a new scope and restrict the visibility of the variables defined inside it. Using this feature in a method typically indicates that the method has too many responsibilities, and should be refactored into smaller methods.

Noncompliant Code Example

public void evaluate(int operator) {
  switch (operator) {
    /* ... */
    case ADD: {                                // Noncompliant - nested code block '{' ... '}'
        int a = stack.pop();
        int b = stack.pop();
        int result = a + b;
        stack.push(result);
        break;
      }
    /* ... */
  }
}

Compliant Solution

public void evaluate(int operator) {
  switch (operator) {
    /* ... */
    case ADD:                                  // Compliant
      evaluateAdd();
      break;
    /* ... */
  }
}

private void evaluateAdd() {
  int a = stack.pop();
  int b = stack.pop();
  int result = a + b;
  stack.push(result);
}
squid:S1200

According to the Single Responsibility Principle, introduced by Robert C. Martin in his book "Principles of Object Oriented Design", a class should have only one responsibility:

If a class has more than one responsibility, then the responsibilities become coupled.

Changes to one responsibility may impair or inhibit the class' ability to meet the others.

This kind of coupling leads to fragile designs that break in unexpected ways when changed.

Classes which rely on many other classes tend to aggregate too many responsibilities and should be split into several smaller ones.

Nested classes dependencies are not counted as dependencies of the outer class.

Noncompliant Code Example

With a threshold of 5:

class Foo {                        // Noncompliant - Foo depends on too many classes: T1, T2, T3, T4, T5, T6 and T7
  T1 a1;                           // Foo is coupled to T1
  T2 a2;                           // Foo is coupled to T2
  T3 a3;                           // Foo is coupled to T3

  public T4 compute(T5 a, T6 b) {  // Foo is coupled to T4, T5 and T6
    T7 result = a.getResult(b);    // Foo is coupled to T7
    return result;
  }

  public static class Bar {        // Compliant - Bar depends on 2 classes: T8 and T9
    T8 a8;
    T9 a9;
  }
}
squid:S1201

"equals" as a method name should be used exclusively to override Object.equals(Object) to prevent any confusion.

It is tempting to overload the method to take a specific class instead of Object as parameter, to save the class comparison check. However, this will not work as expected when that is the only override.

Noncompliant Code Example

class MyClass {
  private int foo = 1;

  public boolean equals(MyClass o) {  // Noncompliant; does not override Object.equals(Object)
    return o != null && o.foo == this.foo;
  }

  public static void main(String[] args) {
    MyClass o1 = new MyClass();
    Object o2 = new MyClass();
    System.out.println(o1.equals(o2));  // Prints "false" because o2 an Object not a MyClass
  }
}

class MyClass2 {
  public boolean equals(MyClass2 o) {  // Ignored; `boolean equals(Object)` also present
    //..
  }

  public boolean equals(Object o) {
    //...
  }
}

Compliant Solution

class MyClass {
  private int foo = 1;

  @Override
  public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }

    MyClass other = (MyClass)o;
    return this.foo == other.foo;
  }

  /* ... */
}

class MyClass2 {
  public boolean equals(MyClass2 o) {
    //..
  }

  public boolean equals(Object o) {
    //...
  }
}
squid:S1206

According to the Java Language Specification, there is a contract between equals(Object) and hashCode():

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results.

However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

In order to comply with this contract, those methods should be either both inherited, or both overridden.

Noncompliant Code Example

class MyClass {    // Noncompliant - should also override "hashCode()"

  @Override
  public boolean equals(Object obj) {
    /* ... */
  }

}

Compliant Solution

class MyClass {    // Compliant

  @Override
  public boolean equals(Object obj) {
    /* ... */
  }

  @Override
  public int hashCode() {
    /* ... */
  }

}

See

  • MITRE, CWE-581 - Object Model Violation: Just One of Equals and Hashcode Defined
  • CERT, MET09-J. - Classes that define an equals() method must also define a hashCode() method
squid:S1210

According to the Java Comparable.compareTo(T o) documentation:

It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)).

Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact.

The recommended language is "Note: this class has a natural ordering that is inconsistent with equals."

If this rule is violated, weird and unpredictable failures can occur.

For example, in Java 5 the PriorityQueue.remove() method relied on compareTo(), but since Java 6 it has relied on equals().

Noncompliant Code Example

public class Foo implements Comparable<Foo> {
  @Override
  public int compareTo(Foo foo) { /* ... */ }      // Noncompliant as the equals(Object obj) method is not overridden
}

Compliant Solution

public class Foo implements Comparable<Foo> {
  @Override
  public int compareTo(Foo foo) { /* ... */ }      // Compliant

  @Override
  public boolean equals(Object obj) { /* ... */ }
}
squid:S1214

According to Joshua Bloch, author of "Effective Java":

The constant interface pattern is a poor use of interfaces.

That a class uses some constants internally is an implementation detail.

Implementing a constant interface causes this implementation detail to leak into the class's exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them. Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility. If a nonfinal class implements a constant interface,

all of its subclasses will have their namespaces polluted by the constants in the interface.

Noncompliant Code Example

interface Status {                      // Noncompliant
   int OPEN = 1;
   int CLOSED = 2;
}

Compliant Solution

public enum Status {                    // Compliant
  OPEN,
  CLOSED;
}

or

public final class Status {             // Compliant
   public static final int OPEN = 1;
   public static final int CLOSED = 2;
}
squid:S1215

Calling System.gc() or Runtime.getRuntime().gc() is a bad idea for a simple reason: there is no way to know exactly what will be done under the hood by the JVM because the behavior will depend on its vendor, version and options:

  • Will the whole application be frozen during the call?
  • Is the -XX:DisableExplicitGC option activated?
  • Will the JVM simply ignore the call?
  • ...

An application relying on these unpredictable methods is also unpredictable and therefore broken. The task of running the garbage collector should be left exclusively to the JVM.

squid:S1220

According to the Java Language Specification:

Unnamed packages are provided by the Java platform principally for convenience when developing small or temporary applications or when just beginning development.

To enforce this best practice, classes located in default package can no longer be accessed from named ones since Java 1.4.

Noncompliant Code Example

public class MyClass { /* ... */ }

Compliant Solution

package org.example;

public class MyClass{ /* ... */ }
squid:S1221

Naming a method tostring, hashcode() or equal is either:

  • A bug in the form of a typo. Overriding toString, Object.hashCode() (note the camelCasing) or Object.equals (note the 's' on the end) was meant, and the application does not behave as expected.
  • Done on purpose. The name however will confuse every other developer, who may not notice the naming difference, or who will think it is a bug.

In both cases, the method should be renamed.

Noncompliant Code Example

public int hashcode() { /* ... */ }  // Noncompliant

public String tostring() { /* ... */ } // Noncompliant

public boolean equal(Object obj) { /* ... */ }  // Noncompliant

Compliant Solution

@Override
public int hashCode() { /* ... */ }

@Override
public String toString() { /* ... */ }

@Override
public boolean equals(Object obj) { /* ... */ }
squid:S1223

Having a class and some of its methods sharing the same name is misleading, and leaves others to wonder whether it was done that way on purpose, or was the methods supposed to be a constructor.

Noncompliant Code Example

public class Foo {
   public Foo() {...}
   public void Foo(String label) {...}  // Noncompliant
}

Compliant Solution

public class Foo {
   public Foo() {...}
   public void foo(String label) {...}  // Compliant
}
squid:S1228

Each package in a Java project should include a package-info.java file. The purpose of this file is to document the Java package using javadoc and declare package annotations.

Compliant Solution

/**
* This package has non null parameters and is documented.
**/
@ParametersAreNonnullByDefault
package org.foo.bar;
squid:S1258

Non-abstract classes and enums with non-static, private members should explicitly initialize those members, either in a constructor or with a default value.

Noncompliant Code Example

class A { // Noncompliant
  private int field;
}

Compliant Solution

class A {
  private int field;

  A(int field) {
    this.field = field;
  }
}
squid:S1264

When only the condition expression is defined in a for loop, and the initialization and increment expressions are missing, a while loop should be used instead to increase readability.

Noncompliant Code Example

for (;condition;) { /*...*/ }

Compliant Solution

while (condition) { /*...*/ }
squid:S1310

This rule allows you to track the use of the PMD suppression comment mechanism.

Noncompliant Code Example

// NOPMD
squid:S1315

This rule allows you to track the use of the Checkstyle suppression comment mechanism.

Noncompliant Code Example

// CHECKSTYLE:OFF
squid:S1317

Instantiating a StringBuilder or a StringBuffer with a character is misleading because most Java developers would expect the character to be the initial value of the StringBuffer.

What actually happens is that the int representation of the character is used to determine the initial size of the StringBuffer.

Noncompliant Code Example

StringBuffer foo = new StringBuffer('x');   //equivalent to StringBuffer foo = new StringBuffer(120);

Compliant Solution

StringBuffer foo = new StringBuffer("x");
squid:S1319

The purpose of the Java Collections API is to provide a well defined hierarchy of interfaces in order to hide implementation details.

Implementing classes must be used to instantiate new collections, but the result of an instantiation should ideally be stored in a variable whose type is a Java Collection interface.

This rule raises an issue when an implementation class:

  • is returned from a public method.
  • is accepted as an argument to a public method.
  • is exposed as a public member.

Noncompliant Code Example

public class Employees {
  private HashSet<Employee> employees = new HashSet<Employee>();  // Noncompliant - "employees" should have type "Set" rather than "HashSet"

  public HashSet<Employee> getEmployees() {                       // Noncompliant
    return employees;
  }
}

Compliant Solution

public class Employees {
  private Set<Employee> employees = new HashSet<Employee>();      // Compliant

  public Set<Employee> getEmployees() {                           // Compliant
    return employees;
  }
}
squid:S134

Nested if, for, while, switch, 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:

if (condition1) {                  // Compliant - depth = 1
  /* ... */
  if (condition2) {                // Compliant - depth = 2
    /* ... */
    for(int i = 0; i < 10; i++) {  // Compliant - depth = 3, not exceeding the limit
      /* ... */
      if (condition4) {            // Noncompliant - depth = 4
        if (condition5) {          // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
          /* ... */
        }
        return;
      }
    }
  }
}
squid:S135

Restricting the number of break and continue statements in a loop is done in the interest of good structured programming.

One break and continue statement is acceptable in a loop, since it facilitates optimal coding. If there is more than one, the code should be refactored to increase readability.

Noncompliant Code Example

for (int i = 1; i <= 10; i++) {     // Noncompliant - 2 continue - one might be tempted to add some logic in between
  if (i % 2 == 0) {
    continue;
  }

  if (i % 3 == 0) {
    continue;
  }

  System.out.println("i = " + i);
}
squid:S138

A method that grows too large tends to aggregate too many responsibilities. Such method inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller methods which focus on well-defined tasks. Those smaller methods will not only be easier to understand, but also probably easier to test.

squid:S1444

There is no good reason to declare a field "public" and "static" without also declaring it "final". Most of the time this is a kludge to share a state among several objects. But with this approach, any object can do whatever it wants with the shared state, such as setting it to null.

Noncompliant Code Example

public class Greeter {
  public static Foo foo = new Foo();
  ...
}

Compliant Solution

public class Greeter {
  public static final Foo FOO = new Foo();
  ...
}

See

squid:S1448

A class that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor the class into smaller ones which focus on well defined topics.

squid:S1449

Failure to specify a locale when calling the methods toLowerCase(), toUpperCase() or format() on String objects means the system default encoding will be used, possibly creating problems with international characters or number representations. For instance with the Turkish language, when converting the small letter 'i' to upper case, the result is capital letter 'I' with a dot over it.

Case conversion without a locale may work fine in its "home" environment, but break in ways that are extremely difficult to diagnose for customers who use different encodings. Such bugs can be nearly, if not completely, impossible to reproduce when it's time to fix them. For locale-sensitive strings, the correct locale should always be used, but Locale.ENGLISH can be used for case-insensitive ones.

Noncompliant Code Example

myString.toLowerCase()

Compliant Solution

myString.toLowerCase(Locale.TR)

See

  • CERT, STR02-J. - Specify an appropriate locale when comparing locale-dependent data
squid:S1452

It is highly recommended not to use wildcard types as return types. Because the type inference rules are fairly complex it is unlikely the user of that API will know how to use it correctly.

Let's take the example of method returning a "List<? extends Animal>". Is it possible on this list to add a Dog, a Cat, ... we simply don't know. And neither does the compiler, which is why it will not allow such a direct use. The use of wildcard types should be limited to method parameters.

This rule raises an issue when a method returns a wildcard type.

Noncompliant Code Example

List<? extends Animal> getAnimals(){...}

Compliant Solution

List<Animal> getAnimals(){...}

or

List<Dog> getAnimals(){...}
squid:S1479

When switch statements have large sets of case clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

Exceptions

This rule ignores switches over Enums and empty, fall-through cases.

squid:S1481

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

public int numberOfMinutes(int hours) {
  int seconds = 0;   // seconds is never used
  return hours * 60;
}

Compliant Solution

public int numberOfMinutes(int hours) {
  return hours * 60;
}
squid:S1596

Since the introduction of generics in Java 5, the use of generic types such as List<String> is recommended over the use of raw ones such as List. Assigning a raw type to a generic one is not type safe, and will generate a warning. The old EMPTY_... fields of the Collections class return raw types, whereas the newer empty...() methods return generic ones.

Noncompliant Code Example

List<String> collection1 = Collections.EMPTY_LIST;  // Noncompliant
Map<String, String> collection2 = Collections.EMPTY_MAP;  // Noncompliant
Set<String> collection3 = Collections.EMPTY_SET;  // Noncompliant

Compliant Solution

List<String> collection1 = Collections.emptyList();
Map<String, String> collection2 = Collections.emptyMap();
Set<String> collection3 = Collections.emptySet();
squid:S1598

By convention, a Java class' physical location (source directories) and its logical representation (packages) should be kept in sync. Thus a Java file located at "src/org/bar/Foo.java" should have a package of "org.bar".

Unfortunately, this convention is not enforced by Java compilers, and nothing prevents a developer from making the "Foo.java" class part of the "com.apple" package, which could degrade the maintainability of both the class and its application.

Similarly, source placed in a folder with dots in its name instead of having the equivalent folder structure will compile but cause problems at run time. For instance, code with a package declaration of org.foo.bar that is placed in org/foo.bar will compile, but the classloader will always search for the class into the folder based on package structure, and will consequently expect sources to be in org/foo/bar folder. foo.bar is therefore not a proper folder name for sources.

squid:S1604

Before Java 8, the only way to partially support closures in Java was by using anonymous inner classes. But the syntax of anonymous classes may seem unwieldy and unclear.

With Java 8, most uses of anonymous inner classes should be replaced by lambdas to highly increase the readability of the source code.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 8.

Noncompliant Code Example

myCollection.stream().map(new Mapper<String,String>() {
  public String map(String input) {
    return new StringBuilder(input).reverse().toString();
  }
});

Predicate<String> isEmpty = new Predicate<String> {
    boolean test(String myString) {
        return myString.isEmpty();
    }
}

Compliant Solution

myCollection.stream().map(input -> new StringBuilder(input).reverse().toString());

Predicate<String> isEmpty = myString -> myString.isEmpty();
squid:S1607

When a test fails due, for example, to infrastructure issues, you might want to ignore it temporarily. But without some kind of notation about why the test is being ignored, it may never be reactivated. Such tests are difficult to address without comprehensive knowledge of the project, and end up polluting their projects.

This rule raises an issue for each ignored test that does not have a notation about why it is being skipped.

Noncompliant Code Example

@Ignore  // Noncompliant
@Test
public void testDoTheThing() {
  // ...

Compliant Solution

@Test
public void testDoTheThing() {
  // ...

Exceptions

The rule doesn't raise an issue if there is a comment in the @Ignore annotation

squid:S1609

A Single Abstract Method (SAM) interface is a Java interface containing only one method. The Java API is full of SAM interfaces, such as java.lang.Runnable, java.awt.event.ActionListener, java.util.Comparator and java.util.concurrent.Callable. SAM interfaces have a special place in Java 8 because they can be implemented using Lambda expressions or Method references.

Using @FunctionalInterface forces a compile break when an additional, non-overriding abstract method is added to a SAM, which would break the use of Lambda implementations.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 8.

Noncompliant Code Example

public interface Changeable<T> {
  public void change(T o);
}

Compliant Solution

@FunctionalInterface
public interface Changeable<T> {
  public void change(T o);
}

Deprecated

This rule is deprecated, and will eventually be removed.

squid:S1610

With Java 8's "default method" feature, any abstract class without direct or inherited field should be converted into an interface. However, this change may not be appropriate in libraries or other applications where the class is intended to be used as an API.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 8.

Noncompliant Code Example

public abstract class Car {
  public abstract void start(Environment c);

  public void stop(Environment c) {
    c.freeze(this);
  }
}

Compliant Solution

public interface Car {
  public void start(Environment c);

  public default void stop(Environment c) {
    c.freeze(this);
  }
}
squid:S1611

There are two possible syntaxes for a lambda having only one input parameter with an inferred type: with and without parentheses around that single parameter. The simpler syntax, without parentheses, is more compact and readable than the one with parentheses, and is therefore preferred.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 8.

Noncompliant Code Example

(x) -> x * 2

Compliant Solution

x -> x * 2
squid:S1612

Method/constructor references are more compact and readable than using lambdas, and are therefore preferred. Similarly, null checks can be replaced with references to the Objects::isNull and Objects::nonNull methods.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 8.

Noncompliant Code Example

class A {
  void process(List<A> list) {
    list.stream()
      .map(a -> a.<String>getObject())
      .forEach(a -> { System.out.println(a); });
  }

  <T> T getObject() {
    return null;
  }
}

Compliant Solution

class A {
  void process(List<A> list) {
    list.stream()
      .map(A::<String>getObject)
      .forEach(System.out::println);
  }

  <T> T getObject() {
    return null;
  }
}
squid:S1641

When all the elements in a Set are values from the same enum, the Set can be replaced with an EnumSet, which can be much more efficient than other sets because the underlying data structure is a simple bitmap.

Noncompliant Code Example

public class MyClass {

  public enum COLOR {
    RED, GREEN, BLUE, ORANGE;
  }

  public void doSomething() {
    Set<COLOR> warm = new HashSet<COLOR>();
    warm.add(COLOR.RED);
    warm.add(COLOR.ORANGE);
  }
}

Compliant Solution

public class MyClass {

  public enum COLOR {
    RED, GREEN, BLUE, ORANGE;
  }

  public void doSomething() {
    Set<COLOR> warm = EnumSet.of(COLOR.RED, COLOR.ORANGE);
  }
}
squid:S1643

Strings are immutable objects, so concatenation doesn't simply add the new String to the end of the existing string. Instead, in each loop iteration, the first String is converted to an intermediate object type, the second string is appended, and then the intermediate object is converted back to a String. Further, performance of these intermediate operations degrades as the String gets longer. Therefore, the use of StringBuilder is preferred.

Noncompliant Code Example

String str = "";
for (int i = 0; i < arrayOfStrings.length ; ++i) {
  str = str + arrayOfStrings[i];
}

Compliant Solution

StringBuilder bld = new StringBuilder();
  for (int i = 0; i < arrayOfStrings.length; ++i) {
    bld.append(arrayOfStrings[i]);
  }
  String str = bld.toString();
squid:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

public void setName(String name) {
  name = name;
}

Compliant Solution

public void setName(String name) {
  this.name = name;
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
squid:S1694

The purpose of an abstract class is to provide some heritable behaviors while also defining methods which must be implemented by sub-classes.

A class with no abstract methods that was made abstract purely to prevent instantiation should be converted to a concrete class (i.e. remove the abstract keyword) with a private constructor.

A class with only abstract methods and no inheritable behavior should be converted to an interface.

Noncompliant Code Example

public abstract class Animal {  // Noncompliant; should be an interface
  abstract void move();
  abstract void feed();
}

public abstract class Color {  // Noncompliant; should be concrete with a private constructor
  private int red = 0;
  private int green = 0;
  private int blue = 0;

  public int getRed() {
    return red;
  }
}

Compliant Solution

public interface Animal {
  void move();
  void feed();
}

public class Color {
  private int red = 0;
  private int green = 0;
  private int blue = 0;

  private Color () {}

  public int getRed() {
    return red;
  }
}

public abstract class Lamp {

  private boolean switchLamp=false;

  public abstract void glow();

  public void flipSwitch() {
    switchLamp = !switchLamp;
    if (switchLamp) {
      glow();
    }
  }
}
squid:S1696

NullPointerException should be avoided, not caught. Any situation in which NullPointerException is explicitly caught can easily be converted to a null test, and any behavior being carried out in the catch block can easily be moved to the "is null" branch of the conditional.

Noncompliant Code Example

public int lengthPlus(String str) {
  int len = 2;
  try {
    len += str.length();
  }
  catch (NullPointerException e) {
    log.info("argument was null");
  }
  return len;
}

Compliant Solution

public int lengthPlus(String str) {
  int len = 2;

  if (str != null) {
    len += str.length();
  }
  else {
    log.info("argument was null");
  }
  return len;
}

See

  • MITRE, CWE-395 - Use of NullPointerException Catch to Detect NULL Pointer Dereference
  • CERT, ERR08-J. - Do not catch NullPointerException or any of its ancestors
squid:S1697

When either the equality operator in a null test or the logical operator that follows it is reversed, the code has the appearance of safely null-testing the object before dereferencing it. Unfortunately the effect is just the opposite - the object is null-tested and then dereferenced only if it is null, leading to a guaranteed null pointer dereference.

Noncompliant Code Example

if (str == null && str.length() == 0) {
  System.out.println("String is empty");
}

if (str != null || str.length() > 0) {
  System.out.println("String is not empty");
}

Compliant Solution

if (str == null || str.length() == 0) {
  System.out.println("String is empty");
}

if (str != null && str.length() > 0) {
  System.out.println("String is not empty");
}

Deprecated

This rule is deprecated; use S2259 instead.

squid:S1699

Calling an overridable method from a constructor could result in failures or strange behaviors when instantiating a subclass which overrides the method.

For example:

  • The subclass class constructor starts by contract by calling the parent class constructor.
  • The parent class constructor calls the method, which has been overridden in the child class.
  • If the behavior of the child class method depends on fields that are initialized in the child class constructor, unexpected behavior (like a NullPointerException) can result, because the fields aren't initialized yet.

Noncompliant Code Example

public class Parent {

  public Parent () {
    doSomething();  // Noncompliant
  }

  public void doSomething () {  // not final; can be overridden
    ...
  }
}

public class Child extends Parent {

  private String foo;

  public Child(String foo) {
    super(); // leads to call doSomething() in Parent constructor which triggers a NullPointerException as foo has not yet been initialized
    this.foo = foo;
  }

  public void doSomething () {
    System.out.println(this.foo.length());
  }

}

See

  • CERT, MET05-J. - Ensure that constructors do not call overridable methods
  • CERT, OOP50-CPP. - Do not invoke virtual functions from constructors or destructors
squid:S1700

It's confusing to have a class member with the same name (case differences aside) as its enclosing class. This is particularly so when you consider the common practice of naming a class instance for the class itself.

Best practice dictates that any field or member with the same name as the enclosing class be renamed to be more descriptive of the particular aspect of the class it represents or holds.

Noncompliant Code Example

public class Foo {
  private String foo;

  public String getFoo() { }
}

Foo foo = new Foo();
foo.getFoo() // what does this return?

Compliant Solution

public class Foo {
  private String name;

  public String getName() { }
}

//...

Foo foo = new Foo();
foo.getName()

Exceptions

When the type of the field is the containing class and that field is static, no issue is raised to allow singletons named like the type.

public class Foo {
  ...
  private static Foo foo;
  public Foo getInstance() {
    if(foo==null) {
      foo = new Foo();
    }
    return foo;
  }
  ...
}
squid:S1710

Before Java 8 if you needed to use multiple instances of the same annotation, they had to be wrapped in a container annotation. With Java 8, that's no longer necessary, allowing for cleaner, more readable code.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 8.

Noncompliant Code Example

@SomeAnnotations({  // Noncompliant
  @SomeAnnotation(..a..),
  @SomeAnnotation(..b..),
  @SomeAnnotation(..c..),
})
public class SomeClass {
  ...
}

Compliant Solution

@SomeAnnotation(..a..)
@SomeAnnotation(..b..)
@SomeAnnotation(..c..)
public class SomeClass {
  ...
}
squid:S1711

Just as there is little justification for writing your own String class, there is no good reason to re-define one of the existing, standard functional interfaces.

Doing so may seem tempting, since it would allow you to specify a little extra context with the name. But in the long run, it will be a source of confusion, because maintenance programmers will wonder what is different between the custom functional interface and the standard one.

Noncompliant Code Example

@FunctionalInterface
public interface MyInterface { // Noncompliant
	double toDouble(int a);
}

@FunctionalInterface
public interface ExtendedBooleanSupplier { // Noncompliant
  boolean get();
  default boolean isFalse() {
    return !get();
  }
}

public class MyClass {
    private int a;
    public double myMethod(MyInterface instance){
	return instance.toDouble(a);
    }
}

Compliant Solution

@FunctionalInterface
public interface ExtendedBooleanSupplier extends BooleanSupplier { // Compliant, extends java.util.function.BooleanSupplier
  default boolean isFalse() {
    return !getAsBoolean();
  }
}

public class MyClass {
    private int a;
    public double myMethod(IntToDoubleFunction instance){
	return instance.applyAsDouble(a);
    }
}
squid:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

Noncompliant Code Example

if ( a == a ) { // always true
  doZ();
}
if ( a != a ) { // always false
  doY();
}
if ( a == b && a == b ) { // if the first one is true, the second one is too
  doX();
}
if ( a == b || a == b ) { // if the first one is true, the second one is too
  doW();
}

int j = 5 / 5; //always 1
int k = 5 - 5; //always 0

c.equals(c); //always true

Exceptions

  • This rule ignores *, +, and =.
  • The specific case of testing a floating point value against itself is a valid test for NaN and is therefore ignored.
  • Similarly, left-shifting 1 onto 1 is common in the construction of bit masks, and is ignored.
float f;
if(f != f) { //test for NaN value
  System.out.println("f is NaN");
}

int i = 1 << 1; // Compliant
int j = a << a; // Noncompliant

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
squid:S1774

While the ternary operator is pleasingly compact, its use can make code more difficult to read. It should therefore be avoided in favor of the more verbose if/else structure.

Noncompliant Code Example

System.out.println(i>10?"yes":"no");

Compliant Solution

if (i > 10) {
  System.out.println(("yes");
} else {
  System.out.println("no");
}
squid:S1820

A class that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain, and having a lot of fields is an indication that a class has grown too large.

Above a specific threshold, it is strongly advised to refactor the class into smaller ones which focus on well defined topics.

squid:S1821

Nested switch structures are difficult to understand because you can easily confuse the cases of an inner switch as belonging to an outer statement. Therefore nested switch statements should be avoided.

Specifically, you should structure your code to avoid the need for nested switch statements, but if you cannot, then consider moving the inner switch to another function.

Noncompliant Code Example

void foo(int n, int m) {
  switch (n) {
    case 0:
      switch (m) {  // Noncompliant; nested switch
        // ...
      }
    case 1:
      // ...
    default:
      // ...
  }
}

Compliant Solution

void foo(int n, int m) {
  switch (n) {
    case 0:
      bar(m);
    case 1:
      // ...
    default:
      // ...
  }
}

void bar(int m){
  switch(m) {
    // ...
  }
}
squid:S1844

From the Java API documentation:

Condition factors out the Object monitor methods (wait, notify and notifyAll) into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitrary Lock implementations. Where a Lock replaces the use of synchronized methods and statements, a Condition replaces the use of the Object monitor methods.

The purpose of implementing the Condition interface is to gain access to its more nuanced await methods. Therefore, calling the method Object.wait(...) on a class implementing the Condition interface is silly and confusing.

Noncompliant Code Example

final Lock lock = new ReentrantLock();
final Condition notFull  = lock.newCondition();
...
notFull.wait();

Compliant Solution

final Lock lock = new ReentrantLock();
final Condition notFull  = lock.newCondition();
...
notFull.await();
squid:S1845

Looking at the set of methods in a class, including superclass methods, and finding two methods or fields that differ only by capitalization is confusing to users of the class. It is similarly confusing to have a method and a field which differ only in capitalization or a method and a field with exactly the same name and visibility.

In the case of methods, it may have been a mistake on the part of the original developer, who intended to override a superclass method, but instead added a new method with nearly the same name.

Otherwise, this situation simply indicates poor naming. Method names should be action-oriented, and thus contain a verb, which is unlikely in the case where both a method and a member have the same name (with or without capitalization differences). However, renaming a public method could be disruptive to callers. Therefore renaming the member is the recommended action.

Noncompliant Code Example

public class Car{

  public DriveTrain drive;

  public void tearDown(){...}

  public void drive() {...}  // Noncompliant; duplicates field name
}

public class MyCar extends Car{
  public void teardown(){...}  // Noncompliant; not an override. It it really what's intended?

  public void drivefast(){...}

  public void driveFast(){...} //Huh?
}

Compliant Solution

public class Car{

  private DriveTrain drive;

  public void tearDown(){...}

  public void drive() {...}  // field visibility reduced
}

public class MyCar extends Car{
  @Override
  public void tearDown(){...}

  public void drivefast(){...}

  public void driveReallyFast(){...}

}
squid:S1849

Calling Iterator.hasNext() is not supposed to have any side effects, and therefore should not change the state of the iterator. Iterator.next() advances the iterator by one item. So calling it inside Iterator.hasNext(), breaks the hasNext() contract, and will lead to unexpected behavior in production.

Noncompliant Code Example

public class FibonacciIterator implements Iterator<Integer>{
...
@Override
public boolean hasNext() {
  if(next() != null) {
    return true;
  }
  return false;
}
...
}
squid:S1850

instanceof operators that always return true or false are either useless or the result of a misunderstanding which could lead to unexpected behavior in production.

Noncompliant Code Example

public boolean isSuitable(Integer param) {
...
  String name = null;

  if (name instanceof String) { // Noncompliant; always false since name is null
    //...
  }

  if(param instanceof Number) {  // Noncompliant; always true unless param is null, because param is an Integer
    doSomething();
  }
...
}

Compliant Solution

public boolean isSuitable(Integer param) {
...
  doSomething();
...
}

Deprecated

This rule is deprecated; use S2589 instead.

squid:S1854

A dead store happens when a local variable is assigned a value that is not read by any subsequent instruction. Calculating or retrieving a value only to then overwrite it or throw it away, could indicate a serious error in the code. Even if it's not an error, it is at best a waste of resources. Therefore all calculated values should be used.

Noncompliant Code Example

i = a + b; // Noncompliant; calculation result not used before value is overwritten
i = compute();

Compliant Solution

i = a + b;
i += compute();

Exceptions

This rule ignores initializations to -1, 0, 1, null, true, false and "".

See

squid:S1858

Invoking a method designed to return a string representation of an object which is already a string is a waste of keystrokes. This redundant construction may be optimized by the compiler, but will be confusing in the meantime.

Noncompliant Code Example

String message = "hello world";
System.out.println(message.toString()); // Noncompliant;

Compliant Solution

String message = "hello world";
System.out.println(message);
squid:S1860

Objects which are pooled and potentially reused should not be used for synchronization. If they are, it can cause unrelated threads to deadlock with unhelpful stacktraces. Specifically, String literals, and boxed primitives such as Integers should not be used as lock objects because they are pooled and reused. The story is even worse for Boolean objects, because there are only two instances of Boolean, Boolean.TRUE and Boolean.FALSE and every class that uses a Boolean will be referring to one of the two.

Noncompliant Code Example

private static final Boolean bLock = Boolean.FALSE;
private static final Integer iLock = Integer.valueOf(0);
private static final String sLock = "LOCK";

public void doSomething() {

  synchronized(bLock) {  // Noncompliant
    // ...
  }
  synchronized(iLock) {  // Noncompliant
    // ...
  }
  synchronized(sLock) {  // Noncompliant
    // ...
  }

Compliant Solution

private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
private static final Object lock3 = new Object();

public void doSomething() {

  synchronized(lock1) {
    // ...
  }
  synchronized(lock2) {
    // ...
  }
  synchronized(lock3) {
    // ...
  }

See

squid:S1862

A chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

Noncompliant Code Example

if (param == 1)
  openWindow();
else if (param == 2)
  closeWindow();
else if (param == 1)  // Noncompliant
  moveWindowToTheBackground();
}

Compliant Solution

if (param == 1)
  openWindow();
else if (param == 2)
  closeWindow();
else if (param == 3)
  moveWindowToTheBackground();
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
squid:S1871

Having two cases in a switch statement or two branches in an if chain 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 chain they should be combined, or for a switch, one should fall through to the other.

Noncompliant Code Example

switch (i) {
  case 1:
    doFirstThing();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  case 3:  // Noncompliant; duplicates case 1's implementation
    doFirstThing();
    doSomething();
    break;
  default:
    doTheRest();
}

if (a >= 0 && a < 10) {
  doFirstThing();
  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else if (a >= 20 && a < 50) {
  doFirstThing();
  doTheThing();  // Noncompliant; duplicates first condition
}
else {
  doTheRest();
}

Exceptions

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a switch statement that contain a single line of code with or without a following break.

if(a == 1) {
  doSomething();  //no issue, usually this is done on purpose to increase the readability
} else if (a == 2) {
  doSomethingElse();
} else {
  doSomething();
}

But this exception does not apply to if chains without else-s, or to switch-es without default clauses when all branches have the same single line of code. In case of if chains with else-s, or of switch-es with default clauses, rule S3923 raises a bug.

if(a == 1) {
  doSomething();  //Noncompliant, this might have been done on purpose but probably not
} else if (a == 2) {
  doSomething();
}
squid:S1872

There is no requirement that class names be unique, only that they be unique within a package. Therefore trying to determine an object's type based on its class name is an exercise fraught with danger. One of those dangers is that a malicious user will send objects of the same name as the trusted class and thereby gain trusted access.

Instead, the instanceof operator or the Class.isAssignableFrom() method should be used to check the object's underlying type.

Noncompliant Code Example

package computer;
class Pear extends Laptop { ... }

package food;
class Pear extends Fruit { ... }

class Store {

  public boolean hasSellByDate(Object item) {
    if ("Pear".equals(item.getClass().getSimpleName())) {  // Noncompliant
      return true;  // Results in throwing away week-old computers
    }
    return false;
  }

  public boolean isList(Class<T> valueClass) {
    if (List.class.getName().equals(valueClass.getName())) {  // Noncompliant
      return true;
    }
    return false;
  }
}

Compliant Solution

class Store {

  public boolean hasSellByDate(Object item) {
    if (item instanceof food.Pear) {
      return true;
    }
    return false;
  }

  public boolean isList(Class<T> valueClass) {
    if (valueClass.isAssignableFrom(List.class)) {
      return true;
    }
    return false;
  }
}

See

squid:S1905

Unnecessary casting expressions make the code harder to read and understand.

Noncompliant Code Example

public void example() {
  for (Foo obj : (List<Foo>) getFoos()) {  // Noncompliant; cast unnecessary because List<Foo> is what's returned
    //...
  }
}

public List<Foo> getFoos() {
  return this.foos;
}

Compliant Solution

public void example() {
  for (Foo obj : getFoos()) {
    //...
  }
}

public List<Foo> getFoos() {
  return this.foos;
}

Exceptions

Casting may be required to distinguish the method to call in the case of overloading:

class A {}
class B extends A{}
class C {
  void fun(A a){}
  void fun(B b){}

  void foo() {
    B b = new B();
    fun(b);
    fun((A) b); //call the first method so cast is not redundant.
  }

}
squid:S1939

All classes extend Object implicitly. Doing so explicitly is redundant.

Further, declaring the implementation of an interface and one if its parents is also redundant. If you implement the interface, you also implicitly implement its parents and there's no need to do so explicitly.

Noncompliant Code Example

public interface MyFace {
  // ...
}

public interface MyOtherFace extends MyFace {
  // ...
}

public class Foo
    extends Object // Noncompliant
    implements MyFace, MyOtherFace {  // Noncompliant
  //...
}

Compliant Solution

public interface MyFace {
  // ...
}

public interface MyOtherFace extends MyFace {
  // ...
}

public class Foo implements MyOtherFace {
  //...
}
squid:S1940

It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.

Noncompliant Code Example

if ( !(a == 2)) { ...}  // Noncompliant
boolean b = !(i < 10);  // Noncompliant

Compliant Solution

if (a != 2) { ...}
boolean b = (i >= 10);
squid:S1941

For the sake of clarity, variables should be declared as close to where they're used as possible. This is particularly true when considering methods that contain early returns and the potential to throw exceptions. In these cases, it is not only pointless, but also confusing to declare a variable that may never be used because conditions for an early return are met first.

Noncompliant Code Example

public boolean isConditionMet(int a, int b) {
  int difference = a - b;
  MyClass foo = new MyClass(a);  // Noncompliant; not used before early return

  if (difference < 0) {
    return false;
  }

  // ...

  if (foo.doTheThing()) {
    return true;
  }
  return false;
}

Compliant Solution

public boolean isConditionMet(int a, int b) {
  int difference = a - b;

  if (difference < 0) {
    return false;
  }

  // ...

  MyClass foo = new MyClass(a);
  if (foo.doTheThing()) {
    return true;
  }
  return false;
}
squid:S1942

Java's import mechanism allows the use of simple class names. Therefore, using a class' fully qualified name in a file that imports the class is redundant and confusing.

Noncompliant Code Example

import java.util.List;
import java.sql.Timestamp;

//...

java.util.List<String> myList;  // Noncompliant
java.sql.Timestamp tStamp; // Noncompliant

Compliant Solution

import java.util.List;
import java.sql.Timestamp;

//...

List<String> myList;
Timestamp tStamp;
squid:S1994

It can be extremely confusing when a for loop's counter is incremented outside of its increment clause. In such cases, the increment should be moved to the loop's increment clause if at all possible.

Noncompliant Code Example

for (i = 0; i < 10; j++) { // Noncompliant
  // ...
  i++;
}

Compliant Solution

for (i = 0; i < 10; i++, j++) {
  // ...
}

Or

for (i = 0; i < 10; i++) {
  // ...
  j++;
}
squid:S1996

A file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. This is doubly true for a file with multiple top-level classes and interfaces. It is strongly advised to divide the file into one top-level class or interface per file.

squid:S2047

Well-named functions can allow the users of your code to understand at a glance what to expect from the function - even before reading the documentation. Toward that end, methods returning a boolean should have names that start with "is" or "has" rather than with "get".

Noncompliant Code Example

public boolean getFoo() { // Noncompliant
  // ...
}

public boolean getBar(Bar c) { // Noncompliant
  // ...
}

public boolean testForBar(Bar c) { // Compliant - The method does not start by 'get'.
  // ...
}

Compliant Solution

public boolean isFoo() {
  // ...
}

public boolean hasBar(Bar c) {
  // ...
}

public boolean testForBar(Bar c) {
  // ...
}

Exceptions

Overriding methods are excluded.

@Override
public boolean getFoo(){
  // ...
}
squid:S2055

When a Serializable object has a non-serializable ancestor in its inheritance chain, object deserialization (re-instantiating the object from file) starts at the first non-serializable class, and proceeds down the chain, adding the properties of each subsequent child class, until the final object has been instantiated.

In order to create the non-serializable ancestor, its no-argument constructor is called. Therefore the non-serializable ancestor of a Serializable class must have a no-arg constructor. Otherwise the class is Serializable but not deserializable.

Noncompliant Code Example

public class Fruit {
  private Season ripe;

  public Fruit (Season ripe) {...}
  public void setRipe(Season ripe) {...}
  public Season getRipe() {...}
}

public class Raspberry extends Fruit
        implements Serializable {  // Noncompliant; nonserializable ancestor doesn't have no-arg constructor
  private static final long serialVersionUID = 1;

  private String variety;

  public Raspberry(Season ripe, String variety) { ...}
  public void setVariety(String variety) {...}
  public String getVarity() {...}
}

Compliant Solution

public class Fruit {
  private Season ripe;

  public Fruit () {...};  // Compliant; no-arg constructor added to ancestor
  public Fruit (Season ripe) {...}
  public void setRipe(Season ripe) {...}
  public Season getRipe() {...}
}

public class Raspberry extends Fruit
        implements Serializable {
  private static final long serialVersionUID = 1;

  private String variety;

  public Raspberry(Season ripe, String variety) {...}
  public void setVariety(String variety) {...}
  public String getVarity() {...}
}
squid:S2059

Serializing a non-static inner class will result in an attempt at serializing the outer class as well. If the outer class is actually serializable, then the serialization will succeed but possibly write out far more data than was intended.

Making the inner class static (i.e. "nested") avoids this problem, therefore inner classes should be static if possible. However, you should be aware that there are semantic differences between an inner class and a nested one:

  • an inner class can only be instantiated within the context of an instance of the outer class.
  • a nested (static) class can be instantiated independently of the outer class.

Noncompliant Code Example

public class Raspberry implements Serializable {
  // ...

  public class Drupelet implements Serializable {  // Noncompliant; output may be too large
    // ...
  }
}

Compliant Solution

public class Raspberry implements Serializable {
  // ...

  public static class Drupelet implements Serializable {
    // ...
  }
}

See

squid:S2060

An Externalizable class is one which handles its own Serialization and deserialization. During deserialization, the first step in the process is a default instantiation using the class' no-argument constructor. Therefore an Externalizable class without a no-arg constructor cannot be deserialized.

Noncompliant Code Example

public class Tomato implements Externalizable {  // Noncompliant; no no-arg constructor

  public Tomato (String color, int weight) { ... }
}

Compliant Solution

public class Tomato implements Externalizable {

  public Tomato() { ... }
  public Tomato (String color, int weight) { ... }
}
squid:S2061

Writers of Serializable classes can choose to let Java's automatic mechanisms handle serialization and deserialization, or they can choose to handle it themselves by implementing specific methods. However, if the signatures of those methods are not exactly what is expected, they will be ignored and the default serialization mechanisms will kick back in.

Noncompliant Code Example

public class Watermelon implements Serializable {
  // ...
  void writeObject(java.io.ObjectOutputStream out)// Noncompliant; not private
        throws IOException
  {...}

  private void readObject(java.io.ObjectInputStream in)
  {...}

  public void readObjectNoData()  // Noncompliant; not private
  {...}

  static Object readResolve() throws ObjectStreamException  // Noncompliant; this method may have any access modifier, may not be static

  Watermelon writeReplace() throws ObjectStreamException // Noncompliant; this method may have any access modifier, but must return Object
  {...}
}

Compliant Solution

public class Watermelon implements Serializable {
  // ...
  private void writeObject(java.io.ObjectOutputStream out)
        throws IOException
  {...}

  private void readObject(java.io.ObjectInputStream in)
        throws IOException, ClassNotFoundException
  {...}

  private void readObjectNoData()
        throws ObjectStreamException
  {...}

  protected Object readResolve() throws ObjectStreamException
  {...}

  private Object writeReplace() throws ObjectStreamException
  {...}

See

  • CERT, SER01-J. - Do not deviate from the proper signatures of serialization methods
squid:S2062

The readResolve() method allows final tweaks to the state of an object during deserialization. Non-final classes which implement readResolve(), should not set its visibility to private since it will then be unavailable to child classes.

Noncompliant Code Example

public class Fruit implements Serializable {
  private static final long serialVersionUID = 1;

  private Object readResolve() throws ObjectStreamException  // Noncompliant
  {...}

  //...
}

public class Raspberry extends Fruit implements Serializable {  // No access to parent's readResolve() method
  //...
}

Compliant Solution

public class Fruit implements Serializable {
  private static final long serialVersionUID = 1;

  protected Object readResolve() throws ObjectStreamException
  {...}

  //...
}

public class Raspberry extends Fruit implements Serializable {
  //...
}
squid:S2063

A non-serializable Comparator can prevent an otherwise-Serializable ordered collection from being serializable. Since the overhead to make a Comparator serializable is usually low, doing so can be considered good defensive programming.

Noncompliant Code Example

public class FruitComparator implements Comparator<Fruit> {  // Noncompliant
  int compare(Fruit f1, Fruit f2) {...}
  boolean equals(Object obj) {...}
}

Compliant Solution

public class FruitComparator implements Comparator<Fruit>, Serializable {
  private static final long serialVersionUID = 1;

  int compare(Fruit f1, Fruit f2) {...}
  boolean equals(Object obj) {...}
}
squid:S2065

transient is used to mark fields in a Serializable class which will not be written out to file (or stream). In a class that does not implement Serializable, this modifier is simply wasted keystrokes, and should be removed.

Noncompliant Code Example

class Vegetable {  // does not implement Serializable
  private transient Season ripe;  // Noncompliant
  // ...
}

Compliant Solution

class Vegetable {
  private Season ripe;
  // ...
}
squid:S2066

Serializing a non-static inner class will result in an attempt at serializing the outer class as well. If the outer class is not serializable, then serialization will fail, resulting in a runtime error.

Making the inner class static (i.e. "nested") avoids this problem, therefore inner classes should be static if possible. However, you should be aware that there are semantic differences between an inner class and a nested one:

  • an inner class can only be instantiated within the context of an instance of the outer class.
  • a nested (static) class can be instantiated independently of the outer class.

Noncompliant Code Example

public class Pomegranate {
  // ...

  public class Seed implements Serializable {  // Noncompliant; serialization will fail
    // ...
  }
}

Compliant Solution

public class Pomegranate {
  // ...

  public static class Seed implements Serializable {
    // ...
  }
}

See

squid:S2093

Java 7 introduced the try-with-resources statement, which guarantees that the resource in question will be closed. Since the new syntax is closer to bullet-proof, it should be preferred over the older try/catch/finally version.

This rule checks that close-able resources are opened in a try-with-resources statement.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 7.

Noncompliant Code Example

FileReader fr = null;
BufferedReader br = null;
try {
  fr = new FileReader(fileName);
  br = new BufferedReader(fr);
  return br.readLine();
} catch (...) {
} finally {
  if (br != null) {
    try {
      br.close();
    } catch(IOException e){...}
  }
  if (fr != null ) {
    try {
      br.close();
    } catch(IOException e){...}
  }
}

Compliant Solution

try (
    FileReader fr = new FileReader(fileName);
    BufferedReader br = new BufferedReader(fr)
  ) {
  return br.readLine();
}
catch (...) {}

or

try (BufferedReader br =
        new BufferedReader(new FileReader(fileName))) { // no need to name intermediate resources if you don't want to
  return br.readLine();
}
catch (...) {}

See

  • CERT, ERR54-J. - Use a try-with-resources statement to safely handle closeable resources
squid:S2094

There is no good excuse for an empty class. If it's being used simply as a common extension point, it should be replaced with an interface. If it was stubbed in as a placeholder for future development it should be fleshed-out. In any other case, it should be eliminated.

Noncompliant Code Example

public class Nothing {  // Noncompliant
}

Compliant Solution

public interface Nothing {
}

Exceptions

Empty classes can be used as marker types (for Spring for instance), therefore empty classes that are annotated will be ignored.

@Configuration
@EnableWebMvc
public final class ApplicationConfiguration {

}
squid:S2096

There's no reason for a main method to throw anything. After all, what's going to catch it?

Instead, the method should itself gracefully handle any exceptions that may bubble up to it, attach as much contextual information as possible, and perform whatever logging or user communication is necessary, and exit with a non-zero (i.e. non-success) exit code if necessary.

Noncompliant Code Example

public static void main(String args[]) throws Exception { // Noncompliant
  doSomething();

Compliant Solution

public static void main(String args[]) {
 try {
    doSomething();
  } catch (Throwable t) {
    log.error(t);
    System.exit(1);  // Default exit code, 0, indicates success. Non-zero value means failure.
  }
}
squid:S2097

Because the equals method takes a generic Object as a parameter, any type of object may be passed to it. The method should not assume it will only be used to test objects of its class type. It must instead check the parameter's type.

Noncompliant Code Example

public boolean equals(Object obj) {
  MyClass mc = (MyClass)obj;  // Noncompliant
  // ...
}

Compliant Solution

public boolean equals(Object obj) {
  if (obj == null)
    return false;

  if (this.getClass() != obj.getClass())
    return false;

  MyClass mc = (MyClass)obj;
  // ...
}
squid:S2109

The writer of an annotation can set one of three retention policies for it:

  • RetentionPolicy.SOURCE - these annotations are dropped during compilation, E.G. @Override, @SuppressWarnings.
  • RetentionPolicy.CLASS - these annotations are present in a compiled class but not loaded into the JVM at runtime. This is the default.
  • RetentionPolicy.RUNTIME - these annotations are present in the class file and loaded into the JVM.

Only annotations that have been given a RUNTIME retention policy will be available to reflection. Testing for annotations with any other retention policy is simply an error, since the test will always return false.

This rule checks that reflection is not used to detect annotations that do not have RUNTIME retention.

Noncompliant Code Example

Method m = String.class.getMethod("getBytes", new Class[] {int.class,
int.class, byte[].class, int.class});
if (m.isAnnotationPresent(Override.class)) {  // Noncompliant; test will always return false, even when @Override is present in the code
squid:S2110

Whether the valid value ranges for Date fields start with 0 or 1 varies by field. For instance, month starts at 0, and day of month starts at 1. Enter a date value that goes past the end of the valid range, and the date will roll without error or exception. For instance, enter 12 for month, and you'll get January of the following year.

This rule checks for bad values used in conjunction with java.util.Date, java.sql.Date, and java.util.Calendar. Specifically, values outside of the valid ranges:

Field Valid
month 0-11
date (day) 0-31
hour 0-23
minute 0-60
second 0-61

Note that this rule does not check for invalid leap years, leap seconds (second = 61), or invalid uses of the 31st day of the month.

Noncompliant Code Example

Date d = new Date();
d.setDate(25);
d.setYear(2014);
d.setMonth(12);  // Noncompliant; rolls d into the next year

Calendar c = new GregorianCalendar(2014, 12, 25);  // Noncompliant
if (c.get(Calendar.MONTH) == 12) {  // Noncompliant; invalid comparison
  // ...
}

Compliant Solution

Date d = new Date();
d.setDate(25);
d.setYear(2014);
d.setMonth(11);

Calendar c = new Gregorian Calendar(2014, 11, 25);
if (c.get(Calendar.MONTH) == 11) {
  // ...
}
squid:S2111

Because of floating point imprecision, you're unlikely to get the value you expect from the BigDecimal(double) constructor.

From the JavaDocs:

The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.

Instead, you should use BigDecimal.valueOf, which uses a string under the covers to eliminate floating point rounding errors, or the constructor that takes a String argument.

Noncompliant Code Example

double d = 1.1;

BigDecimal bd1 = new BigDecimal(d); // Noncompliant; see comment above
BigDecimal bd2 = new BigDecimal(1.1); // Noncompliant; same result

Compliant Solution

double d = 1.1;

BigDecimal bd1 = BigDecimal.valueOf(d);
BigDecimal bd2 = new BigDecimal("1.1"); // using String constructor will result in precise value

See

  • CERT, NUM10-J. - Do not construct BigDecimal objects from floating-point literals
squid:S2112

The equals and hashCode methods of java.net.URL both may trigger a name service (usually DNS) lookup to resolve the host name or IP address. Depending on the configuration, and network status, that can take a long time. URI on the other hand makes no such calls and should be used instead unless the specific URL functionality is required.

In general it is better to use the URI class until access to the resource is actually needed, at which point you can just convert the URI to a URL using URI.toURL().

This rule checks for uses of URL 's in Map and Set , and for explicit calls to the equals and hashCode methods.

Noncompliant Code Example

public void checkUrl(URL url) {
  Set<URL> sites = new HashSet<URL>();  // Noncompliant

  URL homepage = new URL("http://sonarsource.com");  // Compliant
  if (homepage.equals(url)) { // Noncompliant
    // ...
  }
}

Compliant Solution

public void checkUrl(URL url) {
  Set<URI> sites = new HashSet<URI>();  // Compliant

  URI homepage = new URI("http://sonarsource.com");  // Compliant
  URI uri = url.toURI();
  if (homepage.equals(uri)) {  // Compliant
    // ...
  }
}
squid:S2114

Passing a collection as an argument to the collection's own method is either an error - some other argument was intended - or simply nonsensical code.

Further, because some methods require that the argument remain unmodified during the execution, passing a collection to itself can result in undefined behavior.

Noncompliant Code Example

List <Object> objs = new ArrayList<Object>();
objs.add("Hello");

objs.add(objs); // Noncompliant; StackOverflowException if objs.hashCode() called
objs.addAll(objs); // Noncompliant; behavior undefined
objs.containsAll(objs); // Noncompliant; always true
objs.removeAll(objs); // Noncompliant; confusing. Use clear() instead
objs.retainAll(objs); // Noncompliant; NOOP
squid:S2116

While hashCode and toString are available on arrays, they are largely useless. hashCode returns the array's "identity hash code", and toString returns nearly the same value. Neither method's output actually reflects the array's contents. Instead, you should pass the array to the relevant static Arrays method.

Noncompliant Code Example

public static void main( String[] args )
{
    String argStr = args.toString(); // Noncompliant
    int argHash = args.hashCode(); // Noncompliant

Compliant Solution

public static void main( String[] args )
{
    String argStr = Arrays.toString(args);
    int argHash = Arrays.hashCode(args);

squid:S2118

Nothing in a non-serializable class will be written out to file, and attempting to serialize such a class will result in an exception being thrown. Only a class that implements Serializable or one that extends such a class can successfully be serialized (or de-serialized).

Noncompliant Code Example

public class Vegetable {  // neither implements Serializable nor extends a class that does
  //...
}

public class Menu {
  public void meal() throws IOException {
    Vegetable veg;
    //...
    FileOutputStream fout = new FileOutputStream(veg.getName());
    ObjectOutputStream oos = new ObjectOutputStream(fout);
    oos.writeObject(veg);  // Noncompliant. Nothing will be written
  }
}

Compliant Solution

public class Vegetable implements Serializable {  // can now be serialized
  //...
}

public class Menu {
  public void meal() throws IOException {
    Vegetable veg;
    //...
    FileOutputStream fout = new FileOutputStream(veg.getName());
    ObjectOutputStream oos = new ObjectOutputStream(fout);
    oos.writeObject(veg);
  }
}
squid:S2122

java.util.concurrent.ScheduledThreadPoolExecutor's pool is sized with corePoolSize, so setting corePoolSize to zero means the executor will have no threads and run nothing.

This rule detects instances where corePoolSize is set to zero, via either its setter or the object constructor.

Noncompliant Code Example

public void do(){

  ScheduledThreadPoolExecutor stpe1 = new ScheduledThreadPoolExecutor(0); // Noncompliant

  ScheduledThreadPoolExecutor stpe2 = new ScheduledThreadPoolExecutor(POOL_SIZE);
  stpe2.setCorePoolSize(0);  // Noncompliant
squid:S2123

A value that is incremented or decremented and then not stored is at best wasted code and at worst a bug.

Noncompliant Code Example

public int pickNumber() {
  int i = 0;
  int j = 0;

  i = i++; // Noncompliant; i is still zero

  return j++; // Noncompliant; 0 returned
}

Compliant Solution

public int pickNumber() {
  int i = 0;
  int j = 0;

  i++;
  return ++j;
}
squid:S2127

Double.longBitsToDouble expects a 64-bit, long argument. Pass it a smaller value, such as an int and the mathematical conversion into a double simply won't work as anticipated because the layout of the bits will be interpreted incorrectly, as if a child were trying to use an adult's gloves.

Noncompliant Code Example

int i = 42;
double d = Double.longBitsToDouble(i);  // Noncompliant
squid:S2130

Rather than creating a boxed primitive from a String to extract the primitive value, use the relevant parse method instead. It will be clearer and more efficient.

Noncompliant Code Example

String myNum = "12.2";

float f = (new Float(myNum)).floatValue();  // Noncompliant; creates & discards a Float

Compliant Solution

String myNum = "12.2";

float f = Float.parseFloat(myNum);
squid:S2131

"Boxing" is the process of putting a primitive value into a primitive-wrapper object. When that's done purely to use the wrapper class' toString method, it's a waste of memory and cycles because those methods are static, and can therefore be used without a class instance. Similarly, using the static method valueOf in the primitive-wrapper classes with a non-String argument should be avoided.

Noncompliant Code Example

int myInt = 4;
String myIntString = (new Integer(myInt)).toString(); // Noncompliant; creates & discards an Integer object
myIntString = Integer.valueOf(myInt).toString(); // Noncompliant

Compliant Solution

int myInt = 4;
String myIntString = Integer.toString(myInt);
squid:S2133

Creating an object for the sole purpose of calling getClass on it is a waste of memory and cycles. Instead, simply use the class' .class property.

Noncompliant Code Example

MyObject myOb = new MyObject();  // Noncompliant
Class c = myOb.getClass();

Compliant Solution

Class c = MyObject.class;
squid:S2134

According to the Java API documentation:

There are two ways to create a new thread of execution. One is to declare a class to be a subclass of Thread. This subclass should override the run method of class Thread. An instance of the subclass can then be allocated and started...

The other way to create a thread is to declare a class that implements the Runnable interface. That class then implements the run method. An instance of the class can then be allocated, passed as an argument when creating Thread, and started.

By definition, extending the Thread class without overriding the run method doesn't make sense, and implies that the contract of the Thread class is not well understood.

Noncompliant Code Example

public class MyRunner extends Thread { // Noncompliant; run method not overridden

  public void doSometing() {...}
}

Exceptions

If run() is not overridden in a class extending Thread, it means that starting the thread will actually call Thread.run(). However, Thread.run() does nothing if it has not been fed with a target Runnable. The rule consequently ignore classes extending Thread if they are calling, in their constructors, the super(...) constructor with a proper Runnable target.

class MyThread extends Thread { // Compliant - calling super constructor with a Runnable
  MyThread(Runnable target) {
    super(target); // calling super constructor with a Runnable, which will be used for when Thread.run() is executed
    // ...
  }
}
squid:S2140

There is no need to multiply the output of Random's nextDouble method to get a random integer. Use the nextInt method instead.

This rule raises an issue when the return value of any of Random's methods that return a floating point value is converted to an integer.

Noncompliant Code Example

Random r = new Random();
int rand = (int)r.nextDouble() * 50;  // Noncompliant way to get a pseudo-random value between 0 and 50
int rand2 = (int)r.nextFloat(); // Noncompliant; will always be 0;

Compliant Solution

Random r = new Random();
int rand = r.nextInt(50);  // returns pseudo-random value between 0 and 50
squid:S2141

Because Object implements hashCode, any Java class can be put into a hash structure. However, classes that define equals(Object) but not hashCode() aren't truly hash-able because instances that are equivalent according to the equals method can return different hashes.

Noncompliant Code Example

public class Student {  // no hashCode() method; not hash-able
  // ...

  public boolean equals(Object o) {
    // ...
  }
}

public class School {
  private Map<Student, Integer> studentBody = // okay so far
          new HashTable<Student, Integer>(); // Noncompliant

  // ...

Compliant Solution

public class Student {  // has hashCode() method; hash-able
  // ...

  public boolean equals(Object o) {
    // ...
  }
  public int hashCode() {
    // ...
  }
}

public class School {
  private Map<Student, Integer> studentBody = new HashTable<Student, Integer>();

  // ...
squid:S2143

The old, much-derided Date and Calendar classes have always been confusing and difficult to use properly, particularly in a multi-threaded context. JodaTime has long been a popular alternative, but now an even better option is built-in. Java 8's JSR 310 implementation offers specific classes for:

Class Use for
LocalDate a date, without time of day, offset, or zone
LocalTime the time of day, without date, offset, or zone
LocalDateTime the date and time, without offset, or zone
OffsetDate a date with an offset such as +02:00, without time of day, or zone
OffsetTime the time of day with an offset such as +02:00, without date, or zone
OffsetDateTime the date and time with an offset such as +02:00, without a zone
ZonedDateTime the date and time with a time zone and offset
YearMonth a year and month
MonthDay month and day
Year/MonthOfDay/DayOfWeek/... classes for the important fields
DateTimeFields stores a map of field-value pairs which may be invalid
Calendrical access to the low-level API
Period a descriptive amount of time, such as "2 months and 3 days"

Noncompliant Code Example

Date now = new Date();  // Noncompliant
DateFormat df = new SimpleDateFormat("dd.MM.yyyy");
Calendar christmas  = Calendar.getInstance();  // Noncompliant
christmas.setTime(df.parse("25.12.2020"));

Compliant Solution

LocalDate now = LocalDate.now();  // gets calendar date. no time component
LocalTime now2 = LocalTime.now(); // gets current time. no date component
LocalDate christmas = LocalDate.of(2020,12,25);
squid:S2147

Since Java 7 it has been possible to catch multiple exceptions at once. Therefore, when multiple catch blocks have the same code, they should be combined for better readability.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 7.

Noncompliant Code Example

catch (IOException e) {
  doCleanup();
  logger.log(e);
}
catch (SQLException e) {  // Noncompliant
  doCleanup();
  logger.log(e);
}
catch (TimeoutException e) {  // Compliant; block contents are different
  doCleanup();
  throw e;
}

Compliant Solution

catch (IOException|SQLException e) {
  doCleanup();
  logger.log(e);
}
catch (TimeoutException e) {
  doCleanup();
  throw e;
}
squid:S2148

Beginning with Java 7, it is possible to add underscores ('_') to numeric literals to enhance readability. The addition of underscores in this manner has no semantic meaning, but makes it easier for maintainers to understand the code.

The number of digits to the left of a decimal point needed to trigger this rule varies by base.

Base Minimum digits
binary 9
octal 9
decimal 6
hexadecimal 9

It is only the presence of underscores, not their spacing that is scrutinized by this rule.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 7.

Noncompliant Code Example

int i = 10000000;  // Noncompliant; is this 10 million or 100 million?
int  j = 0b01101001010011011110010101011110;  // Noncompliant
long l = 0x7fffffffffffffffL;  // Noncompliant

Compliant Solution

int i = 10_000_000;
int  j = 0b01101001_01001101_11100101_01011110;
long l = 0x7fff_ffff_ffff_ffffL;
squid:S2151

Running finalizers on JVM exit is disabled by default. It can be enabled with System.runFinalizersOnExit and Runtime.runFinalizersOnExit, but both methods are deprecated because they are are inherently unsafe.

According to the Oracle Javadoc:

It may result in finalizers being called on live objects while other threads are concurrently manipulating those objects, resulting in erratic behavior or deadlock.

If you really want to be execute something when the virtual machine begins its shutdown sequence, you should attach a shutdown hook.

Noncompliant Code Example

public static void main(String [] args) {
  ...
  System.runFinalizersOnExit(true);  // Noncompliant
  ...
}

protected void finalize(){
  doSomething();
}

Compliant Solution

public static void main(String [] args) {
  Runtime.addShutdownHook(new Runnable() {
    public void run(){
      doSomething();
    }
  });
  //...

See

squid:S2153

Boxing is the process of putting a primitive value into an analogous object, such as creating an Integer to hold an int value. Unboxing is the process of retrieving the primitive value from such an object.

Since the original value is unchanged during boxing and unboxing, there's no point in doing either when not needed. This also applies to autoboxing and auto-unboxing (when Java implicitly handles the primitive/object transition for you).

Noncompliant Code Example

public void examineInt(int a) {
  //...
}

public void examineInteger(Integer a) {
  // ...
}

public void func() {
  int i = 0;
  Integer iger1 = Integer.valueOf(0);
  double d = 1.0;

  int dIntValue = new Double(d).intValue(); // Noncompliant

  examineInt(new Integer(i).intValue()); // Noncompliant; explicit box/unbox
  examineInt(Integer.valueOf(i));  // Noncompliant; boxed int will be auto-unboxed

  examineInteger(i); // Compliant; value is boxed but not then unboxed
  examineInteger(iger1.intValue()); // Noncompliant; unboxed int will be autoboxed

  Integer iger2 = new Integer(iger1); // Noncompliant; unnecessary unboxing, value can be reused
}

Compliant Solution

public void examineInt(int a) {
  //...
}

public void examineInteger(Integer a) {
  // ...
}

public void func() {
  int i = 0;
  Integer iger1 = Integer.valueOf(0);
  double d = 1.0;

  int dIntValue = (int) d;

  examineInt(i);

  examineInteger(i);
  examineInteger(iger1);
}
squid:S2154

If wrapped primitive values (e.g. Integers and Floats) are used in a ternary operator (e.g. a?b:c), both values will be unboxed and coerced to a common type, potentially leading to unexpected results. To avoid this, add an explicit cast to a compatible type.

Noncompliant Code Example

Integer i = 123456789;
Float f = 1.0f;
Number n = condition ? i : f;  // Noncompliant; i is coerced to float. n = 1.23456792E8

Compliant Solution

Integer i = 123456789;
Float f = 1.0f;
Number n = condition ? (Number) i : f;  // n = 123456789
squid:S2156

The difference between private and protected visibility is that child classes can see and use protected members, but they cannot see private ones. Since a final class will have no children, marking the members of a final class protected is confusingly pointless.

Note that the protected members of a class can also be seen and used by other classes that are placed within the same package, this could lead to accidental, unintended access to otherwise private members.

Noncompliant Code Example

public final class MyFinalClass {

  protected String name = "Fred";  // Noncompliant
  protected void setName(String name) {  // Noncompliant
    // ...
  }

Compliant Solution

public final class MyFinalClass {

  private String name = "Fred";
  public void setName(String name) {
    // ...
  }

Exceptions

Members annotated with Guava's @VisibleForTesting annotation are ignored, as it indicates that visibility has been purposely relaxed to make the code testable.

public final class MyFinalClass {
  @VisibleForTesting
  protected Logger logger; // Compliant

  @VisibleForTesting
  protected int calculateSomethingComplex(String input) { // Compliant
    // ...
  }
}
squid:S2157

Simply implementing Cloneable without also overriding Object.clone() does not necessarily make the class cloneable. While the Cloneable interface does not include a clone method, it is required by convention, and ensures true cloneability. Otherwise the default JVM clone will be used, which copies primitive values and object references from the source to the target. I.e. without overriding clone, any cloned instances will potentially share members with the source instance.

Removing the Cloneable implementation and providing a good copy constructor is another viable (some say preferable) way of allowing a class to be copied.

Noncompliant Code Example

class Team implements Cloneable {  // Noncompliant
  private Person coach;
  private List<Person> players;
  public void addPlayer(Person p) {...}
  public Person getCoach() {...}
}

Compliant Solution

class Team implements Cloneable {
  private Person coach;
  private List<Person> players;
  public void addPlayer(Person p) { ... }
  public Person getCoach() { ... }

  @Override
  public Object clone() {
    Team clone = (Team) super.clone();
    //...
  }
}
squid:S2159

Comparisons of dissimilar types will always return false. The comparison and all its dependent code can simply be removed. This includes:

  • comparing an object with null
  • comparing an object with an unrelated primitive (E.G. a string with an int)
  • comparing unrelated classes
  • comparing an unrelated class and interface
  • comparing unrelated interface types
  • comparing an array to a non-array
  • comparing two arrays

Specifically in the case of arrays, since arrays don't override Object.equals(), calling equals on two arrays is the same as comparing their addresses. This means that array1.equals(array2) is equivalent to array1==array2.

However, some developers might expect Array.equals(Object obj) to do more than a simple memory address comparison, comparing for instance the size and content of the two arrays. Instead, the == operator or Arrays.equals(array1, array2) should always be used with arrays.

Noncompliant Code Example

interface KitchenTool { ... };
interface Plant {...}

public class Spatula implements KitchenTool { ... }
public class Tree implements Plant { ...}
//...

Spatula spatula = new Spatula();
KitchenTool tool = spatula;
KitchenTool [] tools = {tool};

Tree tree = new Tree();
Plant plant = tree;
Tree [] trees = {tree};


if (spatula.equals(tree)) { // Noncompliant; unrelated classes
  // ...
}
else if (spatula.equals(plant)) { // Noncompliant; unrelated class and interface
  // ...
}
else if (tool.equals(plant)) { // Noncompliant; unrelated interfaces
  // ...
}
else if (tool.equals(tools)) { // Noncompliant; array & non-array
  // ...
}
else if (trees.equals(tools)) {  // Noncompliant; incompatible arrays
  // ...
}
else if (tree.equals(null)) {  // Noncompliant
  // ...
}

See

  • CERT, EXP02-J. - Do not use the Object.equals() method to compare two arrays
squid:S2160

Extend a class that overrides equals and add fields without overriding equals in the subclass, and you run the risk of non-equivalent instances of your subclass being seen as equal, because only the superclass fields will be considered in the equality test.

This rule looks for classes that do all of the following:

  • extend classes that override equals.
  • do not themselves override equals.
  • add fields.

Noncompliant Code Example

public class Fruit {
  private Season ripe;

  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (this.class != obj.class) {
      return false;
    }
    Fruit fobj = (Fruit) obj;
    if (ripe.equals(fobj.getRipe()) {
      return true;
    }
    return false;
  }
}

public class Raspberry extends Fruit {  // Noncompliant; instances will use Fruit's equals method
  private Color ripeColor;
}

Compliant Solution

public class Fruit {
  private Season ripe;

  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (this.class != obj.class) {
      return false;
    }
    Fruit fobj = (Fruit) obj;
    if (ripe.equals(fobj.getRipe()) {
      return true;
    }
    return false;
  }
}

public class Raspberry extends Fruit {
  private Color ripeColor;

  public boolean equals(Object obj) {
    if (! super.equals(obj)) {
      return false;
    }
    Raspberry fobj = (Raspberry) obj;
    if (ripeColor.equals(fobj.getRipeColor()) {  // added fields are tested
      return true;
    }
    return false;
  }
}
squid:S2162

A key facet of the equals contract is that if a.equals(b) then b.equals(a), i.e. that the relationship is symmetric.

Using instanceof breaks the contract when there are subclasses, because while the child is an instanceof the parent, the parent is not an instanceof the child. For instance, assume that Raspberry extends Fruit and adds some fields (requiring a new implementation of equals):

Fruit fruit = new Fruit();
Raspberry raspberry = new Raspberry();

if (raspberry instanceof Fruit) { ... } // true
if (fruit instanceof Raspberry) { ... } // false

If similar instanceof checks were used in the classes' equals methods, the symmetry principle would be broken:

raspberry.equals(fruit); // false
fruit.equals(raspberry); //true

Additionally, non final classes shouldn't use a hardcoded class name in the equals method because doing so breaks the method for subclasses. Instead, make the comparison dynamic.

Further, comparing to an unrelated class type breaks the contract for that unrelated type, because while thisClass.equals(unrelatedClass) can return true, unrelatedClass.equals(thisClass) will not.

Noncompliant Code Example

public class Fruit extends Food {
  private Season ripe;

  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (Fruit.class == obj.getClass()) { // Noncompliant; broken for child classes
      return ripe.equals(((Fruit)obj).getRipe());
    }
    if (obj instanceof Fruit ) {  // Noncompliant; broken for child classes
      return ripe.equals(((Fruit)obj).getRipe());
    }
    else if (obj instanceof Season) { // Noncompliant; symmetry broken for Season class
      // ...
    }
    //...

Compliant Solution

public class Fruit extends Food {
  private Season ripe;

  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (this.getClass() == obj.getClass()) {
      return ripe.equals(((Fruit)obj).getRipe());
    }
    return false;
}

See

  • CERT, MET08-J. - Preserve the equality contract when overriding the equals() method
squid:S2164

For small numbers, float math has enough precision to yield the expected value, but for larger numbers, it does not. BigDecimal is the best alternative, but if a primitive is required, use a double.

Noncompliant Code Example

float a = 16777216.0f;
float b = 1.0f;
float c = a + b; // Noncompliant; yields 1.6777216E7 not 1.6777217E7

double d = a + b; // Noncompliant; addition is still between 2 floats

Compliant Solution

float a = 16777216.0f;
float b = 1.0f;
BigDecimal c = BigDecimal.valueOf(a).add(BigDecimal.valueOf(b));

double d = (double)a + (double)b;

Exceptions

This rule doesn't raise an issue when the mathematical expression is only used to build a string.

System.out.println("["+getName()+"] " +
           "\n\tMax time to retrieve connection:"+(max/1000f/1000f)+" ms.");

See

  • CERT, FLP02-C. - Avoid using floating-point numbers when precise computation is needed
squid:S2165

There is no point in setting class fields to null in a finalizer. If this this is a hint to the garbage collector, it is unnecessary - the object will be garbage collected anyway - and doing so may actually cause extra work for the garbage collector.

Noncompliant Code Example

public class Foo {
  private String name;

  @Override
  void finalize() {
    name = null;  // Noncompliant; completely unnecessary
squid:S2167

It is the sign, rather than the magnitude of the value returned from compareTo that matters. Returning Integer.MIN_VALUE does not convey a higher degree of inequality, and doing so can cause errors because the return value of compareTo is sometimes inversed, with the expectation that negative values become positive. However, inversing Integer.MIN_VALUE yields Integer.MIN_VALUE rather than Integer.MAX_VALUE.

Noncompliant Code Example

public int compareTo(MyClass) {
  if (condition) {
    return Integer.MIN_VALUE;  // Noncompliant
  }

Compliant Solution

public int compareTo(MyClass) {
  if (condition) {
    return -1;
  }
squid:S2168

Double-checked locking is the practice of checking a lazy-initialized object's state both before and after a synchronized block is entered to determine whether or not to initialize the object.

It does not work reliably in a platform-independent manner without additional synchronization for mutable instances of anything other than float or int. Using double-checked locking for the lazy initialization of any other type of primitive or mutable object risks a second thread using an uninitialized or partially initialized member while the first thread is still creating it, and crashing the program.

There are multiple ways to fix this. The simplest one is to simply not use double checked locking at all, and synchronize the whole method instead. With early versions of the JVM, synchronizing the whole method was generally advised against for performance reasons. But synchronized performance has improved a lot in newer JVMs, so this is now a preferred solution. If you prefer to avoid using synchronized altogether, you can use an inner static class to hold the reference instead. Inner static classes are guaranteed to load lazily.

Noncompliant Code Example

@NotThreadSafe
public class DoubleCheckedLocking {
    private static Resource resource;

    public static Resource getInstance() {
        if (resource == null) {
            synchronized (DoubleCheckedLocking.class) {
                if (resource == null)
                    resource = new Resource();
            }
        }
        return resource;
    }

    static class Resource {

    }
}

Compliant Solution

@ThreadSafe
public class SafeLazyInitialization {
    private static Resource resource;

    public synchronized static Resource getInstance() {
        if (resource == null)
            resource = new Resource();
        return resource;
    }

    static class Resource {
    }
}

With inner static holder:

@ThreadSafe
public class ResourceFactory {
    private static class ResourceHolder {
        public static Resource resource = new Resource(); // This will be lazily initialised
    }

    public static Resource getResource() {
        return ResourceFactory.ResourceHolder.resource;
    }

    static class Resource {
    }
}

Using "volatile":

class ResourceFactory {
  private volatile Resource resource;

  public Resource getResource() {
    Resource localResource = resource;
    if (localResource == null) {
      synchronized (this) {
        localResource = resource;
        if (localResource == null) {
          resource = localResource = new Resource();
        }
      }
    }
    return localResource;
  }

  static class Resource {
  }
}

See

squid:S2176

While it's perfectly legal to give a class the same simple name as a class in another package that it extends or interface it implements, it's confusing and could cause problems in the future.

Noncompliant Code Example

package my.mypackage;

public class Foo implements a.b.Foo { // Noncompliant

Compliant Solution

package my.mypackage;

public class FooJr implements a.b.Foo {
squid:S2177

When a method in a child class has the same signature as a method in a parent class, it is assumed to be an override. However, that's not the case when:

  • the parent class method is static and the child class method is not.
  • the arguments or return types of the child method are in different packages than those of the parent method.
  • the parent class method is private.

Typically, these things are done unintentionally; the private parent class method is overlooked, the static keyword in the parent declaration is overlooked, or the wrong class is imported in the child. But if the intent is truly for the child class method to be different, then the method should be renamed to prevent confusion.

Noncompliant Code Example

// Parent.java
import computer.Pear;
public class Parent {

  public void doSomething(Pear p) {
    //,,,
  }

  public static void doSomethingElse() {
    //...
  }
}

// Child.java
import fruit.Pear;
public class Child extends Parent {

  public void doSomething(Pear p) {  // Noncompliant; this is not an override
    // ...
  }


  public void doSomethingElse() {  // Noncompliant; parent method is static
    //...
  }
}

Compliant Solution

// Parent.java
import computer.Pear;
public class Parent {

  public void doSomething(Pear p) {
    //,,,
  }

  public static void doSomethingElse() {
    //...
  }
}

// Child.java
import computer.Pear;  // import corrected
public class Child extends Parent {

  public void doSomething(Pear p) {  // true override (see import)
    //,,,
  }

  public static void doSomethingElse() {
    //...
  }
}
squid:S2178

The use of non-short-circuit logic in a boolean context is likely a mistake - one that could cause serious program errors as conditions are evaluated under the wrong circumstances.

Noncompliant Code Example

if(getTrue() | getFalse()) { ... } // Noncompliant; both sides evaluated

Compliant Solution

if(getTrue() || getFalse()) { ... } // true short-circuit logic

See

  • CERT, EXP46-C. - Do not use a bitwise operator with a Boolean-like operand
squid:S2185

Certain math operations are just silly and should not be performed because their results are predictable.

In particular, anyValue % 1 is silly because it will always return 0.

Casting a non-floating-point value to floating-point and then passing it to Math.round, Math.ceil, or Math.floor is silly because the result will always be the original value.

These operations are silly with any constant value: Math.abs, Math.ceil, Math.floor, Math.rint, Math.round.

And these oprations are silly with certain constant values:

Operation Value
acos 0.0 or 1.0
asin 0.0 or 1.0
atan 0.0 or 1.0
atan2 0.0
cbrt 0.0 or 1.0
cos 0.0
cosh 0.0
exp 0.0 or 1.0
expm1 0.0
log 0.0 or 1.0
log10 0.0 or 1.0
sin 0.0
sinh 0.0
sqrt 0.0 or 1.0
tan 0.0
tanh 0.0
toDegrees 0.0 or 1.0
toRadians 0.0

Noncompliant Code Example

public void doMath(int a) {
  double floor = Math.floor((double)a); // Noncompliant
  double ceiling = Math.ceil(4.2);  // Noncompliant
  double arcTan = Math.atan(0.0);  // Noncompliant
}
squid:S2186

JUnit assertions should not be made from the run method of a Runnable, because failed assertions result in AssertionErrors being thrown. If the error is thrown from a thread other than the one that ran the test, the thread will exit but the test won't fail.

Noncompliant Code Example

public void run() {
  // ...
  Assert.assertEquals(expected, actual);  // Noncompliant
}
squid:S2187

There's no point in having a JUnit TestCase without any test methods. Similarly, you shouldn't have a file in the tests directory with "Test" in the name, but no tests in the file. Doing either of these things may lead someone to think that uncovered classes have been tested.

This rule raises an issue when files in the test directory have "Test" in the name or implement TestCase but don't contain any tests.

squid:S2188

Overriding a parent class method prevents that method from being called unless an explicit super call is made in the overriding method. In some cases not calling the super method is acceptable, but not with setUp and tearDown in a JUnit 3 TestCase.

Noncompliant Code Example

public class MyClassTest extends MyAbstractTestCase {

  private MyClass myClass;
    @Override
    protected void setUp() throws Exception {  // Noncompliant
      myClass = new MyClass();
    }

Compliant Solution

public class MyClassTest extends MyAbstractTestCase {

  private MyClass myClass;
    @Override
    protected void setUp() throws Exception {
      super.setUp();
      myClass = new MyClass();
    }
squid:S2189

An infinite loop is one that will never end while the program is running, i.e., you have to kill the program to get out of the loop. Whether it is by meeting the loop's end condition or via a break, every loop should have an end condition.

Noncompliant Code Example

for (;;) {  // Noncompliant; end condition omitted
  // ...
}

int j;
while (true) { // Noncompliant; end condition omitted
  j++;
}

int k;
boolean b = true;
while (b) { // Noncompliant; b never written to in loop
  k++;
}

Compliant Solution

int j;
while (true) { // reachable end condition added
  j++;
  if (j  == Integer.MIN_VALUE) {  // true at Integer.MAX_VALUE +1
    break;
  }
}

int k;
boolean b = true;
while (b) {
  k++;
  b = k < Integer.MAX_VALUE;
}

See

squid:S2196

Since Java 7, Strings can be used as switch arguments. So when a single String is tested against three or more values in an if/else if structure, it should be converted to a switch instead for greater readability.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 7.

Noncompliant Code Example

if ("red".equals(choice)) {  // Noncompliant
  dispenseRed();
} else if ("blue".equals(choice)) {
  dispenseBlue();
} else if ("yellow".equals(choice)) {
  dispenseYellow();
} else {
  promptUser();
}

Compliant Solution

switch(choice) {
  case "Red":
    dispenseRed();
    break;
  case "Blue":
    dispenseBlue():
    break;
  case "Yellow":
    dispenseYellow();
    break;
  default:
    promptUser();
    break;
}
squid:S2197

When the modulus of a negative number is calculated, the result will either be negative or zero. Thus, comparing the modulus of a variable for equality with a positive number (or a negative one) could result in unexpected results.

Noncompliant Code Example

public boolean isOdd(int x) {
  return x % 2 == 1;  // Noncompliant; if x is an odd negative, x % 2 == -1
}

Compliant Solution

public boolean isOdd(int x) {
  return x % 2 != 0;
}

See

  • CERT, NUM51-J. - Do not assume that the remainder operator always returns a nonnegative result for integral operands
  • CERT, INT10-C - Do not assume a positive remainder when using the % operator
squid:S2200

While most compareTo methods return -1, 0, or 1, some do not, and testing the result of a compareTo against a specific value other than 0 could result in false negatives.

Noncompliant Code Example

if (myClass.compareTo(arg) == -1) {  // Noncompliant
  // ...
}

Compliant Solution

if (myClass.compareTo(arg) < 0) {
  // ...
}
squid:S2203

While you can use either forEach(list::add) or collect with a Stream, collect is by far the better choice because it's automatically thread-safe and parallellizable.

Noncompliant Code Example

List<String> bookNames = new ArrayList<>();
books.stream().filter(book -> book.getIsbn().startsWith("0"))
                .map(Book::getTitle)
                .forEach(bookNames::add);  // Noncompliant

Compliant Solution

List<String> bookNames = books.stream().filter(book -> book.getIsbn().startsWith("0"))
                .map(Book::getTitle)
                .collect(Collectors.toList());
squid:S2204

AtomicInteger, and AtomicLong extend Number, but they're distinct from Integer and Long and should be handled differently. AtomicInteger and AtomicLong are designed to support lock-free, thread-safe programming on single variables. As such, an AtomicInteger will only ever be "equal" to itself. Instead, you should .get() the value and make comparisons on it.

This applies to all the atomic, seeming-primitive wrapper classes: AtomicInteger, AtomicLong, and AtomicBoolean.

Noncompliant Code Example

AtomicInteger aInt1 = new AtomicInteger(0);
AtomicInteger aInt2 = new AtomicInteger(0);

if (aInt1.equals(aInt2)) { ... }  // Noncompliant

Compliant Solution

AtomicInteger aInt1 = new AtomicInteger(0);
AtomicInteger aInt2 = new AtomicInteger(0);

if (aInt1.get() == aInt2.get()) { ... }
squid:S2211

Shared coding conventions allow teams to collaborate effectively. While types for lambda arguments are optional, specifying them anyway makes the code clearer and easier to read.

Noncompliant Code Example

Arrays.sort(rosterAsArray,
    (a, b) -> {  // Noncompliant
        return a.getBirthday().compareTo(b.getBirthday());
    }
);

Compliant Solution

Arrays.sort(rosterAsArray,
    (Person a, Person b) -> {
        return a.getBirthday().compareTo(b.getBirthday());
    }
);

Exceptions

When the lambda has one or two parameters and does not have a block this rule will not fire up an issue as things are considered more readable in those cases.

stream.map((a, b) -> a.length); // compliant
squid:S2221

Catching Exception seems like an efficient way to handle multiple possible exceptions. Unfortunately, it traps all exception types, both checked and runtime exceptions, thereby casting too broad a net. Indeed, was it really the intention of developers to also catch runtime exceptions? To prevent any misunderstanding, if both checked and runtime exceptions are really expected to be caught, they should be explicitly listed in the catch clause.

This rule raises an issue if Exception is caught when it is not explicitly thrown by a method in the try block.

Noncompliant Code Example

try {
  // do something that might throw an UnsupportedDataTypeException or UnsupportedEncodingException
} catch (Exception e) { // Noncompliant
  // log exception ...
}

Compliant Solution

try {
  // do something
} catch (UnsupportedEncodingException|UnsupportedDataTypeException|RuntimeException e) {
  // log exception ...
}

or if runtime exceptions should not be caught:

try {
  // do something
} catch (UnsupportedEncodingException|UnsupportedDataTypeException e) {
  // log exception ...
}

See

squid:S2222

If a lock is acquired and released within a method, then it must be released along all execution paths of that method.

Failing to do so will expose the conditional locking logic to the method's callers and hence be deadlock-prone.

Noncompliant Code Example

public class MyClass {
  private Lock lock = new Lock();

  public void doSomething() {
    lock.lock(); // Noncompliant
    if (isInitialized()) {
      // ...
      lock.unlock();
    }
  }
}

Compliant Solution

public class MyClass {
  private Lock lock = new Lock();

  public void doSomething() {
    if (isInitialized()) {
      lock.lock();
      // ...
      lock.unlock();
    }
  }
}

See

squid:S2226

By contract, a servlet container creates one instance of each servlet and then a dedicated thread is attached to each new incoming HTTP request to process the request. So all threads share the servlet instances and by extension their instance fields. To prevent any misunderstanding and unexpected behavior at runtime, all servlet fields should then be either static and/or final, or simply removed.

With Struts 1.X, the same constraint exists on org.apache.struts.action.Action.

Noncompliant Code Example

public class MyServlet extends HttpServlet {
  private String userName;  //As this field is shared by all users, it's obvious that this piece of information should be managed differently
  ...
}

or

public class MyAction extends Action {
  private String userName;  //Same reason
  ...
}

See

  • CERT, MSC11-J. - Do not let session information leak within a servlet
squid:S2229

When using Spring proxies, calling a method in the same class (e.g. this.aMethod()) with an incompatible @Transactional requirement will result in runtime exceptions because Spring only "sees" the caller and makes no provisions for properly invoking the callee.

Therefore, certain calls should never be made within the same class:

From To
non-@Transactional MANDATORY, NESTED, REQUIRED, REQUIRES_NEW
MANDATORY NESTED, NEVER, NOT_SUPPORTED, REQUIRES_NEW
NESTED NESTED, NEVER, NOT_SUPPORTED, REQUIRES_NEW
NEVER MANDATORY, NESTED, REQUIRED, REQUIRES_NEW
NOT_SUPPORTED MANDATORY, NESTED, REQUIRED, REQUIRES_NEW
REQUIRED or @Transactional NESTED, NEVER, NOT_SUPPORTED, REQUIRES_NEW
REQUIRES_NEW NESTED, NEVER, NOT_SUPPORTED, REQUIRES_NEW
SUPPORTS MANDATORY, NESTED, NEVER, NOT_SUPPORTED, REQUIRED, REQUIRES_NEW

Noncompliant Code Example


@Override
public void doTheThing() {
  // ...
  actuallyDoTheThing();  // Noncompliant
}

@Override
@Transactional
public void actuallyDoTheThing() {
  // ...
}
squid:S2230

Marking a non-public method @Transactional is both useless and misleading because Spring doesn't "see" non-public methods, and so makes no provision for their proper invocation. Nor does Spring make provision for the methods invoked by the method it called.

Therefore marking a private method, for instance, @Transactional can only result in a runtime error or exception if the method is actually written to be @Transactional.

Noncompliant Code Example

@Transactional  // Noncompliant
private void doTheThing(ArgClass arg) {
  // ...
}
squid:S2232

There are several reasons to avoid ResultSet.isLast(). First, support for this method is optional for TYPE_FORWARD_ONLY result sets. Second, it can be expensive (the driver may need to fetch the next row to answer the question). Finally, the specification is not clear on what should be returned when the ResultSet is empty, so some drivers may return the opposite of what is expected.

Noncompliant Code Example

stmt.executeQuery("SELECT name, address FROM PERSON");
ResultSet rs = stmt.getResultSet();
while (! rs.isLast()) { // Noncompliant
  // process row
}

Compliant Solution

ResultSet rs = stmt.executeQuery("SELECT name, address FROM PERSON");
while (! rs.next()) {
  // process row
}
squid:S2234

When the names of parameters in a method call match the names of the method arguments, it contributes to clearer, more readable code. However, when the names match, but are passed in a different order than the method arguments, it indicates a mistake in the parameter order which will likely lead to unexpected results.

Noncompliant Code Example

public double divide(int divisor, int dividend) {
  return divisor/dividend;
}

public void doTheThing() {
  int divisor = 15;
  int dividend = 5;

  double result = divide(dividend, divisor);  // Noncompliant; operation succeeds, but result is unexpected
  //...
}

Compliant Solution

public double divide(int divisor, int dividend) {
  return divisor/dividend;
}

public void doTheThing() {
  int divisor = 15;
  int dividend = 5;

  double result = divide(divisor, dividend);
  //...
}
squid:S2236

The methods wait(...), notify() and notifyAll() are available on a Thread instance, but only because all classes in Java extend Object and therefore automatically inherit those methods. But there are two very good reasons for not calling them on a Thread:

  • Internally, the JVM relies on these methods to change the state of the Thread (BLOCKED, WAITING, ...), so calling them will corrupt the behavior of the JVM.
  • It is not clear (perhaps even to the original coder) what is really expected. For instance, it is waiting for the execution of the Thread to suspended, or is it the acquisition of the object monitor that is waited for?

Noncompliant Code Example

Thread myThread = new Thread(new RunnableJob());
...
myThread.wait(2000);
squid:S2250

The time complexity of method calls on collections is not always obvious. For instance, for most collections the size() method takes constant time, but the time required to execute ConcurrentLinkedQueue.size() is O(n), i.e. directly proportional to the number of elements in the collection. When the collection is large, this could therefore be an expensive operation.

This rule raises an issue when the following O(n) methods are called outside of constructors on class fields:

  • ArrayList
    • contains
    • remove
  • LinkedList
    • get
    • contains
  • ConcurrentLinkedQueue
    • size
    • contains
  • ConcurrentLinkedDeque
    • size
    • contains
  • CopyOnWriteArrayList
    • add
    • contains
    • remove
  • CopyOnWriteArraySet
    • add
    • contains
    • remove

Noncompliant Code Example

ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();
//...
log.info("Queue contains " + queue.size() + " elements");  // Noncompliant
squid:S2251

A for loop with a counter that moves in the wrong direction is not an infinite loop. Because of wraparound, the loop will eventually reach its stop condition, but in doing so, it will run many, many more times than anticipated, potentially causing unexpected behavior.

Noncompliant Code Example

public void doSomething(String [] strings) {
  for (int i = 0; i < strings.length; i--) { // Noncompliant;
    String string = strings[i];  // ArrayIndexOutOfBoundsException when i reaches -1
    //...
  }

Compliant Solution

public void doSomething(String [] strings) {
  for (int i = 0; i < strings.length; i++) {
    String string = strings[i];
    //...
  }

See

squid:S2252

If a for loop's condition is false before the first loop iteration, the loop will never be executed. Such loops are almost always bugs, particularly when the initial value and stop conditions are hard-coded.

Noncompliant Code Example

for (int i = 10; i < 10; i++) {  // Noncompliant
  // ...
squid:S2259

A reference to null should never be dereferenced/accessed. Doing so will cause a NullPointerException to be thrown. At best, such an exception will cause abrupt program termination. At worst, it could expose debugging information that would be useful to an attacker, or it could allow an attacker to bypass security measures.

Note that when they are present, this rule takes advantage of @CheckForNull and @Nonnull annotations defined in JSR-305 to understand which values are and are not nullable except when @Nonnull is used on the parameter to equals, which by contract should always work with null.

Noncompliant Code Example

@CheckForNull
String getName(){...}

public boolean isNameEmpty() {
  return getName().length() == 0; // Noncompliant; the result of getName() could be null, but isn't null-checked
}
Connection conn = null;
Statement stmt = null;
try{
  conn = DriverManager.getConnection(DB_URL,USER,PASS);
  stmt = conn.createStatement();
  // ...

}catch(Exception e){
  e.printStackTrace();
}finally{
  stmt.close();   // Noncompliant; stmt could be null if an exception was thrown in the try{} block
  conn.close();  // Noncompliant; conn could be null if an exception was thrown
}
private void merge(@Nonnull Color firstColor, @Nonnull Color secondColor){...}

public  void append(@CheckForNull Color color) {
    merge(currentColor, color);  // Noncompliant; color should be null-checked because merge(...) doesn't accept nullable parameters
}
void paint(Color color) {
  if(color == null) {
    System.out.println("Unable to apply color " + color.toString());  // Noncompliant; NullPointerException will be thrown
    return;
  }
  ...
}

See

squid:S2273

By contract, the method Object.wait(...), Object.notify() and Object.notifyAll() should be called by a thread that is the owner of the object's monitor. If this is not the case an IllegalMonitorStateException exception is thrown. This rule reinforces this constraint by making it mandatory to call one of these methods only inside a synchronized method or statement.

Noncompliant Code Example

private void removeElement() {
  while (!suitableCondition()){
    obj.wait();
  }
  ... // Perform removal
}

or

private void removeElement() {
  while (!suitableCondition()){
    wait();
  }
  ... // Perform removal
}

Compliant Solution

private void removeElement() {
  synchronized(obj) {
    while (!suitableCondition()){
      obj.wait();
    }
    ... // Perform removal
  }
}

or

private synchronized void removeElement() {
  while (!suitableCondition()){
    wait();
  }
  ... // Perform removal
}
squid:S2274

According to the documentation of the Java Condition interface:

When waiting upon a Condition, a "spurious wakeup" is permitted to occur, in general, as a concession to the underlying platform semantics. This has little practical impact on most application programs as a Condition should always be waited upon in a loop, testing the state predicate that is being waited for. An implementation is free to remove the possibility of spurious wakeups but it is recommended that applications programmers always assume that they can occur and so always wait in a loop.

The same advice is also found for the Object.wait(...) method:

waits should always occur in loops, like this one:

synchronized (obj) {
  while (<condition does not hold>){
    obj.wait(timeout);
  }
   ... // Perform action appropriate to condition
}

Noncompliant Code Example

synchronized (obj) {
  if (!suitableCondition()){
    obj.wait(timeout);   //the thread can wake up even if the condition is still false
  }
   ... // Perform action appropriate to condition
}

Compliant Solution

synchronized (obj) {
  while (!suitableCondition()){
    obj.wait(timeout);
  }
   ... // Perform action appropriate to condition
}

See

  • CERT THI03-J. - Always invoke wait() and await() methods inside a loop
squid:S2275

Because printf-style format strings are interpreted at runtime, rather than validated by the Java compiler, they can contain errors that lead to unexpected behavior or runtime errors. This rule statically validates the good behavior of printf-style formats when calling the format(...) methods of java.util.Formatter, java.lang.String, java.io.PrintStream, MessageFormat, and java.io.PrintWriter classes and the printf(...) methods of java.io.PrintStream or java.io.PrintWriter classes.

Noncompliant Code Example

String.format("The value of my integer is %d", "Hello World");  // Noncompliant; an 'int' is expected rather than a String
String.format("Duke's Birthday year is %tX", c);  //Noncompliant; X is not a supported time conversion character
String.format("Display %0$d and then %d", 1);   //Noncompliant; arguments are numbered starting from 1
String.format("Not enough arguments %d and %d", 1);  //Noncompliant; the second argument is missing
String.format("%< is equals to %d", 2);   //Noncompliant; the argument index '<' refers to the previous format specifier but there isn't one

MessageFormat.format("Result {1}.", value); // Noncompliant; Not enough arguments. (first element is {0})
MessageFormat.format("Result {{0}.", value); // Noncompliant; Unbalanced number of curly brace (single curly braces should be escaped)
MessageFormat.format("Result ' {0}", value); // Noncompliant; Unbalanced number of quotes (single quote must be escaped)

java.util.logging.Logger logger;
logger.log(java.util.logging.Level.SEVERE, "Result {1}!", 14); // Noncompliant {{Not enough arguments.}}

org.slf4j.Logger slf4jLog;
org.slf4j.Marker marker;

slf4jLog.debug(marker, "message {}"); // Noncompliant {{Not enough arguments.}}

Compliant Solution

String.format("The value of my integer is %d", 3);
String.format("Duke's Birthday year is %tY", c);
String.format("Display %1$d and then %d", 1);
String.format("Not enough arguments %d and %d", 1, 2);
String.format("%d is equals to %<", 2);

MessageFormat.format("Result {0}.", value);
MessageFormat.format("Result {0} & {1}.", value, value);
MessageFormat.format("Result {0}.", myObject);

java.util.logging.Logger logger;
logger.log(java.util.logging.Level.SEVERE, "Result {1}!", 14, 2); // Noncompliant {{Not enough arguments.}}

org.slf4j.Logger slf4jLog;
org.slf4j.Marker marker;

slf4jLog.debug(marker, "message {}", 1);

See

squid:S2276

If Thread.sleep(...) is called when the current thread holds a lock, it could lead to performance and scalability issues, or even worse to deadlocks because the execution of the thread holding the lock is frozen. It's better to call wait(...) on the monitor object to temporarily release the lock and allow other threads to run.

Noncompliant Code Example

public void doSomething(){
  synchronized(monitor) {
    while(notReady()){
      Thread.sleep(200);
    }
    process();
  }
  ...
}

Compliant Solution

public void doSomething(){
  synchronized(monitor) {
    while(notReady()){
      monitor.wait(200);
    }
    process();
  }
  ...
}

See

  • CERT, LCK09-J. - Do not perform operations that can block while holding a lock
squid:S2293

Java 7 introduced the diamond operator (<>) to reduce the verbosity of generics code. For instance, instead of having to declare a List's type in both its declaration and its constructor, you can now simplify the constructor declaration with <>, and the compiler will infer the type.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 7.

Noncompliant Code Example

List<String> strings = new ArrayList<String>();  // Noncompliant
Map<String,List<Integer>> map = new HashMap<String,List<Integer>>();  // Noncompliant

Compliant Solution

List<String> strings = new ArrayList<>();
Map<String,List<Integer>> map = new HashMap<>();
squid:S2325

private methods that don't access instance data can be static to prevent any misunderstanding about the contract of the method.

Noncompliant Code Example

class Utilities {
  private static String magicWord = "magic";

  private String getMagicWord() { // Noncompliant
    return magicWord;
  }

  private void setMagicWord(String value) { // Noncompliant
    magicWord = value;
  }

}

Compliant Solution

class Utilities {
  private static String magicWord = "magic";

  private static String getMagicWord() {
    return magicWord;
  }

  private static void setMagicWord(String value) {
    magicWord = value;
  }

}

Exceptions

When java.io.Serializable is implemented the following three methods are excluded by the rule:

  • private void writeObject(java.io.ObjectOutputStream out) throws IOException;
  • private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;
  • private void readObjectNoData() throws ObjectStreamException;
squid:S2326

Type parameters that aren't used are dead code, which can only distract and possibly confuse developers during maintenance. Therefore, unused type parameters should be removed.

Noncompliant Code Example

int <T> Add(int a, int b) // Noncompliant; <T> is ignored
{
  return a + b;
}

Compliant Solution

int Add(int a, int b)
{
  return a + b;
}
squid:S2333

The methods declared in an interface are public and abstract by default. Any variables are automatically public static final. There is no need to explicitly declare them so.

Since annotations are implicitly interfaces, the same holds true for them as well.

Similarly, the final modifier is redundant on any method of a final class, and private is redundant on the constructor of an Enum.

Noncompliant Code Example

public interface Vehicle {

  public void go(int speed, Direction direction);  // Noncompliant

Compliant Solution

public interface Vehicle {

  void go(int speed, Direction direction);
squid:S2384

Mutable objects are those whose state can be changed. For instance, an array is mutable, but a String is not. Mutable class members should never be returned to a caller or accepted and stored directly. Doing so leaves you vulnerable to unexpected changes in your class state.

Instead use an unmodifiable Collection (via Collections.unmodifiableCollection, Collections.unmodifiableList, ...) or make a copy of the mutable object, and store or return the copy instead.

This rule checks that arrays, collections and Dates are not stored or returned directly.

Noncompliant Code Example

class A {
  private String [] strings;

  public A () {
    strings = new String[]{"first", "second"};
  }

  public String [] getStrings() {
    return strings; // Noncompliant
  }

  public void setStrings(String [] strings) {
    this.strings = strings;  // Noncompliant
  }
}

public class B {

  private A a = new A();  // At this point a.strings = {"first", "second"};

  public void wreakHavoc() {
    a.getStrings()[0] = "yellow";  // a.strings = {"yellow", "second"};
  }
}

Compliant Solution

class A {
  private String [] strings;

  public A () {
    strings = new String[]{"first", "second"};
  }

  public String [] getStrings() {
    return strings.clone();
  }

  public void setStrings(String [] strings) {
    this.strings = strings.clone();
  }
}

public class B {

  private A a = new A();  // At this point a.strings = {"first", "second"};

  public void wreakHavoc() {
    a.getStrings()[0] = "yellow";  // a.strings = {"first", "second"};
  }
}

See

  • MITRE, CWE-374 - Passing Mutable Objects to an Untrusted Method
  • MITRE, CWE-375 - Returning a Mutable Object to an Untrusted Caller
  • CERT, OBJ05-J. - Do not return references to private mutable class members
  • CERT, OBJ06-J. - Defensively copy mutable inputs and mutable internal components
  • CERT, OBJ13-J. - Ensure that references to mutable objects are not exposed
squid:S2386

There is no good reason to have a mutable object as the public (by default), static member of an interface. Such variables should be moved into classes and their visibility lowered.

Similarly, mutable static members of classes and enumerations which are accessed directly, rather than through getters and setters, should be protected to the degree possible. That can be done by reducing visibility or making the field final if appropriate.

Note that making a mutable field, such as an array, final will keep the variable from being reassigned, but doing so has no effect on the mutability of the internal state of the array (i.e. it doesn't accomplish the goal).

This rule raises issues for public static array, Collection, Date, and awt.Point members.

Noncompliant Code Example

public interface MyInterface {
  public static String [] strings; // Noncompliant
}

public class A {
  public static String [] strings1 = {"first","second"};  // Noncompliant
  public static String [] strings2 = {"first","second"};  // Noncompliant
  public static List<String> strings3 = new ArrayList<>();  // Noncompliant
  // ...
}

See

squid:S2387

Having a variable with the same name in two unrelated classes is fine, but do the same thing within a class hierarchy and you'll get confusion at best, chaos at worst.

Noncompliant Code Example

public class Fruit {
  protected Season ripe;
  protected Color flesh;

  // ...
}

public class Raspberry extends Fruit {
  private boolean ripe;  // Noncompliant
  private static Color FLESH; // Noncompliant
}

Compliant Solution

public class Fruit {
  protected Season ripe;
  protected Color flesh;

  // ...
}

public class Raspberry extends Fruit {
  private boolean ripened;
  private static Color FLESH_COLOR;

}

Exceptions

This rule ignores same-name fields that are static in both the parent and child classes. This rule ignores private parent class fields, but in all other such cases, the child class field should be renamed.

public class Fruit {
  private Season ripe;
  // ...
}

public class Raspberry extends Fruit {
  private Season ripe;  // Compliant as parent field 'ripe' is anyway not visible from Raspberry
  // ...
}
squid:S2388

When an inner class extends another class, and both its outer class and its parent class have a method with the same name, calls to that method can be confusing. The compiler will resolve the call to the superclass method, but maintainers may be confused, so the superclass method should be called explicitly, using super..

Noncompliant Code Example

public class Parent {
  public void foo() { ... }
}

public class Outer {

  public void foo() { ... }

  public class Inner extends Parent {

    public void doTheThing() {
      foo();  // Noncompliant; was Outer.this.foo() intended instead?
      // ...
    }
  }
}

Compliant Solution

public class Parent {
  public void foo() { ... }
}

public class Outer {

  public void foo() { ... }

  public class Inner extends Parent {

    public void doTheThing() {
      super.foo();
      // ...
    }
  }
}
squid:S2391

If the suite method in a JUnit 3 TestCase is not declared correctly, it will not be used. Such a method must be named "suite", have no arguments, be public static, and must return either a junit.framework.Test or a junit.framework.TestSuite.

Similarly, setUp and tearDown methods that aren't properly capitalized will also be ignored.

Noncompliant Code Example

Test suite() { ... }  // Noncompliant; must be public static
public static boolean suite() { ... }  // Noncompliant; wrong return type
public static Test suit() { ... }  // Noncompliant; typo in method name
public static Test suite(int count) { ... } // Noncompliant; must be no-arg

public void setup() { ... } // Noncompliant; should be setUp
public void tearDwon() { ... }  // Noncompliant; should be tearDown

Compliant Solution

public static Test suite() { ... }
public void setUp() { ... }
public void tearDown() { ... }
squid:S2437

Certain bit operations are just silly and should not be performed because their results are predictable.

Specifically, using & -1 with any value will always result in the original value, as will anyValue ^ 0 and anyValue | 0.

squid:S2438

While it is technically correct to use a Thread where a Runnable is called for, the semantics of the two objects are different, and mixing them is a bad practice that will likely lead to headaches in the future.

The crux of the issue is that Thread is a larger concept than Runnable. A Runnable is an object whose running should be managed. A Thread expects to manage the running of itself or other Runnables.

Noncompliant Code Example

	public static void main(String[] args) {
		Thread r =new Thread() {
			int p;
			@Override
			public void run() {
				while(true)
					System.out.println("a");
			}
		};
		new Thread(r).start();  // Noncompliant

Compliant Solution

	public static void main(String[] args) {
		Runnable r =new Runnable() {
			int p;
			@Override
			public void run() {
				while(true)
					System.out.println("a");
			}
		};
		new Thread(r).start();
squid:S2440

static methods can be accessed without an instance of the enclosing class, so there's no reason to instantiate a class that has only static methods.

Noncompliant Code Example

public class TextUtils {
  public static String stripHtml(String source) {
    return source.replaceAll("<[^>]+>", "");
  }
}

public class TextManipulator {

  // ...

  public void cleanText(String source) {
    TextUtils textUtils = new TextUtils(); // Noncompliant

    String stripped = textUtils.stripHtml(source);

    //...
  }
}

Compliant Solution

public class TextUtils {
  public static String stripHtml(String source) {
    return source.replaceAll("<[^>]+>", "");
  }
}

public class TextManipulator {

  // ...

  public void cleanText(String source) {
    String stripped = TextUtils.stripHtml(source);

    //...
  }
}

See Also

  • S1118 - Utility classes should not have public constructors
squid:S2441

If you have no intention of writting an HttpSession object to file, then storing non-serializable objects in it may not seem like a big deal. But whether or not you explicitly serialize the session, it may be written to disk anyway, as the server manages its memory use in a process called "passivation". Further, some servers automatically write their active sessions out to file at shutdown & deserialize any such sessions at startup.

The point is, that even though HttpSession does not extend Serializable, you must nonetheless assume that it will be serialized, and understand that if you've stored non-serializable objects in the session, errors will result.

Noncompliant Code Example

public class Address {
  //...
}

//...
HttpSession session = request.getSession();
session.setAttribute("address", new Address());  // Noncompliant; Address isn't serializable

See

  • MITRE, CWE-579 - J2EE Bad Practices: Non-serializable Object Stored in Session
squid:S2442

java.util.concurrent.locks.Lock offers far more powerful and flexible locking operations than are available with synchronized blocks. So synchronizing on a Lock throws away the power of the object, and is just silly. Instead, such objects should be locked and unlocked using tryLock() and unlock().

Noncompliant Code Example

Lock lock = new MyLockImpl();
synchronized(lock) {  // Noncompliant
  //...
}

Compliant Solution

Lock lock = new MyLockImpl();
lock.tryLock();
//...

See

  • CERT, LCK03-J. - Do not synchronize on the intrinsic locks of high-level concurrency objects
squid:S2444

In a multi-threaded situation, un-synchronized lazy initialization of static fields could mean that a second thread has access to a half-initialized object while the first thread is still creating it. Allowing such access could cause serious bugs. Instead. the initialization block should be synchronized.

Similarly, updates of such fields should also be synchronized.

This rule raises an issue whenever a lazy static initialization is done on a class with at least one synchronized method, indicating intended usage in multi-threaded applications.

Noncompliant Code Example

private static Properties fPreferences = null;

private static Properties getPreferences() {
        if (fPreferences == null) {
            fPreferences = new Properties(); // Noncompliant
            fPreferences.put("loading", "true");
            fPreferences.put("filterstack", "true");
            readPreferences();
        }
        return fPreferences;
    }
}

Compliant Solution

private static Properties fPreferences = null;

private static synchronized Properties getPreferences() {
        if (fPreferences == null) {
            fPreferences = new Properties();
            fPreferences.put("loading", "true");
            fPreferences.put("filterstack", "true");
            readPreferences();
        }
        return fPreferences;
    }
}
squid:S2445

Synchronizing on a class field synchronizes not on the field itself, but on the object assigned to it. So synchronizing on a non-final field makes it possible for the field's value to change while a thread is in a block synchronized on the old value. That would allow a second thread, synchronized on the new value, to enter the block at the same time.

The story is very similar for synchronizing on parameters; two different threads running the method in parallel could pass two different object instances in to the method as parameters, completely undermining the synchronization.

Noncompliant Code Example

private String color = "red";

private void doSomething(){
  synchronized(color) {  // Noncompliant; lock is actually on object instance "red" referred to by the color variable
    //...
    color = "green"; // other threads now allowed into this block
    // ...
  }
  synchronized(new Object()) { // Noncompliant this is a no-op.
     // ...
  }
}

Compliant Solution

private String color = "red";
private final Object lockObj = new Object();

private void doSomething(){
  synchronized(lockObj) {
    //...
    color = "green";
    // ...
  }
}

See

  • MITRE, CWE-412 - Unrestricted Externally Accessible Lock
  • MITRE, CWE-413 - Improper Resource Locking
  • CERT, LCK00-J. - Use private final lock objects to synchronize classes that may interact with untrusted code
squid:S2446

notify and notifyAll both wake up sleeping threads, but notify only rouses one, while notifyAll rouses all of them. Since notify might not wake up the right thread, notifyAll should be used instead.

Noncompliant Code Example

class MyThread extends Thread{

  @Override
  public void run(){
    synchronized(this){
      // ...
      notify();  // Noncompliant
    }
  }
}

Compliant Solution

class MyThread extends Thread{

  @Override
  public void run(){
    synchronized(this){
      // ...
      notifyAll();
    }
  }
}

See

  • CERT, THI02-J. - Notify all waiting threads rather than a single thread
squid:S2447

While null is technically a valid Boolean value, that fact, and the distinction between Boolean and boolean is easy to forget. So returning null from a Boolean method is likely to cause problems with callers' code.

Noncompliant Code Example

public Boolean isUsable() {
  // ...
  return null;  // Noncompliant
}

See

squid:S2637

Fields, parameters and return values marked @NotNull, @NonNull, or @Nonnull are assumed to have non-null values and are not typically null-checked before use. Therefore setting one of these values to null, or failing to set such a class field in a constructor, could cause NullPointerExceptions at runtime.

Noncompliant Code Example

public class MainClass {

  @Nonnull
  private String primary;
  private String secondary;

  public MainClass(String color) {
    if (color != null) {
      secondary = null;
    }
    primary = color;  // Noncompliant; "primary" is Nonnull but could be set to null here
  }

  public MainClass() { // Noncompliant; "primary" Nonnull" but is not initialized
  }

  @Nonnull
  public String indirectMix() {
    String mix = null;
    return mix;  // Noncompliant; return value is Nonnull, but null is returned.}}
  }

See

squid:S2674

You cannot assume that any given stream reading call will fill the byte[] passed in to the method. Instead, you must check the value returned by the read method to see how many bytes were read. Fail to do so, and you introduce bug that is both harmful and difficult to reproduce.

Similarly, you cannot assume that InputStream.skip will actually skip the requested number of bytes, but must check the value returned from the method.

This rule raises an issue when an InputStream.read method that accepts a byte[] is called, but the return value is not checked, and when the return value of InputStream.skip is not checked. The rule also applies to InputStream child classes.

Noncompliant Code Example

public void doSomething(String fileName) {
  try {
    InputStream is = new InputStream(file);
    byte [] buffer = new byte[1000];
    is.read(buffer);  // Noncompliant
    // ...
  } catch (IOException e) { ... }
}

Compliant Solution

public void doSomething(String fileName) {
  try {
    InputStream is = new InputStream(file);
    byte [] buffer = new byte[1000];
    int count = 0;
    while (count = is.read(buffer) > 0) {
      // ...
    }
  } catch (IOException e) { ... }
}

See

  • CERT, FIO10-J. - Ensure the array is filled when using read() to fill an array
squid:S2675

A readObject method is written when a Serializable object needs special handling to be rehydrated from file. It should be the case that the object being created by readObject is only visible to the thread that invoked the method, and the synchronized keyword is not needed, and using synchronized anyway is just confusing. If this is not the case, the method should be refactored to make it the case.

Noncompliant Code Example

private synchronized void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException { // Noncompliant
  //...
}

Compliant Solution

private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException { // Compliant
  //...
}
squid:S2676

It is possible for a call to hashCode to return Integer.MIN_VALUE. Take the absolute value of such a hashcode and you'll still have a negative number. Since your code is likely to assume that it's a positive value instead, your results will be unreliable.

Similarly, Integer.MIN_VALUE could be returned from Random.nextInt() or any object's compareTo method, and Long.MIN_VALUE could be returned from Random.nextLong(). Calling Math.abs on values returned from these methods is similarly ill-advised.

Noncompliant Code Example

public void doSomething(String str) {
  if (Math.abs(str.hashCode()) > 0) { // Noncompliant
    // ...
  }
}

Compliant Solution

public void doSomething(String str) {
  if (str.hashCode() != 0) {
    // ...
  }
}
squid:S2677

When a method is called that returns data read from some data source, that data should be stored rather than thrown away. Any other course of action is surely a bug.

This rule raises an issue when the return value of any of the following is ignored or merely null-checked: BufferedReader.readLine(), Reader.read(), and these methods in any child classes.

Noncompliant Code Example

public void doSomethingWithFile(String fileName) {
  BufferedReader buffReader = null;
  try {
    buffReader = new BufferedReader(new FileReader(fileName));
    while (buffReader.readLine() != null) { // Noncompliant
      // ...
    }
  } catch (IOException e) {
    // ...
  }
}

Compliant Solution

public void doSomethingWithFile(String fileName) {
  BufferedReader buffReader = null;
  try {
    buffReader = new BufferedReader(new FileReader(fileName));
    String line = null;
    while ((line = buffReader.readLine()) != null) {
      // ...
    }
  } catch (IOException e) {
    // ...
  }
}
squid:S2692

Most checks against an indexOf value compare it with -1 because 0 is a valid index. Any checks which look for values >0 ignore the first element, which is likely a bug. If the intent is merely to check inclusion of a value in a String or a List, consider using the contains method instead.

This rule raises an issue when an indexOf value retrieved either from a String or a List is tested against >0.

Noncompliant Code Example

String color = "blue";
String name = "ishmael";

List<String> strings = new ArrayList<String> ();
strings.add(color);
strings.add(name);

if (strings.indexOf(color) > 0) {  // Noncompliant
  // ...
}
if (name.indexOf("ish") > 0) { // Noncompliant
  // ...
}
if (name.indexOf("ae") > 0) { // Noncompliant
  // ...
}

Compliant Solution

String color = "blue";
String name = "ishmael";

List<String> strings = new ArrayList<String> ();
strings.add(color);
strings.add(name);

if (strings.indexOf(color) > -1) {
  // ...
}
if (name.indexOf("ish") >= 0) {
  // ...
}
if (name.contains("ae") {
  // ...
}
squid:S2693

The problem with invoking Thread.start() in a constructor is that you'll have a confusing mess on your hands if the class is ever extended because the superclass' constructor will start the thread before the child class has truly been initialized.

This rule raises an issue any time start is invoked in the constructor of a non-final class.

Noncompliant Code Example

public class MyClass {

  Thread thread = null;

  public MyClass(Runnable runnable) {
    thread = new Thread(runnable);
    thread.start(); // Noncompliant
  }
}

See

  • CERT, TSM02-J. - Do not use background threads during class initialization
squid:S2694

A non-static inner class has a reference to its outer class, and access to the outer class' fields and methods. That class reference makes the inner class larger and could cause the outer class instance to live in memory longer than necessary.

If the reference to the outer class isn't used, it is more efficient to make the inner class static (also called nested). If the reference is used only in the class constructor, then explicitly pass a class reference to the constructor. If the inner class is anonymous, it will also be necessary to name it.

However, while a nested/static class would be more efficient, it's worth noting that there are semantic differences between an inner class and a nested one:

  • an inner class can only be instantiated within the context of an instance of the outer class.
  • a nested (static) class can be instantiated independently of the outer class.

Noncompliant Code Example

public class Fruit {
  // ...

  public class Seed {  // Noncompliant; there's no use of the outer class reference so make it static
    int germinationDays = 0;
    public Seed(int germinationDays) {
      this.germinationDays = germinationDays;
    }
    public int getGerminationDays() {
      return germinationDays;
    }
  }
}

Compliant Solution

public class Fruit {
  // ...

  public static class Seed {
    int germinationDays = 0;
    public Seed(int germinationDays) {
      this.germinationDays = germinationDays;
    }
    public int getGerminationDays() {
      return germinationDays;
    }
  }
}
squid:S2695

The parameters in a PreparedStatement are numbered from 1, not 0, so using any "set" method of a PreparedStatement with a number less than 1 is a bug, as is using an index higher than the number of parameters. Similarly, ResultSet indices also start at 1, rather than 0

Noncompliant Code Example

PreparedStatement ps = con.prepareStatement("SELECT fname, lname FROM employees where hireDate > ? and salary < ?");
ps.setDate(0, date);  // Noncompliant
ps.setDouble(3, salary);  // Noncompliant

ResultSet rs = ps.executeQuery();
while (rs.next()) {
  String fname = rs.getString(0);  // Noncompliant
  // ...
}

Compliant Solution

PreparedStatement ps = con.prepareStatement("SELECT fname, lname FROM employees where hireDate > ? and salary < ?");
ps.setDate(1, date);
ps.setDouble(2, salary);

ResultSet rs = ps.executeQuery();
while (rs.next()) {
  String fname = rs.getString(1);
  // ...
}
squid:S2696

Correctly updating a static field from a non-static method is tricky to get right and could easily lead to bugs if there are multiple class instances and/or multiple threads in play. Ideally, static fields are only updated from synchronized static methods.

This rule raises an issue each time a static field is updated from a non-static method.

Noncompliant Code Example

public class MyClass {

  private static int count = 0;

  public void doSomething() {
    //...
    count++;  // Noncompliant
  }
}
squid:S2698

Adding messages to JUnit assertions is an investment in your future productivity. Spend a few seconds writing them now, and you'll save a lot of time on the other end when either the tests fail and you need to quickly diagnose the problem, or when you need to maintain the tests and the assertion messages work as a sort of documentation.

Noncompliant Code Example

assertEquals(4, list.size());  // Noncompliant

try {
  fail();  // Noncompliant
} catch (Exception e) {
  assertThat(list.get(0)).isEqualTo("pear");  // Noncompliant
}

Compliant Solution

assertEquals("There should have been 4 Fruits in the list", 4, list.size());

try {
  fail("And exception is expected here");
} catch (Exception e) {
  assertThat(list.get(0)).as("check first element").overridingErrorMessage("The first element should be a pear, not a %s", list.get(0)).isEqualTo("pear");
}
squid:S2701

There's no reason to use literal boolean values in assertions. Doing so is at best confusing for maintainers, and at worst a bug.

Noncompliant Code Example

Assert.assertTrue(true);  // Noncompliant
assertThat(true).isTrue(); // Noncompliant
squid:S2718

The use of the ZonedDateTime class introduced in Java 8 to truncate a date can be significantly faster than the DateUtils class from Commons Lang.

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 8.

Noncompliant Code Example

public Date trunc(Date date) {
  return DateUtils.truncate(date, Calendar.SECOND);  // Noncompliant
}

Compliant Solution

public Date trunc(Date date) {
  Instant instant = date.toInstant();
  ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
  ZonedDateTime truncatedZonedDateTime = zonedDateTime.truncatedTo(ChronoUnit.SECONDS);
  Instant truncatedInstant = truncatedZonedDateTime.toInstant();
  return Date.from(truncatedInstant);
}
squid:S2761

The needless repetition of an operator is usually a typo. There is no reason to write !!!i when !i will do.

On the other hand, the repetition of increment and decrement operators may have been done on purpose, but doing so obfuscates the meaning, and should be simplified.

This rule raises an issue for sequences of: !, ~, -, and +.

Noncompliant Code Example

int i = 1;

int j = - - -i;  // Noncompliant; just use -i
int k = ~~~i;    // Noncompliant; same as i
int m = + +i;    // Noncompliant; operators are useless here

boolean b = false;
boolean c = !!!b;   // Noncompliant

Compliant Solution

int i =  1;

int j = -i;
int k = ~i;
int m =  i;

boolean b = false;
boolean c = !b;

Exceptions

Overflow handling for GWT compilation using ~~ is ignored.

squid:S2786

According to the docs:

Nested enum types are implicitly static.

So there's no need to declare them static explicitly.

Noncompliant Code Example

public class Flower {
  static enum Color { // Noncompliant; static is redundant here
    RED, YELLOW, BLUE, ORANGE
  }

  // ...
}

Compliant Solution

public class Flower {
  enum Color { // Compliant
    RED, YELLOW, BLUE, ORANGE
  }

  // ...
}
squid:S2789

The concept of Optional is that it will be used when null could cause errors. In a way, it replaces null, and when Optional is in use, there should never be a question of returning or receiving null from a call.

Noncompliant Code Example

public void doSomething () {
  Optional<String> optional = getOptional();
  if (optional != null) {  // Noncompliant
    // do something with optional...
  }
}

@Nullable // Noncompliant
public Optional<String> getOptional() {
  // ...
  return null;  // Noncompliant
}

Compliant Solution

public void doSomething () {
  Optional<String> optional = getOptional();
  optional.ifPresent(
    // do something with optional...
  );
}

public Optional<String> getOptional() {
  // ...
  return Optional.empty();
}
squid:S2864

When only the keys from a map are needed in a loop, iterating the keySet makes sense. But when both the key and the value are needed, it's more efficient to iterate the entrySet, which will give access to both the key and value, instead.

Noncompliant Code Example

public void doSomethingWithMap(Map<String,Object> map) {
  for (String key : map.keySet()) {  // Noncompliant; for each key the value is retrieved
    Object value = map.get(key);
    // ...
  }
}

Compliant Solution

public void doSomethingWithMap(Map<String,Object> map) {
  for (Map.Entry<String,Object> entry : map.entrySet()) {
    String key = entry.getKey();
    Object value = entry.getValue();
    // ...
  }
}
squid:S2885

Not all classes in the standard Java library were written to be thread-safe. Using them in a multi-threaded manner is highly likely to cause data problems or exceptions at runtime.

This rule raises an issue when an instance of Calendar, DateFormat, javax.xml.xpath.XPath, or javax.xml.validation.SchemaFactory is marked static.

Noncompliant Code Example

public class MyClass {
  private static SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss");  // Noncompliant
  private static Calendar calendar = Calendar.getInstance();  // Noncompliant

Compliant Solution

public class MyClass {
  private SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss");
  private Calendar calendar = Calendar.getInstance();
squid:S2886

When one part of a getter/setter pair is synchronized the other part should be too. Failure to synchronize both sides of a pair may result in inconsistent behavior at runtime as callers access an inconsistent method state.

This rule raises an issue when either the method or the contents of one method in a getter/setter pair are synchrnoized but the other is not.

Noncompliant Code Example

public class Person {
  String name;
  int age;

  public synchronized void setName(String name) {
    this.name = name;
  }

  public String getName() {  // Noncompliant
    return this.name;
  }

  public void setAge(int age) {  // Noncompliant
    this.age = age;
  }

  public int getAge() {
    synchronized (this) {
      return this.age;
    }
  }
}

Compliant Solution

public class Person {
  String name;
  int age;

  public synchronized void setName(String name) {
    this.name = name;
  }

  public synchronized String getName() {
    return this.name;
  }

  public void setAge(int age) {
    synchronized (this) {
      this.age = age;
   }
  }

  public int getAge() {
    synchronized (this) {
      return this.age;
    }
  }
}

See

  • CERT, VNA01-J. - Ensure visibility of shared references to immutable objects
squid:S2912

One thing that makes good code good is the clarity with which it conveys the intent of the original programmer to maintainers, and the proper choice of indexOf methods can help move code from confusing to clear.

If you need to see whether a substring is located beyond a certain point in a string, you can test the indexOf the substring versus the target point, or you can use the version of indexOf which takes a starting point argument. The latter is arguably clearer because the result is tested against -1, which is an easily recognizable "not found" indicator.

Noncompliant Code Example

String name = "ismael";

if (name.indexOf("ae") > 2) { // Noncompliant
  // ...
}

Compliant Solution

String name = "ismael";

if (name.indexOf("ae", 2) > -1) {
  // ...
}
squid:S2925

Using Thread.sleep in a test is just generally a bad idea. It creates brittle tests that can fail unpredictably depending on environment ("Passes on my machine!") or load. Don't rely on timing (use mocks) or use libraries such as Awaitility for asynchroneous testing.

Noncompliant Code Example

@Test
public void testDoTheThing(){

  MyClass myClass = new MyClass();
  myClass.doTheThing();

  Thread.sleep(500);  // Noncompliant
  // assertions...
}

Compliant Solution

@Test
public void testDoTheThing(){

  MyClass myClass = new MyClass();
  myClass.doTheThing();

  await().atMost(2, Duration.SECONDS).until(didTheThing());  // Compliant
  // assertions...
}

private Callable<Boolean> didTheThing() {
  return new Callable<Boolean>() {
    public Boolean call() throws Exception {
      // check the condition that must be fulfilled...
    }
  };
}
squid:S2959

Under the reasoning that cleaner code is better code, the semicolon at the end of a try-with-resources construct should be omitted because it can be omitted.

Noncompliant Code Example

try (ByteArrayInputStream b = new ByteArrayInputStream(new byte[10]);  // ignored; this one's required
      Reader r = new InputStreamReader(b);)   // Noncompliant
{
   //do stuff
}

Compliant Solution

try (ByteArrayInputStream b = new ByteArrayInputStream(new byte[10]);
      Reader r = new InputStreamReader(b))
{
   //do stuff
}
squid:S2970

It is very easy to write incomplete assertions when using some test frameworks. This rule enforces complete assertions in the following cases:

  • Fest: assertThat is not followed by an assertion invocation
  • AssertJ: assertThat is not followed by an assertion invocation
  • Mockito: verify is not followed by a method invocation
  • Truth: assertXXX is not followed by an assertion invocation

In such cases, what is intended to be a test doesn't actually verify anything

Noncompliant Code Example

// Fest
boolean result = performAction();
// let's now check that result value is true
assertThat(result); // Noncompliant; nothing is actually checked, the test passes whether "result" is true or false

// Mockito
List mockedList = Mockito.mock(List.class);
mockedList.add("one");
mockedList.clear();
// let's check that "add" and "clear" methods are actually called
Mockito.verify(mockedList); // Noncompliant; nothing is checked here, oups no call is chained to verify()

Compliant Solution

// Fest
boolean result = performAction();
// let's now check that result value is true
assertThat(result).isTrue();

// Mockito
List mockedList = Mockito.mock(List.class);
mockedList.add("one");
mockedList.clear();
// let's check that "add" and "clear" methods are actually called
Mockito.verify(mockedList).add("one");
Mockito.verify(mockedList).clear();

Exceptions

Variable assignments and return statements are skipped to allow helper methods.

private BooleanAssert check(String filename, String key) {
  String fileContent = readFileContent(filename);
  performReplacements(fileContent);
  return assertThat(fileContent.contains(key)); // No issue is raised here
}

@Test
public void test() {
  check("foo.txt", "key1").isTrue();
  check("bar.txt", "key2").isTrue();
}
squid:S2972

Inner classes should be short and sweet, to manage complexity in the overall file. An inner class that has grown longer than a certain threshold should probably be externalized to its own file.

squid:S2973

The use of Unicode escape sequences should be reserved for characters that would otherwise be ambiguous, such as unprintable characters.

This rule ignores sequences composed entirely of Unicode characters, but otherwise raises an issue for each Unicode character that represents a printable character.

Noncompliant Code Example

String prefix = "n\u00E9e"; // Noncompliant

Compliant Solution

String prefix = "nƩe";
squid:S2974

Classes with only private constructors should be marked final to prevent any mistaken extension attempts.

Noncompliant Code Example

public class PrivateConstructorClass {  // Noncompliant
  private PrivateConstructorClass() {
    // ...
  }

  public static int magic(){
    return 42;
  }
}

Compliant Solution

public final class PrivateConstructorClass {  // Compliant
  private PrivateConstructorClass() {
    // ...
  }

  public static int magic(){
    return 42;
  }
}
squid:S2975

Many consider clone and Cloneable broken in Java, largely because the rules for overriding clone are tricky and difficult to get right, according to Joshua Bloch:

Object's clone method is very tricky. It's based on field copies, and it's "extra-linguistic." It creates an object without calling a constructor. There are no guarantees that it preserves the invariants established by the constructors. There have been lots of bugs over the years, both in and outside Sun, stemming from the fact that if you just call super.clone repeatedly up the chain until you have cloned an object, you have a shallow copy of the object. The clone generally shares state with the object being cloned. If that state is mutable, you don't have two independent objects. If you modify one, the other changes as well. And all of a sudden, you get random behavior.

A copy constructor or copy factory should be used instead.

This rule raises an issue when clone is overridden, whether or not Cloneable is implemented.

Noncompliant Code Example

public class MyClass {
  // ...

  public Object clone() { // Noncompliant
    //...
  }
}

Compliant Solution

public class MyClass {
  // ...

  MyClass (MyClass source) {
    //...
  }
}

See

See Also

  • S2157 - "Cloneables" should implement "clone"
  • S1182 - Classes that override "clone" should be "Cloneable" and call "super.clone()"
squid:S3010

Assigning a value to a static field in a constructor could cause unreliable behavior at runtime since it will change the value for all instances of the class.

Instead remove the field's static modifier, or initialize it statically.

Noncompliant Code Example

public class Person {
  static Date dateOfBirth;
  static int expectedFingers;

  public Person(date birthday) {
    dateOfBirth = birthday;  // Noncompliant; now everyone has this birthday
    expectedFingers = 10;  // Noncompliant
  }
}

Compliant Solution

public class Person {
  Date dateOfBirth;
  static int expectedFingers = 10;

  public Person(date birthday) {
    dateOfBirth = birthday;
  }
}
squid:S3020

Given no arguments, the Collections.toArray method returns an Object [], which will cause a ClassCastException at runtime if you try to cast it to an array of the proper class. Instead, pass an array of the correct type in to the call.

Noncompliant Code Example

public String [] getStringArray(List<String> strings) {
  return (String []) strings.toArray();  // Noncompliant; ClassCastException thrown
}

Compliant Solution

public String [] getStringArray(List<String> strings) {
  return strings.toArray(new String[0]);
}
squid:S3027

An indexOf or lastIndexOf call with a single letter String can be made more performant by switching to a call with a char argument.

Noncompliant Code Example

String myStr = "Hello World";
// ...
int pos = myStr.indexOf("W");  // Noncompliant
// ...
int otherPos = myStr.lastIndexOf("r"); // Noncompliant
// ...

Compliant Solution

String myStr = "Hello World";
// ...
int pos = myStr.indexOf('W');
// ...
int otherPos = myStr.lastIndexOf('r');
// ...
squid:S3030

Importing a class statically allows you to use its public static members without qualifying them with the class name. That can be handy, but if you import too many classes statically, your code can become confusing and difficult to maintain.

Noncompliant Code Example

With the default threshold value: 4

import static java.lang.Math.*;
import static java.util.Collections.*;
import static com.myco.corporate.Constants.*;
import static com.myco.division.Constants.*;
import static com.myco.department.Constants.*;  // Noncompliant
squid:S3034

When reading bytes in order to build other primitive values such as ints or longs, the byte values are automatically promoted, but that promotion can have unexpected results.

For instance, the binary representation of the integer 640 is 0b0000_0010_1000_0000, which can also be written with the array of (unsigned) bytes [2, 128]. However, since Java uses two's complement, the representation of the integer in signed bytes will be [2, -128] (because the byte 0b1000_0000 is promoted to the int 0b1111_1111_1111_1111_1111_1111_1000_0000). Consequently, trying to reconstruct the initial integer by shifting and adding the values of the bytes without taking care of the sign will not produce the expected result.

To prevent such accidental value conversion, use bitwise and (&) to combine the byte value with 0xff (255) and turn all the higher bits back off.

This rule raises an issue any time a byte value is used as an operand without & 0xff, when combined with shifts.

Noncompliant Code Example

  int intFromBuffer() {
    int result = 0;
    for (int i = 0; i < 4; i++) {
      result = (result << 8) | readByte(); // Noncompliant
    }
    return result;
  }

Compliant Solution

  int intFromBuffer() {
    int result = 0;
    for (int i = 0; i < 4; i++) {
      result = (result << 8) | (readByte() & 0xff);
    }
    return result;
  }

See

squid:S3038

There's no point in redundantly defining an abstract method with the same signature as a method in an interface that the class implements. Any concrete child classes will have to implement the method either way.

Noncompliant Code Example

public interface Reportable {
  String getReport();
}

public abstract class AbstractRuleReport implements Reportable{
  public abstract String getReport();  // Noncompliant

  // ...
}
squid:S3042

The purpose of synchronization is to ensure that only one thread executes a given block of code at a time. There's no real problem with marking writeObject synchronized, but it's highly suspicious if this serialization-related method is the only synchronized code in a class.

Noncompliant Code Example

public class RubberBall {

  private Color color;
  private int diameter;

  public RubberBall(Color color, int diameter) {
    // ...
  }

  public void bounce(float angle, float velocity) {
    // ...
  }

  private synchronized void writeObject(ObjectOutputStream stream) throws IOException { // Noncompliant
    // ...
  }
}

Compliant Solution

public class RubberBall {

  private Color color;
  private int diameter;

   public RubberBall(Color color, int diameter) {
    // ...
  }

  public void bounce(float angle, float velocity) {
    // ...
  }

  private void writeObject(ObjectOutputStream stream) throws IOException {
    // ...
  }
}
squid:S3046

When two locks are held simultaneously, a wait call only releases one of them. The other will be held until some other thread requests a lock on the awaited object. If no unrelated code tries to lock on that object, then all other threads will be locked out, resulting in a deadlock.

Noncompliant Code Example

synchronized (this.mon1) {  // threadB can't enter this block to request this.mon2 lock & release threadA
	synchronized (this.mon2) {
		this.mon2.wait();  // Noncompliant; threadA is stuck here holding lock on this.mon1
	}
}
squid:S3047

When a method loops multiple over the same set of data, whether it's a list or a set of numbers, it is highly likely that the method could be made more efficient by combining the loops into a single set of iterations.

Noncompliant Code Example

public void doSomethingToAList(List<String> strings) {
  for (String str : strings) {
    doStep1(str);
  }
  for (String str : strings) {  // Noncompliant
    doStep2(str);
  }
}

Compliant Solution

public void doSomethingToAList(List<String> strings) {
  for (String str : strings) {
    doStep1(str);
    doStep2(str);
  }
}
squid:S3052

The compiler automatically initializes class fields to their default values before setting them with any initialization values, so there is no need to explicitly set a field to its default value. Further, under the logic that cleaner code is better code, it's considered poor style to do so.

Noncompliant Code Example

public class MyClass {

  int count = 0;  // Noncompliant
  // ...

}

Compliant Solution

public class MyClass {

  int count;
  // ...

}

Exceptions

final fields are ignored.

squid:S3066

enums are generally thought of as constant, but an enum with a public field or public setter is not only non-constant, but also vulnerable to malicious code. Ideally fields in an enum are private and set in the constructor, but if that's not possible, their visibility should be reduced as much as possible.

Noncompliant Code Example

public enum Continent {

  NORTH_AMERICA (23, 24709000),
  // ...
  EUROPE (50, 39310000);

  public int countryCount;  // Noncompliant
  private int landMass;

  Continent(int countryCount, int landMass) {
    // ...
  }

  public void setLandMass(int landMass) {  // Noncompliant
    this.landMass = landMass;
  }

Compliant Solution

public enum Continent {

  NORTH_AMERICA (23, 24709000),
  // ...
  EUROPE (50, 39310000);

  private int countryCount;
  private int landMass;

  Continent(int countryCount, int landMass) {
    // ...
  }
squid:S3067

getClass should not be used for synchronization in non-final classes because child classes will synchronize on a different object than the parent or each other, allowing multiple threads into the code block at once, despite the synchronized keyword.

Instead, hard code the name of the class on which to synchronize or make the class final.

Noncompliant Code Example

public class MyClass {
  public void doSomethingSynchronized(){
    synchronized (this.getClass()) {  // Noncompliant
      // ...
    }
  }

Compliant Solution

public class MyClass {
  public void doSomethingSynchronized(){
    synchronized (MyClass.class) {
      // ...
    }
  }

See

  • CERT, LCK02-J. - Do not synchronize on the class object returned by getClass()
squid:S3242

For maximum reusability, methods should accept parameters with as little specialization as possible. So unless specific features from a child class are required by a method, a type higher up the class hierarchy should be used instead.

Noncompliant Code Example

public void printSize(ArrayList<Object> list) {  // Collection can be used instead
    System.out.println(list.size());
}

public static void loop(List<Object> list) { // java.lang.Iterable can be used instead
   for (Object o : list) {
     o.toString();
  }
}

Compliant Solution

public void printSize(Collection<?> list) {  // Collection can be used instead
    System.out.println(list.size());
}

public static void loop(Iterable<?> list) { // java.lang.Iterable can be used instead
   for (Object o : list) {
     o.toString();
  }
}

Exceptions

Parameters in non-public methods are not checked, because such methods are not intended to be generally reusable. java.lang.String parameters are excluded, because String is immutable and can not be always substituted for more generic type. Parameters used in any other context than method invocation or enhanced for loop are also excluded.

squid:S3254

Specifying the default value for an annotation parameter is redundant. Such values should be omitted in the interests of readability.

Noncompliant Code Example

@MyAnnotation(arg = "def")  // Noncompliant
public class MyClass {
  // ...
}
public @interface MyAnnotation {
  String arg() default "def";
}

Compliant Solution

@MyAnnotation
public class MyClass {
  // ...
}
public @interface MyAnnotation {
  String arg() default "def";
}
squid:S3282

Exclusions for default interceptors can be declared either in xml or as class annotations. Since annotations are more visible to maintainers, they are preferred.

Noncompliant Code Example

<assembly-descriptor>
      <interceptor-binding>
         <ejb-name>MyExcludedClass</ejb-name>
         <exclude-default-interceptors>true</exclude-default-interceptors> <!-- Noncompliant -->
         <exclude-class-interceptors>true</exclude-class-interceptors> <!-- Noncomopliant -->
         <method>
           <method-name>doTheThing</method-name>
         </method>
      </interceptor-binding>

</assembly-descriptor>

Compliant Solution

@ExcludeDefaultInterceptors
public class MyExcludedClass implements MessageListener
{

  @ExcludeClassInterceptors
  @ExcludeDefaultInterceptors
  public void doTheThing() {
    // ...
  }
squid:S3305

When @Autowired is used, dependencies need to be resolved when the class is instantiated, which may cause early initialization of beans or lead the context to look in places it shouldn't to find the bean. To avoid this tricky issue and optimize the way the context loads, dependencies should be requested as late as possible. That means using parameter injection instead of field injection for dependencies that are only used in a single @Bean method.

Noncompliant Code Example

@Configuration
public class ​FooConfiguration {

  @Autowired private ​DataSource dataSource​;  // Noncompliant

  @Bean
  public ​MyService myService() {
    return new ​MyService(this​.dataSource​);
  }
}

Compliant Solution

@Configuration
public class ​FooConfiguration {

 @Bean
  public ​MyService myService(DataSource dataSource) {
    return new ​MyService(dataSource);
  }
}

Exceptions

Fields used in methods that are called directly by other methods in the application (as opposed to being invoked automatically by the Spring framework) are ignored by this rule so that direct callers don't have to provide the dependencies themselves.

squid:S3340

For optimal code readability, annotation arguments should be specified in the same order that they were declared in the annotation definition.

Noncompliant Code Example

@interface Pet {
    String name();
    String surname();
}

@Pet(surname ="", name="") // Noncompliant

Compliant Solution

@interface Pet {
    String name();
    String surname();
}

@Pet(name ="", surname="") // Compliant
squid:S3346

Since assert statements aren't executed by default (they must be enabled with JVM flags) developers should never rely on their execution the evaluation of any logic required for correct program function.

Noncompliant Code Example

assert myList.remove(myList.get(0));  // Noncompliant

Compliant Solution

boolean removed = myList.remove(myList.get(0));
assert removed;

See

  • CERT, EXP06-J. - Expressions used in assertions must not produce side effects
squid:S3358

Just because you can do something, doesn't mean you should, and that's the case with nested ternary operations. Nesting ternary operators results in the kind of code that may seem clear as day when you write it, but six months later will leave maintainers (or worse - future you) scratching their heads and cursing.

Instead, err on the side of clarity, and use another line to express the nested operation as a separate statement.

Noncompliant Code Example

public String getTitle(Person p) {
  return p.gender == Person.MALE ? "Mr. " : p.isMarried() ? "Mrs. " : "Miss ";  // Noncompliant
}

Compliant Solution

public String getTitle(Person p) {
  if (p.gender == Person.MALE) {
    return "Mr. ";
  }
  return p.isMarried() ? "Mrs. " : "Miss ";
}
squid:S3366

In single-threaded environments, the use of this in constructors is normal, and expected. But in multi-threaded environments, it could expose partially-constructed objects to other threads, and should be used with caution.

The classic example is a class with a static list of its instances. If the constructor stores this in the list, another thread could access the object before it's fully-formed. Even when the storage of this is the last instruction in the constructor, there's still a danger if the class is not final. In that case, the initialization of subclasses won't be complete before this is exposed.

This rule raises an issue when this is assigned to any globally-visible object in a constructor, and when it is passed to the method of another object in a constructor

Noncompliant Code Example

public class Monument {

  public static final List<Monument> ALL_MONUMENTS = new ArrayList()<>;
  // ...

  public Monument(String location, ...) {
    ALL_MONUMENTS.add(this);  // Noncompliant; passed to a method of another object

    this.location = location;
    // ...
  }
}

Exceptions

This rule ignores instances of assigning this directly to a static field of the same class because that case is covered by S3010.

See

  • CERT, TSM01-J. - Do not let the this reference escape during object construction
  • CERT, TSM03-J. - Do not publish partially initialized objects
squid:S3373

It makes sense to handle all related actions in the same place. Thus, the same <action> might logically handle all facets of CRUD on an entity, with no confusion in the naming about which <forward/> handles which facet. But go very far beyond that, and it becomes difficult to maintain a transparent naming convention.

So to ease maintenance, this rule raises an issue when an <action> has more than the allowed number of <forward/> tags.

Noncompliant Code Example

With the default threshold of 4:

<action path='/book' type='myapp.BookDispatchAction' name='form' parameter='method'>
  <forward name='create' path='/WEB-INF/jsp/BookCreate.jspx' redirect='false'/>
  <forward name='read' path='/WEB-INF/jsp/BookDetails' redirect='false'/>
  <forward name='update' path='/WEB-INF/jsp/BookUpdate.jspx' redirect='false'/>
  <forward name='delete' path='/WEB-INF/jsp/BookDelete.jspx' redirect='false'/>
  <forward name='authorRead' path='WEB-INF/jsp/AuthorDetails' redirect='false'/>  <!-- Noncompliant -->
</action>

Compliant Solution

<action path='/book' type='myapp.BookDispatchAction' name='bookForm' parameter='method'>
  <forward name='create' path='/WEB-INF/jsp/BookCreate.jspx' redirect='false'/>
  <forward name='read' path='/WEB-INF/jsp/BookDetails' redirect='false'/>
  <forward name='update' path='/WEB-INF/jsp/BookUpdate.jspx' redirect='false'/>
  <forward name='delete' path='/WEB-INF/jsp/BookDelete.jspx' redirect='false'/>
</action>

<action path='/author' type='myapp.AuthorDispatchAction' name='authorForm' parameter='method'>
  <forward name='authorRead' path='WEB-INF/jsp/AuthorDetails' redirect='false'/>
</action>
squid:S3374

According to the Common Weakness Enumeration,

If two validation forms have the same name, the Struts Validator arbitrarily chooses one of the forms to use for input validation and discards the other. This decision might not correspond to the programmer's expectations...

In such a case, it is likely that the two forms should be combined. At the very least, one should be removed.

Noncompliant Code Example

<form-validation>
  <formset>
    <form name="BookForm"> ... </form>
    <form name="BookForm"> ... </form>  <!-- Noncompliant -->
  </formset>
</form-validation>

Compliant Solution

<form-validation>
  <formset>
    <form name="BookForm"> ... </form>
  </formset>
</form-validation>

See

squid:S3398

When a private method is only invoked by an inner class, there's no reason not to move it into that class. It will still have the same access to the outer class' members, but the outer class will be clearer and less cluttered.

Noncompliant Code Example

public class Outie {
  private int i=0;

  private void increment() {  // Noncompliant
    i++;
  }

  public class Innie {
    public void doTheThing() {
      Outie.this.increment();
    }
  }
}

Compliant Solution

public class Outie {
  private int i=0;

  public class Innie {
    public void doTheThing() {
      Outie.this.increment();
    }

    private void increment() {
      Outie.this.i++;
    }
  }
}
squid:S3400

There's no point in forcing the overhead of a method call for a method that always returns the same constant value. Even worse, the fact that a method call must be made will likely mislead developers who call the method thinking that something more is done. Declare a constant instead.

This rule raises an issue if on methods that contain only one statement: the return of a constant value.

Noncompliant Code Example

int getBestNumber() {
  return 12;  // Noncompliant
}

Compliant Solution

static int bestNumber = 12;

Exceptions

Methods with annotations, such as @Override and Spring's @RequestMapping, are ignored.

squid:S3415

The standard assertions library methods such as org.junit.Assert.assertEquals, and org.junit.Assert.assertSame 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

org.junit.Assert.assertEquals(runner.exitCode(), 0, "Unexpected exit code");  // Noncompliant; Yields error message like: Expected:<-1>. Actual:<0>.

Compliant Solution

org.junit.Assert.assertEquals(0, runner.exitCode(), "Unexpected exit code");
squid:S3419

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when the a pom's groupId does not match the provided regular expression.

Noncompliant Code Example

With the default regular expression: (com|org)(\.[a-z][a-z-0-9]*)+

<project ...>
  <groupId>myCo</groupId>  <!-- Noncompliant -->

  <!-- ... -->
</project>

Compliant Solution

<project ...>
  <groupId>com.myco</groupId>

  <!-- ... -->
</project>
squid:S3420

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a pom's artifactId does not match the provided regular expression.

Noncompliant Code Example

With the default regular expression: [a-z][a-z-0-9]+

<project ...>
  <artifactId>My_Project</artifactId>  <!-- Noncompliant -->

  <!-- ... -->
</project>

Compliant Solution

<project ...>
  <artifactId>my-project</artifactId>

  <!-- ... -->
</project>
squid:S3421

Deprecated features are those that have been retained temporarily for backward compatibility, but which will eventually be removed. In effect, deprecation announces a grace period to allow the smooth transition from the old features to the new ones. In that period, no use of the deprecated features should be added, and all existing uses should be gradually removed.

This rule raises an issue when ${pom.*} properties are used in a pom.

Noncompliant Code Example

  <build>
    <finalName>${pom.artifactId}-${pom.version}</finalName>  <!-- Noncompliant -->

Compliant Solution

  <build>
    <finalName>${project.artifactId}-${project.version}</finalName>

or

  <build>
    <finalName>${artifactId}-${version}</finalName>
squid:S3422

system dependencies are sought at a specific, specified path. This drastically reduces portability because if you deploy your artifact in an environment that's not configured just like yours is, your code won't work.

Noncompliant Code Example

<dependency>
  <groupId>javax.sql</groupId>
  <artifactId>jdbc-stdext</artifactId>
  <version>2.0</version>
  <scope>system</scope>  <!-- Noncompliant -->
  <systemPath>/usr/bin/lib/rt.jar</systemPath>  <!-- remove this -->
</dependency>
squid:S3423

The POM Code Convention is the Maven project's internal recommendation for POM element ordering. It calls for listing modifiers in the following order:

  1. <modelVersion/>
  2. <parent/>
  3. <groupId/>
  4. <artifactId/>
  5. <version/>
  6. <packaging/>
  7. <name/>
  8. <description/>
  9. <url/>
  10. <inceptionYear/>
  11. <organization/>
  12. <licenses/>
  13. <developers/>
  14. <contributors/>
  15. <mailingLists/>
  16. <prerequisites/>
  17. <modules/>
  18. <scm/>
  19. <issueManagement/>
  20. <ciManagement/>
  21. <distributionManagement/>
  22. <properties/>
  23. <dependencyManagement/>
  24. <dependencies/>
  25. <repositories/>
  26. <pluginRepositories/>
  27. <build/>
  28. <reporting/>
  29. <profiles/>

Not following this convention has no technical impact, but will reduce the pom's readability because most developers are used to the standard order.

See

squid:S3438

Use of a Spring SingleConnectionFactory without enabling the reconnectOnException setting will prevent automatic connection recovery when the connection goes bad.

That's because the reconnectOnException property defaults to false. As a result, even if the code that uses this connection factory (Spring's DefaultMessageListenerContainer or your own code) has reconnect logic, that code won't work because the SingleConnectionFactory will act like a single-connection pool by preventing connection close calls from actually closing anything. As a result, subsequent factory create operations will just hand back the original broken Connection.

Noncompliant Code Example

 <bean id="singleCF" class="org.springframework.jms.connection.SingleConnectionFactory">  <!-- Noncompliant -->
   <constructor-arg ref="dummyConnectionFactory" />
 </bean>

Compliant Solution

 <bean id="singleCF" class="org.springframework.jms.connection.SingleConnectionFactory" p:reconnectOnException="true">
   <constructor-arg ref="dummyConnectionFactory" />
 </bean>

or

 <bean id="singleCF" class="org.springframework.jms.connection.SingleConnectionFactory">
   <constructor-arg ref="dummyConnectionFactory" />
   <property name="reconnectOnException"><value>true</value></property>
 </bean>
squid:S3457

Because printf-style format strings are interpreted at runtime, rather than validated by the compiler, they can contain errors that result in the wrong strings being created. This rule statically validates the correlation of printf-style format strings to their arguments when calling the format(...) methods of java.util.Formatter, java.lang.String, java.io.PrintStream, MessageFormat, and java.io.PrintWriter classes and the printf(...) methods of java.io.PrintStream or java.io.PrintWriter classes.

Noncompliant Code Example

String.format("First {0} and then {1}", "foo", "bar");  //Noncompliant. Looks like there is a confusion with the use of {{java.text.MessageFormat}}, parameters "foo" and "bar" will be simply ignored here
String.format("Display %3$d and then %d", 1, 2, 3);   //Noncompliant; the second argument '2' is unused
String.format("Too many arguments %d and %d", 1, 2, 3);  //Noncompliant; the third argument '3' is unused
String.format("First Line\n");   //Noncompliant; %n should be used in place of \n to produce the platform-specific line separator
String.format("Is myObject null ? %b", myObject);   //Noncompliant; when a non-boolean argument is formatted with %b, it prints true for any nonnull value, and false for null. Even if intended, this is misleading. It's better to directly inject the boolean value (myObject == null in this case)
String.format("value is " + value); // Noncompliant
String s = String.format("string without arguments"); // Noncompliant

MessageFormat.format("Result '{0}'.", value); // Noncompliant; String contains no format specifiers. (quote are discarding format specifiers)
MessageFormat.format("Result {0}.", value, value);  // Noncompliant; 2nd argument is not used
MessageFormat.format("Result {0}.", myObject.toString()); // Noncompliant; no need to call toString() on objects

java.util.Logger logger;
logger.log(java.util.logging.Level.SEVERE, "Result {0}.", myObject.toString()); // Noncompliant; no need to call toString() on objects
logger.log(java.util.logging.Level.SEVERE, "Result.", new Exception()); // compliant, parameter is an exception
logger.log(java.util.logging.Level.SEVERE, "Result '{0}'", 14); // Noncompliant {{String contains no format specifiers.}}

org.slf4j.Logger slf4jLog;
org.slf4j.Marker marker;

slf4jLog.debug(marker, "message {}");
slf4jLog.debug(marker, "message ", 1); // Noncompliant {{String contains no format specifiers.}}

Compliant Solution

String.format("First %s and then %s", "foo", "bar");
String.format("Display %2$d and then %d", 1, 3);
String.format("Too many arguments %d %d", 1, 2);
String.format("First Line%n");
String.format("Is myObject null ? %b", myObject == null);
String.format("value is %d", value);
String s = "string without arguments";

MessageFormat.format("Result {0}.", value);
MessageFormat.format("Result '{0}'  =  {0}", value);
MessageFormat.format("Result {0}.", myObject);

java.util.Logger logger;
logger.log(java.util.logging.Level.SEVERE, "Result {0}.", myObject);
logger.log(java.util.logging.Level.SEVERE, "Result {0}'", 14);


org.slf4j.Logger slf4jLog;
org.slf4j.Marker marker;

slf4jLog.debug(marker, "message {}");
slf4jLog.debug(marker, "message {}", 1);

See

squid:S3516

When a method is designed to return an invariant value, it may be poor design, but it shouldn't adversely affect the outcome of your program. However, when it happens on all paths through the logic, it is surely a bug.

This rule raises an issue when a method contains several return statements that all return the same value.

Noncompliant Code Example

int foo(int a) {
  int b = 12;
  if (a == 1) {
    return b;
  }
  return b;  // Noncompliant
}
squid:S3518

If the denominator to a division or modulo operation is zero it would result in a fatal error.

Noncompliant Code Example

void test_divide() {
  int z = 0;
  if (unknown()) {
    // ..
    z = 3;
  } else {
    // ..
  }
  z = 1 / z; // Noncompliant, possible division by zero
}

Compliant Solution

void test_divide() {
  int z = 0;
  if (unknown()) {
    // ..
    z = 3;
  } else {
    // ..
    z = 1;
  }
  z = 1 / z;
}

See

  • MITRE, CWE-369 - Divide by zero
  • CERT, NUM02-J. - Ensure that division and remainder operations do not result in divide-by-zero errors
  • CERT, INT33-C. - Ensure that division and remainder operations do not result in divide-by-zero errors
squid:S3626

Jump statements such as return and continue let you change the default flow of program execution, but jump statements that direct the control flow to the original direction are just a waste of keystrokes.

Noncompliant Code Example

public void foo() {
  while (condition1) {
    if (condition2) {
      continue; // Noncompliant
    } else {
      doTheThing();
    }
  }
  return; // Noncompliant; this is a void method
}

Compliant Solution

public void foo() {
  while (condition1) {
    if (!condition2) {
      doTheThing();
    }
  }
}
squid:S3631

For arrays of objects, Arrays.asList(T ... a).stream() and Arrays.stream(array) are basically equivalent in terms of performance. However, for arrays of primitives, using Arrays.asList will force the construction of a list of boxed types, and then use that list as a stream. On the other hand, Arrays.stream uses the appropriate primitive stream type (IntStream, LongStream, DoubleStream) when applicable, with much better performance.

Noncompliant Code Example

Arrays.asList("a1", "a2", "b1", "c2", "c1").stream()
    .filter(...)
    .forEach(...);

Arrays.asList(1, 2, 3, 4).stream() // Noncompliant
    .filter(...)
    .forEach(...);

Compliant Solution

Arrays.asList("a1", "a2", "b1", "c2", "c1").stream()
    .filter(...)
    .forEach(...);

int[] intArray = new int[]{1, 2, 3, 4};
Arrays.stream(intArray)
    .filter(...)
    .forEach(...);
squid:S3725

The Files.exists method has noticeably poor performance in JDK 8, and can slow an application significantly when used to check files that don't actually exist.

The same goes for Files.notExists, Files.isDirectory and Files.isRegularFile.

Note that this rule is automatically disabled when the project's sonar.java.source is not 8.

Noncompliant Code Example

Path myPath;
if(java.nio.Files.exists(myPath)) {  // Noncompliant
 // do something
}

Compliant Solution

Path myPath;
if(myPath.toFile().exists())) {
 // do something
}

See

squid:S3750

Spring @Controllers, @Services, and @Repositorys have singleton scope by default, meaning only one instance of the class is ever instantiated in the application. Defining any other scope for one of these class types will result in needless churn as new instances are created and destroyed. In a busy web application, this could cause a significant amount of needless additional load on the server.

This rule raises an issue when the @Scope annotation is applied to a @Controller, @Service, or @Repository with any value but "singleton". @Scope("singleton") is redundant, but ignored.

Noncompliant Code Example

@Scope("prototype")  // Noncompliant
@Controller
public class HelloWorld {

Compliant Solution

@Controller
public class HelloWorld {
squid:S3753

A Spring @Controller that uses @SessionAttributes is designed to handle a stateful / multi-post form. Such @Controllers use the specified @SessionAttributes to store data on the server between requests. That data should be cleaned up when the session is over, but unless setComplete() is called on the SessionStatus object from a @RequestMapping method, neither Spring nor the JVM will know it's time to do that. Note that the SessionStatus object must be passed to that method as a parameter.

Noncompliant Code Example

@Controller
@SessionAttributes("hello")  // Noncompliant; this doesn't get cleaned up
public class HelloWorld {

  @RequestMapping("/greet", method = GET)
  public String greet(String greetee) {

    return "Hello " + greetee;
  }
}

Compliant Solution

@Controller
@SessionAttributes("hello")
public class HelloWorld {

  @RequestMapping("/greet", method = GET)
  public String greet(String greetee) {

    return "Hello " + greetee;
  }

  @RequestMapping("/goodbye", method = POST)
  public String goodbye(SessionStatus status) {
    //...
    status.setComplete();
  }

}
squid:S3824

It's a common pattern to test the result of a java.util.Map.get() against null before proceeding with adding or changing the value in the map. However the java.util.Map API offers a significantly better alternative in the form of the computeIfPresent() and computeIfAbsent() methods. Using these instead leads to cleaner and more readable code.

Note that this rule is automatically disabled when the project's sonar.java.source is not 8.

Noncompliant Code Example

V value = map.get(key);
if (value == null) {  // Noncompliant
  value = V.createFor(key);
  if (value != null) {
    map.put(key, value);
  }
}
return value;

Compliant Solution

return map.computeIfAbsent(key, k -> V.createFor(k));
squid:S3923

Having all branches in a switch or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a switch/if chain at all.

Noncompliant Code Example

if (b == 0) {  // Noncompliant
  doOneMoreThing();
} else {
  doOneMoreThing();
}

int b = a > 12 ? 4 : 4;  // Noncompliant

switch (i) {  // Noncompliant
  case 1:
    doSomething();
    break;
  case 2:
    doSomething();
    break;
  case 3:
    doSomething();
    break;
  default:
    doSomething();
}

Exceptions

This rule does not apply to if chains without else-s, or to switch-es without default clauses.

if(b == 0) {    //no issue, this could have been done on purpose to make the code more readable
  doSomething();
} else if(b == 1) {
  doSomething();
}
squid:S3937

The use of punctuation characters to separate subgroups in a number can make the number more readable. For instance consider 1,000,000,000 versus 1000000000. But when the grouping is irregular, such as 1,000,00,000; it indicates an error.

This rule raises an issue when underscores (_) are used to break a number into irregular subgroups.

Noncompliant Code Example

int duos = 1_00_00;
int million = 1_000_00_000;  // Noncompliant
int thousand = 1000;
int tenThousand = 100_00;  // Noncompliant
squid:S3958

There are two types of stream operations: intermediate operations, which return another stream, and terminal operations, which return something other than a stream. Intermediate operations are lazy, meaning they aren't actually executed until and unless a terminal stream operation is performed on their results. Consequently if the result of an intermediate stream operation is not fed to a terminal operation, it serves no purpose, which is almost certainly an error.

Noncompliant Code Example

widgets.stream().filter(b -> b.getColor() == RED); // Noncompliant

Compliant Solution

int sum = widgets.stream()
                      .filter(b -> b.getColor() == RED)
                      .mapToInt(b -> b.getWeight())
                      .sum();
Stream<Widget> pipeline = widgets.stream()
                                 .filter(b -> b.getColor() == GREEN)
                                 .mapToInt(b -> b.getWeight());
sum = pipeline.sum();

See

Stream Operations

squid:S3959

Stream operations are divided into intermediate and terminal operations, and are combined to form stream pipelines. After the terminal operation is performed, the stream pipeline is considered consumed, and cannot be used again. Such a reuse will yield unexpected results.

Noncompliant Code Example

Stream<Widget> pipeline = widgets.stream().filter(b -> b.getColor() == RED);
int sum1 = pipeline.sum();
int sum2 = pipeline.mapToInt(b -> b.getWeight()).sum(); // Noncompliant

See

Stream Operations

squid:S3972

Code is clearest when each statement has its own line. Nonetheless, it is a common pattern to combine on the same line an if and its resulting then statement. However, when an if is placed on the same line as the closing } from a preceding else or else if, it is either an error - else is missing - or the invitation to a future error as maintainers fail to understand that the two statements are unconnected.

Noncompliant Code Example

if (condition1) {
  // ...
} if (condition2) {  // Noncompliant
  //...
}

Compliant Solution

if (condition1) {
  // ...
} else if (condition2) {
  //...
}

Or

if (condition1) {
  // ...
}

if (condition2) {
  //...
}
squid:S3973

In the absence of enclosing curly braces, the line immediately after a conditional is the one that is conditionally executed. By both convention and good practice, such lines are indented. In the absence of both curly braces and indentation the intent of the original programmer is entirely unclear and perhaps not actually what is executed. Additionally, such code is highly likely to be confusing to maintainers.

Noncompliant Code Example

if (condition)  // Noncompliant
doTheThing();

doTheOtherThing();
somethingElseEntirely();

foo();

Compliant Solution

if (condition)
  doTheThing();

doTheOtherThing();
somethingElseEntirely();

foo();
squid:S3981

The size of a collection and the length of an array are always greater than or equal to zero. So testing that a size or length is greater than or equal to zero doesn't make sense, since the result is always true. Similarly testing that it is less than zero will always return false. Perhaps the intent was to check the non-emptiness of the collection or array instead.

Noncompliant Code Example

if (myList.size() >= 0) { ... }

if (myList.size() < 0) { ... }

boolean result = myArray.length >= 0;

if (0 > myArray.length) { ... }

Compliant Solution

if (!myList.isEmpty()) { ... }

if (myArray.length >= 42) { ... }
squid:S3985

private classes that are never used are dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.

Noncompliant Code Example

public class Foo
{
  ...
  private class MyUnusedPrivateClass {...} // Noncompliant
}
squid:S3986

Few developers are aware of the difference between Y for "Week year" and y for Year when formatting and parsing a date with SimpleDateFormat. That's likely because for most dates, Week year and Year are the same, so testing at any time other than the first or last week of the year will yield the same value for both y and Y. But in the last week of December and the first week of January, you may get unexpected results.

According to the Javadoc:

A week year is in sync with a WEEK_OF_YEAR cycle. All weeks between the first and last weeks (inclusive) have the same week year value. Therefore, the first and last days of a week year may have different calendar year values.

For example, January 1, 1998 is a Thursday. If getFirstDayOfWeek() is MONDAY and getMinimalDaysInFirstWeek() is 4 (ISO 8601 standard compatible setting), then week 1 of 1998 starts on December 29, 1997, and ends on January 4, 1998. The week year is 1998 for the last three days of calendar year 1997. If, however, getFirstDayOfWeek() is SUNDAY, then week 1 of 1998 starts on January 4, 1998, and ends on January 10, 1998; the first three days of 1998 then are part of week 53 of 1997 and their week year is 1997.

Noncompliant Code Example

Date date = new SimpleDateFormat("yyyy/MM/dd").parse("2015/12/31");
String result = new SimpleDateFormat("YYYY/MM/dd").format(date);   //Noncompliant; yields '2016/12/31'

Compliant Solution

Date date = new SimpleDateFormat("yyyy/MM/dd").parse("2015/12/31");
String result = new SimpleDateFormat("yyyy/MM/dd").format(date);   //Yields '2015/12/31' as expected

Exceptions

Date date = new SimpleDateFormat("yyyy/MM/dd").parse("2015/12/31");
String result = new SimpleDateFormat("YYYY-ww").format(date);  //compliant, 'Week year' is used along with 'Week of year'. result = '2016-01'
squid:S4032

There is no reason to have a package that is empty except for "package-info.java". Such packages merely clutter a project, taking up space but adding no value.

squid:S4042

When java.io.File#delete fails, this boolean method simply returns false with no indication of the cause. On the other hand, when java.nio.Files#delete fails, this void method returns one of a series of exception types to better indicate the cause of the failure. And since more information is generally better in a debugging situation, java.nio.Files#delete is the preferred option.

Noncompliant Code Example

public void cleanUp(Path path) {
  File file = new File(path);
  if (!file.delete()) {  // Noncompliant
    //...
  }
}

Compliant Solution

public void cleanUp(Path path) throws NoSuchFileException, DirectoryNotEmptyException, IOException{
  Files.delete(path);
}
squid:S4065

Java 8 introduced ThreadLocal.withInitial which is a simpler alternative to creating an anonymous inner class to initialise a ThreadLocal instance.

This rule raises an issue when a ThreadLocal anonymous inner class can be replaced by a call to ThreadLocal.withInitial.

Noncompliant Code Example

ThreadLocal<List<String>> myThreadLocal =
    new ThreadLocal<List<String>>() { // Noncompliant
        @Override
        protected List<String> initialValue() {
            return new ArrayList<String>();
        }
    };

Compliant Solution

ThreadLocal<List<String>> myThreadLocal = ThreadLocal.withInitial(ArrayList::new);
squid:S4142

There are valid cases for passing a variable multiple times into the same method call, but usually doing so is a mistake, and something else was intended for one of the arguments.

Noncompliant Code Example

if (compare(myPoint.x, myPoint.x) != 0) { // Noncompliant
  //...
}

if (compare(getNextValue(), getNextValue()) != 0) { // Noncompliant
  // ...
}

Compliant Solution

if (compare(myPoint.x, myPoint.y) != 0) {
  //...
}

Object v1 = getNextValue();
Object v2 = getNextValue();
if (compare(v1, v2) != 0) {
  // ...
}

Deprecated

This rule is deprecated, and will eventually be removed.

squid:S4143

It is highly suspicious when a value is saved for a key or index and then unconditionally overwritten. Such replacements are likely in error.

Noncompliant Code Example

letters.put("a", "Apple");
letters.put("a", "Boy");  // Noncompliant

towns[i] = "London";
towns[i] = "Chicago";  // Noncompliant
squid:S4144

When two methods have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, one implementation should invoke the other. Numerical and string literals are not taken into account.

Noncompliant Code Example

private final static String CODE = "bounteous";

public String calculateCode() {
  doTheThing();
  return CODE;
}

public String getName() {  // Noncompliant
  doTheThing();
  return CODE;
}

Compliant Solution

private final static String CODE = "bounteous";

public String getCode() {
  doTheThing();
  return CODE;
}

public String getName() {
  return getCode();
}

Exceptions

Methods that are not accessors (getters and setters), with fewer than 2 statements are ignored.

squid:S4165

The transitive property says that if a == b and b == c, then a == c. In such cases, there's no point in assigning a to c or vice versa because they're already equivalent.

This rule raises an issue when an assignment is useless because the assigned-to variable already holds the value on all execution paths.

Noncompliant Code Example

a = b;
c = a;
b = c; // Noncompliant: c and b are already the same

Compliant Solution

a = b;
c = a;
squid:S4174

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all local, final, initialized, primitive variables, have names that match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$:

public void doSomething() {
  final int local = 42;
  ...
}

Compliant Solution

public void doSomething() {
  final int LOCAL = 42;
  ...
}
squid:S4201

There's no need to null test in conjunction with an instanceof test. null is not an instanceof anything, so a null check is redundant.

Noncompliant Code Example

if (x != null && x instanceof MyClass) { ... }  // Noncompliant

if (x == null || ! x instanceof MyClass) { ... } // Noncompliant

Compliant Solution

if (x instanceof MyClass) { ... }

if (! x instanceof MyClass) { ... }
squid:S4248

The java.util.regex.Pattern.compile() methods have a significant performance cost, and therefore should be used sensibly.

Moreover they are the only mechanism available to create instances of the Pattern class, which are necessary to do any pattern matching using regular expressions. Unfortunately that can be hidden behind convenience methods like String.matches() or String.split().

It is therefore somewhat easy to inadvertently repeatedly compile the same regular expression at great performance cost with no valid reason.

This rule raises an issue when:

  • A Pattern is compiled from a String literal or constant and is not stored in a static final reference.
  • String.matches, String.split, String.replaceAll or String.replaceFirst are invoked with a String literal or constant. In which case the code should be refactored to use a java.util.regex.Pattern while respecting the previous rule.

Noncompliant Code Example

public void doingSomething(String stringToMatch) {
  Pattern regex = Pattern.compile("myRegex");  // Noncompliant
  Matcher matcher = regex.matcher("s");
  // ...
  if (stringToMatch.matches("myRegex2")) {  // Noncompliant
    // ...
  }
}

Compliant Solution

private static final Pattern myRegex = Pattern.compile("myRegex");
private static final Pattern myRegex2 = Pattern.compile("myRegex2");

public void doingSomething(String stringToMatch) {
  Matcher matcher = myRegex.matcher("s");
  // ...
  if (myRegex2.matcher(stringToMatch).matches()) {
    // ...
  }
}

Exceptions

String.split doesn't create a regex when the string passed as argument meets either of these 2 conditions:

  • It is a one-char String and this character is not one of the RegEx's meta characters ".$|()[{^?*+\"
  • It is a two-char String and the first char is the backslash and the second is not the ascii digit or ascii letter.

In which case no issue will be raised.

squid:S4274

An assert is inappropriate for parameter validation because assertions can be disabled at runtime in the JVM, meaning that a bad operational setting would completely eliminate the intended checks. Further, asserts that fail throw AssertionErrors, rather than throwing some type of Exception. Throwing Errors is completely outside of the normal realm of expected catch/throw behavior in normal programs.

This rule raises an issue when a public method uses one or more of its parameters with asserts.

Noncompliant Code Example

 public void setPrice(int price) {
  assert price >= 0 && price <= MAX_PRICE;
  // Set the price
 }

Compliant Solution

 public void setPrice(int price) {
  if (price < 0 || price > MAX_PRICE) {
    throw new IllegalArgumentException("Invalid price: " + price);
  }
  // Set the price
 }

See

Programming With Assertions

squid:S4275

Getters and setters provide a way to enforce encapsulation by providing public methods that give controlled access to private fields. However in classes with multiple fields it is not unusual that cut and paste is used to quickly create the needed getters and setters, which can result in the wrong field being accessed by a getter or setter.

This rule raises an issue in any of these cases:

  • A setter does not update the field with the corresponding name.
  • A getter does not access the field with the corresponding name.

Noncompliant Code Example

class A {
  private int x;
  private int y;

  public void setX(int val) { // Noncompliant: field 'x' is not updated
    this.y = val;
  }

  public int getY() { // Noncompliant: field 'y' is not used in the return value
    return this.x;
  }
}

Compliant Solution

class A {
  private int x;
  private int y;

  public void setX(int val) {
    this.x = val;
  }

  public int getY() {
    return this.y;
  }
}
squid:S4276

The java.util.function package provides a large array of functional interface definitions for use in lambda expressions and method references. In general it is recommended to use the more specialised form to avoid auto-boxing. For instance IntFunction<Foo> should be preferred over Function<Integer, Foo>.

This rule raises an issue when any of the following substitution is possible:

Current Interface Preferred Interface
Function<Integer, R> IntFunction<R>
Function<Long, R> LongFunction<R>
Function<Double, R> DoubleFunction<R>
Function<Double,Integer> DoubleToIntFunction
Function<Double,Long> DoubleToLongFunction
Function<Long,Double> LongToDoubleFunction
Function<Long,Integer> LongToIntFunction
Function<R,Integer> ToIntFunction<R>
Function<R,Long> ToLongFunction<R>
Function<R,Double> ToDoubleFunction<R>
Function<T,T> UnaryOperator<T>
BiFunction<T,T,T> BinaryOperator<T>
Consumer<Integer> IntConsumer
Consumer<Double> DoubleConsumer
Consumer<Long> LongConsumer
BiConsumer<T,Integer> ObjIntConsumer<T>
BiConsumer<T,Long> ObjLongConsumer<T>
BiConsumer<T,Double> ObjDoubleConsumer<T>
Predicate<Integer> IntPredicate
Predicate<Double> DoublePredicate
Predicate<Long> LongPredicate
Supplier<Integer> IntSupplier
Supplier<Double> DoubleSupplier
Supplier<Long> LongSupplier
Supplier<Boolean> BooleanSupplier
UnaryOperator<Integer> IntUnaryOperator
UnaryOperator<Double> DoubleUnaryOperator
UnaryOperator<Long> LongUnaryOperator
BinaryOperator<Integer> IntBinaryOperator
BinaryOperator<Long> LongBinaryOperator
BinaryOperator<Double> DoubleBinaryOperator
Function<T, Boolean> Predicate<T>
BiFunction<T,U,Boolean> BiPredicate<T,U>

Noncompliant Code Example

public class Foo implements Supplier<Integer> {  // Noncompliant
    @Override
    public Integer get() {
      // ...
    }
}

Compliant Solution

public class Foo implements IntSupplier {

  @Override
  public int getAsInt() {
    // ...
  }
}
squid:S4288

Spring @Controller, @Service, and @Repository classes are singletons by default, meaning only one instance of the class is ever instantiated in the application. Typically such a class might have a few static members, such as a logger, but all non-static members should be managed by Spring and supplied via constructor injection rather than by field injection.

This rule raise an issue when any non-static member of a Spring component has an injection annotation, or if the constructor of Spring component does not have injection annotation.

Noncompliant Code Example

@Controller
public class HelloWorld {

  @Autowired
  private String name = null; // Noncompliant

  HelloWorld() {
   // ...
  }

  // ...
}

Compliant Solution

@Controller
public class HelloWorld {

  private String name = null;

  @Autowired
  HelloWorld(String name) {
    this.name = name;
   // ...
  }

  // ...
}
squid:S4348

There are two classes in the Java standard library that deal with iterations: Iterable<T> and Iterator<T>. An Iterable<T> represents a data structure that can be the target of the "for-each loop" statement, and an Iterator<T> represents the state of an ongoing traversal. An Iterable<T> is generally expected to support multiple traversals.

An Iterator<T> that also implements Iterable<t> by returning itself as its iterator() will not support multiple traversals since its state will be carried over.

This rule raises an issue when the iterator() method of a class implementing both Iterable<T> and Iterator<t> returns this.

Noncompliant Code Example

class FooIterator implements Iterator<Foo>, Iterable<Foo> {
  private Foo[] seq;
  private int idx = 0;

  public boolean hasNext() {
    return idx < seq.length;
  }

  public Foo next() {
    return seq[idx++];
  }

  public Iterator<Foo> iterator() {
    return this; // Noncompliant
  }
  // ...
}

Compliant Solution

class FooSequence implements Iterable<Foo> {
  private Foo[] seq;

  public Iterator<Foo> iterator() {
    return new Iterator<Foo>() {
      private int idx = 0;

      public boolean hasNext() {
        return idx < seq.length;
      }

      public Foo next() {
        return seq[idx++];
      }
    };
  }
  // ...
}
squid:S4349

When directly subclassing java.io.OutputStream or java.io.FilterOutputStream, the only requirement is that you implement the method write(int). However most uses for such streams don't write a single byte at a time and the default implementation for write(byte[],int,int) will call write(int) for every single byte in the array which can create a lot of overhead and is utterly inefficient. It is therefore strongly recommended that subclasses provide an efficient implementation of write(byte[],int,int).

This rule raises an issue when a direct subclass of java.io.OutputStream or java.io.FilterOutputStream doesn't provide an override of write(byte[],int,int).

Noncompliant Code Example

public class MyStream extends OutputStream { // Noncompliant
    private FileOutputStream fout;

    public MyStream(File file) throws IOException {
        fout = new FileOutputStream(file);
    }

    @Override
    public void write(int b) throws IOException {
        fout.write(b);
    }

    @Override
    public void close() throws IOException {
        fout.write("\n\n".getBytes());
        fout.close();
        super.close();
    }
}

Compliant Solution

public class MyStream extends OutputStream {
    private FileOutputStream fout;

    public MyStream(File file) throws IOException {
        fout = new FileOutputStream(file);
    }

    @Override
    public void write(int b) throws IOException {
        fout.write(b);
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        fout.write(b, off, len);
    }

    @Override
    public void close() throws IOException {
        fout.write("\n\n".getBytes());
        fout.close();
        super.close();
    }
}

Exceptions

This rule doesn't raise an issue when the class is declared abstract.

squid:S4351

When implementing the Comparable<T>.compareTo method, the parameter's type has to match the type used in the Comparable declaration. When a different type is used this creates an overload instead of an override, which is unlikely to be the intent.

This rule raises an issue when the parameter of the compareTo method of a class implementing Comparable<T> is not same as the one used in the Comparable declaration.

Noncompliant Code Example

public class Foo {
  static class Bar implements Comparable<Bar> {
    public int compareTo(Bar rhs) {
      return -1;
    }
  }

  static class FooBar extends Bar {
    public int compareTo(FooBar rhs) {  // Noncompliant: Parameter should be of type Bar
      return 0;
    }
  }
}

Compliant Solution

public class Foo {
  static class Bar implements Comparable<Bar> {
    public int compareTo(Bar rhs) {
      return -1;
    }
  }

  static class FooBar extends Bar {
    public int compareTo(Bar rhs) {
      return 0;
    }
  }
}
squid:S4425

Using Integer.toHexString is a common mistake when converting sequences of bytes into hexadecimal string representations. The problem is that the method trims leading zeroes, which can lead to wrong conversions. For instance a two bytes value of 0x4508 would be converted into 45 and 8 which once concatenated would give 0x458.

This is particularly damaging when converting hash-codes and could lead to a security vulnerability.

This rule raises an issue when Integer.toHexString is used in any kind of string concatenations.

Noncompliant Code Example

MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] bytes = md.digest(password.getBytes("UTF-8"));

StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
    sb.append(Integer.toHexString( b & 0xFF )); // Noncompliant
}

Compliant Solution

MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] bytes = md.digest(password.getBytes("UTF-8"));

StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
    sb.append(String.format("%02X", b));
}

See

squid:S4449

When using null-related annotations at global scope level, for instance using javax.annotation.ParametersAreNonnullByDefault (from JSR-305) at package level, it means that all the parameters to all the methods included in the package will, or should, be considered Non-null. It is equivalent to annotating every parameter in every method with non-null annotations (such as @Nonnull).

The rule raises an issue every time a parameter could be null for a method invocation, where the method is annotated as forbidding null parameters.

Noncompliant Code Example

@javax.annotation.ParametersAreNonnullByDefault
class A {

  void foo() {
    bar(getValue()); // Noncompliant - method 'bar' do not expect 'null' values as parameter
  }

  void bar(Object o) { // 'o' is by contract expected never to be null
    // ...
  }

  @javax.annotation.CheckForNull
  abstract Object getValue();
}

Compliant Solution

Two solutions are possible:

  • The signature of the method is correct, and null check should be done prior to the call.
  • The signature of the method is not coherent and should be annotated to allow null values being passed as parameter
@javax.annotation.ParametersAreNonnullByDefault
abstract class A {

  void foo() {
      Object o = getValue();
      if (o != null) {
        bar(); // Compliant - 'o' can not be null
      }
  }

  void bar(Object o) {
    // ...
  }

  @javax.annotation.CheckForNull
  abstract Object getValue();
}

or

@javax.annotation.ParametersAreNonnullByDefault
abstract class A {

  void foo() {
    bar(getValue());
  }

  void bar(@javax.annotation.Nullable Object o) { // annotation was missing
    // ...
  }

  @javax.annotation.CheckForNull
  abstract Object getValue();
}
squid:S4454

By contract, the equals(Object) method, from java.lang.Object, should accept a null argument. Among all the other cases, the null case is even explicitly detailed in the Object.equals(...) Javadoc, stating "_For any non-null reference value x, x.equals(null) should return false._"

Assuming that the argument to equals is always non-null, and enforcing that assumption with an annotation is not only a fundamental violation of the contract of equals, but it is also likely to cause problems in the future as the use of the class evolves over time.

The rule raises an issue when the equals method is overridden and its parameter annotated with any kind of @Nonnull annotation.

Noncompliant Code Example

public boolean equals(@javax.annotation.Nonnull Object obj) { // Noncompliant
  // ...
}

Compliant Solution

public boolean equals(Object obj) {
  if (obj == null) {
    return false;
  }
  // ...
}
squid:S4488

Spring framework 4.3 introduced variants of the @RequestMapping annotation to better represent the semantics of the annotated methods. The use of @GetMapping, @PostMapping, @PutMapping, @PatchMapping and @DeleteMapping should be preferred to the use of the raw @RequestMapping(method = RequestMethod.XYZ).

Noncompliant Code Example

@RequestMapping(path = "/greeting", method = RequestMethod.GET) // Noncompliant
public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
...
}

Compliant Solution

@GetMapping(path = "/greeting") // Compliant
public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
...
}
squid:S4551

Testing equality of an enum value with equals is perfectly valid because an enum is an Object and every Java developer knows "==" should not be used to compare the content of an Object. At the same time, using "==" on enums:

- provides the same expected comparison (content) as equals

- is more null-safe than equals()

- provides compile-time (static) checking rather than runtime checking

For these reasons, use of "==" should be preferred to equals.

Noncompliant Code Example

public enum Fruit {
   APPLE, BANANA, GRAPE
}

public enum Cake {
  LEMON_TART, CHEESE_CAKE
}

public boolean isFruitGrape(Fruit candidateFruit) {
  return candidateFruit.equals(Fruit.GRAPE); // Noncompliant; this will raise an NPE if candidateFruit is NULL
}

public boolean isFruitGrape(Cake candidateFruit) {
  return candidateFruit.equals(Fruit.GRAPE); // Noncompliant; always returns false
}

Compliant Solution

public boolean isFruitGrape(Fruit candidateFruit) {
  return candidateFruit == Fruit.GRAPE; // Compliant; there is only one instance of Fruit.GRAPE - if candidateFruit is a GRAPE it will have the same reference as Fruit.GRAPE
}

public boolean isFruitGrape(Cake candidateFruit) {
  return candidateFruit == Fruit.GRAPE; // Compliant; compilation time failure
}

See

squid:S4602

@ComponentScan is used to determine which Spring Beans are available in the application context. The packages to scan can be configured thanks to the basePackageClasses or basePackages (or its alias value) parameters. If neither parameter is configured, @ComponentScan will consider only the package of the class annotated with it. When @ComponentScan is used on a class belonging to the default package, the entire classpath will be scanned.

This will slow-down the start-up of the application and it is likely the application will fail to start with an BeanDefinitionStoreException because you ended up scanning the Spring Framework package itself.

This rule raises an issue when:

- @ComponentScan, @SpringBootApplication and @ServletComponentScan are used on a class belonging to the default package

- @ComponentScan is explicitly configured with the default package

Noncompliant Code Example

import org.springframework.boot.SpringApplication;

@SpringBootApplication // Noncompliant; RootBootApp is declared in the default package
public class RootBootApp {
...
}
@ComponentScan("")
public class Application {
...
}

Compliant Solution

package hello;

import org.springframework.boot.SpringApplication;

@SpringBootApplication // Compliant; RootBootApp belongs to the "hello" package
public class RootBootApp {
...
}
squid:S4603

@ComponentScan is used to find which Spring @Component beans (@Service or @Repository or Controller) are available in the classpath so they can be used in the application context. This is a convenient feature especially when you begin a new project but it comes with the drawback of slowing down the application start-up time especially when the application becomes bigger (ie: it references a large JAR file, or it references a significant number of JAR files, or the base-package refers to a large amount of .class files).

@ComponentScan should be replaced by an explicit list of Spring beans loaded by @Import.

The interface @SpringBootApplication is also considered by this rule because it is annotated with @ComponentScan.

Noncompliant Code Example

@ComponentScan
public class MyApplication {
...
}

@SpringBootApplication
public class MyApplication {
...
}

Compliant Solution

@Configuration
@Import({
        DispatcherServletAutoConfiguration.class,
        ErrorMvcAutoConfiguration.class,
        HttpEncodingAutoConfiguration.class,
        HttpMessageConvertersAutoConfiguration.class,
        MultipartAutoConfiguration.class,
        ServerPropertiesAutoConfiguration.class,
        PropertyPlaceholderAutoConfiguration.class,
        WebMvcAutoConfiguration.class
})
public class MyApplication {
...
}

See

squid:S4604

"@EnableAutoConfiguration" is a convenient feature to configure the Spring Application Context by attempting to guess the beans that you are likely to need. The drawback is that it may load and configure beans the application will never use and therefore consume more CPU and RAM than really required. @EnableAutoConfiguration should be configured to exclude all the beans not required by the application. Alternatively, use the @Import annotation instead of @EnableAutoConfiguration, to explicitly import the useful AutoConfiguration classes.

This rule applies for @SpringBootApplication as well.

Noncompliant Code Example

@SpringBootApplication
public class MyApplication {
...
}
@Configuration
@EnableAutoConfiguration
public class MyApplication {
...
}

Compliant Solution

@SpringBootApplication(exclude = {
  MultipartAutoConfiguration.class,
  JmxAutoConfiguration.class,
})
public class MyApplication {
...
}
@Configuration
@EnableAutoConfiguration(exclude = {
  MultipartAutoConfiguration.class,
  JmxAutoConfiguration.class,
})
public class MyApplication {
...
}
@Configuration
@Import({
        DispatcherServletAutoConfiguration.class,
        EmbeddedServletContainerAutoConfiguration.class,
        ErrorMvcAutoConfiguration.class,
        HttpEncodingAutoConfiguration.class,
        HttpMessageConvertersAutoConfiguration.class,
        JacksonAutoConfiguration.class,
        ServerPropertiesAutoConfiguration.class,
        PropertyPlaceholderAutoConfiguration.class,
        ThymeleafAutoConfiguration.class,
        WebMvcAutoConfiguration.class
})
public class MyApplication {
...
}
squid:S4605

Spring beans belonging to packages that are not included in a @ComponentScan configuration will not be accessible in the Spring Application Context. Therefore, it's likely to be a configuration mistake that will be detected by this rule. Note: the @ComponentScan is implicit in the @SpringBootApplication annotation, case in which Spring Boot will auto scan for components in the package containing the Spring Boot main class and its sub-packages.

Noncompliant Code Example

@Configuration
@ComponentScan("com.mycompany.app.beans")
public class Application {
...
}

package com.mycompany.app.web;

@Controller
public class MyController { // Noncompliant; MyController belong to "com.mycompany.app.web" while the ComponentScan is looking for beans in "com.mycompany.app.beans" package
...
}

Compliant Solution

@Configuration
@ComponentScan({"com.mycompany.app.beans","com.mycompany.app.web"})
public class Application {
...
}

package com.mycompany.app.web;

@Controller
public class MyController { // Compliant; "com.mycompany.app.web" is referenced by a @ComponentScan annotated class
...
}
squid:S4635

Looking for a given substring starting from a specified offset can be achieved by such code: str.substring(beginIndex).indexOf(char1). This works well, but it creates a new String for each call to the substring method. When this is done in a loop, a lot of Strings are created for nothing, which can lead to performance problems if str is large.

To avoid performance problems, String.substring(beginIndex) should not be chained with the following methods:

- indexOf(int ch)

- indexOf(String str)

- lastIndexOf(int ch)

- lastIndexOf(String str)

- startsWith(String prefix)

For each of these methods, another method with an additional parameter is available to specify an offset.

Using these methods gives the same result while avoiding the creation of additional String instances.

Noncompliant Code Example

str.substring(beginIndex).indexOf(char1); // Noncompliant; a new String is going to be created by "substring"

Compliant Solution

str.indexOf(char1, beginIndex);
squid:TrailingCommentCheck

This rule verifies that single-line comments are not located at the ends of lines of code. The main idea behind this rule is that in order to be really readable, trailing comments would have to be properly written and formatted (correct alignment, no interference with the visual structure of the code, not too long to be visible) but most often, automatic code formatters would not handle this correctly: the code would end up less readable. Comments are far better placed on the previous empty line of code, where they will always be visible and properly formatted.

Noncompliant Code Example

int a1 = b + c; // This is a trailing comment that can be very very long

Compliant Solution

// This very long comment is better placed before the line of code
int a2 = b + c;
squid:UnusedPrivateMethod

private methods that are never executed are dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.

Note that this rule does not take reflection into account, which means that issues will be raised on private methods that are only accessed using the reflection API.

Noncompliant Code Example

public class Foo implements Serializable
{
  private Foo(){}     //Compliant, private empty constructor intentionally used to prevent any direct instantiation of a class.
  public static void doSomething(){
    Foo foo = new Foo();
    ...
  }
  private void unusedPrivateMethod(){...}
  private void writeObject(ObjectOutputStream s){...}  //Compliant, relates to the java serialization mechanism
  private void readObject(ObjectInputStream in){...}  //Compliant, relates to the java serialization mechanism
}

Compliant Solution

public class Foo implements Serializable
{
  private Foo(){}     //Compliant, private empty constructor intentionally used to prevent any direct instantiation of a class.
  public static void doSomething(){
    Foo foo = new Foo();
    ...
  }

  private void writeObject(ObjectOutputStream s){...}  //Compliant, relates to the java serialization mechanism

  private void readObject(ObjectInputStream in){...}  //Compliant, relates to the java serialization mechanism
}

Exceptions

This rule doesn't raise any issue on annotated methods.

squid:UselessParenthesesCheck

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

int x = (y / 2 + 1);   //Compliant even if the parenthesis are ignored by the compiler

if (a && ((x+y > 0))) {  // Noncompliant
  //...
}

return ((x + 1));  // Noncompliant

Compliant Solution

int x = (y / 2 + 1);

if (a && (x+y > 0)) {
  //...
}

return (x + 1);
swift:S100

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

swift:S101

Shared coding conventions allow teams to collaborate effectively. This rule allows to check that all class names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression ^[A-Z][a-zA-Z0-9]*$:

class my_class {...}

Compliant Solution

class MyClass {...}
swift:S103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

swift:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

swift:S105

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

swift:S1065

If a label is declared but not used in the program, it can be considered as dead code and should therefore be removed.

This will improve maintainability as developers will not wonder what this label is used for.

Noncompliant Code Example

whileLoopLabel: while x > 0 {    // Noncompliant
    x -= 1
}

Compliant Solution

while x > 0 {
    x -= 1
}

See

  • MISRA C:2012, 2.6 - A function should not contain unused label declarations
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
swift:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if condition1 {
  if condition2 {
    doSomething()
  }
}

if let y = someOptional {
  if x > 0 {
    doSomething()
  }
}

Compliant Solution

if condition1 && condition2 {
  doSomething()
}

if let y = someOptional where x > 0 {
  doSomething()
}

if x > 0, let y = someOptional {
  doSomething()
}
swift:S1067

The complexity of an expression is defined by the number of &&, || and condition ? ifTrue : ifFalse operators it contains.

A single expression's complexity should not become too high to keep the code readable.

Noncompliant Code Example

With the default threshold value 3

  if ((condition1 && condition2) || (condition3 && condition4)) && condition5 { ... }

Compliant Solution

  if (myFirstCondition() || mySecondCondition()) && myLastCondition() { ... }
swift:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function is doing too many things.

Noncompliant Code Example

With a maximum number of 4 parameters:

func doSomething(param1: String, param2: String, param3: String, param4: String, param5: String) {
    // ...
}

Compliant Solution

func doSomething(param1: String, param2: String, param3: String, param4: String) {
    // ...
}
swift:S1075

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.

Noncompliant Code Example

public class Foo {
    public func listUsers() -> [User] {
        var users:[User]
        let location = "/home/mylogin/Dev/users.txt"     // Non-Compliant
        let fileContent = NSString(contentsOfFile: location, encoding: NSUTF8StringEncoding, error: nil)
        users = parse(fileContent!)
        return users
    }
}

Compliant Solution

public class Foo {
    // Configuration is a class that returns customizable properties: it can be mocked to be injected during tests.
    private var config:Configuration
    public init(myConfig:Configuration) {
        config = myConfig
    }
    public func listUsers() -> [User] {
        var users:[User]
        // Find here the way to get the correct folder, in this case using the Configuration object
        let location = config.getProperty("myApplication.listingFile")
        // and use this parameter instead of the hard coded path
        let fileContent = NSString(contentsOfFile: location, encoding: NSUTF8StringEncoding, error: nil)
        users = parse(fileContent!)
        return users
    }
}

See

swift:S108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

for (var i = 0; i < 42; i++){}  // Empty on purpose or missing piece of code ?

Exceptions

When a block contains a comment, this block is not considered to be empty.

swift:S1105

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when an open curly brace is not placed at the end of a line of code.

Noncompliant Code Example

if condition
{
  doSomething()
}

Compliant Solution

if condition {
  doSomething()
}

Exceptions

Closure and inlined blocks (left and right curly braces on the same line) are ignored by this rule.

if condition {doSomething()} // Compliant
reversed = sorted(
    names,
    { (s1: String, s2: String) -> Bool in  // Compliant
        return s1 > s2
    })
swift:S1109

Shared coding conventions make it possible for a team to efficiently collaborate. This rule makes it mandatory to place a close curly brace at the beginning of a line.

Noncompliant Code Example

if condition {
  doSomething()}

Compliant Solution

if condition {
  doSomething()
}

Exceptions

When blocks are inlined (open and close curly braces on the same line), no issue is triggered.

if condition {doSomething()}
swift:S1110

Useless parentheses can sometimes be misleading and so should be removed.

Noncompliant Code Example

return ((x + 1))       // Noncompliant
var x = ((y / 2 + 1))  // Noncompliant
if ((x > 0)) { ... }   // Noncompliant

Compliant Solution

return (x + 1)
return x + 1
var x = (y / 2 + 1)
var x = y / 2 + 1
if (x > 0) { ... }
if x > 0 { ... }
swift:S1117

Shadowing fields or enum cases with a local variable is a bad practice that reduces code readability: It makes it confusing to know whether the field or the variable is being used.

Noncompliant Code Example

public class Foo {
  public var myField:Int = 0

  public func doSomething() {
    var myField = 0
    ...
  }
}

See

swift:S1125

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

Noncompliant Code Example

if condition == true  { /* ... */ } // Noncompliant
if condition != false { /* ... */ } // Noncompliant
if condition && true  { /* ... */ } // Noncompliant
if condition || false { /* ... */ } // Noncompliant
doSomething(!false)                 // Noncompliant
doSomething(condition == true)      // Noncompliant

v = condition ? true  : false   // Noncompliant
v = condition ? true  : exp     // Noncompliant
v = condition ? false : exp     // Noncompliant
v = condition ? exp   : true    // Noncompliant
v = condition ? exp   : false   // Noncompliant

Compliant Solution

if condition { /* ... */ }
if condition { /* ... */ }
if condition { /* ... */ }
if condition { /* ... */ }
doSomething(true)
doSomething(condition)

v = condition
v = condition  || exp
v = !condition && exp
v = !condition || exp
v = condition  && exp

Exceptions

Expression statements are ignored.

expect(value) == true // ignored
swift:S113

Some tools work better when files end with an empty line.

This rule simply generates an issue if it is missing.

For example, a Git diff looks like this if the empty line is missing at the end of the file:

+class Test {
+}
\ No newline at end of file
swift:S1131

Trailing whitespaces are simply useless and should not stay in code. They may generate noise when comparing different versions of the same file.

If you encounter issues from this rule, this probably means that you are not using an automated code formatter - which you should if you have the opportunity to do so.

Noncompliant Code Example

// Noncompliant; there are extra spaces after 'String'
var str:String
swift:S1133

This rule is meant to be used as a way to track code which is marked as being deprecated. Deprecated code should eventually be removed.

Noncompliant Code Example

public class Foo {

  @availability(*, deprecated=1.1)   // Noncompliant
  public func bar() {
  }

  @availability(*, obsoleted=1.1)  // Noncompliant
  public func baz() {
  }
}
swift:S1134

FIXME tags are commonly used to mark places where a bug is suspected, but which the developer wants to deal with later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

func divide(numerator:Int, denominator:Int) -> Int {
  return numerator / denominator              // FIXME denominator value might be  0
}

See

swift:S1135

TODO tags are commonly used to mark places where some more code is required, but which the developer wants to implement later.

Sometimes the developer will not have the time or will simply forget to get back to that tag.

This rule is meant to track those tags and to ensure that they do not go unnoticed.

Noncompliant Code Example

func doSomething() {
  // TODO
}

See

swift:S114

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all protocol names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[A-Z][a-zA-Z0-9]*$:

public protocol myProtocol {...} // Noncompliant

Compliant Solution

public protocol MyProtocol {...}
swift:S1142

Having too many return statements in a function increases the function's essential complexity because the flow of execution is broken each time a return statement is encountered. This makes it harder to read and understand the logic of the function.

Noncompliant Code Example

With the default threshold of 3:

func myMethod() -> Bool { // Noncompliant as there are 4 return statements
  if condition1 {
    return true
  } else {
    if condition2 {
      return false
    } else {
      return true
    }
  }
  return false
}
swift:S1144

private methods that are never executed are dead code: unnecessary, inoperative code that should be removed. Cleaning out dead code decreases the size of the maintained codebase, making it easier to understand the program and preventing bugs from being introduced.

swift:S1145

if statements with conditions that are always false have the effect of making blocks of code non-functional. if statements with conditions that are always true are completely redundant, and make the code less readable.

There are three possible causes for the presence of such code:

  • An if statement was changed during debugging and that debug code has been committed.
  • Some value was left unset.
  • Some logic is not doing what the programmer thought it did.

In any of these cases, unconditional if statements should be removed.

Noncompliant Code Example

if true {  // Noncompliant
  doSomething()
}
...
if false {  // Noncompliant
  doSomethingElse()
}

Compliant Solution

doSomething()

See

  • MITRE, CWE-489 - Leftover Debug Code
  • MITRE, CWE-570 - Expression is Always False
  • MITRE, CWE-571 - Expression is Always True
  • MISRA C:2004, 13.7 - Boolean operations whose results are invariant shall not be permitted.
  • MISRA C:2012, 14.3 - Controlling expressions shall not be invariant
swift:S115

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all constant names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

let Pi = 3.14

Compliant Solution

let pi = 3.14
swift:S1151

The switch statement should be used only to clearly define some new branches in the control flow. As soon as a case clause contains too many statements this highly decreases the readability of the overall control flow statement. In such case, the content of the case clause should be extracted into a dedicated method.

Noncompliant Code Example

The following code snippet illustrates this rule with the default threshold of 5:

switch myVariable {
  case 0: // 6 lines till next case
    methodCall1("")
    methodCall2("")
    methodCall3("")
    methodCall4("")
    methodCall5("")
  case 1:
  ...
}

Compliant Solution

switch myVariable {
  case 0:
    doSomething()
  case 1:
  ...
}
...
func doSomething(){
    methodCall1("")
    methodCall2("")
    methodCall3("")
    methodCall4("")
    methodCall5("")
}
swift:S116

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that field names match a provided regular expression.

Noncompliant Code Example

With the default regular expression ^[a-z][a-zA-Z0-9]*$:

class MyClass {
  var MyField = 1
}

Compliant Solution

class MyClass {
  var myField = 1
}
swift:S117

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a local variable or function parameter name does not match the provided regular expression.

swift:S1172

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

Noncompliant Code Example

func doSomething(a: Int, b: Int) {     // "b" is unused
  compute(a)
}

Compliant Solution

void doSomething(a: Int) {
  compute(a)
}

Exceptions

Override methods are excluded.

override doSomething(a: Int, b: Int) {     // no issue reported on b
  compute(a)
}

See

  • MISRA C++:2008, 0-1-11 - There shall be no unused parameters (named or unnamed) in nonvirtual functions.
  • MISRA C:2012, 2.7 - There should be no unused parameters in functions
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
swift:S1186

There are several reasons for a function or closure not to have a body:

  • It is an unintentional omission, and should be fixed to prevent unexpected behavior in production.
  • It is not yet, or never will be, supported. In this case an exception should be thrown.
  • The function is an intentionally-blank override. In this case a nested comment should explain the reason for the blank override.

Noncompliant Code Example

func fun(p1:Int) {
}

Compliant Solution

func fun(p1:Int) {
  var a = doSomething(p1)
  var threshold = 42
  if a > threshold {
    // ...
  }
}

or

func fun(p1:Int) {
  // Intentionally unimplemented...
}
swift:S1188

Closures are a very convenient and compact way to inject a behaviour without having to create a dedicated function. But those closures should be used only if the behaviour to be injected can be defined in a few lines of code, otherwise the source code can quickly become unreadable.

swift:S119

Shared naming conventions make it possible for a team to collaborate efficiently. Following the established convention of single-letter type parameter names helps users and maintainers of your code quickly see the difference between a type parameter and a poorly named class.

This rule check that all type parameter names match a provided regular expression. The following code snippets use the default regular expression.

Noncompliant Code Example

With the default regular expression ^[A-Z]$:

public class MyClass<TYPE> {    // Noncompliant
  func method<TYPE>(t : TYPE) { // Noncompliant
  }
}

Compliant Solution

public class MyClass<T> {
  func method<T>(t : T) {
  }
}
swift:S1192

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

With the default threshold of 3:

prepare("a message")  // Noncompliant; duplicated 3 times
execute("a message")
release("a message")

Compliant Solution

let message = "a message"

prepare(message)
execute(message)
release(message)

Exceptions

To prevent generating some false-positives, literals having 5 or less characters are excluded as well as literals containing only letters, digits and '_'.

swift:S122

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

if someCondition { doSomething()}
...
var result = doSomething(); return result

Compliant Solution

if someCondition {
  doSomething()
}
...
var result = doSomething()
return result

Exceptions

Variable declaration with initialising code block and closure expressions containing a single statement are ignored.

var x : Int { return 0 }                                       // Variable declaration with initialising code block
doSomething({ (x: Int, y: Int) -> Bool in return x > y }, 5)   // Closure expression
swift:S1244

Floating point math is imprecise because of the challenges of storing such values in a binary representation. Even worse, floating point math is not associative; push a Float or a Double through a series of simple mathematical operations and the answer will be different based on the order of those operation because of the rounding that takes place at each step.

Even simple floating point assignments are not simple:

var f: Float = 0.1 // 0.1000000014901161193847656
var d: Double = 0.1 // 0.1000000000000000055511151

Therefore, the use of the equality (==) and inequality (!=) operators on Float or Double values is almost always an error.

This rule checks for the use of direct and indirect equality/inequailty tests on floats and doubles.

Noncompliant Code Example

var myNumber: Float = 0.3 + 0.6

if myNumber == 0.9 { // Noncompliant. Because of floating point imprecision, this will be false
    // ...
}

if myNumber <= 0.9 && myNumber >= 0.9 { // Noncompliant indirect equality test
  // ...
}

if myNumber < 0.9 || myNumber > 0.9 { // Noncompliant indirect inequality test
  // ...
}

See

  • MISRA C:2004, 13.3 - Floating-point expressions shall not be tested for equality or inequality.
  • MISRA C++:2008, 6-2-2 - Floating-point expressions shall not be directly or indirectly tested for equality or inequality
swift:S125

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
swift:S126

This rule applies whenever an if statement is followed by one or more else if statements; the final else if should be followed by an else statement.

The requirement for a final else statement is defensive programming.

The else statement should either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch statement.

Noncompliant Code Example

if x == 0 {
  doSomething()
} else if x == 1 {
  doSomethingElse()
}

Compliant Solution

if x == 0 {
  doSomething()
} else if x == 1 {
  doSomethingElse()
} else {
  NSException(name:"IllegalStateException", reason:"Unreachable else clause is reached", userInfo:nil).raise()
}

See

  • MISRA C:2004, 14.10 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C++:2008, 6-4-2 - All if...else if constructs shall be terminated with an else clause.
  • MISRA C:2012, 15.7 - All if...else if constructs shall be terminated with an else statement
  • CERT, MSC01-C. - Strive for logical completeness
  • CERT, MSC57-J. - Strive for logical completeness
swift:S1301

switch statements are useful when there are many different cases depending on the value of the same expression.

For just one or two cases however, the code will be more readable with if statements.

Noncompliant Code Example

switch (variable) {
  case 0:
    doSomething();
  default:
    doSomethingElse();
}

Compliant Solution

if (variable == 0) {
  doSomething();
} else {
  doSomethingElse();
}

See

  • MISRA C:2004, 15.5 - Every switch statement shall have at least one case clause.
  • MISRA C++:2008, 6-4-8 - Every switch statement shall have at least one case-clause.
  • MISRA C:2012, 16.6 - Every switch statement shall have at least two switch-clauses
swift:S1311

The cyclomatic complexity of a class should not exceed a defined threshold. Complex code can perform poorly and will in any case be difficult to understand and therefore to maintain.

Deprecated

This rule is deprecated, and will eventually be removed.

swift:S1313

Hardcoding IP addresses is security-sensitive. It has led in the past to the following vulnerabilities:

Today's services have an ever-changing architecture due to their scaling and redundancy needs. It is a mistake to think that a service will always have the same IP address. When it does change, the hardcoded IP will have to be modified too. This will have an impact on the product development, delivery and deployment:

  • The developers will have to do a rapid fix every time this happens, instead of having an operation team change a configuration file.
  • It forces the same address to be used in every environment (dev, sys, qa, prod).

Last but not least it has an effect on application security. Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service at this address or spoof the IP address. Such an attack is always possible, but in the case of a hardcoded IP address the fix will be much slower, which will increase an attack's impact.

Recommended Secure Coding Practices

  • make the IP address configurable.

Noncompliant Code Example

var host : NSHost = NSHost(address: "192.168.12.42")

Compliant Solution

var host : NSHost = NSHost(address: configuration.ipAddress)

Exceptions

No issue is reported for the following cases because they are not considered sensitive:

  • Loopback addresses 127.0.0.0/8 in CIDR notation (from 127.0.0.0 to 127.255.255.255)
  • Broadcast address 255.255.255.255
  • Non routable address 0.0.0.0

See

  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
  • CERT, MSC03-J. - Never hard code sensitive information
swift:S134

Nested if, for, for in, while, do while and switch statements are a key ingredient 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:

  if condition1 {                  // Compliant - depth = 1
    /* ... */
    if condition2 {                // Compliant - depth = 2
      /* ... */
      for var i = 0; i < 10; i++ {  // Compliant - depth = 3, not exceeding the limit
        /* ... */
        if condition4 {            // Non-Compliant - depth = 4
          if condition5 {          // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
            /* ... */
          }
        }
      }
    }
  }
swift:S138

A function that grows too large tends to aggregate too many responsibilities.

Such functions inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions which focus on well-defined tasks.

Those smaller functions will not only be easier to understand, but also probably easier to test.

swift:S139

This rule verifies that single-line comments are not located at the ends of lines of code. The main idea behind this rule is that in order to be really readable, trailing comments would have to be properly written and formatted (correct alignment, no interference with the visual structure of the code, not too long to be visible) but most often, automatic code formatters would not handle this correctly: the code would end up less readable. Comments are far better placed on the previous empty line of code, where they will always be visible and properly formatted.

Noncompliant Code Example

var a1 = b + c // This is a trailing comment that can be very very long

Compliant Solution

// This very long comment is better placed before the line of code
var a2 = b + c
swift:S1438

In Swift, the semicolon (;) is optional as a statement separator, but omitting semicolons can be confusing.

Noncompliant Code Example

var x = 1

Compliant Solution

var x = 1;
swift:S1451

Each source file should start with a header stating file ownership and the license which must be used to distribute the application.

This rule must be fed with the header text that is expected at the beginning of every file.

Compliant Solution

/*
 * SonarQube, open source software quality management tool.
 * Copyright (C) 2008-2013 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * SonarQube is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * SonarQube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
swift:S1479

When switch statements have large sets of case clauses, it is usually an attempt to map two sets of data. A real map structure would be more readable and maintainable, and should be used instead.

swift:S1481

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

public func numberOfMinutes(hours:Int) -> Int {
  var seconds = 0   // seconds is never used
  return hours * 60;
}

Compliant Solution

public func numberOfMinutes(hours:Int) -> Int{
  return hours * 60
}

Exceptions

Simple for-in loop counters are ignored by this rule because while they are often legitimately unused, their declaration is required by the syntax.

for i in 1...10 {  // Ignored
  print("Hello! ");
}

for (a, b) in someElements {  // Noncompliant; b unused
  print(a)
}
swift:S1541

The Cyclomatic Complexity of functions should not exceed a defined threshold. Complex code may perform poorly and can be difficult to test thoroughly.

swift:S1642

Sharing some naming conventions enables teams to collaborate more efficiently. This rule checks that all struct names match a provided regular expression.

Using the default regular expression: "^[A-Z][a-zA-Z0-9]*$"

Noncompliant Code Example

struct my_struct {
    var one : Int
    var two : Int
}

Compliant Solution

struct MyStruct {
    var one : Int
    var two : Int
}
swift:S1700

It's confusing to have a class member with the same name (case differences aside) as its enclosing class. This is particularly so when you consider the common practice of naming a class instance for the class itself.

Best practice dictates that any field or member with the same name as the enclosing class be renamed to be more descriptive of the particular aspect of the class it represents or holds.

Noncompliant Code Example

public class Foo {
  private var foo : String

  public func getFoo() -> String {
     return foo
  }

  //...

}

var foo = Foo()
foo.getFoo() // what does this return?

Compliant Solution

public class Foo {
  private var name : String

  public func getName() -> String {
      return name
  }

  //...

}

var foo = Foo();
foo.getName()
swift:S1751

Having an unconditional break, return in a loop renders it useless; the loop will only execute once and the loop structure itself is simply wasted keystrokes.

Having an unconditional continue in a loop can render the loop meaningless, or is itself wasted keystrokes, depending on where in the loop it occurs.

Having an unconditional return anywhere other than at the end of a function or method simply renders all the rest of the code in the method useless.

For these reasons, unconditional jump statements should never be used except for the final return in a function.

Noncompliant Code Example

var i:Int
for (i = 0; i < 10; ++i) {
    print("i is \(i)")
    break  // loop only executes once
}

for (i = 0; i < 10; ++i) {
    continue
    print("i is \(i)")  // this is never executed
}

for (i = 0; i < 10; ++i) {
    print("i is \(i)")
    continue  // this is meaningless; the loop would continue anyway
}

Compliant Solution

var i:Int
for (i = 0; i < 10; ++i){
    print("i is \(i)")
}

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code.
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code.
  • MISRA C++:2008, 0-1-9 - There shall be no dead code.
  • MISRA C:2012, 2.2 - There shall be no dead code
  • CERT, MSC12-C - Detect and remove code that has no effect
  • CERT, MSC12-CPP - Detect and remove code that has no effect
swift:S1763

Jump statements (return, break, continue, and fallthrough) move control flow out of the current code block. So any statements that come after a jump are dead code.

Noncompliant Code Example

func fun(a:Int)->Int{
  var i = 10;
  return i + a;
  i++;             // this is never executed
}

Compliant Solution

func fun(a:Int)->Int{
  var i = 10;
  return i + a;
}

See

  • MISRA C:2004, 14.1 - There shall be no unreachable code
  • MISRA C++:2008, 0-1-1 - A project shall not contain unreachable code
  • MISRA C++:2008, 0-1-9 - There shall be no dead code
  • MISRA C:2012, 2.1 - A project shall not contain unreachable code
  • MISRA C:2012, 2.2 - There shall be no dead code
  • MITRE, CWE-561 - Dead Code
  • CERT, MSC56-J. - Detect and remove superfluous code and values
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
swift:S1764

Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators, it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified. In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of an operator yields predictable results, and should be simplified.

This rule ignores *, +.

Noncompliant Code Example

if a == a { // always true
  doZ()
}
if  a != a  { // always false
  doY()
}
if a == b && a == b { // if the first one is true, the second one is too
  doX()
}
if a == b || a == b { // if the first one is true, the second one is too
  doW()
}

var j = 5 / 5 //always 1
var k = 5 - 5 //always 0

Exceptions

Left-shifting 1 onto 1 is common in the construction of bit masks, and is ignored.

var i = 1 << 1; // Compliant
var j = a << a; // Noncompliant

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • S1656 - Implements a check on =.
swift:S1821

Nested switch structures are difficult to understand because you can easily confuse the cases of an inner switch as belonging to an outer statement. Therefore nested switch statements should be avoided.

Specifically, you should structure your code to avoid the need for nested switch statements, but if you cannot, then consider moving the inner switch to another function.

swift:S1845

Looking at the set of methods in a class, struct, enum, or extension and finding two methods that differ only by capitalization is confusing to users of the class. It is similarly confusing to have a method and a field or a case which differ only in capitalization.

Noncompliant Code Example

class SomeClass {
    var lookUp = false
    func lookup(){ }        // Noncompliant; method name differs from field name only by capitalization
    func lookUP(){ }        // Noncompliant; method name differs from field and another method name only by capitalization
}

Compliant Solution

class SomeClass {
    var lookUp = false
    func getLookUp(){ }
}
swift:S1854

A dead store happens when a local variable is assigned a value that is not read by any subsequent instruction. Calculating or retrieving a value only to then overwrite it or throw it away, could indicate a serious error in the code. Even if it's not an error, it is at best a waste of resources. Therefore all calculated values should be used.

Noncompliant Code Example

i = a + b; // Noncompliant; calculation result not used before value is overwritten
i = compute();

Compliant Solution

i = a + b;
i += compute();

Exceptions

This rule ignores initializations to 0, 1, nil, true, false and "".

See

swift:S1862

A switch and a chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

Noncompliant Code Example

if param == 1 {
  openWindow()
} else if param == 2 {
  closeWindow()
} else if param == 1 {            // Noncompliant
  moveWindowToTheBackground()
}

switch i {
  case 1:
    //...
  case 3:
    //...
  case 1:                         // Noncompliant
    //...
  default:
    // ...
}

Compliant Solution

if param == 1 {
  openWindow()
} else if param == 2 {
  closeWindow()
} else if param == 3 {
  moveWindowToTheBackground()
}

switch i {
  case 1:
    //...
  case 3:
    //...
  default:
    // ...
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
swift:S1871

Having two cases in the same switch 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 they should be combined.

Noncompliant Code Example

switch i {
  case 1:
    doFirstThing()
    doSomething()
  case 2:
    doSomethingDifferent()
  case 3:  // Noncompliant; duplicates case 1's implementation
    doFirstThing()
    doSomething()
  default:
    doTheRest()
}

if a >= 0 && a < 10 {
  doFirstThing()
  doTheThing()
} else if a >= 10 && a < 20 {
  doTheOtherThing()
} else if a >= 20 && a < 50 {
  doFirstThing()     // Noncompliant; duplicates first condition
  doTheThing()
} else {
  doTheRest()
}

Exceptions

case labels that declare variables cannot have multiple patterns. Therefore this situation is ignored.

switch a {
    case .STR_CASE(let x):
        print(x)
    case .INT_CASE(let x):
        print(x)
    default:
        print("default")
}

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a switch statement that contain a single line of code with or without a following break.

if a >= 0 && a < 10 {    //no issue, usually this is done on purpose to increase the readability
  doTheThing()
} else if a >= 10 && a < 20 {
  doTheThing()
} else if a >= 20 && a < 50 {
  doFirstThing()
}

But this exception does not apply to if chains without else-s, or to switch-es without default clauses when all branches have the same single line of code. In case of if chains with else-s, or of switch-es with default clauses, rule S3923 raises a bug.

if a >= 0 && a < 10 {     //Noncompliant, this might have been done on purpose but probably not
  doTheThing()
} else if a >= 10 && a < 20 {
  doTheThing()
}
swift:S1908

Most of the time, a very complex file breaks the Single Responsibility Principle and should be re-factored into several different files.

Deprecated

This rule is deprecated, and will eventually be removed.

swift:S1940

It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.

Noncompliant Code Example

if !(a == 2) {...}  // Noncompliant
let b = !(i < 10)  // Noncompliant

Compliant Solution

if a != 2 {...}
let b = i >= 10
swift:S1996

A file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. This is doubly true for a file with multiple independent classes, extensions, protocols, enumerations or structures. It is strongly advised to define each individual type in separate source file.

Exceptions

The case when file contains only class and its extensions is ignored.

class MyViewController: UIViewController {
  // class stuff here
}

extension MyViewController: UITableViewDataSource {
  // table view data source methods
}

extension MyViewController: UIScrollViewDelegate {
  // scroll view delegate methods
}
swift:S2007

Defining and using global variables and global functions, when the convention dictates OOP can be confusing and difficult to use properly for multiple reasons:

  • You run the risk of name clashes.
  • Global functions must be stateless, or they can cause difficult-to-track bugs.
  • Global variables can be updated from anywhere and may no longer hold the value you expect.
  • It is difficult to properly test classes that use global functions.

Instead of being declared globally, such variables and functions should be moved into a class, potentially marked static, so they can be used without a class instance.

This rule checks that only object-oriented programming is used and that no functions or procedures are declared outside of a class.

Noncompliant Code Example

var name = "Bob"    // Noncompliant

func doSomething() {   // Noncompliant
  //...
}

class MyClass {
    //...
}

Compliant Solution

public class MyClass {
  public static var name = "Bob"

  public class func doSomething() {              // Compliant
    //...
  }
  //...
}

Exceptions

The operator function is a function with a name that matches the operator to be overloaded. Because such functions can only be defined in a global scope, they are ignored by this rule.

public class Vector2D {
    var x = 0.0, y = 0.0
    // ...
}

func + (left: Vector2D, right: Vector2D) -> Vector2D {
    return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
swift:S2042

A class that grows too much tends to aggregate too many responsibilities, and inevitably becomes harder to understand and to maintain. Above a specific threshold, it is strongly advised to refactor the class into smaller ones which focus on well-defined topics.

This rule raises an issue when classes, structs, or enums have more than the allowed number of lines.

swift:S2094

There is no good excuse for an empty class. If it's being used simply as a common extension point, it should be replaced with a protocol. If it was stubbed in as a placeholder for future development it should be fleshed-out. In any other case, it should be eliminated.

Noncompliant Code Example

public class Nothing {  // Noncompliant
}

Compliant Solution

public protocol Nothing {
}
swift:S2108

Variables that are never updated will always return their default values and so they should be explicitly declared as constant. A let-declaration guarantees and clearly signals to the programmer that its value is supposed to and will never change.

This rule applies to non-constant fields and variables which are not set within the codebase.

swift:S2148

In Swift it is possible to add underscores ('_') to numeric literals to enhance readability. The addition of underscores in this manner has no semantic meaning, but makes it easier for maintainers to understand the code.

The number of digits to the left of a decimal point needed to trigger this rule varies by base.

Base Minimum digits
binary 9
decimal 6
octal 9
hexadecimal 9

Noncompliant Code Example

let i = 10000000  // Noncompliant; is this 10 million or 100 million?
let j = 0b01101001010011011110010101011110  // Noncompliant
let l = 0x7fffffffffffffff  // Noncompliant

Compliant Solution

let i = 10_000_000
let j = 0b01101001_01001101_11100101_01011110
let l = 0x7fff_ffff_ffff_ffff
swift:S2197

When the modulus of a negative number is calculated, the result will either be negative or zero. Thus, comparing the modulus of a variable for equality with a positive number (or a negative one) could result in unexpected results.

Noncompliant Code Example

func isOdd(x:Int) -> Bool {
  return x % 2 == 1  // Noncompliant; if x is negative, x % 2 == -1
}

Compliant Solution

func isOdd(x:Int) -> Bool {
  return x % 2 != 0
}

or

func isOdd(x:Int) -> Bool {
  return abs(x % 2) == 1
}

See

  • CERT, NUM51-J. - Do not assume that the remainder operator always returns a nonnegative result for integral operands
  • CERT, INT10-C - Do not assume a positive remainder when using the % operator
swift:S2201

When the call to a function doesn't have any side effects, what is the point of making the call if the results are ignored? In such case, either the function call is useless and should be dropped or the source code doesn't behave as expected.

This rule raises an issue on the following methods of the Swift standard library:

  • abs function
  • signum method
  • distance method
  • advanced method
  • addingProduct method
  • squareRoot method
  • remainder, truncatingRemainder methods
  • rounded method
  • dropLast, drop, dropFirst methods
  • lowercased, uppercased methods
  • sorted, reversed methods
  • prefix, suffix methods

See

  • MISRA C:2012, 17.7 - The value returned by a function having non-void return type shall be used
  • CERT, EXP12-C. - Do not ignore values returned by functions
  • CERT, EXP00-J. - Do not ignore values returned by methods
swift:S2260

When the parser fails, it is possible to record the failure as an issue on the file. This way, not only is it possible to track the number of files that do not parse but also to easily find out why they do not parse.

swift:S2278

According to the US National Institute of Standards and Technology (NIST), the Data Encryption Standard (DES) is no longer considered secure:

Adopted in 1977 for federal agencies to use in protecting sensitive, unclassified information, the DES is being withdrawn because it no longer provides the security that is needed to protect federal government information.

Federal agencies are encouraged to use the Advanced Encryption Standard, a faster and stronger algorithm approved as FIPS 197 in 2001.

For similar reasons, RC2 should also be avoided.

Noncompliant Code Example

let cryptor = try Cryptor(operation: .encrypt, algorithm: .des, options: [.ecbMode], key: key, iv: []) // Noncompliant

let crypt = CkoCrypt2()
crypt.CryptAlgorithm = "3des" // Noncompliant

Compliant Solution

let cryptor = try Cryptor(operation: .encrypt, algorithm: .aes, options: [.ecbMode], key: key, iv: [])

let crypt = CkoCrypt2()
crypt.CryptAlgorithm = "blowfish"

See

swift:S2309

Files with no lines of code clutter a project and should be removed.

Noncompliant Code Example

//import Foundation
//
//public class Bar {}
swift:S2342

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all enum names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression: ^[A-Z][a-zA-Z0-9]*

enum someEnumeration { // Non-Compliant
    case Bar
}

Compliant Solution

enum SomeEnumeration {
    case Bar
}
swift:S2343

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all enumeration member names match a provided regular expression.

Noncompliant Code Example

With default provided regular expression: ^[a-z][a-zA-Z0-9]*$

enum SomeEnumeration {
    case SomeMember  // Non-Compliant
}

Compliant Solution

enum SomeEnumeration {
    case someMember
}
swift:S2523

Nested comments are confusing and can lead maintainers to misunderstand which code is active.

Noncompliant Code Example

/*
  This is a comment block.
  It may be difficult to figure out that the following line of code is actually commented


variable = function_call();
/* variable contains the result. Noncompliant; inner comment */
*/

See

  • MISRA C:2004, 2.3 - The character sequence /* shall not be used within a comment.
  • MISRA C++:2008, 2-7-1 - The character sequence /* shall not be used within a C-style comment.
  • MISRA C:2012, 3.1 - The character sequences /* and // shall not be used within a comment
  • CERT, MSC04-C. - Use comments consistently and in a readable fashion
swift:S2635

When the last argument to a function is a closure, it's possible and sometimes desirable to write that closure after the function's parentheses. This is called a trailing closure. In order to help distinguish a trailing closure from an independent code block, it is best to begin the closure on the same line as the function call.

Noncompliant Code Example

funWithClosureArgument()
{ // Noncompliant; looks like an independent code block
   print("Hello world")
}

Compliant Solution

funWithClosureArgument() {
   print("Hello world")
}
swift:S2758

When the second and third operands of a ternary operator are the same, the operator will always return the same value regardless of the condition. Either the operator itself is pointless, or a mistake was made in coding it.

Noncompliant Code Example

func canVote(person:Person) -> Bool {
  return person.age > 18 ? true : true // Noncompliant; is this what was intended?
}

Compliant Solution

func canVote(person:Person) -> Bool {
  return person.age > 18 ? true : false
}

Deprecated

This rule is deprecated; use S3923 instead.

swift:S2760

When the same condition is checked twice in a row, it is either confusing - why have separate checks? - or an error - some other condition should have been checked in the second test.

Noncompliant Code Example

if a == b { // Compliant; a reassigned in previous block
  doSomething(b)
}
if a == b {  // Noncompliant; is this really what was intended?
  doTheThing(c)
}

Compliant Solution

if a == b {
  doTheThing(b)
  doTheThing(c)
}

or

if a == b {
  doTheThing(b)
}
if b == c {
  doTheThing(c)
}

Exceptions

Since it is a common pattern to test a variable, reassign it if it fails the test, then re-test it, that pattern is ignored.

swift:S2950

The access level defaults to internal if left unspecified. Since that doesn't make sense for most top-level declarations, access levels should always be specified explicitly, even when internal is what's intended.

This rule raises an issue when the access level is not specified on any top-level declaration.

Noncompliant Code Example

class Foo {  // Noncompliant
  // ...
}

Compliant Solution

public class Foo {
  // ...
}
swift:S2951

Because case statements in a Swift switch do not fall through, there is no need to use break at the end of a case unless it would otherwise be empty. Since an empty case isn't allowed, an explicit break is needed to make such code compilable. There is no other reason to use break in a case.

Noncompliant Code Example

switch weekday {
  case sunday:
    break
  case monday:
    getUpEarly()
    break  // Noncompliant
  case tuesday
    // ...
}

Compliant Solution

switch weekday {
  case sunday:
    break
  case monday:
    getUpEarly()
  case tuesday
    // ...
}
swift:S2957

When a closure contains only a return statement, the return itself can be omitted.

Noncompliant Code Example

someList.sort { a, b in
  return a > b
}

Compliant Solution

someList.sort { a, b in a > b }
swift:S2958

Using trailing closure syntax for the last parameter in a call is often the most elegant way to handle it. But if the call requires multiple function-type arguments, the use of a trailing closure can be messy and confusing. In such cases, it's better to pass closure expressions as normal arguments.

Noncompliant Code Example

var x = complexOperation(
  arg: 2,
  op1: {$0 + 10}
) {$0 * $0}

Compliant Solution

var x = complexOperation(
  arg: 2,
  op1: {$0 + 10},
  op2: {$0 * $0}
)
swift:S2959

The semicolon (;) is optional as a statement separator except in traditional for loops and when several statements are combined on one line (which is a bad practice). For cleaner code, semicolons should be omitted.

Noncompliant Code Example

int a;  // Noncompliant

Compliant Solution

int a
swift:S2960

Surrounding your operators with whitespace in operator declarations will help maintainers derive meaning from what might otherwise look like a meaningless jumble of punctuation.

Noncompliant Code Example

func <*>(a: MyClass, b: MyClass) -> Boolean { // Noncompliant

Compliant Solution

func <*> (a: MyClass, b: MyClass) -> Boolean {
swift:S2961

You can't create a variable named "for". Unless you put backticks (`) around it.

Since that would be the first step down a slippery slope of hopeless confusion, backticks should be removed from identifier names - whether they're keywords or not - and the identifiers renamed as required.

Noncompliant Code Example

var `for` = 1   // Noncompliant
for (var `in` = 0; `in` < 10 && `for` > 0; `in`++) {  // Noncompliant
  // ...
}

var `x` = "hello"  // Noncompliant; why would you do this?

Compliant Solution

var i = a
for (var j=0; j< 10; j++) {
  // ...
}

var x = "hello"

Exceptions

When Objective-C libraries are used in Swift, backticks may be needed around parameter names which are keywords in Swift but not in Objective C. Therefore this rule ignores backticks around parameter names.

var protectionSpace: NSURLProtectionSpace = NSURLProtectionSpace(
  host: host,
  port: port,
  `protocol`: prot,  // Compliant
  realm: nil,
  authenticationMethod: authenticationMethod
);
swift:S2962

For read-only computed properties and subscript declarations, the get keyword and its braces are optional, and should be omitted for the sake of brevity.

Noncompliant Code Example

struct Magic {
  var number:Int {
    get {  // Noncompliant
      return 42
    }
  }
}

Compliant Solution

struct Magic {
  var number:Int {
    return 42
  }
}
swift:S2963

The use of self is optional except when in closure expressions, and when it's needed to distinguish between property names and arguments. For the sake of brevity, self should be omitted when it's not strictly required.

Noncompliant Code Example

class Car {
  var color: Int

  init(color: Int) {
    self.color = color
  }

  func fade() {
    self.color--  // Noncompliant
  }
}

Compliant Solution

class Car {
  var color: Int

  init(color: Int) {
    self.color = color
  }

  func fade() {
    color--
  }
}
swift:S2966

The point of declaring an optional variable is to make explicit the fact that it might contain no valid value, i.e. nil. Force-unwrapping an optional will lead to a runtime error if the optional does contain nil. Even if the value is tested first, it's still considered a bad practice to use force-unwrapping. Instead, optional binding or optional chaining should be used.

Noncompliant Code Example

var greeting: String?

// ...
println( \(greeting!))  // Noncompliant; could cause a runtime error

if greeting != nil {
  println( \(greeting!))  // Noncompliant; better but still not great
}

Compliant Solution

var greeting: String?

// ...
if let howdy = greeting {
  println(howdy)
}
swift:S2967

The point of using an optional is to signal that the value may be nil and to provide graceful ways of dealing with it if it is nil. While implicitly unwrapped optionals still provide means of dealing with nil values, they also signal that the value won't be nil, and unwrap it automatically. In addition to sending a decidedly mixed signal, this could lead to runtime errors if the value ever is nil.

It is safest, and clearest to use either an optional or a plain type and avoid the boggy middle ground of implicitly unwrapped optionals.

Noncompliant Code Example

var greeting : String!  // Noncompliant

println(greeting)  // At this point the value is nil. Runtime error results

Compliant Solution

var greeting : String?

if let howdy = greeting {
  println(howdy)
}
swift:S2968

Trailing closure syntax can only be used with the last argument to a function call. Place a function type parameter anywhere else in the list and you limit the options of the caller.

Noncompliant Code Example

func foo(p1: Int->Int, p2: Int){  // Noncompliant; p1 should come at the end
  print(p1(p2))
}

foo({a in a * 2}, 42) // Trailing closure syntax can't be used here

Compliant Solution

func foo(p2: Int, p1: Int->Int){
  print(p1(p2))
}

foo(42) {a in a * 2}
swift:S2969

The use of trailing closure syntax can make code clearer, but it should only be used when the call only requires a single function type parameter.

This rule raises an issue when trailing closure syntax is not used for the last argument in a call that requires only a single function type parameter.

Noncompliant Code Example

UIView.animateWithDuration(1.0, animations: {  // Noncompliant
  self.myView.alpha = 0
})

Compliant Solution

UIView.animateWithDuration(1.0) {
  self.myView.alpha = 0
}
swift:S3083

It is acceptable to override standard operators to provide appropriate behaviors for your classes. But it is not appropriate to change those operators' associativity or precedence from the standard. Doing so will inevitably lead to misuse and mistakes for users of the class.

Instead of overriding an existing operator's associativity or precedence, you should either let them use the default values or define a completely new operator.

Noncompliant Code Example

infix operator - : CustomAdditionPrecedence   // Noncompliant. For a different behavior create a different operator

precedencegroup CustomAdditionPrecedence {
  associativity: right
}

func - (lhs: MyInt, rhs: MyInt) -> MyInt {
  // ...
}

var a = MyInt(10), b = MyInt(5), c = MyInt(5)
print(a - b - c) // against expectations, this outputs 10

Compliant Solution

infix operator <- : CustomAdditionPrecedence

precedencegroup CustomAdditionPrecedence {
  associativity: right
}

func <- (lhs: MyInt, rhs: MyInt) -> MyInt {
  // ...
}

var a = MyInt(10), b = MyInt(5), c = MyInt(5)

var a = MyInt(10), b = MyInt(5), c = MyInt(5)
print(a - b - c) // prints 0 as expected
print(a <- b <- c) // prints 10
swift:S3086

Making an operator a convenience wrapper around an existing function or method provides additional flexibility to users in how the functionality is called and in what options are passed in.

This rule raises an issue when the function that defines the operation of a operator consists of something other than a single function call.

Noncompliant Code Example

infix operator >< { associativity right precedence 90 }
func >< (left: Double, right: Double) -> Double {  // Noncompliant
  let leftD = (left % 1) * 100
  let rightD = (right % 1) * 100
  let leftW = (left - leftD) / 100
  let rightW = (right - rightD) / 100
  return (leftD + leftW) * (rightD + rightW)
}

Compliant Solution

infix operator >< { associativity right precedence 90 }
func >< (left: Double, right: Double) -> Double {
  return fubar(left, right)
}

func fubar(left: Double, right: Double) -> Double {
  let leftD = (left % 1) * 100
  let rightD = (right % 1) * 100
  let leftW = (left - leftD) / 100
  let rightW = (right - rightD) / 100
  return (leftD + leftW) * (rightD + rightW)
}

Exceptions

Operators that end with = are expected to update their left-hand operands, and are therefore ignored.

func **= (inout p1:Int, p2:Int) {
    p1 = p1 ** p2
}
swift:S3087

The point of using closure expressions is to clearly express a succinct bit of logic. Start nesting closure expressions too deeply and you create a logic snarl that will likely snare both you and future maintainers.

Noncompliant Code Example

With the maximum depth of 2:

foo(42) { (x: Int) in
    bar(x) { (x: Int) in
      foobar(x) { // Noncompliant
        print(x * 42)
      }
      print(x + 42)
    }
    print(x - 42)
}

Compliant Solution

func multPlus(x:Int) {
  foobar(x) {
    print(x * 42)
  }
  print(x + 42)
}

foo(42) { (x: Int) in
    bar(x, multPlus)
    print(x - 42)
}
swift:S3110

The conventional expectation of operators that end with =, such as +=, -=, *=, and so on, is that the result of the operation will be assigned to the operand on the left-hand side of the operator.

Define any other behavior and you almost guarantee that the users of your code will misunderstand and therefore misuse your operator.

Noncompliant Code Example

func **= (p1:Int, p2:Int) -> Int {   // Noncompliant. Change operator name or update value of first parameter
    return p1 ** p2
}

func => (p1:Int, p2:Int) -> Int {  // Compliant; doesn't end with '='
    return p1 ** p1 ** p2
}

Compliant Solution

func **= (inout p1:Int, p2:Int) {
    p1 = p1 ** p2
}

func => (p1:Int, p2:Int) -> Int {
    return p1 ** p1 ** p2
}
swift:S3111

Conditional compilation is generally recognized as a bad practice that is occasionally necessary when dealing with platform-specific code. As much as possible, code should be refactored to minimize or eliminate conditionally-compiled, platform-specific code because even when necessary and well-intentioned, such code segments can leave your codebase in a hopeless tangle.

Noncompliant Code Example

#if os(OSX) // Noncompliant
    let a = 2
#else
    let a = 3
#endif
swift:S3358

Just because you can do something, doesn't mean you should, and that's the case with nested ternary operations. Nesting ternary operators results in the kind of code that may seem clear as day when you write it, but six months later will leave maintainers (or worse - future you) scratching their heads and cursing.

Instead, err on the side of clarity, and use another line to express the nested operation as a separate statement.

Noncompliant Code Example

func getTitle(person: Person) -> String {
  return person.gender == Gender.MALE ? "Mr. " : person.married ? "Mrs. " : "Miss ";  // Noncompliant
}

Compliant Solution

func getTitle(person: Person) -> String {
  let title: String;
  if (person.gender == Gender.MALE) {
     title = "Mr. ";
  }
  else {
     title = person.married ? "Mrs. " : "Miss ";
  }
  return title;
}
swift:S3400

There's no point in forcing the overhead of a function or method call for a function that always returns the same constant value. Even worse, the fact that a function call must be made will likely mislead developers who call the method thinking that something more is done. Declare a constant instead.

This rule raises an issue on functions that contain only one statement: the return of a constant value.

Noncompliant Code Example

func getBestNumber() -> Int {
  return 12  // Noncompliant
}

Compliant Solution

let bestNumber = 12;

Exceptions

Methods which are members of a class having a type inheritance clause are ignored.

swift:S3630

Because force casting (as!) does not perform any type safety validations, it is capable of performing dangerous conversions between unrelated types. When the types are truly unrelated, the cast will cause a system crash.

Noncompliant Code Example

foo as! MyClass  // Noncompliant

Compliant Solution

foo as? MyClass

See

  • CppCoreGuidelines, Type safety profile - Type.1: Don't use reinterpret_cast.
swift:S3661

The use of Swift 2.0's try! lets you execute code that might throw an exception without using the do and catch syntax normally required for such code. By using it, you're guaranteeing that the executed code will never fail. Murphy's Law guarantees you're wrong. And when it does fail, the program will exit abruptly, probably without cleaning up after itself.

Noncompliant Code Example

let myvar = try! dangerousCode(foo);  // Noncompliant
// ...

Compliant Solution

do {
  let myvar = try dangerousCode(foo);
  // ...
} catch {
  // handle error
}
swift:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

swift:S3923

Having all branches in a switch or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a switch/if chain at all.

Noncompliant Code Example

if b == 0 {  // Noncompliant
  doOneMoreThing()
} else {
  doOneMoreThing()
}

var b = a > 12 ? 4 : 4  // Noncompliant; always results in the same value

switch i {  // Noncompliant
  case 1:
    doSomething()
  case 2:
    doSomething()
  default:
    doSomething()
}

Exceptions

This rule does not apply to if chains without else-s, or to switch-es without default clauses.

if b == 0 {    // no issue, this could have been done on purpose to make the code more readable
  doSomething()
} else if b == 1 {
  doSomething()
}
swift:S3981

The number of elements in a collection, an array or a string are always greater than or equal to zero. So testing that a size or length is greater than or equal to zero doesn't make sense, since the result is always true. Similarly testing that it is less than zero will always return false. Perhaps the intent was to check the non-emptiness instead.

Noncompliant Code Example

if (myArray.count >= 0) { ... }

if (myString.characters.count < 0) { ... }

Compliant Solution

if (myArray.isEmpty) { ... }

if (myString.isEmpty) { ... }
swift:S4142

There are valid cases for passing a variable multiple times into the same method call, but usually doing so is a mistake, and something else was intended for one of the arguments.

Noncompliant Code Example

if equal(myPoint.x, myPoint.x) {  // Noncompliant
  //...
}

Compliant Solution

if equal(myPoint.x, myPoint.y) {
  //...
}

Deprecated

This rule is deprecated, and will eventually be removed.

swift:S4143

It is highly suspicious when a value is saved for a key or index and then unconditionally overwritten. Such replacements are likely in error.

Noncompliant Code Example

letters["a"] = "Apple"
letters["a"] = "Boy"  // Noncompliant

towns[i] = "London"
towns[i] = "Chicago"  // Noncompliant
swift:S4144

When two functions have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, one implementation should invoke the other.

Noncompliant Code Example

func calculate() {
  doTheThing()
  doOtherThing()
}

func doEverything() {  // Noncompliant
  doTheThing()
  doOtherThing()
}

Compliant Solution

func calculate() {
  doTheThing()
  doOtherThing()
}

func doEveryting() {
  calculate()
}

Exceptions

Methods with fewer than 2 statements are ignored.

swift:S4173

If you only want one instance that matches certain criteria out of a collection, it's far more efficient to grab the first matching item than it is to fully filter the collection for your criteria and then only use a single value.

Noncompliant Code Example

let one = arr.filter { $0.containsString("yo") }.first  // Noncompliant

Compliant Solution

let one = arr.first(where: { $0.containsString("yo") })
swift:S4184

Marking a variable with IBOutlet allows it to be connected with a Storyboard component through the Interface Builder. Allowing such a variable to be accessed outside the class, may result in other classes making assignments that override the automatic dependency injection from the Storyboard itself.

Noncompliant Code Example

  @IBOutlet var label: UILabel!  // Noncompliant

Compliant Solution

  @IBOutlet private var label: UILabel!
swift:S4186

Adding IBInspectable to a properly-typed variable makes it available in Xcode's Interface Builder. But that only works if variable type is declared explicitly as one of the following:

  • Int types, Double, Float, Bool
  • String (or its optional)
  • CGFloat, CGPoint, CGSize, CGRect
  • UIColor, UIImage (and their optionals)
  • NSString, NSColor, NSImage (and their optionals)
  • NSRect, NSPoint, NSSize,

Noncompliant Code Example

@IBInspectable  // Noncompliant; type is implicit
public var cornerRadius = 2.0 {
  didSet {
     //...
  }
}

Compliant Solution

@IBInspectable
public var cornerRadius: CGFloat  = 2.0 {
  didSet {
     //...
  }
}
swift:S4188

An unordered pair is easy to handle, but the longer an unordered set gets, the harder it is to deal with.

This rule raises an issue when a tuple of more than the allowed number of elements is returned.

Noncompliant Code Example

With the default threshold of 2

func doTheThing() -> (Int, Int, Int) {}  // Noncompliant

Compliant Solution

func doTheThing() -> MyIntStruct {}
swift:S4233

If a closure expression is provided as the function or method’s only argument and you provide that expression as a trailing closure, you do not need to write a pair of parentheses () after the function or method’s name when you call the function. This makes the code somewhat easier to read.

Noncompliant Code Example

reversedNames = names.sorted() { $0 > $1 } // Noncompliant

Compliant Solution

eversedNames = names.sorted { $0 > $1 }
swift:S881

The use of increment and decrement operators in method calls or in combination with other arithmetic operators is not recommended, because:

  • It can significantly impair the readability of the code.
  • It introduces additional side effects into a statement, with the potential for undefined behavior.
  • It is safer to use these operators in isolation from any other arithmetic operators.

Noncompliant Code Example

u8a = ++u8b + u8c--
foo = bar++ / 4

Compliant Solution

The following sequence is clearer and therefore safer:

++u8b
u8a = u8b + u8c
u8c--
foo = bar / 4
bar++

See

  • MISRA C:2004, 12.1 - Limited dependence should be placed on the C operator precedence rules in expressions.
  • MISRA C:2004, 12.13 - The increment (++) and decrement (--) operators should not be mixed with other operators in an expression.
  • MISRA C++:2008, 5-2-10 - The increment (++) and decrement (--) operator should not be mixed with other operators in an expression.
  • MISRA C:2012, 12.1 - The precedence of operators within expressions should be made explicit
  • MISRA C:2012, 13.3 - A full expression containing an increment (++) or decrement (--) operator should have no other potential side effects other than that cause by the increment or decrement operator
  • CERT, EXP30-C. - Do not depend on the order of evaluation for side effects
  • CERT, EXP50-CPP. - Do not depend on the order of evaluation for side effects
  • CERT, EXP05-J. - Do not follow a write by a subsequent write or read of the same object within an expression
tsql:NoSonar

Any issue to quality rule can be deactivated with the NOSONAR marker. This marker is pretty useful to exclude false-positive results but it can also be used abusively to hide real quality flaws.

This rule raises an issue when NOSONAR is used.

tsql:S103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

tsql:S105

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

tsql:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

IF something
  IF something_else
    -- ...

Compliant Solution

IF something AND something_else
  -- ...
tsql:S107

A long parameter list can indicate that a new structure should be created to wrap the numerous parameters or that the function or procedure is doing too many things.

tsql:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

DECLARE @x INT = (@y / 2 + 1); -- Compliant even if the parentheses are ignored
IF (@x > 0) AND ((@x+@y > 0)) -- Noncompliant
BEGIN
  -- ...
END

Compliant Solution

DECLARE @x INT = (@y / 2 + 1);
IF (@x > 0) AND (@x+@y > 0)
BEGIN
  -- ...
END
tsql:S1151

As soon as a WHEN clause contains too much logic this highly decreases the readability of the overall expression. In such case, the content of the WHEN clause may be extracted into a dedicated function.

Noncompliant Code Example

With a threshold of 5:

SELECT CASE column1
  WHEN 1 THEN
    CASE column2
      WHEN 'a' THEN -- Noncompliant, 7 lines till ELSE
        'x'
      ELSE
        'y'
      END
  ELSE
    42
  END
FROM table1;

Compliant Solution

SELECT CASE
  WHEN column1 = 1 AND column2 = 'a' THEN
    'x'
  WHEN column1 = 1 THEN
    'y'
  ELSE
    42
  END
FROM table1;
tsql:S117

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when a local variable or function parameter name does not match the provided regular expression.

Noncompliant Code Example

With the default regular expression @[a-zA-Z0-9_]*:

CREATE PROCEDURE proc1
    @@var1 INT -- Noncompliant
AS
BEGIN
    DECLARE @@var2 INT; -- Noncompliant
END
tsql:S1192

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

With the default threshold of 3:

IF @x='Yes'
  SELECT ...
    FROM ...
    WHERE field='Yes'
...
...
IF @x='Yes'
  ...

Compliant Solution

DECLARE @Yes VARCHAR(3) = 'Yes'
IF @x=@Yes
  SELECT ...
    FROM ...
    WHERE field=@Yes
...
...
IF @x=@Yes
  ...

Exceptions

To prevent generating some false-positives, literals having less than 5 characters are excluded.

tsql:S122

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

IF @x > 0 SET @x = 0; IF @y > 0 SET @y = 0; -- Noncompliant

Compliant Solution

IF @x > 0 SET @x = 0;
IF @y > 0 SET @y = 0;
tsql:S134

Nested IF...ELSE, WHILE and TRY...CATCH statements is a key ingredient 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 4:

IF @flag1 = 1 -- Compliant - depth = 1
  BEGIN
    IF @flag2 = 2 -- Compliant - depth = 2
      BEGIN
        WHILE @var1 > 0  -- Compliant - depth = 3
          BEGIN
            IF @flag3 = 3 -- Compliant - depth = 4, not exceeding the limit
              BEGIN
                IF @flag4 = 4 -- Noncompliant - depth = 5
                  BEGIN
                    IF @flag5 = 5 -- Depth = 6, exceeding the limit, but issues are only reported on depth = 5
                      BREAK
                  END
              END
            SET @var1 = @var1 - 1
          END
      END
  END
tsql:S138

A function or stored procedure that grows too large tends to aggregate too many responsibilities. Such function or stored procedure inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions or stored procedures which focus on well-defined tasks. Those smaller functions or stored procedures will not only be easier to understand, but also probably easier to test.

tsql:S1479

CASE expressions with large sets of WHEN clauses are difficult to understand and maintain, and should be refactored to include fewer WHEN clauses.

tsql:S1481

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.

tsql:S1499

SELECT * should be avoided because it releases control of the returned columns and could therefore lead to errors and potentially to performance issues.

Noncompliant Code Example

SELECT *     -- Noncompliant
       FROM persons
       WHERE city = 'NEW YORK'

Compliant Solution

SELECT firstname, lastname
       FROM persons
       WHERE city = 'NEW YORK'

Exceptions

The following cases are ignored by this rule:

  • SELECT from temporary tables: SELECT * FROM #temp1
  • SELECT using common table expressions: WITH A AS (SELECT C1 FROM T1) SELECT * FROM A;
  • Inside another SELECT: SELECT C1 FROM T1 WHERE C2 IN (SELECT * FROM T2)
  • Inside INSERT: INSERT INTO T1 SELECT * FROM T2
  • Inside CREATE TABLE: CREATE TABLE T1 WITH (C1 = C2) AS SELECT * FROM T2
  • SELECT from rowset providers: SELECT * FROM OPENXML (@idoc, '/ROOT/Customer',1)
  • SELECT INTO: SELECT * INTO NEW_TABLE FROM T1
  • SELECT from variable table: SELECT * FROM @table1
  • SELECT from derived table: SELECT A.* FROM (SELECT X FROM T1) A INNER JOIN B ON A.X = B.X
tsql:S1542

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all function names match a provided regular expression.

Noncompliant Code Example

CREATE PROCEDURE sp_PrintMagicNumber
AS
BEGIN
  PRINT 42
END
GO

CREATE FUNCTION MagicNumber()
RETURNS INT
AS
BEGIN
  RETURN 42
END
GO

Compliant Solution

CREATE PROCEDURE usp_PrintMagicNumber
AS
BEGIN
  PRINT 42
END
GO

CREATE FUNCTION fn_MagicNumber()
RETURNS INT
AS
BEGIN
  RETURN 42
END
GO
tsql:S1631

When you need access to data from multiple tables, it is more efficient, effective, and understandable to use pre-built views than to select the data from a large number of tables - effectively creating in-memory views - at runtime.

Noncompliant Code Example

With a maximum number of 3 joined tables:

SELECT PERSONS.NAME, COUNTRIES.NAME, GENRES.NAME, PROFESSIONS.NAME
FROM PERSONS
  INNER JOIN COUNTRIES ON COUNTRIES.ID = PERSON.COUNTRY_ID
  INNER JOIN GENRES ON GENRES.ID = PERSONS.GENRE_ID
  INNER JOIN PROFESSIONS ON PROFESSIONS.ID = PERSONS.PROFESSIONS_ID  -- Noncompliant; this is table #4
WHERE COUNTRIES.CODE = 'US'

SELECT PERSONS.NAME, COUNTRIES.NAME, GENRES.NAME, PROFESSIONS.NAME
FROM PERSONS, COUNTRIES, GENRES, PROFESSIONS -- Noncompliant
WHERE COUNTRIES.CODE = 'US' AND COUNTRIES.ID = PERSON.COUNTRY_ID AND GENRES.ID = PERSONS.GENRE_ID AND PROFESSIONS.ID = PERSONS.PROFESSIONS_ID
tsql:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

DECLARE @a INT;
DECLARE @b INT = 2;
SET @a = @a; -- Noncompliant

Compliant Solution

DECLARE @a INT;
DECLARE @b INT = 2;
SET @a = @b;

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
tsql:S1735

Even though the ORDER BY clause supports using column numbers, doing so makes the code difficult to read and maintain. Therefore the use of column names is preferred.

Noncompliant Code Example

SELECT FIRST_NAME, LAST_NAME, REGION
FROM PERSONS
ORDER BY 2, 1

Compliant Solution

SELECT FIRST_NAME, LAST_NAME, REGION
FROM PERSONS
ORDER BY LAST_NAME, FIRST_NAME
tsql:S1739

When the value of a LIKE clause starts with '%', '[...]' or '_', indexes on the searched column are ignored, and a full table scan is performed instead.

Noncompliant Code Example

SELECT FIRST_NAME, LAST_NAME FROM PERSONS
WHERE LAST_NAME LIKE '%PONT'
tsql:S1742

To prevent portability issues !=, !> and !< operators should be replaced by the ANSI standard operators: <>, <= or >=.

Noncompliant Code Example

SELECT C1 FROM S1TESTMD WHERE BIRTHDATE != 2000

Compliant Solution

SELECT C1 FROM S1TESTMD WHERE BIRTHDATE <> 2000
tsql:S1745

An INSERT statement that does not explicitly list the columns being inserted into, as well as the values being inserted, is dependent for correct functioning on the structure of the table not changing. Additionally, not having the explicit column list degrades the readability and understandability of the code. Therefore, INSERT statements should always contain an explicit column list.

Noncompliant Code Example

INSERT INTO PERSONS VALUES (1, 'DUPONT', 'Marcel')

Compliant Solution

INSERT INTO PERSONS (ID, LAST_NAME, FIRST_NAME)
VALUES (1, 'DUPONT', 'Marcel')
tsql:S1862

A CASE and a chain of IF/ELSE IF statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

Noncompliant Code Example

IF @x = 1
  PRINT 'A'
ELSE IF @x = 2
  PRINT 'B'
ELSE IF @x = 1 -- Noncompliant
  PRINT 'C'

SELECT
  CASE col1
    WHEN 1
      THEN 'A'
    WHEN 2
      THEN 'B'
    WHEN 1  -- Noncompliant
      THEN 'C'
    ELSE 'D'
  END
FROM table1

Compliant Solution

IF @x = 1
  PRINT 'A'
ELSE IF @x = 2
  PRINT 'B'
ELSE IF @x = 3
  PRINT 'C'

SELECT
  CASE col1
    WHEN 1
      THEN 'A'
    WHEN 2
      THEN 'B'
    WHEN 3
      THEN 'C'
    ELSE 'D'
  END
FROM table1

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
tsql:S2260

When the parser fails, it is possible to record the failure as an issue on the file. This way, not only is it possible to track the number of files that do not parse but also to easily find out why they do not parse.

tsql:S2527

In a Zen-like manner, "NULL" is never equal to anything, even itself. Therefore comparisons using equality operators will always return False, even when the value actually IS NULL.

For that reason, comparison operators should never be used to make comparisons with NULL; IS NULL and IS NOT NULL should be used instead.

Noncompliant Code Example

UPDATE books
SET title = 'unknown'
WHERE title = NULL -- Noncompliant

Compliant Solution

UPDATE books
SET title = 'unknown'
WHERE title IS NULL
tsql:S2761

Calling the +, -, ~ or NOT prefix operator twice does nothing: the second invocation undoes the first. Such mistakes are typically caused by accidentally double-tapping the key in question without noticing.

Either this is a bug, if the operator was actually meant to be called once, or misleading if done on purpose.

Noncompliant Code Example

DECLARE @v1 INTEGER = 1
DECLARE @v2 INTEGER = - - -@v1 -- Noncompliant; -@v1 should be used instead
DECLARE @v3 INTEGER = ~~~@v1 -- Noncompliant; ~@v1 should be used instead
DECLARE @v4 INTEGER = ++@v1 -- Noncompliant; operators are useless here

IF NOT NOT @v1 <> @v2 -- Noncompliant
  BEGIN
    PRINT @msg
  END

Compliant Solution

DECLARE @v1 INTEGER = 1
DECLARE @v2 INTEGER = -@v1
DECLARE @v3 INTEGER = ~@v1
DECLARE @v4 INTEGER = @v1

IF @v1 <> @v2
  BEGIN
    PRINT @msg
  END
tsql:S3643

The use of LIKE in a SQL query without one or more wildcards in the sought value is suspicious. A maintainer can suppose that either = was meant instead, or that the wildcard was unintentionally omitted.

Note that in some cases using LIKE without a wildcard may return different results than the use of =. Thus, the use of LIKE without a wildcard may be intentional. However, it is highly likely to confuse maintainers who either are unaware of this fact, or don't understand that such circumstances apply to the query in question.

Noncompliant Code Example

SELECT name
FROM product
WHERE name LIKE 'choc'

Compliant Solution

SELECT name
FROM product
WHERE name LIKE 'choc%'

or

SELECT name
FROM product
WHERE name = 'choc'
tsql:S3972

Code is clearest when each statement has its own line. Nonetheless, it is a common pattern to combine on the same line an IF and its resulting then statement. However, when an IF is placed on the same line as the closing END from a preceding ELSE or ELSE IF, it is either an error - ELSE is missing - or the invitation to a future error as maintainers fail to understand that the two statements are unconnected.

Noncompliant Code Example

IF (condition1) BEGIN
  EXEC something
END IF (condition2) BEGIN  -- Noncompliant
  EXEC something
END

Compliant Solution

IF (condition1) BEGIN
  EXEC something
END ELSE IF (condition2) BEGIN
  EXEC something
END

Or

IF (condition1) BEGIN
  EXEC something
END

IF (condition2) BEGIN
  EXEC something
END
tsql:S3973

In the absence of enclosing BEGIN...END block, the line immediately after a conditional is the one that is conditionally executed. By both convention and good practice, such lines are indented. In the absence of both BEGIN...END block and indentation the intent of the original programmer is entirely unclear and perhaps not actually what is executed. Additionally, such code is highly likely to be confusing to maintainers.

Noncompliant Code Example

IF @condition  -- Noncompliant
EXEC doTheThing;
EXEC doTheOtherThing;
EXEX somethingElseEntirely;

EXEC foo;

Compliant Solution

IF @condition
BEGIN
  EXEC doTheThing;
  EXEC doTheOtherThing;
  EXEX somethingElseEntirely;
END;

EXEC foo;

Or

IF @condition
  EXEC doTheThing;
EXEC doTheOtherThing;
EXEX somethingElseEntirely;

EXEC foo;
tsql:S4054

Using TOP in a SELECT without ordering the results from which the "top" results are chosen will return a seemingly random set of rows, and is surely a mistake.

The same random behavior also occurs when using TOP in a DELETE, INSERT, UPDATE and MERGE.

Noncompliant Code Example

SELECT TOP 10 -- Noncompliant selects 10 random rows
  fname, lname, city
  FROM people
  WHERE city IS NOT NULL;

DELETE TOP (10) -- Noncompliant deletes 10 random rows
  FROM PurchaseOrder
  WHERE DueDate < '20020701';

Compliant Solution

SELECT TOP 10
  fname, lname, city
  FROM people
  WHERE city IS NOT NULL
  ORDER BY birthdate;

DELETE
  FROM PurchaseOrder
  WHERE OrderID IN (
    SELECT TOP 10
      OrderID
      FROM PurchaseOrder
      WHERE DueDate < '20020701'
      ORDER BY DueDate ASC
  );
tsql:S4075

Deprecated language features are those that have been retained temporarily for backward compatibility, but which will eventually be removed from the language. In effect, deprecation announces a grace period to allow the smooth transition from the old features to the new ones. In that period, no use of the deprecated features should be added to the code, and all existing uses should be gradually removed.

The following features are deprecated or (depending on your version) already removed from TSQL:

Instead of Use
WRITETEXT, UPDATETEXT, READTEXT VARCHAR
GROUP BY ALL UNION or a derived table
FASTFIRSTROW FAST n
SETUSER EXECUTE AS
CREATE RULE CHECK constraints
PASSWORD, MEDIAPASSWORD in BACKUP or RESTORE use access control on the directory or WITH RESTRICTED_USER for RESTORE
DBCC DBREINDEX ALTER INDEX REBUILD
DBCC INDEXDEFRAG ALTER INDEX DEFRAG
DBCC SHOWCONTIG sys.dm_db_index_physical_stats
DBCC CONCURRENCYVIOLATION no replacement
SET ROWCOUNT TOP(n)
SET REMOTE_PROC_TRANSACTIONS distributed queries that reference linked servers (sp_addlinkedserver)
RAISERROR @Errno @ErrMsg the RAISERROR syntax using parentheses
DROP INDEX with two-part name Move table (and database) to an ON clause
String literals as column aliases Remove the quotes around the alias. Use square brackets if escaping is necessary
Numbered procedures Replace with un-numbered procedures
System stored procedure no replacement
fn_virtualservernodes sys.dm_os_cluster_nodes
fn_servershareddrives sys.dm_io_cluster_shared_drives
GRANT / DENY / REVOKE ALL List the specific permissions
TORN_PAGE_DETECTION checksum
TAPE DISK or URL
Table hint without WITH WITH(hint)
tsql:S4078

String data types (char, varchar, nchar, nvarchar) default to a size of 1 if no size is specified in the declaration. For char and nchar this is confusing at best, but it is most probably a mistake for varchar and nvarchar.

This rule raises an issue when no size is specified for varchar or nvarchar.

Noncompliant Code Example

DECLARE @myStr varchar;  -- Noncompliant

Compliant Solution

DECLARE @myStr varchar(255);
tsql:S4094

Under the covers, Simple CASE expressions are evaluated as searched CASE expressions. That is,

CASE @foo
WHEN 1 THEN 'a'
WHEN 2 THEN 'b'

is actually evaluated as

CASE
WHEN @foo = 1 THEN 'a'
WHEN @foo = 2 THEN 'b'

In most situations the difference is inconsequential, but when the input expression isn't fixed, for instance if RAND() is involved, it is likely to yield unexpected results. For that reason, it is better to evaluate the input expression once, assign it to a variable, and use the variable as the CASE's input expression.

This rule raises an issue when any of the following is used in a CASE input expression: RAND, NEWID, CRYPT_GEN_RANDOM.

Noncompliant Code Example

CASE CONVERT(SMALLINT, RAND()*@foo)  -- Noncompliant
WHEN 1 THEN 'a'
WHEN 2 THEN 'b'

Compliant Solution

DECLARE @bar SMALLINT = CONVERT(SMALLINT, RAND()*@foo)
CASE @bar
WHEN 1 THEN 'a'
WHEN 2 THEN 'b'
tsql:S4102

When you add a new constraint to a table, (ALTER TABLE ... ADD CONSTRAINT ...), WITH CHECK is assumed by default, and existing data are automatically validated.

But when you disable/enable an existing constraint, WITH NOCHECK is assumed by default, and existing data are no longer trusted. In this case you will face an integrity issue that prevents some rows from being updated, and a performance issue because the query optimizer cannot trust this constraint anymore.

Of course, WITH CHECK is obviously preferred, but if NOCHECK behavior is desired, it should not be selected by omission, but specified explicitly because WITH NOCHECK has such a significant impact. By making NOCHECK explicit, the developer documents that this behavior has been selected on purpose.

Note: You can list the existing constraints that are in an untrusted state using:

SELECT * FROM sys.foreign_keys WHERE is_not_trusted = 1;

SELECT * FROM sys.check_constraints WHERE is_not_trusted = 1;

Noncompliant Code Example

-- Create a trusted constraint
ALTER TABLE users ADD CONSTRAINT max_age CHECK (age < 200) ;

-- Disable the constraint
ALTER TABLE users NOCHECK CONSTRAINT max_age;

-- Enable the constraint
ALTER TABLE users CHECK CONSTRAINT max_age; -- Noncompliant, 'WITH NOCHECK' is the default mode, but is it really intentional?

Compliant Solution

-- Create a trusted constraint
ALTER TABLE users ADD CONSTRAINT max_age CHECK (age < 200) ;

-- Disable the constraint
ALTER TABLE users NOCHECK CONSTRAINT max_age;

-- Enable the constraint
ALTER TABLE users WITH CHECK CHECK CONSTRAINT max_age;
-- OR
ALTER TABLE users WITH NOCHECK CHECK CONSTRAINT max_age;
tsql:S4103

A FETCH statement fails when the number of variables does not match the number of columns selected in the CURSOR definition.

Noncompliant Code Example

DECLARE c1 cursor FOR SELECT FirstName, LastName FROM customer;
OPEN c1;
FETCH NEXT FROM c1 INTO @Name; -- Noncompliant

Compliant Solution

DECLARE c1 cursor FOR SELECT FirstName, LastName FROM customer;
OPEN c1;
FETCH NEXT FROM c1 INTO @FirstName, @LastName;
tsql:S4108

@@IDENTITY returns the last identity column value created on a connection, regardless of the scope. That means it could return the last identity value you produced, or it could return a value generated by a user defined function or trigger, possibly one fired because of your insert. In order to access the last identity value created in your scope, use SCOPE_IDENTITY() instead.

Noncompliant Code Example

INSERT ...

SET @id = @@IDENTITY  -- Noncompliant

Compliant Solution

INSERT ...

SET @id = SCOPE_IDENTITY()
tsql:S4109

There's almost no point in returning results from a trigger. Because there is generally no expectation that triggers will return anything, any such results are likely to be ignored nearly all the time.

This rule raises an issue when PRINT is used inside a trigger, and when SELECT, or FETCH is used inside a trigger without the retrieved data subsequently being used inside the trigger itself.

Noncompliant Code Example

ALTER TRIGGER TRG_myTrigger
...
  PRINT @diagnostic_message -- Noncompliant
tsql:S4142

There are valid cases for passing a variable multiple times into the same function or procedure call, but usually doing so is a mistake, and something else was intended for one of the arguments.

Noncompliant Code Example

SET @result = dbo.MyAdd(@val1, @val1) -- Noncompliant

Compliant Solution

SET @result = dbo.MyAdd(@val1, @val2)

Deprecated

This rule is deprecated, and will eventually be removed.

tsql:S4149

Referencing a column by specifying the schema or the database is deprecated. It is retained temporarily for backward compatibility, but it will eventually be removed from the language. You should only use one part (column_name) or two part (table_name.column_name) references.

Noncompliant Code Example

SELECT dbo.table1.col1,       -- Noncompliant, three-part column reference
       MY_DB.dbo.table1.col2  -- Noncompliant, four-part column reference
       FROM MY_DB.dbo.table1;

SELECT dbo.table1.name,       -- Noncompliant
       dbo.table2.name        -- Noncompliant
       FROM dbo.table1
       JOIN dbo.table2
         ON dbo.table2.id = dbo.table1.id; -- Noncompliant

Compliant Solution

SELECT col1,
       col2
       FROM MY_DB.dbo.table1;

SELECT table1.name,
       table2.name
       FROM dbo.table1
       JOIN dbo.table2
         ON table2.id = table1.id;
tsql:S4154

Changing the configuration of database options ANSI_NULLS, ANSI_PADDING and CONCAT_NULL_YIELDS_NULL is deprecated. The future versions of SQL Server will only support the ON value, and the SET statement for those options to OFF will eventually generate an error.

Noncompliant Code Example

SET ANSI_NULLS OFF -- Noncompliant
SELECT column1 FROM table1 WHERE id = NULL

SET ANSI_PADDING OFF -- Noncompliant
SET CONCAT_NULL_YIELDS_NULL ON -- Noncompliant

SET ANSI_PADDING ON -- "ON" is ignored

Compliant Solution

SELECT column1 FROM table1 WHERE id IS NULL
tsql:S4155

Deprecated system tables and views are those that have been retained temporarily for backward compatibility, but which will eventually be removed from the language. In effect, deprecation announces a grace period to allow the smooth transition from the old features to the new ones.

This rule raises an issue when system tables or views are used. Catalog tables and views should be used instead.

Noncompliant Code Example

SELECT name FROM syscolumns -- Noncompliant

Compliant Solution

SELECT name FROM sys.columns
tsql:S4196

Marking a parameter for output means that callers will expect its value to be updated with a result from the execution of the procedure. Failing to update the parameter before the procedure returns is surely an error.

Noncompliant Code Example

CREATE PROCEDURE greet
  @Name varchar(20),
  @Greeting varchar(25) OUTPUT  -- Noncompliant
AS
  DECLARE @Message VARCHAR(45)
  SET @Message = N'Hello ' + RTRIM(@Name);
  PRINT @Message
GO

Compliant Solution

CREATE PROCEDURE greet
  @Name varchar(20),
  @Greeting varchar(25) OUTPUT
AS
  SELECT @Greeting = N'Hello ' + RTRIM(@Name);
GO
tsql:S4413

Although, it is syntactically possible (by using delimiters) to use SQL reserved keywords as identifiers and object names, it is best to not use them to avoid any confusion.

Noncompliant Code Example

CREATE TABLE "SELECT" ( "FROM" INT ); -- Noncompliant

SELECT "FROM" FROM "SELECT";
typescript:S101

Shared coding conventions allow teams to collaborate effectively. This rule raises an issue when class or interface names are not in PascalCase (i.e. camel case with an initial capital letter).

Noncompliant Code Example

class my_class {...}

Compliant Solution

class MyClass {...}
typescript:S103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

typescript:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

typescript:S105

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

typescript:S1066

Merging collapsible if statements increases the code's readability.

Noncompliant Code Example

if (x != undefined) {
  if (y === 2) {
    // ...
  }
}

Compliant Solution

if (x != undefined && y === 2) {
  // ...
}
typescript:S108

Most of the time a block of code is empty when a piece of code is really missing. So such empty block must be either filled or removed.

Noncompliant Code Example

for (var i = 0; i < length; i++) {}  // Empty on purpose or missing piece of code ?

Exceptions

When a block contains a comment, this block is not considered to be empty. Moreover catch blocks are ignored.

typescript:S109

A magic number is a number that comes out of nowhere, and is directly used in a statement. Magic numbers are often used, for instance to limit the number of iterations of a loops, to test the value of a property, etc.

Using magic numbers may seem obvious and straightforward when you're writing a piece of code, but they are much less obvious and straightforward at debugging time.

That is why magic numbers must be demystified by first being assigned to clearly named variables before being used.

-1, 0 and 1 are not considered magic numbers.

Noncompliant Code Example

function doSomething() {
  for (let i = 0; i < 4; i++) {    // Noncompliant, 4 is a magic number
    // ...
  }
}

Compliant Solution

function doSomething() {
  const numberOfCycles = 4;
  for (let i = 0; i < numberOfCycles; i++) {
    // ...
  }
}
typescript:S1105

Shared naming conventions allow teams to collaborate effectively. This rule raises an issue when an open curly brace is not placed at the end of a line of code.

Noncompliant Code Example

if (condition)
{                                                      //Noncompliant
  doSomething();
}

Compliant Solution

if (condition) {                                   //Compliant
  doSomething();
}

Exceptions

Object literals appearing as arguments can start on their own line.

functionWithObject(
   {                                                 //Compliant
        g: "someValue"
   }
);
typescript:S1110

The use of parentheses, even those not required to enforce a desired order of operations, can clarify the intent behind a piece of code. But redundant pairs of parentheses could be misleading, and should be removed.

Noncompliant Code Example

let x = (y / 2 + 1);   // Compliant even if those parenthesis are useless for the compiler

if (a && ((x+y > 0))) {  // Noncompliant
  //...
}

return ((x + 1));  // Noncompliant

Compliant Solution

let x = (y / 2 + 1);

if (a && (x+y > 0)) {
  //...
}

return (x + 1);
typescript:S1116

Extra semicolons (;) are usually introduced by mistake, for example because:

  • It was meant to be replaced by an actual statement, but this was forgotten.
  • There was a typo which lead the semicolon to be doubled, i.e. ;;.
  • There was a misunderstanding about where semicolons are required or useful.

Noncompliant Code Example

var x = 1;; // Noncompliant

function foo() {
};  // Noncompliant

Compliant Solution

var x = 1;

function foo() {
}

See

  • MISRA C:2004, 14.3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment provided that the first character following the null statement is a white-space character.
  • MISRA C++:2008, 6-2-3 - Before preprocessing, a null statement shall only occur on a line by itself; it may be followed by a comment, provided that the first character following the null statement is a white-space character.
  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
  • CERT, MSC51-J. - Do not place a semicolon immediately following an if, for, or while condition
  • CERT, EXP15-C. - Do not place a semicolon on the same line as an if, for, or while statement
typescript:S1125

Boolean literals should be avoided in comparison expressions ==, != to improve code readability. This rule also reports on redundant boolean operations.

Noncompliant Code Example

if (booleanMethod() == true) { /* ... */ }
if (booleanMethod() == false) { /* ... */ }
if (booleanMethod() || false) { /* ... */ }
doSomething(!false);
doSomething(booleanMethod() == true);

booleanVariable = booleanMethod() ? true : false;
booleanVariable = notBooleanMethod() ? true : false;

Compliant Solution

if (booleanMethod()) { /* ... */ }
if (!booleanMethod()) { /* ... */ }
if (booleanMethod()) { /* ... */ }
doSomething(true);
doSomething(booleanMethod());

booleanVariable = booleanMethod();
booleanVariable = Boolean(notBooleanMethod());

Exceptions

Expressions with strict comparison operators (=== and !==) are ignored.

typescript:S113

Some tools work better when files end with an empty line.

This rule simply generates an issue if it is missing.

For example, a Git diff looks like this if the empty line is missing at the end of the file:

+class Test {
+}
\ No newline at end of file
typescript:S117

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all variable names match one of the following patterns: lowerCamelCase, PascalCamelCase or UPPER_CASED. This rule also allows leading underscore.

Noncompliant Code Example

const foo_bar = 1;
const baz_ = 2;

Compliant Solution

const fooBar = 1;
const _baz = 2;
typescript:S121

While not technically incorrect, the omission of curly braces can be misleading, and may lead to the introduction of errors during maintenance.

Noncompliant Code Example

if (condition)  // Noncompliant
  executeSomething();

Compliant Solution

if (condition) {
  executeSomething();
}

See

  • MISRA C:2004, 14.8 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C:2004, 14.9 - An if (expression) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C++:2008, 6-3-1 - The statement forming the body of a switch, while, do ... while or for statement shall be a compound statement
  • MISRA C++:2008, 6-4-1 - An if (condition) construct shall be followed by a compound statement. The else keyword shall be followed by either a compound statement, or another if statement
  • MISRA C:2012, 15.6 - The body of an iteration-statement or a selection-statement shall be a compound-statement
  • CERT, EXP19-C. - Use braces for the body of an if, for, or while statement
  • CERT, EXP52-J. - Use braces for the body of an if, for, or while statement
typescript:S122

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

foo(); bar(); // Noncompliant

Compliant Solution

foo();
bar();

Exceptions

Anonymous functions containing a single statement are ignored. Control flow statements with a single nested statement are ignored as well.

onEvent(function() { doSomething(); });               // Compliant
onEvent(function(p) { doSomething(); return p % 2; }); // Noncompliant

if (condition) doSomething();                         // Compliant
if (condition) { doSomething(); }                     // Compliant
typescript:S1226

While it is technically correct to assign to parameters from within function bodies, doing so before the parameter value is read is likely a bug. Instead, initial values of parameters, caught exceptions, and foreach parameters should be, if not treated as read-only, then at least read before reassignment.

Noncompliant Code Example

function doTheThing(str : string, i: number, strings: string[]) {
  str = i.toString();  // Noncompliant

  for (let s in strings) {
    s = "hello world" + str;  // Noncompliant
    console.log(s);
  }
}

See

  • MISRA C:2012, 17.8 - A function parameter should not be modified
typescript:S125

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
typescript:S1264

When only the condition expression is defined in a for loop, and the initialization and increment expressions are missing, a while loop should be used instead to increase readability.

Noncompliant Code Example

for (;condition;) { /*...*/ }

Compliant Solution

while (condition) { /*...*/ }
typescript:S1301

switch statements are useful when there are many different cases depending on the value of the same expression.

For just one or two cases however, the code will be more readable with if statements.

Noncompliant Code Example

switch (variable) {
  case 0:
    doSomething();
    break;
  default:
    doSomethingElse();
    break;
}

Compliant Solution

if (variable == 0) {
  doSomething();
} else {
  doSomethingElse();
}

See

  • MISRA C:2004, 15.5 - Every switch statement shall have at least one case clause.
  • MISRA C++:2008, 6-4-8 - Every switch statement shall have at least one case-clause.
  • MISRA C:2012, 16.6 - Every switch statement shall have at least two switch-clauses
typescript:S138

A function that grows too large tends to aggregate too many responsibilities.

Such functions inevitably become harder to understand and therefore harder to maintain.

Above a specific threshold, it is strongly advised to refactor into smaller functions which focus on well-defined tasks.

Those smaller functions will not only be easier to understand, but also probably easier to test.

typescript:S1438

In JavaScript, the semicolon (;) is optional as a statement separator, but omitting semicolons can be confusing, and lead to unexpected results because a semicolon is implicitly inserted at the end of each line.

Noncompliant Code Example

function fun() {
  return  // Noncompliant. ';' implicitly inserted at end of line
       5   // Noncompliant. ';' implicitly inserted at end of line
}
print(fun());  // prints "undefined", not "5"

Compliant Solution

function fun() {
  return 5;
}
print(fun());
typescript:S1439

Any statement or block of statements can be identified by a label, but those labels should be used only on while, do-while, for and switch statements. Using labels in any other context leads to unstructured, confusing code.

Noncompliant Code Example

myLabel: if (i % 2 == 0) {  // Noncompliant
  if (i == 12) {
    console.log("12");
    break myLabel;
  }
  console.log("Odd number, but not 12");
}

Compliant Solution

myLabel: for (i = 0; i < 10; i++) {   // Compliant
  console.log("Loop");
  break myLabel;
}
typescript:S1440

The == and != operators do type coercion before comparing values. This is bad because it can mask type errors. For example, it evaluates ' \t\r\n' == 0 as true.

It is best to always use the side-effect-less === and !== operators instead.

Noncompliant Code Example

if (var == 'howdy') {...} // Noncompliant

Compliant Solution

if (var === 'howdy') {...}

Exceptions

Even if testing the equality of a variable against null doesn't do exactly what most TypeScript developers believe, the use of == or != is tolerated in such contexts. As shown below, if foo hasn't been initialized, its default value is not null but undefined. Nevertheless undefined == null, so TypeScript developers get the expected behavior.

if (foo == null) {...}  // ignored
typescript:S1441

Shared code conventions allow teams to collaborate efficiently. This rule checks that all non-JSX string literals use the same kind of quotes, and requires double quotes in JSX code, regardless of the parameter value.

Noncompliant Code Example

Using the parameter default (forcing single quotes):

let message = "Hello, World!"; // Noncompliant

Compliant Solution

let message = 'Hello, World!';

Exceptions

Strings that contain quotes are ignored.

let heSaid = "Then he said 'What?'."  // ignored
let sheSaid = '"Whatever!" she replied.'  // ignored
typescript:S1488

Declaring a variable only to immediately return or throw it is a bad practice.

Some developers argue that the practice improves code readability, because it enables them to explicitly name what is being returned. However, this variable is an internal implementation detail that is not exposed to the callers of the method. The method name should be sufficient for callers to know exactly what will be returned.

Noncompliant Code Example

function ms(hours: number, minutes: number, seconds: number) {
  const duration = ((hours * 60 + minutes) * 60 + seconds) * 1000;
  return duration;
}

Compliant Solution

function ms(hours: number, minutes: number, seconds: number) {
  return ((hours * 60 + minutes) * 60 + seconds) * 1000;
}
typescript:S1516

Continuing a string across a linebreak is supported in most script engines, but it is not a part of ECMAScript. Additionally, the whitespace at the beginning of each line can't be safely stripped at compile time, and any whitespace after the slash will result in tricky errors.

Noncompliant Code Example

var myString = 'A rather long string of English text, an error message \
                actually that just keeps going and going -- an error \
                message to make the Energizer bunny blush (right through \
                those Schwarzenegger shades)! Where was I? Oh yes, \
                you\'ve got an error and all the extraneous whitespace is \
                just gravy.  Have a nice day.';  // Noncompliant

Compliant Solution

var myString = 'A rather long string of English text, an error message ' +
    'actually that just keeps going and going -- an error ' +
    'message to make the Energizer bunny blush (right through ' +
    'those Schwarzenegger shades)! Where was I? Oh yes, ' +
    'you\'ve got an error and all the extraneous whitespace is ' +
    'just gravy.  Have a nice day.';
typescript:S1524

Overriding a variable declared in an outer scope can strongly impact the readability, and therefore the maintainability, of a piece of code. Further, it could lead maintainers to introduce bugs because they think they're using one variable but are really using another.

Noncompliant Code Example

function foo() {
  let x = bar(1);
  if (x > 0) {
      let x = bar(2); // Noncompliant
      console.log(x);
  } else {
     console.log("Wrong Value");
  }
}

Compliant Solution

function foo() {
  let x = bar(1);
  if (x > 0) {
      let y = bar(2);
      console.log(y);
  } else {
     console.log("Wrong Value");
  }
}

See

  • MISRA C:2004, 5.2 - Identifiers in an inner scope shall not use the same name as an identifier in an outer scope, and therefore hide that identifier
  • MISRA C++:2008, 2-10-2 - Identifiers declared in an inner scope shall not hide an identifier declared in an outer scope
  • MISRA C:2012, 5.3 - An identifier declared in an inner scope shall not hide an identifier declared in an outer scope
  • CERT, DCL01-C. - Do not reuse variable names in subscopes
typescript:S1526

Variables declared with var have the special property that regardless of where they're declared in a function they "float" to the top of the function and are available for use even before they're declared. That makes scoping confusing, especially for new coders. To keep confusion to a minimum, var declarations should happen before the variables they declare are used for the first time.

Noncompliant Code Example

var x = 1;

function fun(){
  alert(x); // Noncompliant as x is declared later in the same scope
  if(something) {
    var x = 42; // Declaration in function scope (not block scope!) shadows global variable
  }
}

fun(); // Unexpectedly alerts "undefined" instead of "1"

Compliant Solution

var x = 1;

function fun() {
  print(x);
  if (something) {
    x = 42;
  }
}

fun(); // Print "1"
typescript:S1533

The use of wrapper objects for primitive types is gratuitous, confusing and dangerous. If you use a wrapper object constructor for type conversion, just remove the new keyword, and you'll get a primitive value automatically. If you use a wrapper object as a way to add properties to a primitive, you should re-think the design. Such uses are considered bad practice, and should be refactored. Finally, this rule reports usages of wrapper objects in type declaration section.

Noncompliant Code Example

let x = new Number("0"); // Noncompliant
if (x) {
  alert('hi');  // Shows 'hi'.
}

function log(msg: String) { // Noncompliant
  console.log(msg);
}

Compliant Solution

let x = Number("0");
if (x) {
  alert('hi');
}

function log(msg: string) {
  console.log(msg);
}
typescript:S1541

The Cyclomatic Complexity of functions should not exceed a defined threshold. Complex code may perform poorly and can be difficult to test thoroughly.

typescript:S1656

There is no reason to re-assign a variable to itself. Either this statement is redundant and should be removed, or the re-assignment is a mistake and some other value or variable was intended for the assignment instead.

Noncompliant Code Example

function setName(name) {
    name = name;
}

Compliant Solution

function setName(name) {
    this.name = name;
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
typescript:S1862

A switch and a chain of if/else if statements is evaluated from top to bottom. At most, only one branch will be executed: the first one with a condition that evaluates to true.

Therefore, duplicating a condition automatically leads to dead code. Usually, this is due to a copy/paste error. At best, it's simply dead code and at worst, it's a bug that is likely to induce further bugs as the code is maintained, and obviously it could lead to unexpected behavior.

For a switch, if the first case ends with a break, the second case will never be executed, rendering it dead code. Worse there is the risk in this situation that future maintenance will be done on the dead case, rather than on the one that's actually used.

On the other hand, if the first case does not end with a break, both cases will be executed, but future maintainers may not notice that.

Noncompliant Code Example

if (param == 1)
  openWindow();
else if (param == 2)
  closeWindow();
else if (param == 1)  // Noncompliant
  moveWindowToTheBackground();


switch(i) {
  case 1:
    //...
    break;
  case 3:
    //...
    break;
  case 1:  // Noncompliant
    //...
    break;
  default:
    // ...
    break;
}

Compliant Solution

if (param == 1)
  openWindow();
else if (param == 2)
  closeWindow();
else if (param == 3)
  moveWindowToTheBackground();


switch(i) {
  case 1:
    //...
    break;
  case 3:
    //...
    break;
  default:
    // ...
    break;
}

See

  • CERT, MSC12-C. - Detect and remove code that has no effect or is never executed
typescript:S1871

Having two cases in a switch statement or two branches in an if chain 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 chain they should be combined, or for a switch, one should fall through to the other.

Noncompliant Code Example

switch (i) {
  case 1:
    doFirstThing();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  case 3:  // Noncompliant; duplicates case 1's implementation
    doFirstThing();
    doSomething();
    break;
  default:
    doTheRest();
}

if (a >= 0 && a < 10) {
  doFirstThing();
  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else if (a >= 20 && a < 50) {
  doFirstThing();
  doTheThing();  // Noncompliant; duplicates first condition
}
else {
  doTheRest();
}

Compliant Solution

switch (i) {
  case 1:
  case 3:
    doFirstThing();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  default:
    doTheRest();
}

if ((a >= 0 && a < 10) || (a >= 20 && a < 50)) {
  doFirstThing();
  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else {
  doTheRest();
}

or

switch (i) {
  case 1:
    doFirstThing();
    doSomething();
    break;
  case 2:
    doSomethingDifferent();
    break;
  case 3:
    doFirstThing();
    doThirdThing();
    break;
  default:
    doTheRest();
}

if (a >= 0 && a < 10) {
  doFirstThing();
  doTheThing();
}
else if (a >= 10 && a < 20) {
  doTheOtherThing();
}
else if (a >= 20 && a < 50) {
  doFirstThing();
  doTheThirdThing();
}
else {
  doTheRest();
}

Exceptions

Blocks in an if chain that contain a single line of code are ignored, as are blocks in a switch statement that contain a single line of code with or without a following break.

typescript:S1940

It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.

Noncompliant Code Example

if ( !(a == 2)) { ... }  // Noncompliant

Compliant Solution

if (a != 2) { ... }
typescript:S2123

A value that is incremented or decremented and then not stored is at best wasted code and at worst a bug.

Noncompliant Code Example

let i = 0;
i = i++; // Noncompliant; i is still zero

Compliant Solution

let i = 0;
i++;
typescript:S2201

When the call to a function doesn't have any side effects, what is the point of making the call if the results are ignored? In such case, either the function call is useless and should be dropped or the source code doesn't behave as expected.

To prevent generating any false-positives, this rule triggers an issues only on a predefined list of known objects & functions.

Noncompliant Code Example

'hello'.lastIndexOf('e'); // Noncompliant

Compliant Solution

let char = 'hello'.lastIndexOf('e');

See

  • MISRA C:2012, 17.7 - The value returned by a function having non-void return type shall be used
  • CERT, EXP12-C. - Do not ignore values returned by functions
  • CERT, EXP00-J. - Do not ignore values returned by methods
typescript:S2228

Debug statements are always useful during development. But include them in production code - particularly in code that runs client-side - and you run the risk of inadvertently exposing sensitive information, slowing down the browser, or even erroring-out the site for some users.

Noncompliant Code Example

console.log(password_entered); // Noncompliant

See

  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
typescript:S2685

The arguments.callee property holds the current function. It could be useful in an anonymous function, but its usage would make quite a few optimizations impossible so it was deprecated in the latest versions of JavaScript. In fact, EcmaScript 5 forbids its use in strict mode, according to the docs:

Arguments objects for strict mode functions define non-configurable accessor properties named "caller" and "callee" which throw a TypeError exception on access.

This rule raises an issue when arguments.callee is used.

Noncompliant Code Example

[1, 2, 3, 4, 5].map(function(n) {
  if (n === 0) {
    return 1;
  } else {
    return arguments.callee(n - 1) * n;
  }
});
typescript:S2688

NaN is not equal to anything, even itself. Testing for equality or inequality against NaN will yield predictable results, but probably not the ones you want.

Instead, the best way to see whether a variable is equal to NaN is to use Number.isNaN(), since ES2015, or (perhaps counter-intuitively) to compare it to itself. Since NaN !== NaN, when a !== a, you know it must equal NaN.

Noncompliant Code Example

var a = NaN;

if (a === NaN) {  // Noncompliant; always false
  console.log("a is not a number");  // this is dead code
}
if (a !== NaN) { // Noncompliant; always true
  console.log("a is not NaN"); // this statement is not necessarily true
}

Compliant Solution

if (Number.isNaN(a)) {
  console.log("a is not a number");
}
if (!Number.isNaN(a)) {
  console.log("a is not NaN");
}

See

typescript:S2757

The use of operators pairs (=+, =- or =!) where the reversed, single operator was meant (+=, -= or !=) will compile and run, but not produce the expected results.

This rule raises an issue when =+, =- and =! are used without any space between the two operators and when there is at least one whitespace after.

Noncompliant Code Example

let target =-5;
let num = 3;

target =- num;  // Noncompliant; target = -3. Is that really what's meant?
target =+ num; // Noncompliant; target = 3

Compliant Solution

let target = -5;
let num = 3;

target = -num;  // Compliant; intent to assign inverse value of num is clear
target += num;
typescript:S2814

This rule checks that a declaration doesn't use a name that is already in use. Indeed, it is possible to use the same symbol multiple times as either a variable or a function, but doing so is likely to confuse maintainers. Further it's possible that such reassignments are made in error, with the developer not realizing that the value of the variable is overwritten by the new assignment.

This rule also applies to function parameters.

Noncompliant Code Example

function myFunc(arg) {
  var a = "Ayyyyye";
  var arg = "event"; // Noncompliant, argument value is lost
  var a = "Howdy";  // Noncompliant
}

Compliant Solution

var a = 'foo';
function otherName() {}
console.log(a);

function myFunc(arg) {
  var newName = "event";
}

fun(); // prints "foo"

function fun() {
  print("foo");
}

fun(); // prints "foo"

function printBar() {
  print("bar");
}

printBar(); // prints "bar"
typescript:S2870

The delete operator can be used to remove a property from any object. Arrays are objects, so the delete operator can be used here too, but if it is, a hole will be left in the array because the indexes/keys won't be shifted to reflect the deletion.

The proper method for removing an element at a certain index would be:

  • Array.prototype.splice - add/remove elements from the array
  • Array.prototype.pop - add/remove elements from the end of the array
  • Array.prototype.shift - add/remove elements from the beginning of the array

Noncompliant Code Example

var myArray = ['a', 'b', 'c', 'd'];

delete myArray[2];  // Noncompliant. myArray => ['a', 'b', undefined, 'd']
console.log(myArray[2]); // expected value was 'd' but output is undefined

Compliant Solution

var myArray = ['a', 'b', 'c', 'd'];

// removes 1 element from index 2
removed = myArray.splice(2, 1);  // myArray => ['a', 'b', 'd']
console.log(myArray[2]); // outputs 'd'
typescript:S2933

readonly properties can only be assigned in a class constructor or at the point of declaration. If a class has a property that's not marked readonly but is only set in the constructor, it could cause confusion about the property's intended use. To avoid confusion, such properties should be marked readonly to make their intended use explicit, and to prevent future maintainers from inadvertently changing their use.

Noncompliant Code Example

class Person {
  private _birthYear: number;  // Noncompliant
  constructor(birthYear: number) {
    this._birthYear = birthYear;
  }
}

Compliant Solution

class Person {
  private readonly _birthYear: number;  // Noncompliant
  constructor(birthYear: number) {
    this._birthYear = birthYear;
  }
}
typescript:S2966

The point of declaring an optional property or parameter is to make explicit the fact that it might contain no valid value, i.e. null or undefined. Using a non-null assertion (the !. operator) will lead to a runtime error if the optional does contain null or undefined. Even if the value is tested first, it's still considered a bad practice to use a non-null assertion.

Noncompliant Code Example

function doTheThing(foo?: Foo) {
  let s = foo!.bar;  // Noncompliant
}

Compliant Solution

function doTheThing(foo?: Foo) {
  if (foo) {
    let s = foo.bar;
  }
}
typescript:S3257

Unnecessarily verbose declarations and initializations make it harder to read the code, and should be simplified. Specifically, primitive (number, string, and boolean) types should be omitted from variable and parameter declaration when they can be easily inferred from the initialized or defaulted value.

Noncompliant Code Example

const n: number = 1; // Noncompliant, "number" can be omitted

function foo(s: string = "") {} // Noncompliant, "string" can be omitted

class Bar {
  b: boolean = true;  // Noncompliant, "boolean" can be omitted
}

Compliant Solution

const n = 1;

function foo(s = "") {}

class Bar {
  b = true;
}
typescript:S3353

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

function seek(input: number[]) {
  let target = 32;  // Noncompliant
  for (let i of input) {
    if (i == target) {
      return true;
    }
  }
  return false;
}

Compliant Solution

function seek(input: number[]) {
  const target = 32;
  for (let i of input) {
    if (i == target) {
      return true;
    }
  }
  return false;
}
typescript:S3402

Use a + with two numbers and you'll get addition. But use it with a string and anything else, and you'll get concatenation. This could be confusing, specially if it's not obvious that one of the operands is a string. It is recommended to explicitly convert the non-string component to make it easier to understand to future maintainers.

This rule raises an issue when + is used with a string and a non-string.

Noncompliant Code Example

function foo() {
  let x = 5 + 8;  // okay
  let z = "8"
  return x + z;  // Noncompliant; yields string "138"
}

Compliant Solution

function foo() {
  let x = 5 + 8;
  let z = "8"
  return x + Number(z);
}
typescript:S3498

When an already-defined variable is given the same name within a new object, object-shorthand syntax is preferred as being more compact. Similarly, object-shorthand is also preferred for the definition of functions in object literals.

Noncompliant Code Example

let a = 1;

let myObj = {
  a : a,  // Noncompliant
  fun: function () {  // Noncompliant
    //...
  }
}

Compliant Solution

let a = 1;

let myObj = {
  a,
  fun () {
    //...
  }
}
typescript:S3504

The distinction between the variable types created by var and by let is significant, and a switch to let will help alleviate many of the variable scope issues which have caused confusion in the past.

This rule raises an issue when var is used instead of const or let.

Noncompliant Code Example

var color = "blue";
var size = 4;

Compliant Solution

const color = "blue";
let size = 4;
typescript:S3512

ECMAScript 2015 added the ability to use template literals instead of concatenation. Since their use is clearer and more concise, they are preferred.

This rule raises an issue when a string is created from the result of two or more concatenations.

Noncompliant Code Example

function sayHello(name) {
  console.log("hello " + name);  // ignored
}

function madLib(verb, noun) {
  console.log("I really " + verb + " one or two " + noun);  // Noncompliant
}

Compliant Solution

function sayHello(name) {
  console.log(`hello ${name}`);  // no issue raised before, but this is better
}

function madLib(verb, noun) {
  console.log(`I really ${verb} one or two ${noun}`);
}
typescript:S3516

When a function is designed to return an invariant value, it may be poor design, but it shouldn't adversely affect the outcome of your program. However, when it happens on all paths through the logic, it is surely a bug.

This rule raises an issue when a function contains several return statements that all return the same value.

Noncompliant Code Example

function foo(a: number) {  // Noncompliant
  if (a == 1) {
    return 42;
  }
  return 42;
}
typescript:S3533

TypeScript provides the import and export keywords as language-standard mechanisms for module management. Javascript's require() usages should be converted to the new syntax.

Noncompliant Code Example

// circle.js
module.exports = function (r) {
  return PI * r * r;
};

// foo.js
const circle = require('./circle.js');  // Noncompliant

Compliant Solution

// circle.ts
export default function (r) {
  return PI * r * r;
}

// foo.ts
import circle from "./circle.ts"
typescript:S3616

The logical OR operator (||) will not work in a switch case as one might think, only the first argument will be considered at execution time.

Noncompliant Code Example

switch (x) {
  case 1 || 2: // Noncompliant; only '1' is handled
    doSomething(x);
    break;
  case 3:
    doAnotherThing(x);
    break;
  default:
    console.log("Boom!");  // this happens when x is 2
}

Compliant Solution

switch (x) {
  case 1:
  case 2:
    doSomething(x);
    break;
  case 3:
    doAnotherThing(x);
    break;
  default:
    console.log("Boom!");
}
typescript:S3626

Jump statements, such as return, break and continue let you change the default flow of program execution, but jump statements that direct the control flow to the original direction are just a waste of keystrokes.

Noncompliant Code Example

function redundantJump(x: number) {
  if (x == 1) {
    console.log("x == 1");
    return;
//  ^^^^^^^ {{Remove this redundant jump.}}
  }
}

Compliant Solution

function redundantJump(x: number) {
  if (x == 1) {
    console.log("x == 1");
  }
}

Exceptions

break and return inside switch statement are ignored, because they are often used for consistency. continue with label is also ignored, because label is usually used for clarity.

typescript:S3696

It is a bad practice to throw something that's not derived at some level from Error. If you can't find an existing Error type that suitably conveys what you need to convey, then you should extend Error to create one.

Specifically, part of the point of throwing Errors is to communicate about the conditions of the error, but strings have far less ability to communicate meaningfully than Errors because they don't include stacktraces.

Noncompliant Code Example

throw "Invalid negative index.";        // Noncompliant

Compliant Solution

throw new Error("Invalid negative index.");

See

  • MISRA C++:2008, 15-1-2 - NULL shall not be thrown explicitly.
typescript:S3699

If a function does not return anything, it makes no sense to use its output. Specifically, passing it to another function, or assigning its "result" to a variable is probably a bug because such functions return undefined, which is probably not what was intended.

Noncompliant Code Example

function foo() {
  console.log("Hello, World!");
}

a = foo();

Compliant Solution

function foo() {
  console.log("Hello, World!");
}

foo();
typescript:S3776

Cognitive Complexity is a measure of how hard the control flow of a function is to understand. Functions with high Cognitive Complexity will be difficult to maintain.

See

typescript:S3786

Template strings allow developers to embed variables or expressions in strings using template literals, instead of string concatenation. This is done by using expressions like ${variable} in a string between two back-ticks (`). However, when used in a regular string literal (between double or single quotes) the template will not be evaluated and will be used as a literal, which is probably not what was intended.

Noncompliant Code Example

console.log("Today is ${date}"); // Noncompliant

Compliant Solution

console.log(`Today is ${date}`);
typescript:S3799

Destructuring is a convenient way of extracting multiple values from data stored in (possibly nested) objects and arrays. However, it is possible to create an empty pattern that has no effect. When empty curly braces or brackets are used to the right of a property name most of the time the intent was to use a default value instead.

This rule raises an issue when empty destructuring pattern is used.

Noncompliant Code Example

var {a: {}, b} = myObj; // Noncompliant
function foo({first: [], second}) { // Noncompliant
  // ...
}

Compliant Solution

var {a = {}, b} = myObj;
function foo({first = [], second}) {
  // ...
}
typescript:S3801

In TypeScript a function can return a value explicitly, by using a return statement with a value, or implicitly, at the end of the function or by a return with no value, resulting in the function returning undefined. Implicit returns of undefined not declared in the function signature, can be confusing for the maintainer.

This rule ensures that returns are either all explicit or all implicit, or the function signatures makes the implicit return obvious.

Noncompliant Code Example

function foo(a) { // Noncompliant, function exits without "return"
  if (a == 1) {
    return true;
  }
}

Compliant Solution

function foo(a): boolean | undefined {
  if (a == 1) {
    return true;
  }
}
typescript:S3854

super() should only be invoked once in a constructor. Additional invocations will result in runtime errors.

Noncompliant Code Example

class Dog extends Animal {
  constructor(name) {
    super();
    this.name = name;
    super();         // Noncompliant
    super.doSomething();
  }
}

Compliant Solution

class Dog extends Animal {
  constructor(name) {
    super();
    this.name = name;
    super.doSomething();
  }
}
typescript:S3863

Multiple imports from the same module should be merged together to improve readability.

Noncompliant Code Example

import { B1 } from 'b';
import { B2 } from 'b'; // Noncompliant

Compliant Solution

import { B1, B2 } from 'b';
typescript:S3923

Having all branches in a switch or if chain with the same implementation is an error. Either a copy-paste error was made and something different should be executed, or there shouldn't be a switch/if chain at all.

Noncompliant Code Example

if (b == 0) {  // Noncompliant
  doOneMoreThing();
}
else {
  doOneMoreThing();
}

let a = (b == 0) ? getValue() : getValue();   // Noncompliant

switch (i) {  // Noncompliant
  case 1:
    doSomething();
    break;
  case 2:
    doSomething();
    break;
  case 3:
    doSomething();
    break;
  default:
    doSomething();
}

Exceptions

This rule does not apply to if chains without else-s, or to switch-es without default clauses.

if(b == 0) {    //no issue, this could have been done on purpose to make the code more readable
  doSomething();
} else if(b == 1) {
  doSomething();
}
typescript:S3972

Code is clearest when each statement has its own line. Nonetheless, it is a common pattern to combine on the same line an if and its resulting then statement. However, when an if is placed on the same line as the closing } from a preceding else or else if, it is either an error - else is missing - or the invitation to a future error as maintainers fail to understand that the two statements are unconnected.

Noncompliant Code Example

if (condition1) {
  // ...
} if (condition2) {  // Noncompliant
  //...
}

Compliant Solution

if (condition1) {
  // ...
} else if (condition2) {
  //...
}

Or

if (condition1) {
  // ...
}

if (condition2) {
  //...
}
typescript:S3981

The size of a collection and the length of an array are always greater than or equal to zero. So testing that a size or length is greater than or equal to zero doesn't make sense, since the result is always true. Similarly testing that it is less than zero will always return false. Perhaps the intent was to check the non-emptiness of the collection or array instead.

Noncompliant Code Example

if (someSet.size >= 0) {...} // Noncompliant

if (someMap.size < 0) {...} // Noncompliant

const result = someArray.length >= 0;  // Noncompliant

Compliant Solution

if (someSet.size > 0) {...}

if (someMap.size == 0) {...}

const result = someArray.length > 0;
typescript:S4023

An empty interface is equivalent to an empty object ('{}'). Normally you cannot directly assign an object literal to a type when the object literal contains more properties than are specified in the type. But in the case of an empty interface, this check is not done, and such assignments will be successful. The result is highly likely to confuse maintainers.

Noncompliant Code Example

interface MyFace {}  // Noncompliant

Compliant Solution

interface MyFace {
  foo: number;
}
typescript:S4030

When a collection is populated but its contents are never used, then it is surely some kind of mistake. Either refactoring has rendered the collection moot, or an access is missing.

This rule raises an issue when no methods are called on a collection other than those that add or remove values.

Noncompliant Code Example

function getLength(a: string, b: string, c: string) {
  const strings = [];  // Noncompliant
  strings.push(a);
  strings.push(b);
  strings.push(c);

  return a.length + b.length + c.length;
}

Compliant Solution

function getLength(a: string, b: string, c: string) {
  return a.length + b.length + c.length;
}
typescript:S4043

Many of JavaScript's Array methods return an altered version of the array while leaving the source array intact. reverse and sort do not fall into this category. Instead, they alter the source array in addition to returning the altered version, which is likely not what was intended.

This rule raises an issue when the return values of these methods are assigned, which could lead maintainers to overlook the fact that the original value is altered.

Noncompliant Code Example

var b = a.reverse(); // Noncompliant
var d = c.sort(); // Noncompliant

Compliant Solution

var b = [...a].reverse();  // de-structure and create a new array, so reverse doesn't impact 'a'
a.reverse();

c.sort(); // this sorts array in place
typescript:S4123

It is possible to use await on values which are not Promises, but it's useless and misleading. The point of await is to pause execution until the Promise's asynchronous code has run to completion. With anything other than a Promise, there's nothing to wait for.

This rule raises an issue when an awaited value is guaranteed not to be a Promise.

Noncompliant Code Example

let x = 42;
await x; // Noncompliant

Compliant Solution

let x = new Promise(resolve => resolve(42));
await x;

let y = p ? 42 : new Promise(resolve => resolve(42));
await y;
typescript:S4124

Declare a constructor inside an interface, and you will get a simple method with the name "constructor". The same thing will happen if you create a new method inside the interface: you'll get a simple method named "new".

Instead, the intent was probably to specify that the type did not originate from a TypeScript file. In such cases, just use the declare class syntax.

Noncompliant Code Example

interface TypeDeclaredElsewhere {
  someMethod(): number;
  new(b: boolean): TypeDeclaredElsewhere; // Noncompliant
  constructor(b: boolean): void; // Noncompliant
}

Compliant Solution

declare class TypeDeclaredElsewhere {
  someMethod(): number;
  constructor(b: boolean);
}

typescript:S4136

For clarity, all overloads of the same method should be grouped together. That lets both users and maintainers quickly understand all the current available options.

Noncompliant Code Example

interface MyInterface {
  doTheThing(): number;
  doTheOtherThing(): string;
  doTheThing(str: string): string;  // Noncompliant
}

Compliant Solution

interface MyInterface {
  doTheThing(): number;
  doTheThing(str: string): string;
  doTheOtherThing(): string;
}
typescript:S4137

Type assertion can be done in two ways: with as MyType or with <MyType>. But since there is an ambiguity in the latter when using JSX and there is no ambiguity in the former, as is preferred.

Noncompliant Code Example

var foo = <any>"foo";  // Noncompliant

Compliant Solution

var foo = "foo" as any;
typescript:S4138

If you have an iterable, such as an array, set, or list, your best option for looping through its values is the for of syntax. Use a counter, and ... well you'll get the right behavior, but your code just isn't as clean or clear.

Noncompliant Code Example

const arr = [4, 3, 2, 1];

for (let i = 0; i < arr.length; i++) {  // Noncompliant
  console.log(arr[i]);
}

Compliant Solution

const arr = [4, 3, 2, 1];

for (let value of arr) {
  console.log(value);
}
typescript:S4139

If you have an iterable, such as an array, set, or list, your best option for looping through its values is the for of syntax. Use for in and you'll iterate the properties, rather than the values.

Noncompliant Code Example

const arr = [4, 3, 2, 1];

for (let value in arr) {  // Noncompliant
  console.log(value);  // logs 0, 1, 2, 3
}

Compliant Solution

const arr = [4, 3, 2, 1];

for (let value of arr) {
  console.log(value);
}
typescript:S4140

An array declared with missing ("sparse") elements is likely to be an error: an extra comma was inserted or perhaps the developer meant to insert the missing value and forgot.

Noncompliant Code Example

var a = [1, , 3, 6, 9];  // Noncompliant

Compliant Solution

var a = [1, 3, 6, 9];
typescript:S4143

It is highly suspicious when a value is saved for a key or index and then unconditionally overwritten. Such replacements are likely in error.

Noncompliant Code Example

 fruits[1] = "banana";
 fruits[1] = "apple";  // Noncompliant - value on index 1 is overwritten

 myMap.set("key", 1);
 myMap.set("key", 2); // Noncompliant - value for key "key" is replaced

 mySet.add(1);
 mySet.add(1); // Noncompliant - element is already in the set
typescript:S4144

When two functions have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, the code should be refactored. Numerical and string literals are not taken into account.

Noncompliant Code Example

class MyClass {
  private readonly CODE = "bounteous";

  public calculateCode(): string {
    doTheThing();
    doOtherThing();
    return this.CODE;
  }

  public getName(): string {  // Noncompliant
    doTheThing();
    doOtherThing();
    return this.CODE;
  }
}

Compliant Solution

class MyClass {
  private readonly CODE = "bounteous";

  public calculateCode(): string {
    doTheThing();
    doOtherThing();
    return this.CODE;
  }

  public getName(): string {
    return this.calculateCode();
  }
}

Exceptions

Functions with fewer than 3 lines are ignored.

typescript:S4156

Each file is considered an "external" module. The use of the module keyword creates an internal module, and was used before the ECMAScript 2015 addition of namespaces for the same purpose. Now that namespace is available, the use of module is deprecated because it does the same thing, and its use could confuse maintainers unaware of the history of the language.

Noncompliant Code Example

module myMod {  // Noncompliant
  // ...
}

Compliant Solution

namespace myMod {
  // ...
}
typescript:S4157

There's no reason to repeat a default type unless it is early in a list and other, non-default types come after it. Instead, leave it out and only supply type when it is something other than the default.

Noncompliant Code Example

function foo<N = number, S = string>() {}
foo<number, string>();  // Noncompliant; both types redundant
foo<string, string>();  // Noncompliant; 2nd string is redundant
foo<number, number>();  // Ignored; number is redundant but required

Compliant Solution

function foo<N = number, S = string>() {}
foo();
foo<string>();
foo<number, number>();
typescript:S4204

Variables can be declared with or without types. Variables declared without a type will be implicitly typed if the declaration includes an initialization, and compiler type checking will be automatically applied to any typed variable. But if you declare a variable with the any "type" then you've explicitly told the compiler not to do any type checking, which is risky.

Noncompliant Code Example

let a = 42;  // implicitly typed to number
let b: number = 42;  // explicitly typed to number
let c: any = 42;  // Noncompliant

Compliant Solution

let a = 42;
let b: number = 42;
let c: number = 42;
typescript:S4275

Getters and setters provide a way to enforce encapsulation by providing public methods that give controlled access to private fields. However in classes with multiple fields it is not unusual that cut and paste is used to quickly create the needed getters and setters, which can result in the wrong field being accessed by a getter or setter.

This rule raises an issue in any of these cases:

  • A setter does not update the field with the corresponding name.
  • A getter does not access the field with the corresponding name.

Noncompliant Code Example

class A {
  private _x: number = 0;
  private y: number = 0;

  public get x() {  // Noncompliant: field 'x' is not used in the return value
    return this.y;
  }

  public setX(val: number) { // Noncompliant: field 'x' is not updated
    this.y = val;
  }

  public getY() { // Noncompliant: field 'y' is not used in the return value
    return this.x;
  }
}

Compliant Solution

class A {
  private _x: number = 0;
  private y: number = 0;

  public get x() {
    return this._x;
  }

  public setX(val: number) {
    this.x = val;
  }

  public getY() {
    return this.y;
  }
}
typescript:S4323

Union and intersection types are convenient but can make code harder to read and maintain. So if a particular union or intersection is used in multiple places, the use of a type alias is recommended.

Noncompliant Code Example

function foo(x:string|null|number) { // Noncompliant
  // ...
}
function bar(x:string|null|number) {
  // ...
}
function zoo(): string|null|number {
  return null;
}

Compliant Solution

type MyType = string | null | number;

function foo(x: MyType) {
  // ...
}
function bar(x: MyType) {
  // ...
}
function zoo(): MyType {
  return null;
}
typescript:S4324

The return type any should be avoided because it prevents the type safety checks normally done by the compiler. When a function returns a primitive type (i.e. number, string or boolean) it is safe to replace any with number, string or boolean type respectively, or remove the return type completely and let compiler infer it.

Noncompliant Code Example

function foo() : any { // Noncompliant
  return 1;
}

Compliant Solution

function foo() {
  return 1;
}
// or
function foo(): number {
  return 1;
}
typescript:S4325

The TypeScript compiler automatically casts a variable to the relevant type inside conditionals where it is possible to infer the type (because typeof, instanceof, etc was used). This compiler feature makes casts and not-null assertions unnecessary.

Noncompliant Code Example

function getName(x?: string | UserName) {
  if (x) {
    console.log("Getting name for " + x!); // Noncompliant

    if (typeof x === "string")
      return (x as string); // Noncompliant
    else
      return (x as UserName).name; // Noncompliant
  }
  return "NoName";
}

Compliant Solution

function getName(x?: string | UserName) {
  if (x) {
    console.log("Getting name for " + x);

    if (typeof x === "string")
      return x;
    else
      return x.name;
  }
  return "NoName";
}
typescript:S4326

An async function always wraps the return value in a Promise. Using return await is therefore redundant.

Noncompliant Code Example

async function foo() {
  // ...
}

async function bar() {
  // ...
  return await foo(); // Noncompliant
}

Compliant Solution

async function foo() {
  // ...
}

async function bar() {
  // ...
  return foo();
}
typescript:S4327

Assigning this to a local variable is a way to reference parent context inside inner functions. In TypeScript when using arrow functions this happens automatically.

This rule raises an issue when this is assigned to a local variable.

Noncompliant Code Example

function Foo() {
  let that = this;  // Noncompliant
  that.val = 0;

  setInterval(function() {
    that.val++;
  }, 1000);
}

Compliant Solution

function Foo() {
  this.val = 0;

  setInterval(() => {
    this.val++;
  }, 1000);
}

Exceptions

This rule ignores this used for destructuring.

const { foo, bar } = this;
typescript:S4335

An intersection type combines multiple types into one. This allows you to add together existing types to get a single type that has all the features you need. However an intersection with a type without members doesn't change the resulting type. In the opposite the usage of any or never as part of an intersection will always results in any or never respectively. This is almost certainly an error.

Noncompliant Code Example

function foo(p: MyType & null) { // Noncompliant
 // ...
}

function bar(p: MyType & any) { // Noncompliant
 // ...
}

Compliant Solution

function foo(p: MyType | null) {
 // ...
}
// or
function foo(p: MyType & AnotherType) {
 // ...
}

function bar(p: any) {
 // ...
}
typescript:S4524

switch can contain a default clause for various reasons: to handle unexpected values, to show that all the cases were properly considered.

For readability purpose, to help a developer to quickly find the default behavior of a switch statement, it is recommended to put the default clause at the end of the switch statement. This rule raises an issue if the default clause is not the last one of the switch's cases.

Noncompliant Code Example

switch (param) {
  default: // default clause should be the last one
    error();
    break;
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
}

Compliant Solution

switch (param) {
  case 0:
    doSomething();
    break;
  case 1:
    doSomethingElse();
    break;
  default:
    error();
    break;
}

See

  • MISRA C:2004, 15.3 - The final clause of a switch statement shall be the default clause
  • MISRA C++:2008, 6-4-6 - The final clause of a switch statement shall be the default-clause
  • MISRA C:2012, 16.4 - Every switch statement shall have a default label
  • MISRA C:2012, 16.5 - A default label shall appear as either the first or the last switch label of a switch statement
typescript:S4619

The in operator used on an array is valid but the code will certainly not have the expected behavior. The in operator deals with the indexes of the array, not with the values.

Noncompliant Code Example

function func1() {
    let arr = ["a", "b", "c"];

    let expectedValue = "b";
    if (expectedValue in arr) { // Noncompliant, will be always false
        return expectedValue + " found in the array";
    } else {
        return expectedValue + " not found";
    }
}

function func2() {
    let arr = ["a", "b", "c"];

    let expectedValue = "1"; // index #1 is corresponding to the value "b"
    if (expectedValue in arr) { // Noncompliant, will be always true because the array is made of 3 elements and the #1 is always there whatever its value
        return expectedValue + " found in the array";
    } else {
        return expectedValue + " not found";
    }
}

Compliant Solution

function func() {
    let arr = ["a", "b", "c"];

    let expectedValue = "b";
    if (arr.includes(expectedValue)) {
        return expectedValue + " was found in the array";
    } else {
        return expectedValue + " not found";
    }
}
typescript:S4621

The TypeScript type system offers a basic support for composite types:

  • Union Types represent a value that can be one of the several types. They are constructed using a vertical bar (|) like the following type NumberOrString = number | string.
  • Intersection Types combine multiple types into one, so that the object of such type will have all the members of all intersection type elements. They are constructed using an ampersand (&) like the following type SerializablePerson = Person & Serializable. Intersection Types are often used to represent mixins.

Duplicating types when defining a union or interaction type makes the code less readable. Moreover duplicated types might be a simple mistake and another type should be used instead.

Noncompliant Code Example

function padLeft(value: string, padding: string | number | string) { // Noncompliant; 'string' type is used twice in a union type declaration
  // ...
}

function extend(p : Person) : Person & Person & Loggable { // Noncompliant; 'Person' is used twice
 // ...
}

Compliant Solution

function padLeft(value: string, padding: string | number | boolean) {
  // ...
}

function extend(p : Person) : Person & Loggable {
  // ...
}
typescript:S4622

Union types represent a value that can be one of the several types. When a union type is used for a function parameter and it is accepting too many types, it may indicate the function is having too many responsibilities. Sometimes it's worth creating a type alias for this union type. In all cases, the code should be reviewed and refactored to make it more maintainable.

Noncompliant Code Example

With the default threshold of 3:

let x: MyType1 | MyType2 | MyType3 | MyType4; // Noncompliant

function foo(p1: string, p2: MyType1 | MyType2 | MyType3 | MyType4) { // Noncompliant
    // ...
}

Compliant Solution

type MyUnionType = MyType1 | MyType2 | MyType3 | MyType4; // Compliant, "type" statements are ignored
let x: MyUnionType;

function foo(value: string, padding: MyUnionType) {
    // ...
}

Exceptions

This rule ignores union types part of type statement:

type MyUnionType = MyType1 | MyType2 | MyType3 | MyType4;
typescript:S4623

Unlike in JavaScript, where every parameter can be omitted, in TypeScript you need to explicitly declare this in the function signature. Either you add ? in the parameter declaration and undefined will be automatically applied to this parameter. Or you add an initializer with a default value in the parameter declaration. In the latter case, when passing undefined for such parameter, default value will be applied as well. So it's better to avoid passing undefined value to an optional or default parameter because it creates more confusion than it brings clarity. Note, that this rule is only applied to the last arguments in function call.

Noncompliant Code Example

function foo(x: number, y: string = "default", z?: number) {
  // ...
}

foo(42, undefined); // Noncompliant
foo(42, undefined, undefined); // Noncompliant
foo(42, undefined, 5); // OK, there is no other way to force default value for second parameter

Compliant Solution

function foo(x: number, y: string = "default", z?: number) {
  // ...
}

foo(42);
typescript:S4624

Template literals (previously named "template strings") are an elegant way to build a string without using the + operator to make strings concatenation more readable.

However, it's possible to build complex string literals by nesting together multiple template literals, and therefore lose readability and maintainability.

In such situations, it's preferable to move the nested template into a separate statement.

Noncompliant Code Example

let color = "red";
let count = 3;
let message = `I have ${color ? `${count} ${color}` : count} apples`; // Noncompliant; nested template strings not easy to read

Compliant Solution

let color = "red";
let count = 3;
let apples = color ? `${count} ${color}` : count;
let message = `I have ${apples} apples`;
typescript:S4634

When a Promise needs to only "resolve" or "reject", it's more efficient and readable to use the methods specially created for such use cases: Promise.resolve(value) and Promise.reject(error).

Noncompliant Code Example

let fulfilledPromise = new Promise(resolve => resolve(42));
let rejectedPromise = new Promise(function(resolve, reject) {
  reject('fail');
});

Compliant Solution

let fulfilledPromise = Promise.resolve(42);
let rejectedPromise = Promise.reject('fail');
typescript:S4782

In TypeScript there are several ways to declare an optional property, i.e. a property which might be missing from an object: adding | undefined in the property type or adding ? after its name. The latter is preferred as it brings more clarity and readability to a code.

Noncompliant Code Example

interface Person {
  name: string;
  nickname: string | undefined; // Noncompliant
  pet?: Animal | undefined; // Noncompliant, "undefined" is redundant
  age: number;
}

Compliant Solution

interface Person {
  name: string;
  nickname?: string;
  pet?: Animal;
  age: number;
}
typescript:S878

The comma operator takes two expressions, executes them from left to right and returns the result of the second one. Use of this operator is generally detrimental to the readability and reliability of code, and the same effect can be achieved by other means.

Noncompliant Code Example

i = a += 2, a + b;  // What's the value of i ?

Compliant Solution

a +=  2;
i = a + b;

Exceptions

Use of comma operator is tolerated in initialization and increment expressions of for loops.

for(i = 0, j = 5; i < 6; i++, j++) { ... }

See

  • MISRA C:2004, 12.10 - The comma operator shall not be used.
  • MISRA C++:2008, 5-18-1 - The comma operator shall not be used.
  • MISRA C:2012, 12.3 - The comma operator should not be used
typescript:S881

The use of increment and decrement operators in method calls or in combination with other arithmetic operators is not recommended, because:

  • It can significantly impair the readability of the code.
  • It introduces additional side effects into a statement, with the potential for undefined behavior.
  • It is safer to use these operators in isolation from any other arithmetic operators.

Noncompliant Code Example

u8a = ++u8b + u8c--;
foo = bar++ / 4;

Compliant Solution

The following sequence is clearer and therefore safer:

++u8b;
u8a = u8b + u8c;
u8c--;
foo = bar / 4;
bar++;

See

  • MISRA C:2004, 12.1 - Limited dependence should be placed on the C operator precedence rules in expressions.
  • MISRA C:2004, 12.13 - The increment (++) and decrement (--) operators should not be mixed with other operators in an expression.
  • MISRA C++:2008, 5-2-10 - The increment (++) and decrement (--) operator should not be mixed with other operators in an expression.
  • MISRA C:2012, 12.1 - The precedence of operators within expressions should be made explicit
  • MISRA C:2012, 13.3 - A full expression containing an increment (++) or decrement (--) operator should have no other potential side effects other than that cause by the increment or decrement operator
  • CERT, EXP30-C. - Do not depend on the order of evaluation for side effects
  • CERT, EXP50-CPP. - Do not depend on the order of evaluation for side effects
  • CERT, EXP05-J. - Do not follow a write by a subsequent write or read of the same object within an expression
vbnet:S101

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate. This rule allows to check that all class names match a provided regular expression.

The default configuration is the one recommended by Microsoft:

  • Pascal casing, starting with an upper case character, e.g. BackColor
  • Short abbreviations of 2 letters can be capitalized, e.g. GetID
  • Longer abbreviations need to be lower cased, e.g. GetHtml

Noncompliant Code Example

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

Class foo ' Noncompliant
End Class

Compliant Solution

Class Foo ' Compliant
End Class
vbnet:S103

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

vbnet:S104

A source file that grows too much tends to aggregate too many responsibilities and inevitably becomes harder to understand and therefore to maintain. Above a specific threshold, it is strongly advised to refactor it into smaller pieces of code which focus on well defined tasks. Those smaller files will not only be easier to understand but also probably easier to test.

vbnet:S105

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

vbnet:S1067

Complex boolean expressions are hard to read and so to maintain.

Noncompliant Code Example

With the default threshold value of 3

If ((condition1 AndAlso condition2) OrElse (condition3 AndAlso condition4)) AndAlso condition5) Then  'Noncompliant
  ...
End If

Compliant Solution

If ((MyFirstCondition() OrElse MySecondCondition()) AndAlso MyLastCondition()) Then
  ...
End If
vbnet:S114

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate.

This rule allows to check that all interface names match a provided regular expression.

The default configuration is the one recommended by Microsoft:

  • Must start with an upper case 'I' character, e.g. IFoo
  • Followed by Pascal casing, starting with an upper case character, e.g. IEnumerable
  • Short abbreviations of 2 letters can be capitalized, e.g. IFooID
  • Longer abbreviations need to be lower cased, e.g. IFooHtml

Noncompliant Code Example

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

Interface Foo  ' Noncompliant
End Interface

Compliant Solution

Interface IFoo ' Compliant
End Interface
vbnet:S117

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:

  • 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

Noncompliant Code Example

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

Module Module1
    Sub Main()
        Dim Foo = 0 ' Noncompliant
    End Sub
End Module

Compliant Solution

Module Module1
    Sub Main()
        Dim foo = 0 ' Compliant
    End Sub
End Module
vbnet:S1197

Array designators should always be located on the type for better code readability. Otherwise, developers must look both at the type and the variable name to know whether or not a variable is an array.

Noncompliant Code Example

Module Module1
    Sub Main()
        Dim foo() As String ' Noncompliant
    End Sub
End Module

Compliant Solution

Module Module1
    Sub Main()
        Dim foo As String() ' Compliant
    End Sub
End Module
vbnet:S122

For better readability, do not put more than one statement on a single line.

Noncompliant Code Example

Module Module1
    Sub Main()
        Dim a = 0 : Dim b = 0  ' Noncompliant
    End Sub
End Module

Compliant Solution

Module Module1
    Sub Main()
        Dim a = 0              ' Compliant
        Dim b = 0              ' Compliant
    End Sub
End Module
vbnet:S134

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:

If condition1 ' Compliant - depth = 1
  ' ...
  If condition2 ' Compliant - depth = 2
    ' ...
    For i = 0 to 10 ' Compliant - depth = 3, not exceeding the limit
      ' ...
      If condition4 ' Noncompliant - depth = 4
        If condition5 ' Depth = 5, exceeding the limit, but issues are only reported on depth = 4
          ' ...
        End If
        Return
      End If
    Next
  End If
End If
vbnet:S139

This rule verifies that single-line comments are not located at the ends of lines of code. The main idea behind this rule is that in order to be really readable, trailing comments would have to be properly written and formatted (correct alignment, no interference with the visual structure of the code, not too long to be visible) but most often, automatic code formatters would not handle this correctly: the code would end up less readable. Comments are far better placed on the previous empty line of code, where they will always be visible and properly formatted.

Noncompliant Code Example

With the default comment pattern ^'\s*\S+\s*$, which ignores single word comments:

Module Module1
  Sub Main()
    Console.WriteLine("Hello, world!") ' Noncompliant - My first program!
    Console.WriteLine("Hello, world!") ' CompliantOneWord
  End Sub
End Module

Compliant Solution

Module Module1
  Sub Main()
    ' Compliant - My first program!
    Console.WriteLine("Hello, world!")
    Console.WriteLine("Hello, world!") ' CompliantOneWord
  End Sub
End Module
vbnet:S1541

The cyclomatic complexity of a function, procedure or property should not exceed a defined threshold. Complex code can perform poorly and will in any case be difficult to understand and therefore to maintain.

vbnet:S1542

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all subroutine and function names match a provided regular expression.

The default configuration is the one recommended by Microsoft:

  • Pascal casing, starting with an upper case character, e.g. BackColor
  • Short abbreviations of 2 letters can be capitalized, e.g. GetID
  • Longer abbreviations need to be lower cased, e.g. GetHtml
  • Event handlers with a handles clause and two-parameter methods with EventArgs second parameter are not covered by this rule.

Noncompliant Code Example

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

Module Module1
  Sub bad_subroutine()                      ' Noncompliant
  End Sub

  Public Function Bad_Function() As Integer ' Noncompliant
    Return 42
  End Function
End Module

Compliant Solution

Module Module1
  Sub GoodSubroutine()                      ' Compliant
  End Sub

  Public Function GoodFunction() As Integer ' Compliant
    Return 42
  End Function
End Module
vbnet:S1643

StringBuilder is more efficient than string concatenation, especially when the operator is repeated over and over as in loops.

Noncompliant Code Example

Module Module1
    Sub Main()
        Dim foo = ""
        foo &= "Result: "       ' Compliant - outside of loop

        For i = 1 To 9
            foo &= i            ' Noncompliant
        Next
    End Sub
End Module

Compliant Solution

Module Module1
    Sub Main()
        Dim foo = New System.Text.StringBuilder
        foo.Append("Result: ")  ' Compliant

        For i = 1 To 9
            foo.Append(i)       ' Compliant
        Next
    End Sub
End Module
vbnet:S1645

Consistently using the & operator for string concatenation make the developer intentions clear.

&, unlike +, will convert its operands to strings and perform an actual concatenation.

+ on the other hand can be an addition, or a concatenation, depending on the operand types.

Noncompliant Code Example

Module Module1
    Sub Main()
        Console.WriteLine("1" + 2) ' Noncompliant - will display "3"
    End Sub
End Module

Compliant Solution

Module Module1
    Sub Main()
        Console.WriteLine(1 & 2)   ' Compliant - will display "12"
        Console.WriteLine(1 + 2)   ' Compliant - but will display "3"
        Console.WriteLine("1" & 2) ' Compliant - will display "12"
    End Sub
End Module
vbnet:S1654

Sharing some naming conventions is a key point to make it possible for a team to efficiently collaborate.

This rule allows to check that all parameter names match a provided regular expression.

The default configuration is the one recommended by Microsoft:

  • 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

Noncompliant Code Example

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

Module Module1
    Sub GetSomething(ByVal ID As Integer) ' Noncompliant
    End Sub
End Module

Compliant Solution

Module Module1
    Sub GetSomething(ByVal id As Integer) ' Compliant
    End Sub
End Module
vbnet:S1871

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

Select i
  Case 1
    DoFirst()
    DoSomething()
  Case 2
    DoSomethingDifferent()
  Case 3  ' Noncompliant; duplicates case 1's implementation
    DoFirst()
    DoSomething()
  Case Else:
    DoTheRest()
End Select

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

Exceptions

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

If a >= 0 AndAlso a < 10 Then
  DoTheThing()
ElseIf a >= 10 AndAlso a < 20 Then
  DoTheOtherThing()
ElseIf a >= 20 AndAlso a < 50   ' no issue, usually this is done on purpose to increase the readability
  DoTheThing()
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 S3923 raises a bug.

If a >= 0 AndAlso a < 10 Then
  DoTheThing()
ElseIf a >= 10 AndAlso a < 20 Then
  DoTheOtherThing()  ' Noncompliant, this might have been done on purpose but probably not
End If
vbnet:S2304

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all namespace names match a provided regular expression.

The default configuration is the one recommended by Microsoft:

  • Pascal casing, starting with an upper case character, e.g. Microsoft, System
  • Short abbreviations of 2 letters can be capitalized, e.g. System.IO
  • Longer abbreviations need to be lower cased

Noncompliant Code Example

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

Namespace foo  ' Noncompliant
End Namespace

Compliant Solution

Namespace Foo  ' Compliant
End Namespace
vbnet:S2339

Constant members are copied at compile time to the call sites, instead of being fetched at runtime.

As an example, say you have a library with a constant Version member set to 1.0, and a client application linked to it. This library is then updated and Version is set to 2.0. Unfortunately, even after the old DLL is replaced by the new one, Version will still be 1.0 for the client application. In order to see 2.0, the client application would need to be rebuilt against the new version of the library.

This means that you should use constants to hold values that by definition will never change, such as Zero. In practice, those cases are uncommon, and therefore it is generally better to avoid constant members.

This rule only reports issues on public constant fields, which can be reached from outside the defining assembly.

Noncompliant Code Example

Public Class Foo
    Public Const Version = 1.0           ' Noncompliant
End Class

Compliant Solution

Public Class Foo
    Public Shared ReadOnly Property Version = 1.0 ' Compliant
End Class
vbnet:S2340

A Do ... Loop without a While or Until condition must be terminated by an unstructured Exit Do statement. It is safer and more readable to use structured loops instead.

Noncompliant Code Example

Module Module1
    Sub Main()
        Dim i = 1

        Do                        ' Non-Compliant
            If i = 10 Then
                Exit Do
            End If

            Console.WriteLine(i)

            i = i + 1
        Loop
    End Sub
End Module

Compliant Solution

Module Module1
    Sub Main()
        For i = 1 To 9            ' Compliant
            Console.WriteLine(i)
        Next
    End Sub
End Module
vbnet:S2342

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all enum names match a provided regular expression.

The default configuration is the one recommended by Microsoft:

  • Pascal casing, starting with an upper case character, e.g. BackColor
  • Short abbreviations of 2 letters can be capitalized, e.g. GetID
  • Longer abbreviations need to be lower case, e.g. GetHtml
  • If the enum is marked as [Flags] then its name should be plural (e.g. MyOptions), otherwise, names should be singular (e.g. MyOption)

Noncompliant Code Example

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

Public Enum foo ' Noncompliant
    FooValue = 0
End Enum

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

<Flags()>
Public Enum Option ' Noncompliant
    None = 0,
    Option1 = 1,
    Option2 = 2
End Enum

Compliant Solution

Public Enum Foo
    FooValue = 0
End Enum
<Flags()>
Public Enum Options
    None = 0,
    Option1 = 1,
    Option2 = 2
End Enum
vbnet:S2343

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all enumeration value names match a provided regular expression.

The default configuration is the one recommended by Microsoft:

  • Pascal casing, starting with an upper case character, e.g. BackColor
  • Short abbreviations of 2 letters can be capitalized, e.g. GetID
  • Longer abbreviations need to be lower cased, e.g. GetHtml

Noncompliant Code Example

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

Enum Foo
    fooValue   ' Noncompliant
End Enum

Compliant Solution

Enum Foo
    FooValue   ' Compliant
End Enum
vbnet:S2344

The information that an enumeration type is actually an enumeration or a set of flags should not be duplicated in its name.

Noncompliant Code Example

Enum FooFlags ' Noncompliant
    Foo = 1
    Bar = 2
    Baz = 4
End Enum

Compliant Solution

Enum Foo      ' Compliant
    Foo = 1
    Bar = 2
    Baz = 4
End Enum
vbnet:S2345

Flags enumerations should not rely on the language to initialize the values of their members. Implicit initialization will set the first member to 0, and increment the value by one for each subsequent member. This implicit behavior does not allow members to be combined using the bitwise or operator in a useful way.

Instead, 0 and powers of two (i.e. 1, 2, 4, 8, 16, ...) should be used to explicitly initialize all the members.

Noncompliant Code Example

<Flags()>
Enum FruitType    ' Non-Compliant
  None
  Banana
  Orange
  Strawberry
End Enum

Module Module1
  Sub Main()
    Dim bananaAndStrawberry = FruitType.Banana Or FruitType.Strawberry

    ' Will display only Strawberry!
    Console.WriteLine(bananaAndStrawberry.ToString())
  End Sub
End Module

Compliant Solution

<Flags()>
Enum FruitType    ' Compliant
  None = 0
  Banana = 1
  Orange = 2
  Strawberry = 4
End Enum

Module Module1
  Sub Main()
    Dim bananaAndStrawberry = FruitType.Banana Or FruitType.Strawberry

    ' Will display Banana and Strawberry, as expected.
    Console.WriteLine(bananaAndStrawberry.ToString())
  End Sub
End Module

Exceptions

The default initialization of 0, 1, 2, 3, 4, ... matches 0, 1, 2, 4, 8 ... in the first three values, so no issue is reported if the first three members of the enumeration is not initialized.

vbnet:S2346

Consistent use of "None" in flags enumerations indicates that all flag values are cleared. The value 0 should not be used to indicate any other state, since there is no way to check that the bit 0 is set.

Noncompliant Code Example

<Flags()>
Enum FruitType
    Void = 0        ' Non-Compliant
    Banana = 1
    Orange = 2
    Strawberry = 4
End Enum

Compliant Solution

<Flags()>
Enum FruitType
    None = 0        ' Compliant
    Banana = 1
    Orange = 2
    Strawberry = 4
End Enum
vbnet:S2347

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all even handler names match a provided regular expression.

The default configuration is:

  • Either in Pascal case, i.e. starting with an upper case letter, e.g. OnMyButtonClicked
  • Or, a subject, in Pascal or camel case, followed by an underscore followed by an event name, in Pascal case, e.g. btn1_Clicked

Event handlers with a handles clause and two-parameter methods with EventArgs second parameter are covered by this rule.

Noncompliant Code Example

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

Module Module1
    Sub subject__SomeEvent() Handles X.SomeEvent   ' Noncompliant - two underscores
    End Sub
End Module

Compliant Solution

Module Module1
    Sub subject_SomeEvent() Handles X.SomeEvent    ' Compliant
    End Sub
End Module
vbnet:S2348

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all even names match a provided regular expression.

The default configuration is the one recommended by Microsoft:

  • Pascal casing, starting with an upper case character, e.g. BackColor
  • Short abbreviations of 2 letters can be capitalized, e.g. GetID
  • Longer abbreviations need to be lower cased, e.g. GetHtml

Noncompliant Code Example

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

Class Foo
    Event fooEvent() ' Noncompliant
End Class

Compliant Solution

Class Foo
    Event FooEvent() ' Compliant
End Class
vbnet:S2349

"After" and "Before" prefixes or suffixes should not be used to indicate pre and post events. The concepts of before and after should be given to events using the present and past tense.

Noncompliant Code Example

Class Foo
    Event BeforeClose() ' Noncompliant
    Event AfterClose()  ' Noncompliant
End Class

Compliant Solution

Class Foo
    Event Closing()     ' Compliant
    Event Closed()      ' Compliant
End Class
vbnet:S2352

Indexed properties are meant to represent access to a logical collection. When multiple parameters are required, this design guideline may be violated, and refactoring the property into a method is preferable.

Noncompliant Code Example

Module Module1
    ReadOnly Property Sum(ByVal a As Integer, ByVal b As Integer) ' Noncompliant
        Get
            Return a + b
        End Get
    End Property
End Module

Compliant Solution

Module Module1
    Function Sum(ByVal a As Integer, ByVal b As Integer)          ' Compliant
        Return a + b
    End Function
End Module
vbnet:S2353

In most cases, indexed properties should be named Item for consistency. Exceptions are when there exists a name which is obviously better, for example System.String.Chars(System.Int32).

Noncompliant Code Example

Module Module1
    Dim array = {"apple", "banana", "orange", "strawberry"}

    ReadOnly Property Foo(ByVal index As Integer)  ' Noncompliant
        Get
            Return array(index)
        End Get
    End Property
End Module

Compliant Solution

Module Module1
    Dim array = {"apple", "banana", "orange", "strawberry"}

    ReadOnly Property Item(ByVal index As Integer)
        Get
            Return array(index)
        End Get
    End Property
End Module

Deprecated

This rule is deprecated, and will eventually be removed.

vbnet:S2354

To improve the code readability, the explicit line continuation character, _, should not be used. Instead, it is better to break lines after an operator.

Noncompliant Code Example

Module Module1
    Sub Main()
        ' Noncompliant
        Console.WriteLine("Hello" _
                          & "world")
    End Sub
End Module

Compliant Solution

Module Module1
    Sub Main()

        Console.WriteLine("Hello" &
                          "world")
    End Sub
End Module
vbnet:S2355

Array literals are more compact than array creation expressions.

Noncompliant Code Example

Module Module1
    Sub Main()
        Dim foo = New String() {"a", "b", "c"} ' Noncompliant
    End Sub
End Module

Compliant Solution

Module Module1
    Sub Main()
        Dim foo = {"a", "b", "c"}              ' Compliant
    End Sub
End Module
vbnet:S2357

Fields should not be part of an API, and therefore should always be private. Indeed, they cannot be added to an interface for instance, and validation cannot be added later on without breaking backward compatibility. Instead, developers should encapsulate their fields into properties. Explicit property getters and setters can be introduced for validation purposes or to smooth the transition to a newer system.

Noncompliant Code Example

Class Foo
    Public Foo = 42          ' Noncompliant
End Class

Compliant Solution

Class Foo
    Public Property Foo = 42 ' Compliant
End Class

Exceptions

Shared and Const fields are ignored.

vbnet:S2358

The ... IsNot ... syntax is more compact and more readable than the Not ... Is ... syntax.

Noncompliant Code Example

Module Module1
    Sub Main()
        Dim a = Not "a" Is Nothing ' Noncompliant
    End Sub
End Module

Compliant Solution

Module Module1
    Sub Main()
        Dim a = "a" IsNot Nothing  ' Compliant
    End Sub
End Module
vbnet:S2359

Prefer the use of Try ... Catch blocks instead of On Error statements.

Visual Basic .NET and Visual Basic 2005 offer structured exception handling that provides a powerful, more readable alternative to the On Error Goto error handling from previous versions of Microsoft Visual Basic. Structured exception handling is more powerful because it allows you to nest error handlers inside other error handlers within the same procedure. Furthermore, structured exception handling uses a block syntax similar to the If...Else...End If statement. This makes Visual Basic .NET and Visual Basic 2005 code more readable and easier to maintain.

Noncompliant Code Example

Sub DivideByZero()
  On Error GoTo nextstep
  Dim result As Integer
  Dim num As Integer
  num = 100
  result = num / 0
nextstep:
  System.Console.WriteLine("Error")
End Sub

Compliant Solution

Sub DivideByZero()
  Try
    Dim result As Integer
    Dim num As Integer
    num = 100
    result = num / 0
  Catch
    System.Console.WriteLine("Error")
  End Try
End Sub
vbnet:S2362

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all Private Const field names comply with the provided regular expression.

The default configuration is:

  • Optionally, can start with an underscore character or "s_", e.g. foo, sfoo
  • 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" in productID
  • Longer abbreviations need to be lower cased, e.g. html

Noncompliant Code Example

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

Module Module1
    Private Const Foo = 0  ' Noncompliant
End Module

Compliant Solution

Module Module1
    Private Const foo = 0  ' Compliant
End Module
vbnet:S2363

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all Private Shared ReadOnly field names comply with the provided regular expression.

The default configuration is:

  • Optionally, can start with an underscore character or "s_", e.g. foo, sfoo
  • 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" in productID
  • Longer abbreviations need to be lower cased, e.g. html

Noncompliant Code Example

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

Class Foo
    Private Shared ReadOnly Foo As Integer  ' Noncompliant
End Class

Compliant Solution

Class Foo
    Private Shared ReadOnly foo As Integer  ' Compliant
End Class
vbnet:S2364

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all Private field names match the provided regular expression.

Note that this rule does not apply to Private Shared ReadOnly fields, which are checked by another rule.

The default configuration is:

  • Optionally, can start with an underscore character or "s_", e.g. foo, sfoo
  • 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" in productID
  • Longer abbreviations need to be lower cased, e.g. html

Noncompliant Code Example

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

Class Foo
    Private Foo As Integer  ' Noncompliant
End Class

Compliant Solution

Class Foo
    Private foo As Integer  ' Compliant
End Class
vbnet:S2365

Most developers expect property access to be as efficient as field access. However, if a property returns a copy of an array or collection, it will be much slower than a simple field access, contrary to the caller's likely expectations. Therefore, such properties should be refactored into methods so that callers are not surprised by unexpectedly poor performance.

Noncompliant Code Example

Module Module1
    ' Internal state
    Dim array = {"apple", "banana", "orange", "pineapple", "strawberry"}

    ReadOnly Property Foo() As String() ' Noncompliant
        Get
            Dim copy = array.Clone      ' Expensive call
            Return copy
        End Get
    End Property
End Module

Compliant Solution

Module Module1
    ' Internal state
    Dim array = {"apple", "banana", "orange", "pineapple", "strawberry"}

    Function GetFoo() As String()       ' Compliant
        Dim copy = array.Clone
        Return copy
    End Function
End Module
vbnet:S2366

Shared coding conventions allow teams to collaborate efficiently. This rule checks that property names match a provided regular expression.

The default configuration is the one recommended by Microsoft:

  • Pascal casing, starting with an upper case character, e.g. BackColor
  • Short abbreviations of 2 letters can be capitalized, e.g. GetID
  • Longer abbreviations need to be lower cased, e.g. GetHtml

Noncompliant Code Example

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

Module Module1
    Public Property foo As Integer   ' Noncompliant
End Module

Compliant Solution

Module Module1
    Public Property Foo As Integer   ' Compliant
End Module
vbnet:S2367

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all non-private Const field names comply with the provided regular expression.

The default configuration is the one recommended by Microsoft:

  • Pascal casing, starting with an upper case character, e.g. BackColor
  • Short abbreviations of 2 letters can be capitalized, e.g. GetID
  • Longer abbreviations need to be lower cased, e.g. GetHtml

Noncompliant Code Example

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

Module Module1
    Public Const foo = 0  ' Noncompliant
End Module

Compliant Solution

Module Module1
    Public Const Foo = 0  ' Compliant
End Module
vbnet:S2368

Exposing methods with multidimensional array parameters requires developers to have advanced knowledge about the language in order to be able to use them. Moreover, what exactly to pass to such parameters is not intuitive. Therefore, such methods should not be exposed, but can be used internally.

Noncompliant Code Example

Module Module1
    Sub WriteMatrix(ByVal matrix As Integer()()) ' Non-Compliant
        ' ...
    End Sub
End Module

Compliant Solution

Class Matrix
    ' ...
End Class

Module Module1
    Sub WriteMatrix(ByVal matrix As Matrix)      ' Compliant
        ' ...
    End Sub
End Module
vbnet:S2369

Shared coding conventions allow teams to collaborate efficiently. This rule checks that all non-private fields names match a provided regular expression.

Note that this rule does not apply to non-private Shared ReadOnly fields, for which there is another rule.

The default configuration is:

  • Pascal casing, starting with an upper case character, e.g. BackColor
  • Short abbreviations of 2 letters can be capitalized, e.g. GetID
  • Longer abbreviations need to be lower cased, e.g. GetHtml

Noncompliant Code Example

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

Class Foo
    Public foo As Integer  ' Noncompliant
End Class

Compliant Solution

Class Foo
    Public Foo As Integer  ' Compliant
End Class
vbnet:S2370

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all non-private Shared ReadOnly fields names match a provided regular expression.

The default configuration is:

  • Pascal casing, starting with an upper case character, e.g. BackColor
  • Short abbreviations of 2 letters can be capitalized, e.g. GetID
  • Longer abbreviations need to be lower cased, e.g. GetHtml

Noncompliant Code Example

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

Class Foo
    Public Shared ReadOnly foo As Integer  ' Noncompliant
End Class

Compliant Solution

Class Foo
    Public Shared ReadOnly Foo As Integer  ' Compliant
End Class
vbnet:S2372

Property getters should be simple operations that are always safe to call. If exceptions need to be thrown, it is best to convert the property to a method.

It is valid to throw exceptions from indexed property getters and from property setters, which are not detected by this rule.

Noncompliant Code Example

Module Module1
    Public Property Foo() As Integer
        Get
            Throw New Exception  ' Non-Compliant
        End Get
        Set(ByVal value As Integer)
            ' ... some code ...
        End Set
    End Property
End Module

Compliant Solution

Module Module1
    Sub SetFoo(ByVal value As Integer)         ' Compliant
        ' ... some code ...
    End Sub
End Module

Exceptions

No issue is raised when the thrown exception derives from or is of type NotImplementedException, NotSupportedException or InvalidOperationException.

vbnet:S2373

Shared naming conventions allow teams to collaborate efficiently. This rule checks that all generic type parameter names match a provided regular expression.

The default configuration is the one recommended by Microsoft:

  • Must start with an upper case 'T' character, e.g. T
  • Followed by Pascal casing, starting with an upper case character, e.g. TKey
  • Short abbreviations of 2 letters can be capitalized, e.g. TFooID
  • Longer abbreviations need to be lower cased, e.g. TFooHtml

Noncompliant Code Example

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

Public Class Foo(Of t) ' Noncompliant
End Class

Compliant Solution

Public Class Foo(Of T) ' Compliant
End Class
vbnet:S2374

Unsigned integers have different arithmetic operators than signed ones - operators that few developers understand. Therefore, signed types should be preferred where possible.

Noncompliant Code Example

Module Module1
    Sub Main()
        Dim foo1 As UShort   ' Noncompliant
        Dim foo2 As UInteger ' Noncompliant
        Dim foo3 As ULong    ' Noncompliant
    End Sub
End Module

Compliant Solution

Module Module1
    Sub Main()
        Dim foo1 As Short
        Dim foo2 As Integer
        Dim foo3 As Long
    End Sub
End Module
vbnet:S2375

Using the With statement for a series of calls to the same object makes the code more readable.

Noncompliant Code Example

With the default value of 6:

Module Module1
    Dim product = New With {.Name = "paperclips", .RetailPrice = 1.2, .WholesalePrice = 0.6, .A = 0, .B = 0, .C = 0}

    Sub Main()
        product.Name = ""           ' Noncompliant
        product.RetailPrice = 0
        product.WholesalePrice = 0
        product.A = 0
        product.B = 0
        product.C = 0
    End Sub
End Module

Compliant Solution

Module Module1
    Dim product = New With {.Name = "paperclips", .RetailPrice = 1.2, .WholesalePrice = 0.6, .A = 0, .B = 0, .C = 0}

    Sub Main()
        With product
            .Name = ""
            .RetailPrice = 0
            .WholesalePrice = 0
            .A = 0
            .B = 0
            .C = 0
        End With
    End Sub
End Module
vbnet:S2376

Properties with only setters are confusing and counterintuitive. Instead, a property getter should be added if possible, or the property should be replaced with a setter method.

Noncompliant Code Example

Module Module1
    WriteOnly Property Foo() As Integer ' Non-Compliant
        Set(ByVal value As Integer)
            ' ... some code ...
        End Set
    End Property
End Module

Compliant Solution

Module Module1
    Sub SetFoo(ByVal value As Integer)  ' Compliant
        ' ... some code ...
    End Sub
End Module
vbnet:S2429

The ... = {} syntax is more compact, more readable and less error-prone.

Noncompliant Code Example

Module Module1
  Sub Main()
    Dim foo(1) As String   ' Noncompliant
    foo(0) = "foo"
    foo(1) = "bar"
  End Sub
End Module

Compliant Solution

Module Module1
  Sub Main()
    Dim foo = {"foo", "bar"}  ' Compliant
  End Sub
End Module
vbnet:S2951

Visual Basic .NET, unlike many other programming languages, has no "fall-through" for its Select cases. Each case already has an implicit Exit Select as its last instruction. It therefore is redundant to explicitly add one.

Noncompliant Code Example

Module Module1
  Sub Main()
    Dim x = 0
    Select Case x
      Case 0
        Console.WriteLine("0")
        Exit Select                ' Noncompliant
      Case Else
        Console.WriteLine("Not 0")
        Exit Select                ' Noncompliant
    End Select
  End Sub
End Module

Compliant Solution

Module Module1
  Sub Main()
    Dim x = 0
    Select Case x
      Case 0                         ' Compliant
        Console.WriteLine("0")
      Case Else                      ' Compliant
        Console.WriteLine("Not 0")
    End Select
  End Sub
End Module
vbnet:S3385

Other than Exit Select, using an Exit statement is never a good idea.

Exit Do, Exit For, Exit Try, and Exit While will all result in unstructured control flow, i.e. spaghetti code.

Exit Function, Exit Property, and Exit Sub are all poor, less-readable substitutes for a simple return, and if used with code that should return a value (Exit Function and in some cases Exit Property) they could result in a NullReferenceException.

This rule raises an issue for all uses of Exit except Exit Select and Exit Do statements in loops without condition.

Noncompliant Code Example

Public Class Sample
  Dim condition As Boolean

  Public Sub MySub()
    If condition Then
      Exit Sub                  ' Noncompliant
    End If

    For index = 1 To 10
      If index = 5 Then
          Exit For               ' Noncompliant
      End If
      ' ...
    Next
  End Sub
  Function MyFunction() As Object
    ' ...
    MyFunction = 42
    Exit Function              ' Noncompliant
  End Function
End Class

Compliant Solution

Public Class Sample
  Dim condition As Boolean

  Public Sub MySub()
    If condition Then
        Return
    End If

    For index = 1 To 4
        ' ...
    Next
  End Sub
  Function MyFunction() As Object
    ' ...
    Return 42
  End Function
End Class
vbnet:S3860

Since Visual Studio 2010 SP1, the ByVal parameter modifier is implicitly applied, and therefore not required anymore. Removing it from your source code will improve readability.

Noncompliant Code Example

Sub Foo(ByVal bar As String)
  ' ...
End Sub

Compliant Solution

Sub Foo(bar As String)
  ' ...
End Sub
vbnet:S3866

Visual Basic .NET offers a non-short-circuit conditional function, IIf(), which returns either its second or third parameter based on the expression in the first parameter. Using it is slower than using If() because each parameter is unconditionally evaluated. Further, its use can lead to runtime exceptions because IIf always evaluates all three of its arguments.

The newer version, If(), should be used instead because it short-circuits the evaluation of its parameters.

Noncompliant Code Example

Public Class Foo
    Public Sub Bar()
        Dim var As Object = IIf(Date.Now.Year = 1999, "Lets party!", "Lets party like it is 1999!") ' Noncompliant
    End Sub
End Class

Compliant Solution

Public Class Foo
    Public Sub Bar()
        Dim var As String = If(Date.Now.Year = 1999, "Lets party!", "Lets party like it is 1999!")
    End Sub
End Class

See

vbnet:S3981

The size of a collection and the length of an array are always greater than or equal to zero. So testing that a size or length is greater than or equal to zero doesn't make sense, since the result is always true. Similarly testing that it is less than zero will always return false. Perhaps the intent was to check the non-emptiness of the collection or array instead.

Noncompliant Code Example

If Collection.Count >= 0 Then ...

If Enumerable.Count < 0 Then ...

If array.Length >= 0 Then ...

Dim result As Boolean = Array.Length >= 0

Compliant Solution

If list.Count = 0 Then ...
If array.Length >= 42 Then ...
vbnet:S4142

There are valid cases for passing a variable multiple times into the same method call, but usually doing so is a mistake, and something else was intended for one of the arguments.

Noncompliant Code Example

If compare(myPoint.x, myPoint.x) <> 0 Then ' Noncompliant
    '...
End If

If compare(getNextValue(), getNextValue()) <> 0 Then ' Noncompliant
    '...
End If

Compliant Solution

If compare(myPoint.x, myPoint.y) <> 0 Then
    '...
End If

Dim v1 As Integer = getNextValue()
Dim v2 As Integer = getNextValue()
If compare(v1, v2) <> 0 Then
    '...
End If

Deprecated

This rule is deprecated, and will eventually be removed.

vbnet:S4144

When two methods have the same implementation, either it was a mistake - something else was intended - or the duplication was intentional, but may be confusing to maintainers. In the latter case, one implementation should invoke the other.

Noncompliant Code Example

Private Const CODE As String = "bounteous"
Private callCount As Integer = 0

Public Function GetCode() As String
  callCount = callCount + 1
  Return CODE
End Function

Public Function GetName() As String ' Noncompliant
  callCount = callCount + 1
  Return CODE
End Function

Compliant Solution

Private Const CODE As String = "bounteous"
Private callCount As Integer = 0

Public Function GetCode() As String
  callCount = callCount + 1
  Return CODE
End Function

Public Function GetName() As String
  Return GetCode()
End Function

Exceptions

Empty methods, methods with only one line of code and methods with the same name (overload) are ignored.

Web:AvoidCommentedOutCodeCheck

Programmers should not comment out code as it bloats programs and reduces readability.

Unused code should be deleted and can be retrieved from source control history if required.

See

  • MISRA C:2004, 2.4 - Sections of code should not be "commented out".
  • MISRA C++:2008, 2-7-2 - Sections of code shall not be "commented out" using C-style comments.
  • MISRA C++:2008, 2-7-3 - Sections of code should not be "commented out" using C++ comments.
  • MISRA C:2012, Dir. 4.4 - Sections of code should not be "commented out"
Web:AvoidHtmlCommentCheck

Using HTML-style comments in a page that will be generated or interpolated server-side before being served to the user increases the risk of exposing data that should be kept private. For instance, a developer comment or line of debugging information that's left in a page could easily (and has) inadvertently expose:

  • Version numbers and host names
  • Full, server-side path names
  • Sensitive user data

Because every other language has its own native comment format, there is no justification for using HTML-style comments in anything other than a pure HTML or XML file.

Noncompliant Code Example

  <%
      out.write("<!-- ${username} -->");  // Noncompliant
  %>
      <!-- <% out.write(userId) %> -->  // Noncompliant
      <!-- #{userPhone} -->  // Noncompliant
      <!-- ${userAddress} --> // Noncompliant

      <!-- Replace 'world' with name --> // Noncompliant
      <h2>Hello world!</h2>

Compliant Solution

      <%-- Replace 'world' with name --%>  // Compliant
      <h2>Hello world!</h2>

See

  • MITRE, CWE-615 - Information Exposure Through Comments
  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
Web:BoldAndItalicTagsCheck

The <strong>/<b> and <em>/<i> tags have exactly the same effect in most web browsers, but there is a fundamental difference between them: <strong> and <em> have a semantic meaning whereas <b> and <i> only convey styling information like CSS.

While <b> can have simply no effect on a some devices with limited display or when a screen reader software is used by a blind person, <strong> will:

  • Display the text bold in normal browsers
  • Speak with lower tone when using a screen reader such as Jaws

Consequently:

  • in order to convey semantics, the <b> and <i> tags shall never be used,
  • in order to convey styling information, the <b> and <i> should be avoided and CSS should be used instead.

Noncompliant Code Example

<i>car</i>             <!-- Noncompliant -->
<b>train</b>         <!-- Noncompliant -->

Compliant Solution

<em>car</em>
<strong>train</strong>

Exceptions

This rule is relaxed in case of icon fonts usage.

<i class="..." aria-hidden="true" />    <!-- Compliant icon fonts usage -->
Web:DoctypePresenceCheck

The <!DOCTYPE> declaration tells the web browser which (X)HTML version is being used on the page, and therefore how to interpret the various elements.

Validators also rely on it to know which rules to enforce.

It should always preceed the <html> tag.

Noncompliant Code Example

<html>  <!-- Noncompliant -->
...
</html>

Compliant Solution

<!DOCTYPE html>
<html>  <!-- Compliant -->
...
</html>
Web:DoubleQuotesCheck

Checker to find use of single quote where double quote is preferred.

Noncompliant Code Example

<div id='header'></div>

Compliant Solution

<div id="header"></div>
Web:DynamicJspIncludeCheck

Content that doesn't change or that doesn't change often should be included using a mechanism which won't try to interpret it. Specifically, <%@ include file="..." %>, which includes the file in the JSP servlet translation phase (i.e. it happens once), should be used instead of <jsp:include page="..." />, which includes the page on the file, when the content is being served to the user.

Noncompliant Code Example

<jsp:include page="header.jsp">  <!-- Noncompliant -->

Compliant Solution

<%@ include file="header.jsp" %>
Web:FieldsetWithoutLegendCheck

For users of assistive technology such as screen readers, it may be challenging to know what is expected in each form's input. The input's label alone might not be sufficient: 'street' could be part of a billing or a shipping address for instance.

Fieldset legends are read out loud by screen readers before the label each time the focus is set on an input. For example, a legend 'Billing address' with a label 'Street' will read 'Billing address street'. Legends should be short, and 'Your' should not be repeated in both the legend and the label, as it would result in 'Your address Your City' being read.

Noncompliant Code Example

<fieldset>                                 <!-- Noncompliant -->
  Street: <input type="text"><br />
  Town: <input type="text"><br />
  Country: <input type="text"><br />
</fieldset>

Compliant Solution

<fieldset>
  <legend>Billing address</legend>
  Street: <input type="text"><br />
  Town: <input type="text"><br />
  Country: <input type="text"><br />
</fieldset>
Web:FlashUsesBothObjectAndEmbedCheck

The <object> tag is used by Internet Explorer 3.0 or later on Windows platforms or any browser that supports the use of the Flash ActiveX control. The <embed> tag is used by Netscape Navigator 2.0 or later, or browsers that support the use of the Netscape-compatible plug-in version of Flash Player.

When an ActiveX-enabled browser loads the HTML page, it reads the values set on the <object> and ignores the <embed> tag. When browsers using the Flash plug-in load the HTML page, they read the values set on the <embed> tag and ignore the <object> tag.

Noncompliant Code Example

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="100" height="100">      <!-- Non-Compliant -->
  <param name="movie" value="movie_name.swf" />
</object>

<embed src="movie_name.swf"                                                                 <!-- Non-Compliant -->
       width="550"
       height="400"
       type="application/x-shockwave-flash"
       pluginspage="http://www.macromedia.com/go/getflashplayer" />

Compliant Solution

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="100" height="100">      <!-- Compliant -->
  <param name="movie" value="movie_name.swf" />
  <embed src="movie_name.swf"                                                               <!-- Compliant -->
       width="550"
       height="400"
       type="application/x-shockwave-flash"
       pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
Web:FrameWithoutTitleCheck

Frames allow different web pages to be put together on the same visual space. Users without disabilities can easily scan the contents of all frames at once. However, visually impaired users using screen readers hear the page content linearly.

The title attribute is used to list all the page's frames, enabling those users to easily navigate among them. Therefore, the <frame> and <iframe> tags should always have a title attribute.

Noncompliant Code Example

<frame src="index.php?p=menu">                                      <-- Non-Compliant -->
<frame src="index.php?p=home" name="contents">                      <-- Non-Compliant -->

Compliant Solution

<frame src="index.php?p=menu" title="Navigation menu">              <-- Compliant -->
<frame src="index.php?p=home" title="Main content" name="contents"> <-- Compliant -->
Web:IllegalElementCheck

This rule checks that the specified HTML elements are not present.

Noncompliant Code Example

For a disallowed list of "font,center":

<center><font color="red">Hello World!</font></center> <!-- Noncompliant -->

Compliant Solution

<div class="centerRed">Hello World!</div>
Web:IllegalNamespaceCheck

This rule allows to ban declaration of some namespaces in the root element of XHML documents.

Noncompliant Code Example

With a "namespaces" value of "http://java.sun.com/jsf/facelets":

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:ui="http://java.sun.com/jsf/facelets"    <!-- Noncompliant -->
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core">

Compliant Solution

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core">
Web:IllegalTabCheck

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

Web:IllegalTagLibsCheck

This rule checks that the disallowed tag libraries are not used.

Noncompliant Code Example

Using the default parameter for this rule, "http://java.sun.com/jstl/sql":

<%@ taglib uri="http://java.sun.com/jstl/sql" prefix="prefixOfTag" > <!-- Noncompliant -->
<jsp:directive.taglib uri="http://java.sun.com/jstl/sql" prefix="prefixOfTag" /> <!-- Noncompliant -->
Web:ImgWithoutAltCheck

The alt attribute provides a textual alternative to an image.

It is used whenever the actual image cannot be rendered.

Common reasons for that include:

  • The image can no longer be found
  • Visually impaired users using a screen reader software
  • Images loading is disabled, to reduce data consumption on mobile phones

Empty alt attributes are not allowed, since purely decorative images should be specified using CSS, not using the img tag.

Noncompliant Code Example

<img src="foo.png" />                                           <!-- Noncompliant -->
<img src="foo.png" alt="" />                                    <!-- Noncompliant -->
<input type="image" src="bar.png" />                            <!-- Noncompliant -->

Compliant Solution

<img src="foo.png" alt="Some textual description of foo.png" />
<input type="image" src="bar.png" alt="Textual description of bar.png" />
Web:InputWithoutLabelCheck

The <label> tag defines a label for <input>, <select> and <textarea> elements.

The <label> tag does not render as anything special. However, it provides a usability improvement for mouse users: when the text within the <label> element is clicked, the associated input field is toggled.

It also improves usability for visually impaired users: Screen readers will announce the label text whenever the focus is set on the input field.

The for attribute of the <label> tag should be equal to the id attribute of the related element to bind them together.

The purpose of this rule is to make sure that every input (except submit, button, image and hidden inputs), select, and <textarea> field has an associated label element.

Noncompliant Code Example

<input type="text" name="firstname" />               <!-- Non-Compliant - no id -->

<input type="text" name="lastname" id="lastname" />  <!-- Non-Compliant - no matching label for "lastname" -->

<label for="address">Address</label>
<input type="text" name="address" id="address" />    <!-- Compliant -->

<input type="hidden" name="time" value="...">        <!-- Compliant - "hidden" type is excluded -->
<input type="submit" value="Send" />                 <!-- Compliant - "submit" type is excluded -->

Compliant Solution

<label for="firstname">First name</label>
<input type="text" name="firstname" id="firstname" />

<label for="lastname">Last name</label>
<input type="text" name="lastname" id="lastname" />

<label for="address">Address</label>
<input type="text" name="address" id="address" />

<input type="hidden" name="time" value="...">
<input type="submit" value="Send" />
Web:ItemTagNotWithinContainerTagCheck

Using a <li> or <dt> item tag outside of a <ul>, <ol> or <dl> one does not make sense and indicates a bug.

Noncompliant Code Example

<li>Apple</li>          <!-- Noncompliant -->
<li>Strawberry</li>     <!-- Noncompliant -->

<li>Apple</li>          <!-- Noncompliant -->
<li>Strawberry</li>     <!-- Noncompliant -->

<dt>Apple</dt>          <!-- Noncompliant -->
<dt>Strawberry</dt>     <!-- Noncompliant -->

Compliant Solution

<ul>
  <li>Apple</li>
  <li>Strawberry</li>
</ul>

<ol>
  <li>Apple</li>
  <li>Strawberry</li>
</ol>

<dl>
  <dt>Apple</dt>
  <dt>Strawberry</dt>
</dl>
Web:JspScriptletCheck

JSP expressions (using <%= ... %>) have been deprecated because they:

  • Are not unit testable.
  • Are not reusable.
  • Cannot make use of object oriented concepts such as inheritence.
  • Have poor error handling capabilities: if an exception is thrown, an empty page is rended.
  • Mix the business and presentation logic.

JSP Standard Tag Library (JSTL) and Expression Language should be used instead, enabiling the adoption of the model-view-controller (MVC) design pattern which reduces the coupling between the presentation tier and the business logic.

Noncompliant Code Example

<input type="text" name="foo" value="<%= request.getParameter("foo") %>" />

Compliant Solution

<input type="text" name="foo" value="${fn:escapeXml(param.foo)}" />
Web:LinksIdenticalTextsDifferentTargetsCheck

When links with different targets are given identical link text, this can produce confusion for users of assistive technologies, some of which provide users the ability to view a list of all links on the page.

When this list of links is presented to the user they may be left not knowing the links go to different destinations.

Even if they do realize the links go to different destinations, they may be left not knowing which link to follow to go to the destination they desire.

Noncompliant Code Example

<a href="a.html">qux</a>
<a href="b.html">qux</a>          <!-- Noncompliant; same text, different targets -->

<a href="c.html">foo</a>
<a href="d.html">foo</a>          <!-- Noncompliant; same text, different targets -->

Compliant Solution

<a href="a.html">qux</a>
<a href="b.html">qaz</a>          <!-- Compliant; different text, different targets -->

<a href="c.html">foo</a>
<a href="c.html">foo</a>          <!-- Compliant; same text, same targets -->
Web:LinkToImageCheck

Whenever a user clicks on a link that targets an image, the website's navigation menu will be lost.

From a user point of view, it is as if she left the website.

The only way to return to it is using the browser's 'Back' button.

Instead, it is better to create a page which will display the image using the <img> tag and preserve the navigation menu.

Further, in terms of accessibility, when the image is embedded into a page, content providers are able to provide an alternate text equivalent through the alt attribute.

Noncompliant Code Example

<a href="image.png">...</a>  <!-- Non-Compliant -->

Compliant Solution

<a href="page.html">...</a>  <!-- Compliant -->
Web:LinkToNothingCheck

There are two ways to build a link that has the sole purpose of running JavaScript code. The goal of this rule is to ban such patterns in order to support browsing with JavaScript disabled.

Noncompliant Code Example

<a href="#" onclick="alert('Clicked!'); return false;">Run JavaScript Code</a> <!-- Noncompliant -->
<a href="javascript:void(0)" onclick="alert('Clicked!'); return false;">Run JavaScript Code</a>  <!-- Noncompliant -->
<a id="inPageAnchor">Jump down the page to me</a>  <!-- Compliant -->

Compliant Solution

<a id="inPageAnchor">Jump down the page to me</a>  <!-- Compliant -->
Web:LongJavaScriptCheck

Long pieces of JavaScript should be located in dedicated *.js source files. This makes maintenance of both the script and the pages that use it easier. Additionally, it offers some efficiencies in serving the files, since it takes better advantage of browser caching to only re-serve the parts of a web page that have actually changed.

Noncompliant Code Example

With the default parameter value of 5:

<head>
  ...
  <script type="text/javascript" language="JavaScript">  <!-- Noncompliant -->
    function doTheThing(arg1) {
      ...
      ...
    }

    function doTheOtherThing(arg1) {
      ...
    }

    function andSoOn() {
      ...
    }
  </script>
</head>

Compliant Solution

<head>
  ...
  <script type="text/javascript" language="JavaScript" src="myLongScript.js"> </script>
</head>
Web:MaxLineLengthCheck

Having to scroll horizontally makes it harder to get a quick overview and understanding of any piece of code.

Web:MetaRefreshCheck

Use of <meta http-equiv="refresh"> is discouraged by the World Wide Web Consortium (W3C).

If a user clicks the 'Back' button, some browers will go back to the redirecting page, which will prevent the user from actually going back.

To refresh the page, a better alternative is to use Ajax, to refresh only what needs to be refreshed and not the whole page.

To redirect to another page, using the HTTP response status code 301 'Moved Permanently' and 302 'Found' is a better option.

Noncompliant Code Example

<head>
  <meta http-equiv="refresh" content="5">   <!-- Non-Compliant -->
  <meta name="description" content="...">
</head>

Compliant Solution

<head>
  <meta name="description" content="...">
</head>
Web:MouseEventWithoutKeyboardEquivalentCheck

Offering the same experience with the mouse and the keyboard allow users to pick their preferred devices.

Additionally, users of assistive technology will also be able to browse the site even if they cannot use the mouse.

Noncompliant Code Example

<a onClick="doSomething();" ...>                                <!-- Noncompliant - 'onKeyPress' missing -->
<a onMouseover="doSomething();" ...>                            <!-- Noncompliant - 'onFocus' missing -->
<a onMouseout="doSomething();" ...>                             <!-- Noncompliant - 'onBlur' missing -->

Compliant Solution

<a onClick="doSomething();" onKeyPress="doSomething();" ...>    <!-- Compliant -->
<a onMouseover="doSomething();" onFocus="doSomething();" ...>   <!-- Compliant -->
<a onMouseout="doSomething();" onBlur="doSomething();" ...>     <!-- Compliant -->
Web:MultiplePageDirectivesCheck

While you can use as many page directives as you like, it is more readable to set multiple page attributes in a single directive.

The exception to this rule is when multiple packages are being imported. In that case, imports may be done in separate directives and all other attributes should be set in a single, additional directive.

Noncompliant Code Example

<%@ page session="false" %>
<%@ page import="java.util.*" %>
<%@ page errorPage="error.jsp" %> <!-- Noncompliant -->
<%@ page import="java.text.*" %>

Compliant Solution

<%@ page session="false"
                   errorPage="error.jsp" %>
<%@ page import="java.util.*" %>
<%@ page import="java.text.*" %>
Web:NonConsecutiveHeadingCheck

Heading tags are used by search engines and screen reader softwares to construct an outline of the page.

Starting at <h1> and not skipping any level eases this automatic construction.

Noncompliant Code Example

<h2>My Title</h2>     <!-- Non-Compliant - h1 is not being used -->

<h3>My Sub Title</h3> <!-- Compliant -->

Compliant Solution

<h1>My Title</h1>     <!-- Compliant -->

<h2>My Sub Title</h2> <!-- Compliant -->
Web:PageWithoutFaviconCheck

Favicons are shown for example in the browser's address bar, bookmark list, or tabs.

They enable users to quickly identify and recognize websites.

Noncompliant Code Example

<head>                                                                  <!-- Noncompliant -->
  <title>...<title>
</head>

Compliant Solution

<head>
  <title>...<title>
  <link rel="shortcut icon" href="http://example.com/myicon.ico" />
</head>
Web:PageWithoutTitleCheck

Titles are important because they are displayed in search engine results as well as the browser's toolbar.

This rule verifies that the <head> tag contains a <title> one, and the <html> tag a <head> one.

Noncompliant Code Example

<html>         <!-- Non-Compliant -->

<body>
...
</body>

</html>

Compliant Solution

<html>         <!-- Compliant -->

<head>
  <title>Some relevant title</title>
</head>

<body>
...
</body>

</html>
Web:RequiredAttributeCheck

This rule checks that the specified attributes are present in HTML tags.

Noncompliant Code Example

Given a required attribute list of: img.alt,img.height,img.width:

<img src="/images/queen.png"> <!-- Noncompliant; missing all required attributes -->

Compliant Solution

<img src="/images/queen.png" width="60" height="85" alt="Elizabeth II">
Web:S1436

This rule allows you to make sure that each HTML page contains an element with your configured ID, regardless of element type. This rule is useful, for instance, if your design requires a placeholder to be present in each page, for example to dynamically insert a footer.

Compliant Solution

With a required id of "#footer":

<div id="#footer">
...
</div>
Web:S1827

With the advent of HTML5, many old attributes were deprecated. To ensure the best user experience, deprecated attributes should not be used. This rule checks for the following deprecated attributes, where CSS should be used instead.

Attributes

Attribute Removed from
accept form
align caption, col, div, embed, h1-h6, hr, iframe, img, input, legend, object, p, table, tbody, thead, tfoot, td, th, tr
alink body
allowtransparency iframe
archive object
axis td, th
background body, table, thead, tbody, tfoot, tr, td, th
bgcolor body, table, td, th, tr
border img (border="0" allowed), object
bordercolor table
cellpadding table
cellspacing table
char col, tbody, thead, tfoot, td, th, tr
charoff col, tbody, thead, tfoot, td, th, tr
charset a, link
classid object
clear br
code object
codebase object
codetype object
color hr
compact dl, ol, ul
coords a
datafld a, applet, button, div, fieldset, frame, iframe, img, input, label, legend, marquee, object, param, select, span, textarea
dataformatas button, div, input, label, legend, marquee, object, option, select, span, table
datapagesize table
datasrc a, applet, button, div, frame, iframe, img, input, label, legend, marquee, object, option, select, span, table, textarea
declare object
event script
for script
frame table
frameborder iframe
height td, th
hspace embed, iframe, img, input, object
ismap input
langauge script (language="javascript", case insensitive, allowed)
link body
lowsrc img
marginbottom body
marginheight body, iframe
marginleft body
marginright body
margintop body
marginwidth body, iframe
methods a, link
name a (name="[a's element id]" allowed), embed, img, option
nohref area
noshade hr
nowrap td, th
profile head
rules table
scheme meta
scope td
scrolling iframe
shape a
size hr
standby object
summary table
target link
text body
type li, param, ul
urn a, link
usemap input
valign col, tbody, thead, tfoot, td, th, tr
valuetype param
version html
vlink body
vspace embed, iframe, img, input, object
width col, hr, pre, table, td, th

See

Web:S1829

It is considered best-practice to use relative URLs in web pages to prevent having to update the addresses if the web address in use changes. Moreover, if some absolute URLs are missed in such a process, it will obviously impact the user experience.

Noncompliant Code Example

<img src="http://www.myserver.com/smiley.gif" alt="Smiley face" height="42" width="42" />

Compliant Solution

<img src="smiley.gif" alt="Smiley face" height="42" width="42" />
Web:S4084

In order to make your site usable by as many people as possible, subtitles should be provided for videos.

This rule raises an issue when a video does not include at least one <track/> tag with the kind attribute set to captions, or descriptions or at the very least subtitles.

Note that the subtitles kind is not meant for accessibility but for translation. The kind captions targets people with hearing impairment, whereas descriptions targets people with vision impairment.

Noncompliant Code Example

<video id="video" controls preload="metadata">
   <source src="resources/myvideo.mp4" type="video/mp4">
   <source src="resources/myvideo.webm" type="video/webm">
</video>

Compliant Solution

<video id="video" controls preload="metadata">
   <source src="resources/myvideo.mp4" type="video/mp4">
   <source src="resources/myvideo.webm" type="video/webm">
   <track label="English" kind="captions" srclang="en" src="resources/myvideo-en.vtt" default>
   <track label="Deutsch" kind="captions" srclang="de" src="resources/myvideo-de.vtt">
   <track label="EspaƱol" kind="captions" srclang="es" src="resources/myvideo-es.vtt">
</video>
Web:ServerSideImageMapsCheck

The ismap attribute in an img tag creates a server-side image map: The browser sends the coordinates of the clicked point to the server.

For any person who cannot use a mouse, this form of navigation is inaccessible because it is the position of the cursor on the image that determines the action.

On the other hand, client-side image maps, which use the usemap attribute allow for each clickable area to specify an alternate text, enabling accessibility for the blind.

Further, in terms of separation of concerns, it is definitely better to leave the task of mapping pixels to links to the client.

Noncompliant Code Example

<a href="click_on_world_map.php" target="_self">
  <img src="world_map.png" ismap>              <!-- Noncompliant -->
</a>

Compliant Solution

<img src="world_map.png" usemap="#world_map">

<map name="world_map">
  <area shape="rect" coords="0,0,10,10" href="france.html" alt="France">
  <area shape="circle" coords="20,20,10" href="spain.html" alt="Spain">
  <area shape="circle" coords="30,30,8" href="england.html" alt="England">
  <!-- ... -->
</map>
Web:TableHeaderHasIdOrScopeCheck

Associating table headers with a row, column, or a group of rows or columns enables screen readers to announce the header prior to the data. This considerably increases the accessibility of tables to visually impaired users.

Noncompliant Code Example

<table border="1">
  <caption>Contact Information</caption>
  <tr>
    <td></td>
    <th>Name</th>                                          <!-- Non-Compliant -->
    <th>Phone#</th>                                        <!-- Non-Compliant -->
    <th>City</th>                                          <!-- Non-Compliant -->
  </tr>
  <tr>
    <td>1.</td>
    <th>Joel Garner</th>                                   <!-- Non-Compliant -->
    <td>412-212-5421</td>
    <td>Pittsburgh</td>
  </tr>
  <tr>
    <td>2.</td>
    <th>Clive Lloyd</th>                                   <!-- Non-Compliant -->
    <td>410-306-1420</td>
    <td>Baltimore</td>
  </tr>
</table>

Compliant Solution

<table border="1">
  <caption>Contact Information</caption>
  <tr>
    <td></td>
    <th scope="col">Name</th>                              <!-- Compliant -->
    <th scope="col">Phone#</th>                            <!-- Compliant -->
    <th scope="col">City</th>                              <!-- Compliant -->
  </tr>
  <tr>
    <td>1.</td>
    <th scope="row">Joel Garner</th>                       <!-- Compliant -->
    <td>412-212-5421</td>
    <td>Pittsburgh</td>
  </tr>
  <tr>
    <td>2.</td>
    <th scope="row">Clive Lloyd</th>                       <!-- Compliant -->
    <td>410-306-1420</td>
    <td>Baltimore</td>
  </tr>
</table>

or:

<table border="1">
  <caption>Contact Information</caption>
  <tr>
    <td></td>
    <th id="name">Name</th>                                <!-- Compliant -->
    <th id="phone">Phone#</th>                             <!-- Compliant -->
    <th id="city">City</th>                                <!-- Compliant -->
  </tr>
  <tr>
    <td>1.</td>
    <th id="person1" headers="name">Joel Garner</th>       <!-- Compliant -->
    <td headers="phone person1">412-212-5421</td>
    <td headers="city person1">Pittsburgh</td>
  </tr>
  <tr>
    <td>2.</td>
    <th id="person2" headers="name">Clive Lloyd</th>       <!-- Compliant -->
    <td headers="phone person2">410-306-1420</td>
    <td headers="city person2">Baltimore</td>
  </tr>
</table>
Web:TableWithoutCaptionCheck

In order to be accessible to visually impaired users, it is important that tables have a caption briefly describing its contents.

Noncompliant Code Example

<table>                                                         <!-- Noncompliant -->
  ...
<table>

Compliant Solution

<table>
  <caption>New York City Marathon Results 2013</caption>
  ...
<table>
Web:UnclosedTagCheck

Even if all browsers are fault-tolerant, HTML tags should be closed to prevent any unexpected behavior.

Noncompliant Code Example

<html>
  <head>
    <title>Test Page    <!-- Noncompliant; title not closed -->
  <!-- Noncompliant; head not closed -->
  <body>
    <em>Emphasized Text  <!-- Noncompliant; em not closed -->
  <!-- Noncompliant; body not closed -->
</html>

Compliant Solution

<html>
  <head>
    <title>Test Page</title>
  </head>
  <body>
    <em>Emphasized Text</em>
  </body>
</html>
Web:UnifiedExpressionCheck

This rule allows to make sure that all JSF Expressions are syntactically correct.

Noncompliant Code Example

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
   xmlns:h="http://java.sun.com/jsf/html">
   <h:body>
     First name
     <h:outputText value="#{user.firstName && @@}"/>   <!-- Noncompliant -->
   </h:body>
</html>
Web:UnsupportedTagsInHtml5Check

With the advent of HTML5, many old elements were deprecated. To ensure the best user experience, deprecated elements should not be used. This rule checks for the following deprecated elements:

Element Remediation Action
basefont, big, blink, center, font, marquee, multicol, nobr, spacer, tt use CSS
acronym use abbr
applet use embed or object
bgsound use audio
frame, frameset, noframes restructure the page to remove frames
isindex use form controls
dir use ul
hgroup use header or div
listing use pre and code
nextid use GUIDS
noembed use object instead of embed when fallback is necessary
plaintext use the "text/plain" MIME type
strike use del or s
xmp use pre or code, and escape "<" and "&" characters

See

Web:WhiteSpaceAroundCheck

The proper use of white space makes a major contribution to code readability.

This rule raises an issue when there is not a space character after the beginning and before the end of each comment (<!-- ... -->), directive (<%@ ... %>), and expression (<% ... %>).

Noncompliant Code Example

<!--Do the thing-->  <!-- Noncompliant; missing space at beginning and end of text-->
<%@page import="java.io.*,java.util.*" %> <!-- Noncompliant; missing space at beginning -->
<% String title = "My Page";%> <!-- Noncompliant; missing space at end -->

Compliant Solution

<!-- Do the thing -->
<%@ page import="java.io.*,java.util.*" %>
<% String title = "My Page"; %>
Web:WmodeIsWindowCheck

Browsers best support the window mode for the wmode parameter, also in terms of accessibility.

As it is the default mode, it is acceptable to either not specify a wmode parameter altogether, or to set it explicitly to window.

Noncompliant Code Example

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="400">
  <param name="movie" value="movie_name.swf" />
  <param name="wmode" value="direct" />                              <!-- Non-Compliant -->
</object>

<embed src="movie_name.swf"
       width="550"
       height="400"
       wmode="direct"                                                                 <!-- Non-Compliant -->
       type="application/x-shockwave-flash"
       pluginspage="http://www.macromedia.com/go/getflashplayer" />

Compliant Solution

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="400">
  <param name="movie" value="movie_name.swf" />
</object>

<embed src="movie_name.swf"
       width="550"
       height="400"
       type="application/x-shockwave-flash"
       pluginspage="http://www.macromedia.com/go/getflashplayer" />

or

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="400">
  <param name="movie" value="movie_name.swf" />
  <param name="wmode" value="window" />
</object>

<embed src="movie_name.swf"
       width="550"
       height="400"
       wmode="window"
       type="application/x-shockwave-flash"
       pluginspage="http://www.macromedia.com/go/getflashplayer" />
xml:IllegalTabCheck

Developers should not need to configure the tab width of their text editors in order to be able to read source code.

So the use of the tabulation character must be banned.

xml:IndentCheck

Proper indentation is a simple and effective way to improve the code's readability. Consistent indentation among the developers within a team also reduces the differences that are committed to source control systems, making code reviews easier.

By default this rule checks that each block of code is indented, although it does not check the size of the indent. Parameter "indentSize" allows the expected indent size to be defined. Only the first line of a badly indented section is reported.

xml:NewlineCheck

Each element should be on a line to itself.

Noncompliant Code Example

<parent><child /></parent>  <!-- Noncompliant -->

Compliant Solution

<parent>
  <child />
</parent>
xml:S2260

When the XML parser fails, it is possible to record the failure as a violation on the file. This way, not only it is possible to track the number of files that do not parse but also to easily find out why they do not parse.