False Negative: EqualsArray.ql misses array identity comparisons once the array is widened to `Object` or routed through helper APIs.
- Langage dominant
- CodeQL
- Étoiles
- 10.1k
- Forks
- 2.1k
- Merge moyen
- 2 j 15 h
- PR mergées (30 j)
- 141
Description
# False Negative: EqualsArray.ql misses array identity comparisons once the array is widened to `Object` or routed through helper APIs.
Version
codeql 2.24.3
## Checker
- Checker id: `Likely Bugs/Comparison/EqualsArray.ql`
- Checker description: Detects calls to equals or hashCode methods on array objects, which compare object identity rather than array contents.
## Description of the false negative
These samples still use array identity operations where content comparison was almost certainly intended. The difference is only that the array is first widened to `Object` or compared through `Objects.equals(...)`, which still ends up using reference equality for arrays.
## Affected test cases
### `PosCase1_Var2.java`
Widening the array to `Object` does not change the fact that `equals` still performs identity comparison.
```java
// Calling hashCode() on an array should be flagged as comparing object identity.
package scensct.var.pos;
public class PosCase1_Var2 {
public static void main(String[] args) {
// Variant 2: Intra-procedural refactoring - using a temporary reference
int[] arr = {1, 2, 3};
Object objRef = arr;
int hash = objRef.hashCode(); // Still calling hashCode on the array object
System.out.println(hash);
}
}
```
### `PosCase2_Var1.java`
Calling `equals(Object)` on the array still compares object identity rather than contents.
```java
// Calling equals(Object) on an array with compatible array argument should be flagged as comparing object identity.
package scensct.var.pos;
public class PosCase2_Var1 {
public static void main(String[] args) {
Integer[] a = {1, 2, 3};
Integer[] b = {1, 2, 3};
// Using a temporary variable to alias the array
Object obj1 = a;
Object obj2 = b;
boolean same = obj1.equals(obj2);
System.out.println(same);
}
}
```
### `PosCase2_Var2.java`
The helper API does not change the semantics of array `equals`; it is still an identity comparison.
```java
// Calling equals(Object) on an array with compatible array argument should be flagged as comparing object identity.
package scensct.var.pos;
import java.util.Objects;
public class PosCase2_Var2 {
public static void main(String[] args) {
String[] arr1 = {"x", "y"};
String[] arr2 = {"x", "y"};
// Using Objects.equals which internally calls equals on the first argument
boolean result = Objects.equals(arr1, arr2);
System.out.println(result);
}
}
```
## Cause analysis
The query appears to recognize only direct `array.equals(...)` or `array.hashCode()` calls on obviously array-typed expressions. Once the array is widened to `Object` or the call is wrapped by a library helper like `Objects.equals(...)`, the identity-based behavior is no longer modeled.
That is a real usability gap. Developers often pass arrays through generic APIs before comparing them, and the bug remains the same.
## References
None known.
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
Commencez par le checker Likely Bugs/Comparison/EqualsArray.ql et examinez les cas affectés PosCase1_Var2.java, PosCase2_Var1.java et PosCase2_Var2.java. Suivez la manière dont les références Object élargies et Objects.equals(...) sont modélisées. Le travail est terminé lorsque ces comparaisons d’identité sont détectées sans perdre la couverture existante des appels directs.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- java
- Domaine
- devtools, security
- Type d'issue
- Bug
- Difficulté
- 3/5
- Temps estimé
- 1-2 jours
- Activité
- Calme
- Clarté
- Plutôt claire
- Accessibilité débutants
- 48/100