soot-oss / soot

Soot - A Java optimization framework
GNU Lesser General Public License v2.1
2.89k stars 710 forks source link

ArraySet.addAll Implementation Bug #2091

Closed caoliqingstudio closed 3 months ago

caoliqingstudio commented 3 months ago

Describe the bug The implementation of addAll in ArraySet has a logical issue that almost certainly triggers the oops exception in the add method.

https://github.com/soot-oss/soot/blob/d4061dca597daa54b72ef093f027ceed5072178e/src/main/java/soot/util/ArraySet.java#L121 image

To reproduce

a = new ArraySet();
b = new ArraySet();
b.addAll(a);  // throw exception
a = new ArraySet(1);
a.add("x");
a.clear();
b = new ArraySet();
b.addAll(a);  // throw exception or  b = {"x"}

Additional context

The following logic is incorrect because the valid data for as needs to take into account the content of numElements. Thus, directly iterating through the entire elements will not only generate exceptions but also lead to incorrect additions.

for (E elem : as.elements) {
    ret |= add(elem);
}

=>

for (int i = 0; i < as.numElements; i++) {
    ret |= add(as.elements[i]);
}
StevenArzt commented 3 months ago

Thank you for the analysis and the fix. That's great work.