mirror of
https://github.com/github/codeql.git
synced 2025-12-19 18:33:16 +01:00
92 lines
2.8 KiB
Plaintext
92 lines
2.8 KiB
Plaintext
/**
|
|
* Provides classes and predicates for reasoning about instances of
|
|
* `java.util.Map` and their methods.
|
|
*/
|
|
overlay[local?]
|
|
module;
|
|
|
|
import java
|
|
import Collections
|
|
|
|
/** A reference type that extends a parameterization of `java.util.Map`. */
|
|
class MapType extends RefType {
|
|
MapType() {
|
|
this.getSourceDeclaration().getASourceSupertype*().hasQualifiedName("java.util", "Map")
|
|
}
|
|
|
|
/** Gets the type of keys stored in this map. */
|
|
RefType getKeyType() {
|
|
exists(GenericInterface map | map.hasQualifiedName("java.util", "Map") |
|
|
indirectlyInstantiates(this, map, 0, result)
|
|
)
|
|
}
|
|
|
|
/** Gets the type of values stored in this map. */
|
|
RefType getValueType() {
|
|
exists(GenericInterface map | map.hasQualifiedName("java.util", "Map") |
|
|
indirectlyInstantiates(this, map, 1, result)
|
|
)
|
|
}
|
|
}
|
|
|
|
/** A method declared in a map type. */
|
|
class MapMethod extends Method {
|
|
MapMethod() { this.getDeclaringType() instanceof MapType }
|
|
|
|
/** Gets the type of keys of the map to which this method belongs. */
|
|
RefType getReceiverKeyType() { result = this.getDeclaringType().(MapType).getKeyType() }
|
|
|
|
/** Gets the type of values of the map to which this method belongs. */
|
|
RefType getReceiverValueType() { result = this.getDeclaringType().(MapType).getValueType() }
|
|
}
|
|
|
|
/** A method that mutates the map it belongs to. */
|
|
class MapMutator extends MapMethod {
|
|
MapMutator() {
|
|
pragma[only_bind_into](this).getName().regexpMatch("(put.*|remove|clear|replace.*)")
|
|
}
|
|
}
|
|
|
|
/** The `size` method of `java.util.Map`. */
|
|
class MapSizeMethod extends MapMethod {
|
|
MapSizeMethod() { this.hasName("size") and this.hasNoParameters() }
|
|
}
|
|
|
|
/** A method call that mutates a map. */
|
|
class MapMutation extends MethodCall {
|
|
MapMutation() { this.getMethod() instanceof MapMutator }
|
|
|
|
/** Holds if the result of this call is not immediately discarded. */
|
|
predicate resultIsChecked() { not this instanceof ValueDiscardingExpr }
|
|
}
|
|
|
|
/** A method that queries the contents of the map it belongs to without mutating it. */
|
|
class MapQueryMethod extends MapMethod {
|
|
MapQueryMethod() {
|
|
pragma[only_bind_into](this).getName() =
|
|
["get", "containsKey", "containsValue", "entrySet", "keySet", "values", "isEmpty", "size"]
|
|
}
|
|
}
|
|
|
|
/** A `new` expression that allocates a fresh, empty map. */
|
|
class FreshMap extends ClassInstanceExpr {
|
|
FreshMap() {
|
|
this.getConstructedType() instanceof MapType and
|
|
this.getNumArgument() = 0 and
|
|
not exists(this.getAnonymousClass())
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A call to `Map.put(key, value)`.
|
|
*/
|
|
class MapPutCall extends MethodCall {
|
|
MapPutCall() { this.getCallee().(MapMethod).hasName("put") }
|
|
|
|
/** Gets the key argument of this call. */
|
|
Expr getKey() { result = this.getArgument(0) }
|
|
|
|
/** Gets the value argument of this call. */
|
|
Expr getValue() { result = this.getArgument(1) }
|
|
}
|