Collection Add To Self
ID |
kotlin.collection_add_to_self |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Kotlin |
Tags |
best-practice, reliability |
Description
Reports add(self) and addAll(self) calls where the receiver and the sole
argument are the same identifier. Adding a collection to itself produces
undefined behaviour at runtime.
Rationale
val list = mutableListOf<Any>()
list.add(list) // FLAW — infinite recursion on toString/hashCode/equals
list.addAll(list) // FLAW — usually ConcurrentModificationException
add(self) stores a reference to the collection inside itself. The very next
call to toString, hashCode, or equals recurses indefinitely and crashes
with StackOverflowError. addAll(self) iterates the collection while
mutating it; most JDK implementations detect the mid-iteration resize and
throw ConcurrentModificationException.
Remediation
Add the right collection — usually a copy of the receiver, or the contents of a different collection:
val list = mutableListOf<Any>()
// If you wanted to duplicate the contents:
list.addAll(list.toList()) // OK — toList() snapshots first
// If you wanted to merge from another source:
val other = listOf("a", "b")
list.addAll(other) // OK