...
As an example, an Enumeration
is used in the following code to display the contents of a Vector
.
Code Block |
---|
for (Enumeration e = vector.elements(); e.hasMoreElements();) {
System.out.println(e.nextElement());
}
|
Unfortunately, a Vector
and an Enumeration
may not always work well together. In fact, the Java API [API 2006] recommends, "New implementations should consider using Iterator
in preference to Enumeration
."
Noncompliant Code Example
This noncompliant code example implements a BankOperations
class with a removeAccounts()
method used to terminate all the accounts of a particular account holder, as identified by the name. Names can be repeated in the vector if a person has more than one account. The remove()
method attempts to iterate through all the vector entries comparing each entry with the name "Harry."
Code Block | ||
---|---|---|
| ||
class BankOperations {
private static void removeAccounts(Vector v, String name) {
Enumeration e = v.elements();
while (e.hasMoreElements()) {
String s = (String) e.nextElement();
if (s.equals(name)) {
v.remove("Harry"); // Second Harry is not removed
}
}
// Display current account holders
System.out.println("The names are:");
e = v.elements();
while (e.hasMoreElements()) {
System.out.println(e.nextElement()); // Prints Dick, Harry, Tom
}
}
public static void main(String args[]) {
// List contains a sorted array of account holder names
// Repeats are admissible
List list = new ArrayList(Arrays.asList(
new String[] {"Dick", "Harry", "Harry", "Tom"}));
Vector v = new Vector(list);
removeAccount(v, "Harry");
}
}
|
Upon encountering the first "Harry," it successfully removes the entry, and the size of the vector diminishes to three. However, the index of the Enumeration
does not decrease by 1, causing the program to use "Tom" for the next (now final) comparison. As a result, the second "Harry" remains in the vector unscathed, having shifted to the second position in the vector.
Compliant Solution
According to the Java API [API 2006], interface Iterator
documentation,
...
This compliant solution remedies the problem described in the noncompliant code example and demonstrates the advantages of using an Iterator
over an Enumeration
.
Code Block | ||
---|---|---|
| ||
class BankOperations {
private static void removeAccounts(Vector v, String name) {
Iterator i = v.iterator();
while (i.hasNext()) {
String s = (String) i.next();
if (s.equals(name)) {
i.remove(); // Correctly removes all instances of the name Harry
}
}
// Display current account holders
System.out.println("The names are:");
i = v.iterator();
while (i.hasNext()) {
System.out.println(i.next()); // Prints Dick, Tom only
}
}
public static void main(String args[]) {
List list = new ArrayList(Arrays.asList(
new String[] {"Dick", "Harry", "Harry", "Tom"}));
Vector v = new Vector(list);
remove(v, "Harry");
}
}
|
Risk Assessment
Using Enumeration
when performing remove operations on a vector may cause unexpected program behavior.
Rule Guideline | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MSC12MSC61-J JG | low | unlikely | medium | P2 | L3 |
Automated Detection
The Coverity Prevent Version 5.0 ITERATOR checker can detect the instance where next()
or previous()
on an iterator is called that may not have a next or previous element.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Bibliography
[API 2006] Interfaces: Enumeration and Iterator
[Daconta 2003] Item 21: Use Iteration over Enumeration
...