Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Sometimes null is returned intentionally to account for zero available instancesSome APIs intentionally return a null reference to indicate that instances are unavailable. This practice can lead to denial-of-service vulnerabilities when the client code does not fails to explicitly handle the null return value case. A null value is an example of an in-band error indicator, which is discouraged by ERR52-J. Avoid in-band error indicators. For methods that return a set of values using an array or collection, returning an empty array or collection is an excellent alternative to returning a null value, as most callers are better equipped to handle and empty set than a null value.

Noncompliant Code Example

This noncompliant code example returns a null ArrayList when the size of the ArrayList is zero0. The class Inventory contains a getStock() method that constructs a list of items that have zero 0 inventory and returns the list of items to the caller. When the size of this list is zero, a null is returned with the assumption that the client will install the necessary checks. Here, the client omits the check causing a NullPointerException at runtime.  

Code Block
bgColor#FFCCCC

class Inventory {
  private final Hashtable<String, Integer> items;
  public Inventory() {
    items = new Hashtable<String, Integer>();	
  }

  public List<String> getStock() {
    List<String> stock = new ArrayList<String>();
    Enumeration itemKeys = items.keys();
    while (itemKeys.hasMoreElements()) {
      Object value = itemKeys.nextElement();
      if((items.get(value)) == 0) {  		
        stock.add((String)value);	 
      }
    }
    
    if(items.size() == 0) {	
      return null;
    } else {
      return stock;
    }	
  }
}

public class Client {
  public static void main(String[] args) {
    Inventory inv = new Inventory();  
    List<String> items = inv.getStock();
    System.out.println(items.size()); // Throws a NPE
  }
}

Compliant Solution

When the size of this list is 0, a null value is returned with the assumption that the client will install the necessary checks. In this code example, the client lacks any null value check, causing a NullPointerException at runtime.

Compliant Solution

Instead of returning a null value, this compliant solution This compliant solution eliminates the null return and simply returns the List, even if when it is zero-length. The client can effectively handle this situation without being interrupted by runtime exceptions. When arrays are returned instead of collections, care must be taken to ensure that the client does not access individual elements of a zero-length array. This prevents an ArrayOutOfBoundsException.empty. 

Code Block
bgColor#ccccff

class Inventory {
  private final Hashtable<String, Integer> items;
  public Inventory() {
    items = new Hashtable<String, Integer>();	
  }

  public List<String> getStock() {
    List<String> stock = new ArrayList<String>();
    Integer noOfItems; // Number of items left in the inventory
    Enumeration itemKeys = items.keys();
    while (itemkeysitemKeys.hasMoreElements()) {
      Object value = itemKeys.nextElement();
		
      if((noOfItems = items.get(value)) == 0) {  		
        stock.add((String)value);	 
      }
    }	
    return stock; // Return list (possibly zero-length)
  }
}

public class Client {
  public static void main(String[] args) {
    Inventory inv = new Inventory();  
    List<String> items = inv.getStock();
    System.out.println(items.size()); // Does not throw a NPE
  }
}

The client can handle this situation effectively without being interrupted by runtime exceptions. When returning arrays rather than collections, ensure that the client avoids attempts to access individual elements of a zero-length array. This prevents an ArrayOutOfBoundsException from being thrown.

Compliant Solution

This compliant solution returns an explicit empty - list, which is an equivalent, permissible technique.

Code Block
bgColor#ccccff

public List<String> getStock() {
  List<String> stock = new ArrayList<String>();
  Integer noOfItems; // Number of items left in the inventory
  Enumeration itemkeysitemKeys = items.keys();
  while (itemkeysitemKeys.hasMoreElements()) {
    Object value = itemKeys.nextElement();
		
    if((noOfItems = items.get(value)) == 0) {  		
      stock.add((String)value);	 
    }
  }	
  
  if(l.isEmpty()) {
    return Collections.EMPTY_LIST; // Always zero-length
  } else {
    return stock; // Return list 
  }
}

// Class Client ...

...

Applicability

Returning a null value rather than a zero-length array or collection may lead to denial-of-service vulnerabilities when the client code does not fails to handle null return values properly.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

MET10-J

low

unlikely

high

P1

L3

Automated Detection

TODO

Other Languages

This guideline appears in the C Secure Coding Standard as MSC19-C. For functions that return an array, prefer returning an empty array over a null value.

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this guideline on the CERT website.

Bibliography

Wiki Markup
\[[Bloch 2008|AA. Bibliography#Bloch 08]\] Item 43: return empty arrays or collections, not nulls

Automatic detection is straightforward; fixing the problem typically requires programmer intervention.

Automated Detection

ToolVersionCheckerDescription
SonarQube
Include Page
SonarQube_V
SonarQube_V
S1168 

 

Bibliography

[Bloch 2008]Item 43, "Return Empty Arrays or Collections, Not Nulls"

 

...

Image Added Image Added Image AddedMET53-J. Always provide feedback about the resulting value of a method      05. Methods (MET)      MET11-J. Never declare a class method that hides a method declared in a superclass or superinterface