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. |
...
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.
...
{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. |
...
Do not rely on ConcurrentModificationException
to stop any side effects resulting from modifying an underlying Collection while iterating over it. Notably, the enhanced for
loop (for-each idiom) internally uses an Iterator
.
Noncompliant Code Example
This noncompliant code example (based on a bug report 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 Block | ||
---|---|---|
| ||
{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. 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(); // ... |
Exceptions
...
{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 | P4 | L3 |
Automated Detection
TODO
Related Vulnerabilities
References
...
|| 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] [!The CERT Sun Microsystems Secure Coding Standard for Java^button_arrow_up.png!|49. Miscellaneous (MSC)] [!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] |