Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Wiki Markup
According to the Java API documentation \[[API 06|AA. Java References#API 06]\] for {{Iterator.remove()}} method:
{quote}
The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method. 
{quote}

Such behavior may be observed in both single and multithreaded programs. In single threaded programs, this usually happens when an element is removed when the iteration is in progress. In a multithreaded program, it is possible that one thread iterates over a collection while another concurrently modifies it. This can result in unspecified behavior. Many implementations throw a {{ConcurrentModificationException}} when such a condition is detected.  

According to the Java API documentation \[[API 06|AA. Java References#API 06]\] for {{ConcurrentModificationException}}:
{quote}
... it is not generally permissible for one thread to modify a {{Collection}} while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances. Some {{Iterator}} implementations (including those of all the general purpose collection implementations provided by the JRE) may choose to throw this exception if this behavior is detected. {{Iterators}} that do this are known as fail-fast iterators, as they fail quickly and cleanly, rather that risking arbitrary, non-deterministic behavior at an undetermined time in the future. 

Note that fail-fast behavior cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast operations throw {{ConcurrentModificationException}} on a best-effort basis. Consequently, it would be wrong to write a program that depended on this exception for its correctness: {{ConcurrentModificationException}} should be used only to detect bugs.
{quote}

Do not rely on {{ConcurrentModificationException}} to stop any side effects resulting from modifying an underlying Collection while iterating over it. The fail-fast behavior may occur after processing an arbitrary number of elements. "\[Fail-fast iterators\] are implemented by associating a modification count with the collection: if the modification count changes during iteration, {{hasNext}} or {{next}} throws {{ConcurrentModificationException}}. However, this check is done without synchronization, so there is a risk of seeing a stale value of the modification count and therefore that the iterator does not realize a modification has been made. This was a deliberate design tradeoff to reduce the performance impact of the concurrent modification detection code." \[[Goetz 06|AA. Java References#Goetz 06]\].

Notably, the enhanced {{for}} loop (for-each idiom) internally uses an {{Iterator}} {mc} consequences? {mc}.

h2. Noncompliant Code Example

This noncompliant code example (based on a bug report [6687277|http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6687277]) removes an element from an {{ArrayList}} using the Collection's {{remove()}} method. This is done while iterating over the {{Collection}}. The resulting behavior is unspecified.

{code:bgColor=#FFcccc}
class BadIterate {
  public static void main(String[] args) {
  List<String> list = new ArrayList<String>();
  list.add("one");
  list.add("two");
        
  Iterator iter = list.iterator();
  while(iter.hasNext()) {
    String s = (String)iter.next();
    if(s.equals("one"))
      list.remove(s);
    }
  }    
}
{code}

h2. Compliant Solution

The {{Iterator.remove()}} method removes from the underlying {{Collection}} the last element returned by the iterator. Its behavior is fully specified.

{code:bgColor=#ccccff}
// ...
if(s.equals("one"))
  iter.remove();
// ...
{code}

h2. Exceptions

*EX1:*  The {{Iterator.remove()}} method can be used to modify the underlying collection when an iteration is in progress. This is also shown in the compliant solution. 

h2. Risk Assessment

Modifying a Collection while iterating over it can lead to nondeterministic behavior.

|| Rule || Severity || Likelihood || Remediation Cost || Priority || Level ||
| MSC13- J | low | probable | medium | {color:green}{*}P4{*}{color} | {color:green}{*}L3{*}{color} |


h3. Automated Detection

TODO



h3. Related Vulnerabilities

[HARMONY-6236|http://issues.apache.org/jira/browse/HARMONY-6236]

h2. References

\[[API 06|AA. Java References#API 06]\] Class [ConcurrentModificationException|http://java.sun.com/j2se/1.5.0/docs/api/java/util/ConcurrentModificationException.html] 
\[[SDN 08|AA. Java References#SDN 08]\] [Sun Bug database, Bug ID:6687277|http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6687277]
\[[Goetz 06|AA. Java References#Goetz 06]\] 5.1.2. Iterators and Concurrentmodificationexception

----
[!The CERT Sun Microsystems Secure Coding Standard for Java^button_arrow_left.png!|MSC12-J. Prefer using Iterators over Enumerations]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[!The CERT Sun Microsystems Secure Coding Standard for Java^button_arrow_up.png!|49. Miscellaneous (MSC)]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[!The CERT Sun Microsystems Secure Coding Standard for Java^button_arrow_right.png!|MSC14-J. Finish every set of statements associated with a case label with a break statement]