Merge remote-tracking branch 'origin/main' into dbartol/threat-models-2

This commit is contained in:
Dave Bartolomeo
2023-10-26 14:05:40 -04:00
622 changed files with 14772 additions and 6166 deletions

View File

@@ -13,17 +13,17 @@ private import AutomodelEndpointTypes
private import AutomodelJavaUtil
from
Endpoint endpoint, SinkType sinkType, FrameworkModeMetadataExtractor meta, DollarAtString package,
DollarAtString type, DollarAtString subtypes, DollarAtString name, DollarAtString signature,
DollarAtString input, DollarAtString output, DollarAtString parameterName,
DollarAtString extensibleType
Endpoint endpoint, EndpointType endpointType, FrameworkModeMetadataExtractor meta,
DollarAtString package, DollarAtString type, DollarAtString subtypes, DollarAtString name,
DollarAtString signature, DollarAtString input, DollarAtString output,
DollarAtString parameterName, DollarAtString extensibleType
where
endpoint.getExtensibleType() = extensibleType and
meta.hasMetadata(endpoint, package, type, subtypes, name, signature, input, output, parameterName) and
// Extract positive examples of sinks belonging to the existing ATM query configurations.
CharacteristicsImpl::isKnownAs(endpoint, sinkType, _)
CharacteristicsImpl::isKnownAs(endpoint, endpointType, _)
select endpoint,
sinkType + "\nrelated locations: $@, $@." + "\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@.", //
endpointType + "\nrelated locations: $@, $@." + "\nmetadata: $@, $@, $@, $@, $@, $@, $@, $@, $@.", //
CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, MethodDoc()), "MethodDoc", //
CharacteristicsImpl::getRelatedLocationOrCandidate(endpoint, ClassDoc()), "ClassDoc", //
package, "package", //

View File

@@ -0,0 +1,183 @@
# Automodel Java Extraction Queries
This pack contains the automodel extraction queries for Java. Automodel uses extraction queries to extract the information it needs in order to create a prompt for a large language model. There's extraction queries for positive examples (things that are known to be, e.g., a sink), for negative examples (things that are known not to be, e.g., a sink), and for candidates (things where we should ask the large language model to classify).
## Extraction Queries in `java/ql/automodel/src`
Included in this pack are queries for both application mode and framework mode.
| Kind | Mode | Query File |
|------|------|------------|
| Candidates | Application Mode | [AutomodelApplicationModeExtractCandidates.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelApplicationModeExtractCandidates.ql) |
| Positive Examples | Application Mode | [AutomodelApplicationModeExtractPositiveExamples.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelApplicationModeExtractPositiveExamples.ql) |
| Negative Examples | Application Mode | [AutomodelApplicationModeExtractNegativeExamples.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelApplicationModeExtractNegativeExamples.ql) |
| Candidates | Framework Mode | [AutomodelFrameworkModeExtractCandidates.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelFrameworkModeExtractCandidates.ql) |
| Positive Examples | Framework Mode | [AutomodelFrameworkModeExtractPositiveExamples.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelFrameworkModeExtractPositiveExamples.ql) |
| Negative Examples | Framework Mode | [AutomodelFrameworkModeExtractNegativeExamples.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelFrameworkModeExtractNegativeExamples.ql) |
## Running the Queries
The extraction queries are part of a separate query pack, `codeql/java-automodel-queries`. Use this pack to run them. The queries are tagged appropriately, you can use the tags (example here: https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelApplicationModeExtractNegativeExamples.ql#L8) to construct query suites.
For example, a query suite selecting all example extraction queries (positive and negative) for application mode looks like this:
```
# File: automodel-application-mode-extraction-examples.qls
# ---
# Query suite for extracting examples for automodel
- description: Automodel application mode examples extraction.
- queries: .
from: codeql/java-automodel-queries
- include:
tags contain all:
- automodel
- extract
- application-mode
- examples
```
## Important Software Design Concepts and Goals
### Concept: `Endpoint`
Endpoints are source code locations of interest. All positive examples, negative examples, and all candidates are endpoints, but not all endpoints are examples or candidates. Each mode decides which endpoints are relevant. For instance, if the Java application mode wants to support candidates for sinks that are arguments passed to unknown method calls, then the Java application mode implementation needs to make sure that method arguments are endpoints. If you look at the `TApplicationModeEndpoint` implementation in [AutomodelApplicationModeCharacteristics.qll](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll), you can see that this is the case: the `TExplicitArgument` implements this behavior.
Whether or not an endpoint is a positive/negative example, or a candidate depends on the individual extraction queries.
### Concept: `EndpointCharacteristics`
In the file [AutomodelSharedCharacteristics.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelSharedCharacteristics.ql), you will find the definition of the QL class `EndpointCharacteristic`.
An endpoint characteristic is a QL class that "tags" all endpoints for which the characteristic's `appliesToEndpoint` predicate holds. The characteristic defines a `hasImplications` predicate that declares whether all the endpoints should be considered as sinks/sources/negatives, and with which confidence.
The positive, negative, and candidate extraction queries largely[^1] use characteristics to decide which endpoint to select. For instance, if a characteristic exists that applies to an endpoint, and the characteristic implies (cf. `hasImplications`) that the endpoint is a sink with a high confidence – then that endpoint will be selected as a positive example. See the use of `isKnownAs` in [AutomodelFrameworkModeExtractPositiveExamples.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelFrameworkModeExtractPositiveExamples.ql).
[^1]: Candidate extraction queries are an exception, they treat `UninterestingToModelCharacteristic` differently.
#### :warning: Warning
Do not try to "fix" shortcomings that could be fixed by a better prompt or better example selection by adding language- or mode-specific characteristics . Those "fixes" tend to be confusing downstream when questions like "why wasn't this location selected as a candidate?" becomes progressively harder and harder to answer. It's best to rely on characteristics in the code that is shared across all languages and modes (see [Shared Code](#shared-code)).
## Shared Code
A significant part of the behavior of extraction queries is implemented in shared modules. When we add support for new languages, we expect to move the shared code to a separate QL pack. In the mean time, shared code modules must not import any java libraries.
## Packaging
Automodel extraction queries come as a dedicated package. See [qlpack.yml](https://github.com/github/codeql/blob/main/java/ql/automodel/src/qlpack.yml). The [publish.sh](https://github.com/github/codeql/blob/main/java/ql/automodel/publish.sh) script is responsible for publishing a new version to the [package registry](https://github.com/orgs/codeql/packages/container/package/java-automodel-queries).
### Backwards Compatibility
We try to keep changes to extraction queries backwards-compatible whenever feasible. There's several reasons:
- That automodel can always decide which version of the package to run is a flawed assumption. We don't have direct control over the version of the extraction queries running on the user's local machine.
- An automodel deployment will sometimes require the extraction queries to be published. If the new version of the extraction queries works with the old version of automodel, then it is much easier to roll back deployments of automodel.
## Candidate Examples
This section contains a few examples of the kinds of candidates that our queries might select, and why.
:warning: For clarity, this section presents "candidates" that are **actual** sinks. Therefore, the candidates presented here would actually be selected as positive examples in practice - rather than as candidates.
### Framework Mode Candidates
Framework mode is special because in framework mode, we extract candidates (as well as examples) from the implementation of a framework or library while the resulting models are applied in code bases that are _using_ the framework or library.
In framework mode, endpoints currently can have a number of shapes (see: `newtype TFrameworkModeEndpoint` in [AutomodelApplicationModeExtractCandidates.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelFrameworkModeCharacteristics.qll)). Depending on what kind of endpoint it is, the candidate is a candidate for one or several extensible types (eg., `sinkModel`, `sourceModel`).
#### Framework Mode Sink Candidates
Sink candidates in framework mode are modelled as formal parameters of functions defined within the framework. We use these to represent the corresponding inputs of function calls in a client codebase, which would be passed into those parameters.
For example, customer code could call the `Files.copy` method:
```java
// customer code using a library
...
Files.copy(userInputPath, outStream);
...
```
In order for `userInputPath` to be modeled as a sink, the corresponding parameter must be selected as a candidate. In the following example, assuming they're not modeled yet, the parameters `source` and `out` would be candidates:
```java
// Files.java
// library code that's analyzed in framework mode
public class Files {
public static void copy(Path source, OutputStream out) throws IOException {
// ...
}
}
```
#### Framework Mode Source Candidates
Source candidates are a bit more varied than sink candidates:
##### Parameters as Source Candidates
A parameter could be a source, e.g. when a framework passes user-controlled data to a handler defined in customer code.
```java
// customer code using a library:
import java.net.http.WebSocket;
final class MyListener extends WebSocket.Listener {
@override
public CompletionStage<?> onText(WebSocket ws, CharSequence cs, boolean last) {
... process data that was received from websocket
}
}
```
In this case, data passed to the program via a web socket connection is a source of remote data. Therefore, when we look at the implementation of `WebSocket.Listener` in framework mode, we need to produce a candidate for each parameter:
```java
// WebSocket.java
// library code that's analyzed in framework mode
interface Listener {
...
default CompletionStage<?> onText(WebSocket webSocket CharSequence data, boolean last) {
// <omitting default implementation>
}
...
}
```
For framework mode, all parameters of the `onText` method should be candidates. If the candidates result in a model, the parameters of classes implementing this interface will be recognized as sources of remote data.
:warning: a consequence of this is that we can have endpoints in framework mode that are both sink candidates, as well as source candidates.
##### Return Values as Source Candidates
The other kind of source candidate we model is the return value of a method. For example:
```java
public class Socket {
...
public InputStream getInputStream() throws IOException {
...
}
...
}
```
This method returns a source of remote data that should be modeled as a sink. We therefore want to select the _method_ as a candidate.
### Application Mode Candidates
In application mode, we extract candidates from an application that is using various libraries.
#### Application Mode Source Candidates
##### Overridden Parameters as Source Candidates
In application mode, a parameter of a method that is overriding another method is taken as a source parameter to account for cases like the `WebSocket.Listener` example above where an application is implementing a "handler" that receives remote data.
##### Return Values as Source Candidates
Just like in framework mode, application mode also has to consider the return value of a call as a source candidate. The difference is that in application mode, we extract from the application sources, not the library sources. Therefore, we use the invocation expression as a candidate (unlike in framework mode, where we use the method definition).
#### Application Mode Sink Candidates
In application mode, arguments to calls are sink candidates.

View File

@@ -1,6 +1,6 @@
import java
from MethodAccess ma
from MethodCall ma
// Generally Kotlin calls will always use an explicit qualifier, except for calls
// to the synthetic instance initializer <obinit>, which use an implicit `this`.
where

View File

@@ -44,7 +44,7 @@ predicate shouldBeDeadEnd(ControlFlowNode n) {
or
n instanceof WildcardTypeAccess // TODO
or
n instanceof MethodAccess // TODO
n instanceof MethodCall // TODO
or
n instanceof Method
or

View File

@@ -37,11 +37,11 @@ predicate gapInChildren(Element e, int i) {
// For statements may or may not declare a new variable (child 0), or
// have a condition (child 1).
not (e instanceof ForStmt and i = [0, 1]) and
// TODO: Clarify situation with Kotlin and MethodAccess.
// TODO: Clarify situation with Kotlin and MethodCall.
// -1 can be skipped (type arguments from -2 down, no qualifier at -1,
// then arguments from 0).
// Can we also skip arguments, e.g. due to defaults for parameters?
not (e instanceof MethodAccess and e.getFile().isKotlinSourceFile()) and
not (e instanceof MethodCall and e.getFile().isKotlinSourceFile()) and
// Kotlin-extracted annotations can have missing children where a default
// value should be, because kotlinc doesn't load annotation defaults and we
// want to leave a space for another extractor to fill in the default if it

View File

@@ -8,7 +8,7 @@
import java
from MethodAccess call, Method method
from MethodCall call, Method method
where
call.getMethod() = method and
method.hasName("methodName") and

View File

@@ -10,7 +10,7 @@ import java
from Method m, Method n
where
exists(MethodAccess ma | ma.getCaller() = m and ma.getCallee() = n) and
exists(MethodAccess ma | ma.getCaller() = n and ma.getCallee() = m) and
exists(MethodCall ma | ma.getCaller() = m and ma.getCallee() = n) and
exists(MethodCall ma | ma.getCaller() = n and ma.getCallee() = m) and
m != n
select m, n

View File

@@ -11,7 +11,7 @@
import java
from MethodAccess call, Method add
from MethodCall call, Method add
where
call.getMethod().overrides*(add) and
add.hasName("add") and

View File

@@ -10,10 +10,10 @@ User.java:
# 3| 0: [TypeAccess] Ann2
# 3| 5: [BlockStmt] { ... }
# 4| 0: [ExprStmt] <Expr>;
# 4| 0: [MethodAccess] x(...)
# 4| 0: [MethodCall] x(...)
# 4| -1: [VarAccess] a1
# 4| 1: [ExprStmt] <Expr>;
# 4| 0: [MethodAccess] z(...)
# 4| 0: [MethodCall] z(...)
# 4| -1: [VarAccess] a2
# 4| 2: [ExprStmt] <Expr>;
# 4| 0: [ClassInstanceExpr] new Annotated(...)
@@ -49,7 +49,7 @@ ktUser.kt:
# 8| 3: [ExprStmt] <Expr>;
# 8| 0: [ImplicitCoercionToUnitExpr] <implicit coercion to unit>
# 8| 0: [TypeAccess] Unit
# 8| 1: [MethodAccess] isJavaLetter(...)
# 8| 1: [MethodCall] isJavaLetter(...)
# 8| -1: [TypeAccess] Character
# 8| 0: [CharacterLiteral] a
test.kt:

View File

@@ -5,7 +5,7 @@ private import semmle.code.java.dataflow.ExternalFlow
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node n) {
n.asExpr().(MethodAccess).getCallee().getName() = "source"
n.asExpr().(MethodCall).getCallee().getName() = "source"
or
sourceNode(n, "kotlinMadFlowTest")
}

View File

@@ -1,4 +1,4 @@
import java
from MethodAccess ma
from MethodCall ma
select ma, ma.getCallee()

View File

@@ -31,11 +31,11 @@ app/src/main/kotlin/testProject/App.kt:
# 7| 0: [IntegerLiteral] 3
# 7| 1: [VarAccess] seen1
# 7| 1: [ExprStmt] <Expr>;
# 7| 0: [MethodAccess] throwMissingFieldException(...)
# 7| 0: [MethodCall] throwMissingFieldException(...)
# 7| -1: [TypeAccess] PluginExceptionsKt
# 7| 0: [VarAccess] seen1
# 7| 1: [IntegerLiteral] 3
# 7| 2: [MethodAccess] getDescriptor(...)
# 7| 2: [MethodCall] getDescriptor(...)
# 7| -1: [VarAccess] INSTANCE
# 7| 1: [SuperConstructorInvocationStmt] super(...)
# 7| 2: [ExprStmt] <Expr>;
@@ -118,7 +118,7 @@ app/src/main/kotlin/testProject/App.kt:
# 0| 1: [VarAccess] p0.language
# 0| -1: [VarAccess] p0
# 0| 2: [ReturnStmt] return ...
# 0| 0: [MethodAccess] copy(...)
# 0| 0: [MethodCall] copy(...)
# 0| -1: [VarAccess] p0
# 0| 0: [VarAccess] p1
# 0| 1: [VarAccess] p2
@@ -176,7 +176,7 @@ app/src/main/kotlin/testProject/App.kt:
# 0| 5: [BlockStmt] { ... }
# 0| 0: [LocalVariableDeclStmt] var ...;
# 0| 1: [LocalVariableDeclExpr] result
# 0| 0: [MethodAccess] hashCode(...)
# 0| 0: [MethodCall] hashCode(...)
# 0| -1: [VarAccess] this.name
# 0| -1: [ThisAccess] this
# 0| 1: [ExprStmt] <Expr>;
@@ -186,7 +186,7 @@ app/src/main/kotlin/testProject/App.kt:
# 0| 0: [MulExpr] ... * ...
# 0| 0: [VarAccess] result
# 0| 1: [IntegerLiteral] 31
# 0| 1: [MethodAccess] hashCode(...)
# 0| 1: [MethodCall] hashCode(...)
# 0| -1: [VarAccess] this.language
# 0| -1: [ThisAccess] this
# 0| 2: [ReturnStmt] return ...
@@ -226,18 +226,18 @@ app/src/main/kotlin/testProject/App.kt:
# 0| 0: [TypeAccess] SerialDescriptor
# 7| 5: [BlockStmt] { ... }
# 7| 0: [ExprStmt] <Expr>;
# 7| 0: [MethodAccess] encodeStringElement(...)
# 7| 0: [MethodCall] encodeStringElement(...)
# 7| -1: [VarAccess] output
# 7| 0: [VarAccess] serialDesc
# 7| 1: [IntegerLiteral] 0
# 7| 2: [MethodAccess] getName(...)
# 7| 2: [MethodCall] getName(...)
# 7| -1: [VarAccess] self
# 7| 1: [ExprStmt] <Expr>;
# 7| 0: [MethodAccess] encodeIntElement(...)
# 7| 0: [MethodCall] encodeIntElement(...)
# 7| -1: [VarAccess] output
# 7| 0: [VarAccess] serialDesc
# 7| 1: [IntegerLiteral] 1
# 7| 2: [MethodAccess] getLanguage(...)
# 7| 2: [MethodCall] getLanguage(...)
# 7| -1: [VarAccess] self
# 7| 10: [Class] $serializer
#-----| -3: (Annotations)
@@ -274,7 +274,7 @@ app/src/main/kotlin/testProject/App.kt:
# 7| 5: [BlockStmt] { ... }
# 7| 0: [LocalVariableDeclStmt] var ...;
# 7| 1: [LocalVariableDeclExpr] tmp0_desc
# 7| 0: [MethodAccess] getDescriptor(...)
# 7| 0: [MethodCall] getDescriptor(...)
# 7| -1: [ThisAccess] this
# 7| 1: [LocalVariableDeclStmt] var ...;
# 7| 1: [LocalVariableDeclExpr] tmp1_flag
@@ -293,20 +293,20 @@ app/src/main/kotlin/testProject/App.kt:
# 7| 0: [IntegerLiteral] 0
# 7| 6: [LocalVariableDeclStmt] var ...;
# 7| 1: [LocalVariableDeclExpr] tmp6_input
# 7| 0: [MethodAccess] beginStructure(...)
# 7| 0: [MethodCall] beginStructure(...)
# 7| -1: [VarAccess] decoder
# 7| 0: [VarAccess] tmp0_desc
# 7| 7: [ExprStmt] <Expr>;
# 7| 0: [WhenExpr] when ...
# 7| 0: [WhenBranch] ... -> ...
# 7| 0: [MethodAccess] decodeSequentially(...)
# 7| 0: [MethodCall] decodeSequentially(...)
# 7| -1: [VarAccess] tmp6_input
# 7| 1: [BlockStmt] { ... }
# 7| 0: [BlockStmt] { ... }
# 7| 0: [ExprStmt] <Expr>;
# 7| 0: [AssignExpr] ...=...
# 7| 0: [VarAccess] tmp4_local0
# 7| 1: [MethodAccess] decodeStringElement(...)
# 7| 1: [MethodCall] decodeStringElement(...)
# 7| -1: [VarAccess] tmp6_input
# 7| 0: [VarAccess] tmp0_desc
# 7| 1: [IntegerLiteral] 0
@@ -320,7 +320,7 @@ app/src/main/kotlin/testProject/App.kt:
# 7| 0: [ExprStmt] <Expr>;
# 7| 0: [AssignExpr] ...=...
# 7| 0: [VarAccess] tmp5_local1
# 7| 1: [MethodAccess] decodeIntElement(...)
# 7| 1: [MethodCall] decodeIntElement(...)
# 7| -1: [VarAccess] tmp6_input
# 7| 0: [VarAccess] tmp0_desc
# 7| 1: [IntegerLiteral] 1
@@ -338,7 +338,7 @@ app/src/main/kotlin/testProject/App.kt:
# 7| 0: [ExprStmt] <Expr>;
# 7| 0: [AssignExpr] ...=...
# 7| 0: [VarAccess] tmp2_index
# 7| 1: [MethodAccess] decodeElementIndex(...)
# 7| 1: [MethodCall] decodeElementIndex(...)
# 7| -1: [VarAccess] tmp6_input
# 7| 0: [VarAccess] tmp0_desc
# 7| 1: [ExprStmt] <Expr>;
@@ -359,7 +359,7 @@ app/src/main/kotlin/testProject/App.kt:
# 7| 0: [ExprStmt] <Expr>;
# 7| 0: [AssignExpr] ...=...
# 7| 0: [VarAccess] tmp4_local0
# 7| 1: [MethodAccess] decodeStringElement(...)
# 7| 1: [MethodCall] decodeStringElement(...)
# 7| -1: [VarAccess] tmp6_input
# 7| 0: [VarAccess] tmp0_desc
# 7| 1: [IntegerLiteral] 0
@@ -377,7 +377,7 @@ app/src/main/kotlin/testProject/App.kt:
# 7| 0: [ExprStmt] <Expr>;
# 7| 0: [AssignExpr] ...=...
# 7| 0: [VarAccess] tmp5_local1
# 7| 1: [MethodAccess] decodeIntElement(...)
# 7| 1: [MethodCall] decodeIntElement(...)
# 7| -1: [VarAccess] tmp6_input
# 7| 0: [VarAccess] tmp0_desc
# 7| 1: [IntegerLiteral] 1
@@ -394,7 +394,7 @@ app/src/main/kotlin/testProject/App.kt:
# 7| -3: [TypeAccess] UnknownFieldException
# 7| 0: [VarAccess] tmp2_index
# 7| 8: [ExprStmt] <Expr>;
# 7| 0: [MethodAccess] endStructure(...)
# 7| 0: [MethodCall] endStructure(...)
# 7| -1: [VarAccess] tmp6_input
# 7| 0: [VarAccess] tmp0_desc
# 7| 9: [ReturnStmt] return ...
@@ -426,21 +426,21 @@ app/src/main/kotlin/testProject/App.kt:
# 7| 5: [BlockStmt] { ... }
# 7| 0: [LocalVariableDeclStmt] var ...;
# 7| 1: [LocalVariableDeclExpr] tmp0_desc
# 7| 0: [MethodAccess] getDescriptor(...)
# 7| 0: [MethodCall] getDescriptor(...)
# 7| -1: [ThisAccess] this
# 7| 1: [LocalVariableDeclStmt] var ...;
# 7| 1: [LocalVariableDeclExpr] tmp1_output
# 7| 0: [MethodAccess] beginStructure(...)
# 7| 0: [MethodCall] beginStructure(...)
# 7| -1: [VarAccess] encoder
# 7| 0: [VarAccess] tmp0_desc
# 7| 2: [ExprStmt] <Expr>;
# 7| 0: [MethodAccess] write$Self(...)
# 7| 0: [MethodCall] write$Self(...)
# 7| -1: [TypeAccess] Project
# 7| 0: [VarAccess] value
# 7| 1: [VarAccess] tmp1_output
# 7| 2: [VarAccess] tmp0_desc
# 7| 3: [ExprStmt] <Expr>;
# 7| 0: [MethodAccess] endStructure(...)
# 7| 0: [MethodCall] endStructure(...)
# 7| -1: [VarAccess] tmp1_output
# 7| 0: [VarAccess] tmp0_desc
# 7| 6: [Constructor] $serializer
@@ -456,12 +456,12 @@ app/src/main/kotlin/testProject/App.kt:
# 7| 0: [TypeAccess] $serializer
# 7| 2: [IntegerLiteral] 2
# 7| 1: [ExprStmt] <Expr>;
# 7| 0: [MethodAccess] addElement(...)
# 7| 0: [MethodCall] addElement(...)
# 7| -1: [VarAccess] tmp0_serialDesc
# 7| 0: [StringLiteral] "name"
# 7| 1: [BooleanLiteral] false
# 7| 2: [ExprStmt] <Expr>;
# 7| 0: [MethodAccess] addElement(...)
# 7| 0: [MethodCall] addElement(...)
# 7| -1: [VarAccess] tmp0_serialDesc
# 7| 0: [StringLiteral] "language"
# 7| 1: [BooleanLiteral] false
@@ -477,7 +477,7 @@ app/src/main/kotlin/testProject/App.kt:
# 7| 0: [WildcardTypeAccess] ? ...
# 7| 5: [BlockStmt] { ... }
# 7| 0: [ReturnStmt] return ...
# 7| 0: [MethodAccess] typeParametersSerializers(...)
# 7| 0: [MethodCall] typeParametersSerializers(...)
# 7| -1: [SuperAccess] GeneratedSerializer.super
# 7| 0: [TypeAccess] GeneratedSerializer
# 7| 11: [Class] Companion
@@ -564,11 +564,11 @@ app/src/main/kotlin/testProject/App.kt:
# 14| 0: [IntegerLiteral] 0
# 14| 1: [VarAccess] seen1
# 14| 1: [ExprStmt] <Expr>;
# 14| 0: [MethodAccess] throwMissingFieldException(...)
# 14| 0: [MethodCall] throwMissingFieldException(...)
# 14| -1: [TypeAccess] PluginExceptionsKt
# 14| 0: [VarAccess] seen1
# 14| 1: [IntegerLiteral] 0
# 14| 2: [MethodAccess] getDescriptor(...)
# 14| 2: [MethodCall] getDescriptor(...)
# 14| -1: [VarAccess] INSTANCE
# 14| 1: [SuperConstructorInvocationStmt] super(...)
# 14| 2: [ExprStmt] <Expr>;
@@ -616,7 +616,7 @@ app/src/main/kotlin/testProject/App.kt:
# 14| 0: [WhenBranch] ... -> ...
# 14| 0: [WhenExpr] when ...
# 14| 0: [WhenBranch] ... -> ...
# 14| 0: [MethodAccess] shouldEncodeElementDefault(...)
# 14| 0: [MethodCall] shouldEncodeElementDefault(...)
# 14| -1: [VarAccess] output
# 14| 0: [VarAccess] serialDesc
# 14| 1: [IntegerLiteral] 0
@@ -626,15 +626,15 @@ app/src/main/kotlin/testProject/App.kt:
# 14| 0: [BooleanLiteral] true
# 14| 1: [ExprStmt] <Expr>;
# 14| 0: [ValueNEExpr] ... (value not-equals) ...
# 14| 0: [MethodAccess] getId(...)
# 14| 0: [MethodCall] getId(...)
# 14| -1: [VarAccess] self
# 16| 1: [StringLiteral] "X"
# 14| 1: [ExprStmt] <Expr>;
# 14| 0: [MethodAccess] encodeStringElement(...)
# 14| 0: [MethodCall] encodeStringElement(...)
# 14| -1: [VarAccess] output
# 14| 0: [VarAccess] serialDesc
# 14| 1: [IntegerLiteral] 0
# 14| 2: [MethodAccess] getId(...)
# 14| 2: [MethodCall] getId(...)
# 14| -1: [VarAccess] self
# 14| 3: [Class] $serializer
#-----| -3: (Annotations)
@@ -671,7 +671,7 @@ app/src/main/kotlin/testProject/App.kt:
# 14| 5: [BlockStmt] { ... }
# 14| 0: [LocalVariableDeclStmt] var ...;
# 14| 1: [LocalVariableDeclExpr] tmp0_desc
# 14| 0: [MethodAccess] getDescriptor(...)
# 14| 0: [MethodCall] getDescriptor(...)
# 14| -1: [ThisAccess] this
# 14| 1: [LocalVariableDeclStmt] var ...;
# 14| 1: [LocalVariableDeclExpr] tmp1_flag
@@ -687,20 +687,20 @@ app/src/main/kotlin/testProject/App.kt:
# 14| 0: [NullLiteral] null
# 14| 5: [LocalVariableDeclStmt] var ...;
# 14| 1: [LocalVariableDeclExpr] tmp5_input
# 14| 0: [MethodAccess] beginStructure(...)
# 14| 0: [MethodCall] beginStructure(...)
# 14| -1: [VarAccess] decoder
# 14| 0: [VarAccess] tmp0_desc
# 14| 6: [ExprStmt] <Expr>;
# 14| 0: [WhenExpr] when ...
# 14| 0: [WhenBranch] ... -> ...
# 14| 0: [MethodAccess] decodeSequentially(...)
# 14| 0: [MethodCall] decodeSequentially(...)
# 14| -1: [VarAccess] tmp5_input
# 14| 1: [BlockStmt] { ... }
# 14| 0: [BlockStmt] { ... }
# 14| 0: [ExprStmt] <Expr>;
# 14| 0: [AssignExpr] ...=...
# 14| 0: [VarAccess] tmp4_local0
# 14| 1: [MethodAccess] decodeStringElement(...)
# 14| 1: [MethodCall] decodeStringElement(...)
# 14| -1: [VarAccess] tmp5_input
# 14| 0: [VarAccess] tmp0_desc
# 14| 1: [IntegerLiteral] 0
@@ -718,7 +718,7 @@ app/src/main/kotlin/testProject/App.kt:
# 14| 0: [ExprStmt] <Expr>;
# 14| 0: [AssignExpr] ...=...
# 14| 0: [VarAccess] tmp2_index
# 14| 1: [MethodAccess] decodeElementIndex(...)
# 14| 1: [MethodCall] decodeElementIndex(...)
# 14| -1: [VarAccess] tmp5_input
# 14| 0: [VarAccess] tmp0_desc
# 14| 1: [ExprStmt] <Expr>;
@@ -739,7 +739,7 @@ app/src/main/kotlin/testProject/App.kt:
# 14| 0: [ExprStmt] <Expr>;
# 14| 0: [AssignExpr] ...=...
# 14| 0: [VarAccess] tmp4_local0
# 14| 1: [MethodAccess] decodeStringElement(...)
# 14| 1: [MethodCall] decodeStringElement(...)
# 14| -1: [VarAccess] tmp5_input
# 14| 0: [VarAccess] tmp0_desc
# 14| 1: [IntegerLiteral] 0
@@ -756,7 +756,7 @@ app/src/main/kotlin/testProject/App.kt:
# 14| -3: [TypeAccess] UnknownFieldException
# 14| 0: [VarAccess] tmp2_index
# 14| 7: [ExprStmt] <Expr>;
# 14| 0: [MethodAccess] endStructure(...)
# 14| 0: [MethodCall] endStructure(...)
# 14| -1: [VarAccess] tmp5_input
# 14| 0: [VarAccess] tmp0_desc
# 14| 8: [ReturnStmt] return ...
@@ -787,21 +787,21 @@ app/src/main/kotlin/testProject/App.kt:
# 14| 5: [BlockStmt] { ... }
# 14| 0: [LocalVariableDeclStmt] var ...;
# 14| 1: [LocalVariableDeclExpr] tmp0_desc
# 14| 0: [MethodAccess] getDescriptor(...)
# 14| 0: [MethodCall] getDescriptor(...)
# 14| -1: [ThisAccess] this
# 14| 1: [LocalVariableDeclStmt] var ...;
# 14| 1: [LocalVariableDeclExpr] tmp1_output
# 14| 0: [MethodAccess] beginStructure(...)
# 14| 0: [MethodCall] beginStructure(...)
# 14| -1: [VarAccess] encoder
# 14| 0: [VarAccess] tmp0_desc
# 14| 2: [ExprStmt] <Expr>;
# 14| 0: [MethodAccess] write$Self(...)
# 14| 0: [MethodCall] write$Self(...)
# 14| -1: [TypeAccess] X
# 14| 0: [VarAccess] value
# 14| 1: [VarAccess] tmp1_output
# 14| 2: [VarAccess] tmp0_desc
# 14| 3: [ExprStmt] <Expr>;
# 14| 0: [MethodAccess] endStructure(...)
# 14| 0: [MethodCall] endStructure(...)
# 14| -1: [VarAccess] tmp1_output
# 14| 0: [VarAccess] tmp0_desc
# 14| 6: [Constructor] $serializer
@@ -817,7 +817,7 @@ app/src/main/kotlin/testProject/App.kt:
# 14| 0: [TypeAccess] $serializer
# 14| 2: [IntegerLiteral] 1
# 14| 1: [ExprStmt] <Expr>;
# 14| 0: [MethodAccess] addElement(...)
# 14| 0: [MethodCall] addElement(...)
# 14| -1: [VarAccess] tmp0_serialDesc
# 14| 0: [StringLiteral] "id"
# 14| 1: [BooleanLiteral] true
@@ -833,7 +833,7 @@ app/src/main/kotlin/testProject/App.kt:
# 14| 0: [WildcardTypeAccess] ? ...
# 14| 5: [BlockStmt] { ... }
# 14| 0: [ReturnStmt] return ...
# 14| 0: [MethodAccess] typeParametersSerializers(...)
# 14| 0: [MethodCall] typeParametersSerializers(...)
# 14| -1: [SuperAccess] GeneratedSerializer.super
# 14| 0: [TypeAccess] GeneratedSerializer
# 14| 4: [Class] Companion

View File

@@ -30,9 +30,7 @@ query predicate nestedTypes(NestedType nt, RefType parent) {
parent = nt.getEnclosingType()
}
query predicate javaKotlinCalleeAgreement(
MethodAccess javaMa, MethodAccess kotlinMa, Callable callee
) {
query predicate javaKotlinCalleeAgreement(MethodCall javaMa, MethodCall kotlinMa, Callable callee) {
javaMa.getCallee() = callee and
kotlinMa.getCallee() = callee and
javaMa.getFile().getExtension() = "java" and

View File

@@ -39,7 +39,7 @@ c.kt:
# 0| 0: [TypeAccess] ProcessBuilder
# 0| 5: [BlockStmt] { ... }
# 0| 0: [ReturnStmt] return ...
# 0| 0: [MethodAccess] start(...)
# 0| 0: [MethodCall] start(...)
# 0| -1: [VarAccess] param
# 1| 2: [Constructor] C
# 1| 5: [BlockStmt] { ... }
@@ -62,7 +62,7 @@ e.kt:
# 0| 3: [TypeAccess] boolean
# 0| 5: [BlockStmt] { ... }
# 0| 0: [ReturnStmt] return ...
# 0| 0: [MethodAccess] add(...)
# 0| 0: [MethodCall] add(...)
# 0| -1: [ClassInstanceExpr] new ArrayList<Object>(...)
# 0| -3: [TypeAccess] ArrayList<Object>
# 0| 0: [IntegerLiteral] 1
@@ -71,7 +71,7 @@ e.kt:
# 0| 3: [TypeAccess] Object
# 0| 5: [BlockStmt] { ... }
# 0| 0: [ReturnStmt] return ...
# 0| 0: [MethodAccess] put(...)
# 0| 0: [MethodCall] put(...)
# 0| -1: [ClassInstanceExpr] new LinkedHashMap<Object,Object>(...)
# 0| -3: [TypeAccess] LinkedHashMap<Object,Object>
# 0| 0: [IntegerLiteral] 1

View File

@@ -1,4 +1,4 @@
import java
from MethodAccess ma
from MethodCall ma
select ma, ma.getCallee().toString(), ma.getCallee().getAParamType().toString()

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added up to date models related to Spring Framework 6's `org.springframework.http.ResponseEntity`.

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Java classes `MethodAccess`, `LValue` and `RValue` were renamed to `MethodCall`, `VarWrite` and `VarRead` respectively, along with related predicates and class names. The old names remain usable for the time being but are deprecated and should be replaced.
* New class `NewClassExpr` was added to represent specifically an explicit `new ClassName(...)` invocation, in contrast to `ClassInstanceExpr` which also includes expressions that implicitly instantiate classes, such as defining a lambda or taking a method reference.

View File

@@ -15,7 +15,7 @@ import IDEContextual
* the location may be slightly inaccurate and include such whitespace,
* but it should suffice for the purpose of avoiding overlapping definitions.
*/
private class LocationOverridingMethodAccess extends MethodAccess {
private class LocationOverridingMethodCall extends MethodCall {
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
exists(MemberRefExpr e | e.getReferencedCallable() = this.getMethod() |
exists(int elRef, int ecRef | e.hasLocationInfo(path, _, _, elRef, ecRef) |
@@ -152,7 +152,7 @@ private class LocationOverridingImportStaticTypeMember extends ImportStaticTypeM
}
private Element definition(Element e, string kind) {
e.(MethodAccess).getMethod().getSourceDeclaration() = result and
e.(MethodCall).getMethod().getSourceDeclaration() = result and
kind = "M" and
not result instanceof InitializerMethod
or

View File

@@ -64,10 +64,16 @@ extensions:
- ["org.springframework.http", "RequestEntity", True, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(MultiValueMap,HttpStatus)", "", "Argument[0].MapKey", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(MultiValueMap,HttpStatus)", "", "Argument[0].MapValue.Element", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(MultiValueMap,HttpStatusCode)", "", "Argument[0].MapKey", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(MultiValueMap,HttpStatusCode)", "", "Argument[0].MapValue.Element", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,HttpStatus)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,HttpStatusCode)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatus)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatus)", "", "Argument[1].MapKey", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatus)", "", "Argument[1].MapValue.Element", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatusCode)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatusCode)", "", "Argument[1].MapKey", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatusCode)", "", "Argument[1].MapValue.Element", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,int)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,int)", "", "Argument[1].MapKey", "Argument[this]", "taint", "manual"]
- ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,int)", "", "Argument[1].MapValue.Element", "Argument[this]", "taint", "manual"]

View File

@@ -8,6 +8,7 @@ upgrades: upgrades
dependencies:
codeql/dataflow: ${workspace}
codeql/mad: ${workspace}
codeql/rangeanalysis: ${workspace}
codeql/regex: ${workspace}
codeql/threat-models: ${workspace}
codeql/tutorial: ${workspace}

View File

@@ -82,7 +82,7 @@ class CollectionMutator extends CollectionMethod {
}
/** A method call that mutates a collection. */
class CollectionMutation extends MethodAccess {
class CollectionMutation extends MethodCall {
CollectionMutation() { this.getMethod() instanceof CollectionMutator }
/** Holds if the result of this call is not immediately discarded. */

View File

@@ -43,7 +43,7 @@
*
* An important goal of the CFG is to get the order of side-effects correct.
* Most expressions can have side-effects and must therefore be modeled in the
* CFG in AST post-order. For example, a `MethodAccess` evaluates its arguments
* CFG in AST post-order. For example, a `MethodCall` evaluates its arguments
* before the call. Most statements don't have side-effects, but merely affect
* the control-flow and some could therefore be excluded from the CFG. However,
* as a design choice, all statements are included in the CFG and generally
@@ -190,7 +190,7 @@ private module ControlFlowGraphImpl {
/**
* Bind `t` to an unchecked exception that may occur in a precondition check.
*/
private predicate uncheckedExceptionFromMethod(MethodAccess ma, ThrowableType t) {
private predicate uncheckedExceptionFromMethod(MethodCall ma, ThrowableType t) {
conditionCheckArgument(ma, _, _) and
(t instanceof TypeError or t instanceof TypeRuntimeException)
}
@@ -349,8 +349,8 @@ private module ControlFlowGraphImpl {
forall(Parameter p | p = this.getAParameter() | exists(p.getAnAccess()))
}
/** Gets a `MethodAccess` that calls this method. */
MethodAccess getAnAccess() { result.getMethod().getAPossibleImplementation() = this }
/** Gets a `MethodCall` that calls this method. */
MethodCall getAnAccess() { result.getMethod().getAPossibleImplementation() = this }
}
/** Holds if a call to `m` indicates that `m` is expected to return. */
@@ -390,9 +390,9 @@ private module ControlFlowGraphImpl {
}
/**
* Gets a `MethodAccess` that always throws an exception or calls `exit`.
* Gets a `MethodCall` that always throws an exception or calls `exit`.
*/
private MethodAccess nonReturningMethodAccess() {
private MethodCall nonReturningMethodCall() {
result.getMethod().getSourceDeclaration() = nonReturningMethod() or
result = likelyNonReturningMethod().getAnAccess()
}
@@ -422,7 +422,7 @@ private module ControlFlowGraphImpl {
* Gets an expression that always throws an exception or calls `exit`.
*/
private Expr nonReturningExpr() {
result = nonReturningMethodAccess()
result = nonReturningMethodCall()
or
result.(StmtExpr).getStmt() = nonReturningStmt()
or
@@ -473,7 +473,7 @@ private module ControlFlowGraphImpl {
or
this instanceof ClassExpr
or
this instanceof RValue
this instanceof VarRead
or
this instanceof Call // includes both expressions and statements
or
@@ -554,7 +554,7 @@ private module ControlFlowGraphImpl {
or
index = 0 and result = this.(LocalVariableDeclExpr).getInit()
or
index = 0 and result = this.(RValue).getQualifier() and not result instanceof TypeAccess
index = 0 and result = this.(VarRead).getQualifier() and not result instanceof TypeAccess
or
exists(Call e | e = this |
index = -1 and result = e.getQualifier() and not result instanceof TypeAccess
@@ -588,7 +588,7 @@ private module ControlFlowGraphImpl {
not this instanceof BooleanLiteral and
not this instanceof ReturnStmt and
not this instanceof ThrowStmt and
not this = nonReturningMethodAccess()
not this = nonReturningMethodCall()
}
}

View File

@@ -530,6 +530,9 @@ class Literal extends Expr, @literal {
* Gets a string representation of this literal as it appeared
* in the source code.
*
* For Kotlin the result might not match the exact representation
* used in the source code.
*
* **Important:** Unless a query explicitly wants to check how
* a literal was written in the source code, the predicate
* `getValue()` (or value predicates of subclasses) should be
@@ -1251,6 +1254,14 @@ class ClassInstanceExpr extends Expr, ConstructorCall, @classinstancexpr {
override string getAPrimaryQlClass() { result = "ClassInstanceExpr" }
}
/**
* An explicit `new TypeName(...)` expression.
*
* Note this does not include implicit instance creation such as lambda expressions
* or `instanceVar::methodName` references. To include those too, use `ClassInstanceExpr`.
*/
class NewClassExpr extends @newexpr, ClassInstanceExpr { }
/** A functional expression is either a lambda expression or a member reference expression. */
abstract class FunctionalExpr extends ClassInstanceExpr {
/** Gets the implicit method corresponding to this functional expression. */
@@ -1372,7 +1383,7 @@ class MemberRefExpr extends FunctionalExpr, @memberref {
*/
RefType getReceiverType() {
exists(Expr resultExpr | resultExpr = this.getResultExpr() |
result = resultExpr.(MethodAccess).getReceiverType() or
result = resultExpr.(MethodCall).getReceiverType() or
result = resultExpr.(ClassInstanceExpr).getConstructedType() or
result = resultExpr.(ArrayCreationExpr).getType()
)
@@ -1768,24 +1779,29 @@ class VarAccess extends Expr, @varaccess {
Variable getVariable() { variableBinding(this, result) }
/**
* Holds if this variable access is an l-value.
* Holds if this variable access is a write access.
*
* An l-value is a write access to a variable, which occurs as the destination of an assignment.
* That means the access is the destination of an assignment.
*/
predicate isLValue() {
predicate isVarWrite() {
exists(Assignment a | a.getDest() = this) or
exists(UnaryAssignExpr e | e.getExpr() = this)
}
/** DEPRECATED: Alias for `isVarWrite`. */
deprecated predicate isLValue() { this.isVarWrite() }
/**
* Holds if this variable access is an r-value.
* Holds if this variable access is a read access.
*
* An r-value is a read access to a variable.
* In other words, it is a variable access that does _not_ occur as the destination of
* a simple assignment, but it may occur as the destination of a compound assignment
* or a unary assignment.
*/
predicate isRValue() { not exists(AssignExpr a | a.getDest() = this) }
predicate isVarRead() { not exists(AssignExpr a | a.getDest() = this) }
/** DEPRECATED: Alias for `isVarRead`. */
deprecated predicate isRValue() { this.isVarRead() }
/** Gets a printable representation of this expression. */
override string toString() {
@@ -1831,37 +1847,46 @@ class ExtensionReceiverAccess extends VarAccess {
}
/**
* An l-value is a write access to a variable, which occurs as the destination of an assignment.
* A write access to a variable, which occurs as the destination of an assignment.
*/
class LValue extends VarAccess {
LValue() { this.isLValue() }
class VarWrite extends VarAccess {
VarWrite() { this.isVarWrite() }
/**
* Gets a source expression used in an assignment to this l-value.
* Gets a source of the assignment that executes this variable write.
*
* For assignments using the `=` operator, the source expression
* is simply the RHS of the assignment.
*
* Note that for l-values occurring on the LHS of compound assignment operators
* Note that for writes occurring on the LHS of compound assignment operators
* (such as (`+=`), both the RHS and the LHS of the compound assignment
* are source expressions of the assignment.
*/
Expr getRhs() { exists(Assignment e | e.getDest() = this and e.getSource() = result) }
Expr getASource() { exists(Assignment e | e.getDest() = this and e.getSource() = result) }
/** DEPRECATED: (Inaccurately-named) alias for `getASource` */
deprecated Expr getRhs() { result = this.getASource() }
}
/** DEPRECATED: Alias for `VarWrite`. */
deprecated class LValue = VarWrite;
/**
* An r-value is a read access to a variable.
* A read access to a variable.
*
* In other words, it is a variable access that does _not_ occur as the destination of
* a simple assignment, but it may occur as the destination of a compound assignment
* or a unary assignment.
*/
class RValue extends VarAccess {
RValue() { this.isRValue() }
class VarRead extends VarAccess {
VarRead() { this.isVarRead() }
}
/** A method access is an invocation of a method with a list of arguments. */
class MethodAccess extends Expr, Call, @methodaccess {
/** DEPRECATED: Alias for `VarRead`. */
deprecated class RValue = VarRead;
/** A method call is an invocation of a method with a list of arguments. */
class MethodCall extends Expr, Call, @methodaccess {
/** Gets the qualifying expression of this method access, if any. */
override Expr getQualifier() { result.isNthChildOf(this, -1) }
@@ -1909,21 +1934,30 @@ class MethodAccess extends Expr, Call, @methodaccess {
}
/**
* Holds if this is a method access to an instance method of `this`. That is,
* Holds if this is a method call to an instance method of `this`. That is,
* the qualifier is either an explicit or implicit unqualified `this` or `super`.
*/
predicate isOwnMethodAccess() { Qualifier::ownMemberAccess(this) }
predicate isOwnMethodCall() { Qualifier::ownMemberAccess(this) }
/** DEPRECATED: Alias for `isOwnMethodCall`. */
deprecated predicate isOwnMethodAccess() { this.isOwnMethodCall() }
/**
* Holds if this is a method access to an instance method of the enclosing
* Holds if this is a method call to an instance method of the enclosing
* class `t`. That is, the qualifier is either an explicit or implicit
* `t`-qualified `this` or `super`.
*/
predicate isEnclosingMethodAccess(RefType t) { Qualifier::enclosingMemberAccess(this, t) }
predicate isEnclosingMethodCall(RefType t) { Qualifier::enclosingMemberAccess(this, t) }
override string getAPrimaryQlClass() { result = "MethodAccess" }
/** DEPRECATED: Alias for `isEnclosingMethodCall`. */
deprecated predicate isEnclosingMethodAccess(RefType t) { this.isEnclosingMethodCall(t) }
override string getAPrimaryQlClass() { result = "MethodCall" }
}
/** DEPRECATED: Alias for `MethodCall`. */
deprecated class MethodAccess = MethodCall;
/** A type access is a (possibly qualified) reference to a type. */
class TypeAccess extends Expr, Annotatable, @typeaccess {
/** Gets the qualifier of this type access, if any. */
@@ -2085,23 +2119,32 @@ class Call extends ExprParent, @caller {
}
/** A polymorphic call to an instance method. */
class VirtualMethodAccess extends MethodAccess {
VirtualMethodAccess() {
class VirtualMethodCall extends MethodCall {
VirtualMethodCall() {
this.getMethod().isVirtual() and
not this.getQualifier() instanceof SuperAccess
}
}
/** DEPRECATED: Alias for `VirtualMethodCall`. */
deprecated class VirtualMethodAccess = VirtualMethodCall;
/** A static method call. */
class StaticMethodAccess extends MethodAccess {
StaticMethodAccess() { this.getMethod().isStatic() }
class StaticMethodCall extends MethodCall {
StaticMethodCall() { this.getMethod().isStatic() }
}
/** DEPRECATED: Alias for `StaticMethodCall`. */
deprecated class StaticMethodAccess = StaticMethodCall;
/** A call to a method in the superclass. */
class SuperMethodAccess extends MethodAccess {
SuperMethodAccess() { this.getQualifier() instanceof SuperAccess }
class SuperMethodCall extends MethodCall {
SuperMethodCall() { this.getQualifier() instanceof SuperAccess }
}
/** DEPRECATED: Alias for `SuperMethodCall`. */
deprecated class SuperMethodAccess = SuperMethodCall;
/**
* A constructor call, which occurs either as a constructor invocation inside a
* constructor, or as part of a class instance expression.
@@ -2150,23 +2193,23 @@ private module Qualifier {
TThis() or
TEnclosing(RefType t)
/** An expression that accesses a member. That is, either a `FieldAccess` or a `MethodAccess`. */
/** An expression that accesses a member. That is, either a `FieldAccess` or a `MethodCall`. */
class MemberAccess extends Expr {
MemberAccess() {
this instanceof FieldAccess or
this instanceof MethodAccess
this instanceof MethodCall
}
/** Gets the member accessed by this member access. */
Member getMember() {
result = this.(FieldAccess).getField() or
result = this.(MethodAccess).getMethod()
result = this.(MethodCall).getMethod()
}
/** Gets the qualifier of this member access, if any. */
Expr getQualifier() {
result = this.(FieldAccess).getQualifier() or
result = this.(MethodAccess).getQualifier()
result = this.(MethodCall).getQualifier()
}
}
@@ -2236,10 +2279,10 @@ private module Qualifier {
}
/** An expression that assigns a value to a field. */
class FieldWrite extends FieldAccess, LValue { }
class FieldWrite extends FieldAccess, VarWrite { }
/** An expression that reads a field. */
class FieldRead extends FieldAccess, RValue { }
class FieldRead extends FieldAccess, VarRead { }
private predicate hasInstantiation(RefType t) {
t instanceof TypeVariable or

View File

@@ -479,7 +479,7 @@ class GenericCall extends Call {
}
private RefType getAnExplicitTypeArgument(TypeVariable v) {
exists(GenericCallable gen, MethodAccess call, int i |
exists(GenericCallable gen, MethodCall call, int i |
this = call and
gen = call.getCallee() and
v = gen.getTypeParameter(i) and

View File

@@ -259,10 +259,10 @@ class MethodSystemGetProperty extends ValuePreservingMethod {
}
/**
* An access to a method named `getProperty` on class `java.lang.System`.
* A call to a method named `getProperty` on class `java.lang.System`.
*/
class MethodAccessSystemGetProperty extends MethodAccess {
MethodAccessSystemGetProperty() { this.getMethod() instanceof MethodSystemGetProperty }
class MethodCallSystemGetProperty extends MethodCall {
MethodCallSystemGetProperty() { this.getMethod() instanceof MethodSystemGetProperty }
/**
* Holds if this call has a compile-time constant first argument with the value `propertyName`.
@@ -276,6 +276,9 @@ class MethodAccessSystemGetProperty extends MethodAccess {
}
}
/** DEPRECATED: Alias for `MethodCallSystemGetProperty`. */
deprecated class MethodAccessSystemGetProperty = MethodCallSystemGetProperty;
/**
* Any method named `exit` on class `java.lang.Runtime` or `java.lang.System`.
*/

View File

@@ -39,7 +39,7 @@ class RegisteredManagedBeanImpl extends Class {
/**
* A call that registers an object with the `MBeanServer`, directly or indirectly.
*/
class JmxRegistrationCall extends MethodAccess {
class JmxRegistrationCall extends MethodCall {
JmxRegistrationCall() { this.getCallee() instanceof JmxRegistrationMethod }
/**

View File

@@ -49,7 +49,7 @@ class MapSizeMethod extends MapMethod {
}
/** A method call that mutates a map. */
class MapMutation extends MethodAccess {
class MapMutation extends MethodCall {
MapMutation() { this.getMethod() instanceof MapMutator }
/** Holds if the result of this call is not immediately discarded. */
@@ -76,7 +76,7 @@ class FreshMap extends ClassInstanceExpr {
/**
* A call to `Map.put(key, value)`.
*/
class MapPutCall extends MethodAccess {
class MapPutCall extends MethodCall {
MapPutCall() { this.getCallee().(MapMethod).hasName("put") }
/** Gets the key argument of this call. */

View File

@@ -129,7 +129,7 @@ class Callable extends StmtParent, Member, @callable {
* Holds if this callable calls `target`
* using a `super` method call.
*/
predicate callsSuper(Method target) { this.getACallSite(target) instanceof SuperMethodAccess }
predicate callsSuper(Method target) { this.getACallSite(target) instanceof SuperMethodCall }
/**
* Holds if this callable calls `c` using
@@ -161,13 +161,13 @@ class Callable extends StmtParent, Member, @callable {
* Holds if field `f` may be assigned a value
* within the body of this callable.
*/
predicate writes(Field f) { f.getAnAccess().(LValue).getEnclosingCallable() = this }
predicate writes(Field f) { f.getAnAccess().(VarWrite).getEnclosingCallable() = this }
/**
* Holds if field `f` may be read
* within the body of this callable.
*/
predicate reads(Field f) { f.getAnAccess().(RValue).getEnclosingCallable() = this }
predicate reads(Field f) { f.getAnAccess().(VarRead).getEnclosingCallable() = this }
/**
* Holds if field `f` may be either read or written
@@ -526,7 +526,7 @@ class Method extends Callable, @method {
this.getSourceDeclaration().getAPossibleImplementationOfSrcMethod() = result
}
override MethodAccess getAReference() { result = Callable.super.getAReference() }
override MethodCall getAReference() { result = Callable.super.getAReference() }
override predicate isPublic() {
Callable.super.isPublic()

View File

@@ -3,7 +3,7 @@
import java
/** A call to a string to number conversion. */
private class SpecialMethodAccess extends MethodAccess {
private class SpecialMethodCall extends MethodCall {
predicate isValueOfMethod(string klass) {
this.getMethod().getName() = "valueOf" and
this.getQualifier().getType().(RefType).hasQualifiedName("java.lang", klass) and
@@ -78,7 +78,7 @@ deprecated predicate catchesNFE = catchesNfe/1;
/** Holds if `java.lang.NumberFormatException` can be thrown. */
predicate throwsNfe(Expr e) {
e.(SpecialClassInstanceExpr).throwsNfe() or e.(SpecialMethodAccess).throwsNfe()
e.(SpecialClassInstanceExpr).throwsNfe() or e.(SpecialMethodCall).throwsNfe()
}
/** DEPRECATED: Alias for throwsNfe */

View File

@@ -300,7 +300,7 @@ private class PpCall extends PpAst, Call {
or
i = 2 and
(
result = this.(MethodAccess).getMethod().getName()
result = this.(MethodCall).getMethod().getName()
or
result = "this" and this instanceof ThisConstructorInvocationStmt
or

View File

@@ -62,8 +62,8 @@ private class ReflectiveClassIdentifierLiteral extends ReflectiveClassIdentifier
/**
* A call to a Java standard library method which constructs or returns a `Class<T>` from a `String`.
*/
class ReflectiveClassIdentifierMethodAccess extends ReflectiveClassIdentifier, MethodAccess {
ReflectiveClassIdentifierMethodAccess() {
class ReflectiveClassIdentifierMethodCall extends ReflectiveClassIdentifier, MethodCall {
ReflectiveClassIdentifierMethodCall() {
// A call to `Class.forName(...)`, from which we can infer `T` in the returned type `Class<T>`.
this.getCallee().getDeclaringType() instanceof TypeClass and this.getCallee().hasName("forName")
or
@@ -83,6 +83,9 @@ class ReflectiveClassIdentifierMethodAccess extends ReflectiveClassIdentifier, M
}
}
/** DEPRECATED: Alias for `ReflectiveClassIdentifierMethodCall`. */
deprecated class ReflectiveClassIdentifierMethodAccess = ReflectiveClassIdentifierMethodCall;
/**
* Gets a `ReflectiveClassIdentifier` that we believe may represent the value of `expr`.
*/
@@ -92,7 +95,7 @@ private ReflectiveClassIdentifier pointsToReflectiveClassIdentifier(Expr expr) {
or
// Or if this is an access of a variable which was defined as an expression creating a `Class<T>`,
// return the inferred `T` from the definition expression.
exists(RValue use, VariableAssign assign |
exists(VarRead use, VariableAssign assign |
use = expr and
defUsePair(assign, use) and
// The source of the assignment must be a `ReflectiveClassIdentifier`.
@@ -211,7 +214,7 @@ private predicate expectsEnclosingInstance(RefType r) {
/**
* A call to `Class.newInstance()` or `Constructor.newInstance()`.
*/
class NewInstance extends MethodAccess {
class NewInstance extends MethodCall {
NewInstance() {
(
this.getCallee().getDeclaringType() instanceof TypeClass or
@@ -301,10 +304,10 @@ class NewInstance extends MethodAccess {
}
/**
* A `MethodAccess` on a `Class` element.
* A `MethodCall` on a `Class` instance.
*/
class ClassMethodAccess extends MethodAccess {
ClassMethodAccess() { this.getCallee().getDeclaringType() instanceof TypeClass }
class ClassMethodCall extends MethodCall {
ClassMethodCall() { this.getCallee().getDeclaringType() instanceof TypeClass }
/**
* Gets an inferred type for the `Class` represented by this expression.
@@ -317,31 +320,40 @@ class ClassMethodAccess extends MethodAccess {
}
}
/** DEPRECATED: Alias for `ClassMethodCall`. */
deprecated class ClassMethodAccess = ClassMethodCall;
/**
* A call to `Class.getConstructors(..)` or `Class.getDeclaredConstructors(..)`.
*/
class ReflectiveConstructorsAccess extends ClassMethodAccess {
ReflectiveConstructorsAccess() {
class ReflectiveGetConstructorsCall extends ClassMethodCall {
ReflectiveGetConstructorsCall() {
this.getCallee().hasName("getConstructors") or
this.getCallee().hasName("getDeclaredConstructors")
}
}
/** DEPRECATED: Alias for `ReflectiveGetConstructorsCall`. */
deprecated class ReflectiveConstructorsAccess = ReflectiveGetConstructorsCall;
/**
* A call to `Class.getMethods(..)` or `Class.getDeclaredMethods(..)`.
*/
class ReflectiveMethodsAccess extends ClassMethodAccess {
ReflectiveMethodsAccess() {
class ReflectiveGetMethodsCall extends ClassMethodCall {
ReflectiveGetMethodsCall() {
this.getCallee().hasName("getMethods") or
this.getCallee().hasName("getDeclaredMethods")
}
}
/** DEPRECATED: Alias for `ReflectiveGetMethodsCall`. */
deprecated class ReflectiveMethodsAccess = ReflectiveGetMethodsCall;
/**
* A call to `Class.getMethod(..)` or `Class.getDeclaredMethod(..)`.
*/
class ReflectiveMethodAccess extends ClassMethodAccess {
ReflectiveMethodAccess() {
class ReflectiveGetMethodCall extends ClassMethodCall {
ReflectiveGetMethodCall() {
this.getCallee().hasName("getMethod") or
this.getCallee().hasName("getDeclaredMethod")
}
@@ -366,11 +378,14 @@ class ReflectiveMethodAccess extends ClassMethodAccess {
}
}
/** DEPRECATED: Alias for `ReflectiveGetMethodCall`. */
deprecated class ReflectiveMethodAccess = ReflectiveGetMethodCall;
/**
* A call to `Class.getAnnotation(..)`.
*/
class ReflectiveAnnotationAccess extends ClassMethodAccess {
ReflectiveAnnotationAccess() { this.getCallee().hasName("getAnnotation") }
class ReflectiveGetAnnotationCall extends ClassMethodCall {
ReflectiveGetAnnotationCall() { this.getCallee().hasName("getAnnotation") }
/**
* Gets a possible annotation type for this reflective annotation access.
@@ -380,11 +395,14 @@ class ReflectiveAnnotationAccess extends ClassMethodAccess {
}
}
/** DEPRECATED: Alias for `ReflectiveGetAnnotationCall`. */
deprecated class ReflectiveAnnotationAccess = ReflectiveGetAnnotationCall;
/**
* A call to `Class.getField(..)` that accesses a field.
*/
class ReflectiveFieldAccess extends ClassMethodAccess {
ReflectiveFieldAccess() {
class ReflectiveGetFieldCall extends ClassMethodCall {
ReflectiveGetFieldCall() {
this.getCallee().hasName("getField") or
this.getCallee().hasName("getDeclaredField")
}
@@ -405,3 +423,6 @@ class ReflectiveFieldAccess extends ClassMethodAccess {
result.hasName(this.getArgument(0).(StringLiteral).getValue())
}
}
/** DEPRECATED: Alias for `ReflectiveGetFieldCall`. */
deprecated class ReflectiveFieldAccess = ReflectiveGetFieldCall;

View File

@@ -242,7 +242,7 @@ predicate implicitToStringCall(Expr e) {
or
exists(AddExpr add | add.getType() instanceof TypeString and add.getAnOperand() = e)
or
exists(MethodAccess ma, Method m, int i |
exists(MethodCall ma, Method m, int i |
ma.getMethod() = m and
ma.getArgument(i) = e and
printMethod(m, i)
@@ -253,7 +253,7 @@ predicate implicitToStringCall(Expr e) {
/**
* A call to a `format` or `printf` method.
*/
class StringFormat extends MethodAccess, FormattingCall {
class StringFormat extends MethodCall, FormattingCall {
StringFormat() { this.getCallee() instanceof StringFormatMethod }
}

View File

@@ -1090,6 +1090,24 @@ class PrimitiveType extends Type, @primitive {
override string getAPrimaryQlClass() { result = "PrimitiveType" }
}
private int getByteSize(PrimitiveType t) {
t.hasName("boolean") and result = 1
or
t.hasName("byte") and result = 1
or
t.hasName("char") and result = 2
or
t.hasName("short") and result = 2
or
t.hasName("int") and result = 4
or
t.hasName("float") and result = 4
or
t.hasName("long") and result = 8
or
t.hasName("double") and result = 8
}
/** The type of the `null` literal. */
class NullType extends Type, @primitive {
NullType() { this.hasName("<nulltype>") }
@@ -1282,6 +1300,12 @@ class IntegralType extends Type {
name = ["byte", "char", "short", "int", "long"]
)
}
/** Gets the size in bytes of this numeric type. */
final int getByteSize() {
result = getByteSize(this) or
result = getByteSize(this.(BoxedType).getPrimitiveType())
}
}
/** A boolean type, which may be either a primitive or a boxed type. */

View File

@@ -187,14 +187,14 @@ private predicate switchCaseControls(SwitchCase sc, BasicBlock bb) {
}
private predicate preconditionBranchEdge(
MethodAccess ma, BasicBlock bb1, BasicBlock bb2, boolean branch
MethodCall ma, BasicBlock bb1, BasicBlock bb2, boolean branch
) {
conditionCheckArgument(ma, _, branch) and
bb1.getLastNode() = ma.getControlFlowNode() and
bb2 = bb1.getLastNode().getANormalSuccessor()
}
private predicate preconditionControls(MethodAccess ma, BasicBlock controlled, boolean branch) {
private predicate preconditionControls(MethodCall ma, BasicBlock controlled, boolean branch) {
exists(BasicBlock check, BasicBlock succ |
preconditionBranchEdge(ma, check, succ, branch) and
dominatingEdge(check, succ) and
@@ -249,7 +249,7 @@ private predicate equalityGuard(Guard g, Expr e1, Expr e2, boolean polarity) {
eqtest.hasOperands(e1, e2)
)
or
exists(MethodAccess ma |
exists(MethodCall ma |
ma = g and
ma.getMethod() instanceof EqualsMethod and
polarity = true and
@@ -257,7 +257,7 @@ private predicate equalityGuard(Guard g, Expr e1, Expr e2, boolean polarity) {
ma.getQualifier() = e2
)
or
exists(MethodAccess ma, Method equals |
exists(MethodCall ma, Method equals |
ma = g and
ma.getMethod() = equals and
polarity = true and

View File

@@ -59,7 +59,7 @@ predicate implies_v1(Guard g1, boolean b1, Guard g2, boolean b2) {
or
g1.(DefaultCase).getSwitchExpr().getAConstCase() = g2 and b1 = true and b2 = false
or
exists(MethodAccess check, int argIndex | check = g1 |
exists(MethodCall check, int argIndex | check = g1 |
conditionCheckArgument(check, argIndex, _) and
g2 = check.getArgument(argIndex) and
b1 = [true, false] and

View File

@@ -17,7 +17,7 @@ predicate conditionCheckMethodArgument(Method m, int argument, boolean checkTrue
or
condtionCheckMethodTestingFramework(m, argument, checkTrue)
or
exists(Parameter p, MethodAccess ma, int argIndex, boolean ct, Expr arg |
exists(Parameter p, MethodCall ma, int argIndex, boolean ct, Expr arg |
p = m.getParameter(argument) and
not m.isOverridable() and
m.getBody().getStmt(0).(ExprStmt).getExpr() = ma and
@@ -100,6 +100,6 @@ private predicate condtionCheckMethodTestingFramework(Method m, int argument, bo
* Holds if `ma` is an access to a non-overridable method that checks that its
* zero-indexed `argument` is equal to `checkTrue` and throws otherwise.
*/
predicate conditionCheckArgument(MethodAccess ma, int argument, boolean checkTrue) {
predicate conditionCheckArgument(MethodCall ma, int argument, boolean checkTrue) {
conditionCheckMethodArgument(ma.getMethod().getSourceDeclaration(), argument, checkTrue)
}

View File

@@ -25,16 +25,8 @@ abstract class Bound extends TBound {
/** Gets an expression that equals this bound. */
Expr getExpr() { result = this.getExpr(0) }
/**
* Holds if this element is at the specified location.
* The location spans column `sc` of line `sl` to
* column `ec` of line `el` in file `path`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0
}
/** Gets the location of this bound. */
abstract Location getLocation();
}
/**
@@ -45,6 +37,8 @@ class ZeroBound extends Bound, TBoundZero {
override string toString() { result = "0" }
override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta }
override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) }
}
/**
@@ -58,9 +52,7 @@ class SsaBound extends Bound, TBoundSsa {
override Expr getExpr(int delta) { result = this.getSsa().getAUse() and delta = 0 }
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
this.getSsa().getLocation().hasLocationInfo(path, sl, sc, el, ec)
}
override Location getLocation() { result = this.getSsa().getLocation() }
}
/**
@@ -72,7 +64,5 @@ class ExprBound extends Bound, TBoundExpr {
override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 }
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
this.getExpr().getLocation().hasLocationInfo(path, sl, sc, el, ec)
}
override Location getLocation() { result = this.getExpr().getLocation() }
}

View File

@@ -13,7 +13,7 @@ private import SSA
*
* This is the transitive closure of `adjacentUseUseSameVar`.
*/
predicate useUsePairSameVar(RValue use1, RValue use2) { adjacentUseUseSameVar+(use1, use2) }
predicate useUsePairSameVar(VarRead use1, VarRead use2) { adjacentUseUseSameVar+(use1, use2) }
/**
* Holds if `use1` and `use2` form a use-use-pair of the same
@@ -23,7 +23,7 @@ predicate useUsePairSameVar(RValue use1, RValue use2) { adjacentUseUseSameVar+(u
*
* This is the transitive closure of `adjacentUseUse`.
*/
predicate useUsePair(RValue use1, RValue use2) { adjacentUseUse+(use1, use2) }
predicate useUsePair(VarRead use1, VarRead use2) { adjacentUseUse+(use1, use2) }
/**
* Holds if there exists a path from `def` to `use` without passing through another
@@ -31,7 +31,7 @@ predicate useUsePair(RValue use1, RValue use2) { adjacentUseUse+(use1, use2) }
*
* Other paths may also exist, so the SSA variables in `def` and `use` can be different.
*/
predicate defUsePair(VariableUpdate def, RValue use) {
predicate defUsePair(VariableUpdate def, VarRead use) {
exists(SsaVariable v |
v.getAUse() = use and v.getAnUltimateDefinition().(SsaExplicitUpdate).getDefiningExpr() = def
)
@@ -43,7 +43,7 @@ predicate defUsePair(VariableUpdate def, RValue use) {
*
* Other paths may also exist, so the SSA variables can be different.
*/
predicate parameterDefUsePair(Parameter p, RValue use) {
predicate parameterDefUsePair(Parameter p, VarRead use) {
exists(SsaVariable v |
v.getAUse() = use and v.getAnUltimateDefinition().(SsaImplicitInit).isParameterDefinition(p)
)

View File

@@ -122,9 +122,9 @@ private predicate variableStep(Expr tracked, VarAccess sink) {
private class ReverseDnsSource extends RemoteFlowSource {
ReverseDnsSource() {
// Try not to trigger on `localhost`.
exists(MethodAccess m | m = this.asExpr() |
exists(MethodCall m | m = this.asExpr() |
m.getMethod() instanceof ReverseDnsMethod and
not exists(MethodAccess l |
not exists(MethodCall l |
(variableStep(l, m.getQualifier()) or l = m.getQualifier()) and
l.getMethod().getName() = "getLocalHost"
)
@@ -321,7 +321,7 @@ class AndroidIntentInput extends DataFlow::Node {
Type receiverType;
AndroidIntentInput() {
exists(MethodAccess ma, AndroidGetIntentMethod m |
exists(MethodCall ma, AndroidGetIntentMethod m |
ma.getMethod().overrides*(m) and
this.asExpr() = ma and
receiverType = ma.getReceiverType()

View File

@@ -58,9 +58,7 @@ private predicate implicitEnclosingThisCopy(ConstructorCall cc, RefType t1, RefT
private predicate enclosingInstanceAccess(ExprParent e, RefType t) {
e.(InstanceAccess).isEnclosingInstanceAccess(t)
or
exists(MethodAccess ma |
ma.isEnclosingMethodAccess(t) and ma = e and not exists(ma.getQualifier())
)
exists(MethodCall ma | ma.isEnclosingMethodCall(t) and ma = e and not exists(ma.getQualifier()))
or
exists(FieldAccess fa | fa.isEnclosingFieldAccess(t) and fa = e and not exists(fa.getQualifier()))
or
@@ -95,7 +93,7 @@ private newtype TInstanceAccessExt =
or
c instanceof SuperConstructorInvocationStmt
or
c.(MethodAccess).isOwnMethodAccess() and not exists(c.getQualifier())
c.(MethodCall).isOwnMethodCall() and not exists(c.getQualifier())
} or
TThisEnclosingInstanceCapture(ConstructorCall cc) { implicitSetEnclosingInstanceToThis(cc) } or
TEnclosingInstanceAccess(ExprParent e, RefType t) {
@@ -113,7 +111,7 @@ private newtype TInstanceAccessExt =
* - Implicit field qualifier: The implicit access associated with an
* unqualified `FieldAccess` to a non-static field.
* - Implicit method qualifier: The implicit access associated with an
* unqualified `MethodAccess` to a non-static method.
* unqualified `MethodCall` to a non-static method.
* - Implicit this constructor argument: The implicit argument of the value of
* `this` to a constructor call of the form `this()` or `super()`.
* - Implicit enclosing instance capture: The implicit capture of the value of
@@ -180,7 +178,7 @@ class InstanceAccessExt extends TInstanceAccessExt {
}
/** Holds if this is the implicit qualifier of `ma`. */
predicate isImplicitMethodQualifier(MethodAccess ma) {
predicate isImplicitMethodQualifier(MethodCall ma) {
this = TThisArgument(ma) or
this = TEnclosingInstanceAccess(ma, _)
}
@@ -234,7 +232,7 @@ class InstanceAccessExt extends TInstanceAccessExt {
e instanceof InstanceAccess and result = e
or
exists(FieldAccess fa | fa = e |
if fa instanceof RValue then fa = result else result.(AssignExpr).getDest() = fa
if fa instanceof VarRead then fa = result else result.(AssignExpr).getDest() = fa
)
)
}

View File

@@ -15,10 +15,10 @@ private Expr exprWithIntValue(int i) {
/**
* An expression for which the predicate `integerGuard` is relevant.
* This includes `RValue` and `MethodAccess`.
* This includes `VarRead` and `MethodCall`.
*/
class IntComparableExpr extends Expr {
IntComparableExpr() { this instanceof RValue or this instanceof MethodAccess }
IntComparableExpr() { this instanceof VarRead or this instanceof MethodCall }
/** Gets an integer that is directly assigned to the expression in case of a variable; or zero. */
int relevantInt() {
@@ -132,7 +132,7 @@ Expr integerGuard(IntComparableExpr e, boolean branch, int k, boolean is_k) {
* If `branch_with_lower_bound_k` is true then `result` is equivalent to `k <= x`
* and if it is false then `result` is equivalent to `k > x`.
*/
Expr intBoundGuard(RValue x, boolean branch_with_lower_bound_k, int k) {
Expr intBoundGuard(VarRead x, boolean branch_with_lower_bound_k, int k) {
exists(ComparisonExpr comp, ConstantIntegerExpr c, int val |
comp = result and
comp.hasOperands(x, c) and

View File

@@ -79,7 +79,7 @@ Expr clearlyNotNullExpr(Expr reason) {
(reason = r1 or reason = r2)
)
or
exists(SsaVariable v, boolean branch, RValue rval, Guard guard |
exists(SsaVariable v, boolean branch, VarRead rval, Guard guard |
guard = directNullGuard(v, branch, false) and
guard.controls(rval.getBasicBlock(), branch) and
reason = guard and
@@ -89,7 +89,7 @@ Expr clearlyNotNullExpr(Expr reason) {
or
exists(SsaVariable v | clearlyNotNull(v, reason) and result = v.getAUse())
or
exists(Method m | m = result.(MethodAccess).getMethod() and reason = result |
exists(Method m | m = result.(MethodCall).getMethod() and reason = result |
m.getDeclaringType().hasQualifiedName("com.google.common.base", "Strings") and
m.hasName("nullToEmpty")
)
@@ -187,7 +187,7 @@ Expr basicNullGuard(Expr e, boolean branch, boolean isnull) {
or
result.(InstanceOfExpr).getExpr() = e and branch = true and isnull = false
or
exists(MethodAccess call |
exists(MethodCall call |
call = result and
call.getAnArgument() = e and
nullCheckMethod(call.getMethod(), branch, isnull)
@@ -212,7 +212,7 @@ Expr basicNullGuard(Expr e, boolean branch, boolean isnull) {
Expr basicOrCustomNullGuard(Expr e, boolean branch, boolean isnull) {
result = basicNullGuard(e, branch, isnull)
or
exists(MethodAccess call, Method m, int ix |
exists(MethodCall call, Method m, int ix |
call = result and
call.getArgument(ix) = e and
call.getMethod().getSourceDeclaration() = m and

View File

@@ -106,7 +106,7 @@ predicate dereference(Expr e) {
or
exists(FieldAccess fa, Field f | fa.getQualifier() = e and fa.getField() = f and not f.isStatic())
or
exists(MethodAccess ma, Method m |
exists(MethodCall ma, Method m |
ma.getQualifier() = e and ma.getMethod() = m and not m.isStatic()
)
or
@@ -149,10 +149,10 @@ private ControlFlowNode ensureNotNull(SsaVariable v) {
or
exists(AssertNotNullMethod m | result = m.getACheck(v.getAUse()))
or
exists(AssertThatMethod m, MethodAccess ma |
exists(AssertThatMethod m, MethodCall ma |
result = m.getACheck(v.getAUse()) and ma.getControlFlowNode() = result
|
ma.getAnArgument().(MethodAccess).getMethod().getName() = "notNullValue"
ma.getAnArgument().(MethodCall).getMethod().getName() = "notNullValue"
)
}
@@ -195,7 +195,7 @@ private predicate varMaybeNull(SsaVariable v, string msg, Expr reason) {
not exists(TryStmt try | try.getFinally() = e.getEnclosingStmt().getEnclosingStmt*()) and
(
e = any(ConditionalExpr c).getCondition().getAChildExpr*() or
not exists(MethodAccess ma | ma.getAnArgument().getAChildExpr*() = e)
not exists(MethodCall ma | ma.getAnArgument().getAChildExpr*() = e)
) and
// Don't use a guard as reason if there is a null assignment.
not v.(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource() = nullExpr()
@@ -250,7 +250,7 @@ private Expr nonEmptyExpr() {
// ...it is guarded by a condition...
cond.controls(result.getBasicBlock(), branch) and
// ...and it isn't modified in the scope of the condition...
forall(MethodAccess ma, Method m |
forall(MethodCall ma, Method m |
m = ma.getMethod() and
ma.getQualifier() = v.getSourceVariable().getAnAccess() and
cond.controls(ma.getBasicBlock(), branch)
@@ -260,12 +260,12 @@ private Expr nonEmptyExpr() {
cond.getCondition() = c
|
// ...and the condition proves that it is non-empty, either by using the `isEmpty` method...
c.(MethodAccess).getMethod().hasName("isEmpty") and
c.(MethodCall).getMethod().hasName("isEmpty") and
branch = false and
c.(MethodAccess).getQualifier() = v.getAUse()
c.(MethodCall).getQualifier() = v.getAUse()
or
// ...or a check on its `size`.
exists(MethodAccess size |
exists(MethodCall size |
c = integerGuard(size, branch, 0, false) and
size.getMethod().hasName("size") and
size.getQualifier() = v.getAUse()
@@ -485,7 +485,7 @@ private predicate correlatedConditions(
inverted = branch1.booleanXor(branch2)
)
or
exists(SsaVariable v, RValue rv1, RValue rv2, int k, boolean branch1, boolean branch2 |
exists(SsaVariable v, VarRead rv1, VarRead rv2, int k, boolean branch1, boolean branch2 |
rv1 = v.getAUse() and
rv2 = v.getAUse() and
cond1.getCondition() = integerGuard(rv1, branch1, k, true) and

File diff suppressed because it is too large Load Diff

View File

@@ -145,6 +145,9 @@ class ConstantStringExpr extends Expr {
string getStringValue() { constantStringExpr(this, result) }
}
bindingset[f]
private predicate okInt(float f) { -2.pow(31) <= f and f <= 2.pow(31) - 1 }
/**
* Gets an expression that equals `v - d`.
*/
@@ -153,14 +156,16 @@ Expr ssaRead(SsaVariable v, int delta) {
or
exists(int d1, ConstantIntegerExpr c |
result.(AddExpr).hasOperands(ssaRead(v, d1), c) and
delta = d1 - c.getIntValue()
delta = d1 - c.getIntValue() and
okInt(d1.(float) - c.getIntValue().(float))
)
or
exists(SubExpr sub, int d1, ConstantIntegerExpr c |
result = sub and
sub.getLeftOperand() = ssaRead(v, d1) and
sub.getRightOperand() = c and
delta = d1 + c.getIntValue()
delta = d1 + c.getIntValue() and
okInt(d1.(float) + c.getIntValue().(float))
)
or
v.(SsaExplicitUpdate).getDefiningExpr().(PreIncExpr) = result and delta = 0

View File

@@ -275,7 +275,7 @@ private module SsaImpl {
}
/** Holds if `VarAccess` `use` of `v` occurs in `b` at index `i`. */
private predicate variableUse(TrackedVar v, RValue use, BasicBlock b, int i) {
private predicate variableUse(TrackedVar v, VarRead use, BasicBlock b, int i) {
v.getAnAccess() = use and b.getNode(i) = use
}
@@ -381,7 +381,7 @@ private module SsaImpl {
* ```
*/
private predicate intraInstanceCallEdge(Callable c1, Method m2) {
exists(MethodAccess ma, RefType t1 |
exists(MethodCall ma, RefType t1 |
ma.getCaller() = c1 and
m2 = viableImpl_v2(ma) and
not m2.isStatic() and
@@ -652,7 +652,7 @@ private module SsaImpl {
* Holds if the SSA definition of `v` at `def` reaches `use` in the same basic block
* without crossing another SSA definition of `v`.
*/
private predicate ssaDefReachesUseWithinBlock(TrackedVar v, TrackedSsaDef def, RValue use) {
private predicate ssaDefReachesUseWithinBlock(TrackedVar v, TrackedSsaDef def, VarRead use) {
exists(BasicBlock b, int rankix, int i |
ssaDefReachesRank(v, def, b, rankix) and
defUseRank(v, b, rankix, i) and
@@ -665,7 +665,7 @@ private module SsaImpl {
* SSA definition of `v`.
*/
cached
predicate ssaDefReachesUse(TrackedVar v, TrackedSsaDef def, RValue use) {
predicate ssaDefReachesUse(TrackedVar v, TrackedSsaDef def, VarRead use) {
ssaDefReachesUseWithinBlock(v, def, use)
or
exists(BasicBlock b |
@@ -813,7 +813,7 @@ private module SsaImpl {
* any other uses, but possibly through phi nodes and uncertain implicit updates.
*/
cached
predicate firstUse(TrackedSsaDef def, RValue use) {
predicate firstUse(TrackedSsaDef def, VarRead use) {
exists(TrackedVar v, BasicBlock b1, int i1, BasicBlock b2, int i2 |
adjacentVarRefs(v, b1, i1, b2, i2) and
def.definesAt(v, b1, i1) and
@@ -838,7 +838,7 @@ private module SsaImpl {
* through any other use or any SSA definition of the variable.
*/
cached
predicate adjacentUseUseSameVar(RValue use1, RValue use2) {
predicate adjacentUseUseSameVar(VarRead use1, VarRead use2) {
exists(TrackedVar v, BasicBlock b1, int i1, BasicBlock b2, int i2 |
adjacentVarRefs(v, b1, i1, b2, i2) and
variableUse(v, use1, b1, i1) and
@@ -853,7 +853,7 @@ private module SsaImpl {
* except for phi nodes and uncertain implicit updates.
*/
cached
predicate adjacentUseUse(RValue use1, RValue use2) {
predicate adjacentUseUse(VarRead use1, VarRead use2) {
adjacentUseUseSameVar(use1, use2)
or
exists(TrackedVar v, TrackedSsaDef def, BasicBlock b1, int i1, BasicBlock b2, int i2 |
@@ -938,7 +938,7 @@ class SsaVariable extends TSsaVariable {
BasicBlock getBasicBlock() { result = this.getCfgNode().getBasicBlock() }
/** Gets an access of this SSA variable. */
RValue getAUse() {
VarRead getAUse() {
ssaDefReachesUse(_, this, result) or
this = TSsaUntracked(_, result)
}
@@ -952,7 +952,7 @@ class SsaVariable extends TSsaVariable {
* Subsequent uses can be found by following the steps defined by
* `adjacentUseUse`.
*/
RValue getAFirstUse() {
VarRead getAFirstUse() {
firstUse(this, result) or
this = TSsaUntracked(_, result)
}

View File

@@ -54,7 +54,7 @@ private Expr getAnInterestingPrefix(InterestingPrefix root) {
result.(AddExpr).getAnOperand() = getAnInterestingPrefix(root)
}
private class StringBuilderAppend extends MethodAccess {
private class StringBuilderAppend extends MethodCall {
StringBuilderAppend() {
this.getMethod().getDeclaringType() instanceof StringBuildingType and
this.getMethod().hasName("append")
@@ -68,7 +68,7 @@ private class StringBuilderConstructorOrAppend extends Call {
}
}
private Expr getQualifier(Expr e) { result = e.(MethodAccess).getQualifier() }
private Expr getQualifier(Expr e) { result = e.(MethodCall).getQualifier() }
/**
* An extension of `StringBuilderVar` that also accounts for strings appended in StringBuilder/Buffer's constructor

View File

@@ -118,7 +118,7 @@ private module SsaImpl {
}
/** Holds if `VarAccess` `use` of `v` occurs in `b` at index `i`. */
private predicate variableUse(BaseSsaSourceVariable v, RValue use, BasicBlock b, int i) {
private predicate variableUse(BaseSsaSourceVariable v, VarRead use, BasicBlock b, int i) {
v.getAnAccess() = use and b.getNode(i) = use
}
@@ -243,7 +243,7 @@ private module SsaImpl {
* without crossing another SSA definition of `v`.
*/
private predicate ssaDefReachesUseWithinBlock(
BaseSsaSourceVariable v, TrackedSsaDef def, RValue use
BaseSsaSourceVariable v, TrackedSsaDef def, VarRead use
) {
exists(BasicBlock b, int rankix, int i |
ssaDefReachesRank(v, def, b, rankix) and
@@ -257,7 +257,7 @@ private module SsaImpl {
* SSA definition of `v`.
*/
cached
predicate ssaDefReachesUse(BaseSsaSourceVariable v, TrackedSsaDef def, RValue use) {
predicate ssaDefReachesUse(BaseSsaSourceVariable v, TrackedSsaDef def, VarRead use) {
ssaDefReachesUseWithinBlock(v, def, use)
or
exists(BasicBlock b |
@@ -378,7 +378,7 @@ private module SsaImpl {
* any other uses, but possibly through phi nodes.
*/
cached
predicate firstUse(TrackedSsaDef def, RValue use) {
predicate firstUse(TrackedSsaDef def, VarRead use) {
exists(BaseSsaSourceVariable v, BasicBlock b1, int i1, BasicBlock b2, int i2 |
adjacentVarRefs(v, b1, i1, b2, i2) and
def.definesAt(v, b1, i1) and
@@ -405,7 +405,7 @@ private module SsaImpl {
* through any other use or any SSA definition of the variable.
*/
cached
predicate baseSsaAdjacentUseUseSameVar(RValue use1, RValue use2) {
predicate baseSsaAdjacentUseUseSameVar(VarRead use1, VarRead use2) {
exists(BaseSsaSourceVariable v, BasicBlock b1, int i1, BasicBlock b2, int i2 |
adjacentVarRefs(v, b1, i1, b2, i2) and
variableUse(v, use1, b1, i1) and
@@ -420,7 +420,7 @@ private module SsaImpl {
* except for phi nodes.
*/
cached
predicate baseSsaAdjacentUseUse(RValue use1, RValue use2) {
predicate baseSsaAdjacentUseUse(VarRead use1, VarRead use2) {
baseSsaAdjacentUseUseSameVar(use1, use2)
or
exists(
@@ -490,7 +490,7 @@ class BaseSsaVariable extends TBaseSsaVariable {
BasicBlock getBasicBlock() { result = this.getCfgNode().getBasicBlock() }
/** Gets an access of this SSA variable. */
RValue getAUse() { ssaDefReachesUse(_, this, result) }
VarRead getAUse() { ssaDefReachesUse(_, this, result) }
/**
* Gets an access of the SSA source variable underlying this SSA variable
@@ -500,7 +500,7 @@ class BaseSsaVariable extends TBaseSsaVariable {
* Subsequent uses can be found by following the steps defined by
* `baseSsaAdjacentUseUse`.
*/
RValue getAFirstUse() { firstUse(this, result) }
VarRead getAFirstUse() { firstUse(this, result) }
/** Holds if this SSA variable is live at the end of `b`. */
predicate isLiveAtEndOfBlock(BasicBlock b) { ssaDefReachesEndOfBlock(_, this, b) }

View File

@@ -184,13 +184,13 @@ private predicate taintPreservingQualifierToMethod(Method m) {
m.(MapMethod).hasName(["elements", "search", "searchEntries", "searchValues"])
}
private predicate qualifierToMethodStep(Expr tracked, MethodAccess sink) {
private predicate qualifierToMethodStep(Expr tracked, MethodCall sink) {
taintPreservingQualifierToMethod(sink.getMethod()) and
tracked = sink.getQualifier()
}
private predicate qualifierToArgumentStep(Expr tracked, Expr sink) {
exists(MethodAccess ma, CollectionMethod method |
exists(MethodCall ma, CollectionMethod method |
method = ma.getMethod() and
(
// java.util.Vector
@@ -350,7 +350,7 @@ private predicate taintPreservingArgToArg(Method method, int input, int output)
}
private predicate argToQualifierStep(Expr tracked, Expr sink) {
exists(Method m, int i, MethodAccess ma |
exists(Method m, int i, MethodCall ma |
taintPreservingArgumentToQualifier(m, i) and
ma.getMethod() = m and
tracked = ma.getArgument(i) and
@@ -359,7 +359,7 @@ private predicate argToQualifierStep(Expr tracked, Expr sink) {
}
/** Access to a method that passes taint from an argument. */
private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
private predicate argToMethodStep(Expr tracked, MethodCall sink) {
exists(Method m |
m = sink.getMethod() and
(
@@ -383,7 +383,7 @@ private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
* between arguments.
*/
private predicate argToArgStep(Expr tracked, Expr sink) {
exists(MethodAccess ma, Method method, int input, int output |
exists(MethodCall ma, Method method, int input, int output |
ma.getMethod() = method and
ma.getArgument(input) = tracked and
ma.getArgument(output) = sink and

View File

@@ -38,7 +38,7 @@ private module DispatchImpl {
* might be improved by knowing the call context. This is the case if the
* qualifier is the `i`th parameter of the enclosing callable `c`.
*/
private predicate mayBenefitFromCallContext(MethodAccess ma, Callable c, int i) {
private predicate mayBenefitFromCallContext(MethodCall ma, Callable c, int i) {
exists(Parameter p |
2 <= strictcount(sourceDispatch(ma)) and
ma.getQualifier().(VarAccess).getVariable() = p and
@@ -58,7 +58,7 @@ private module DispatchImpl {
/**
* Holds if the call `ctx` might act as a context that improves the set of
* dispatch targets of a `MethodAccess` that occurs in a viable target of
* dispatch targets of a `MethodCall` that occurs in a viable target of
* `ctx`.
*/
pragma[nomagic]
@@ -128,7 +128,7 @@ private module DispatchImpl {
*/
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
result = viableCallable(call) and
exists(int i, Callable c, Method def, RefType t, boolean exact, MethodAccess ma |
exists(int i, Callable c, Method def, RefType t, boolean exact, MethodCall ma |
ma = call.asCall() and
mayBenefitFromCallContext(ma, c, i) and
c = viableCallable(ctx).asCallable() and

View File

@@ -84,7 +84,7 @@ private module Cached {
import Cached
private predicate explicitInstanceArgument(Call call, Expr instarg) {
call instanceof MethodAccess and
call instanceof MethodCall and
instarg = call.getQualifier() and
not call.getCallee().isStatic()
}
@@ -463,7 +463,7 @@ module Private {
/** A data flow node that represents the output of a call. */
class OutNode extends Node {
OutNode() {
this.asExpr() instanceof MethodAccess
this.asExpr() instanceof MethodCall
or
this.(FlowSummaryNode).isOut(_)
}

View File

@@ -114,7 +114,7 @@ private module CaptureInput implements VariableCapture::InputSig {
CapturedVariable getVariable() { result = v }
}
class VariableRead extends Expr instanceof RValue {
class VariableRead extends Expr instanceof VarRead {
CapturedVariable v;
VariableRead() { super.getVariable() = v }
@@ -246,7 +246,7 @@ predicate readStep(Node node1, ContentSet f, Node node2) {
fr = node2.asExpr()
)
or
exists(Record r, Method getter, Field recf, MethodAccess get |
exists(Record r, Method getter, Field recf, MethodCall get |
getter.getDeclaringType() = r and
recf.getDeclaringType() = r and
getter.getNumberOfParameters() = 0 and

View File

@@ -169,7 +169,7 @@ predicate localMustFlowStep(Node node1, Node node2) {
import Cached
private predicate capturedVariableRead(Node n) {
n.asExpr().(RValue).getVariable() instanceof CapturedVariable
n.asExpr().(VarRead).getVariable() instanceof CapturedVariable
}
/**
@@ -225,7 +225,7 @@ private predicate simpleLocalFlowStep0(Node node1, Node node2) {
or
simpleAstFlowStep(node1.asExpr(), node2.asExpr())
or
exists(MethodAccess ma, ValuePreservingMethod m, int argNo |
exists(MethodCall ma, ValuePreservingMethod m, int argNo |
ma.getCallee().getSourceDeclaration() = m and m.returnsValue(argNo)
|
node2.asExpr() = ma and
@@ -379,7 +379,7 @@ signature predicate guardChecksSig(Guard g, Expr e, boolean branch);
module BarrierGuard<guardChecksSig/3 guardChecks> {
/** Gets a node that is safely guarded by the given guard check. */
Node getABarrierNode() {
exists(Guard g, SsaVariable v, boolean branch, RValue use |
exists(Guard g, SsaVariable v, boolean branch, VarRead use |
guardChecks(g, v.getAUse(), branch) and
use = v.getAUse() and
g.controls(use.getBasicBlock(), branch) and

View File

@@ -333,7 +333,7 @@ predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode n) {
exists(FieldWrite fw |
c = "" and
fw.getField() = mid.asElement() and
n.asNode().asExpr() = fw.getRhs()
n.asNode().asExpr() = fw.getASource()
)
}

View File

@@ -53,10 +53,16 @@ private predicate isJdkInternal(CompilationUnit cu) {
cu.getPackage().getName() = ""
}
/** Holds if the given compilation unit's package is internal. */
private predicate isInternal(CompilationUnit cu) {
isJdkInternal(cu) or
cu.getPackage().getName().matches("%internal%")
}
/** Holds if the given callable is not worth modeling. */
predicate isUninterestingForModels(Callable c) {
isInTestFile(c.getCompilationUnit().getFile()) or
isJdkInternal(c.getCompilationUnit()) or
isInternal(c.getCompilationUnit()) or
c instanceof MainMethod or
c instanceof StaticInitializer or
exists(FunctionalExpr funcExpr | c = funcExpr.asMethod()) or

View File

@@ -290,7 +290,7 @@ private int argToParam(Call call, int argIdx) {
/** Access to a method that passes taint from qualifier to argument. */
private predicate qualifierToArgumentStep(Expr tracked, Expr sink) {
exists(MethodAccess ma, int arg |
exists(MethodCall ma, int arg |
ma.getMethod().(TaintPreservingCallable).transfersTaint(-1, argToParam(ma, arg)) and
tracked = ma.getQualifier() and
sink = ma.getArgument(arg)
@@ -298,7 +298,7 @@ private predicate qualifierToArgumentStep(Expr tracked, Expr sink) {
}
/** Access to a method that passes taint from the qualifier. */
private predicate qualifierToMethodStep(Expr tracked, MethodAccess sink) {
private predicate qualifierToMethodStep(Expr tracked, MethodCall sink) {
taintPreservingQualifierToMethod(sink.getMethod()) and
tracked = sink.getQualifier()
}
@@ -331,7 +331,7 @@ private predicate taintPreservingQualifierToMethod(Method m) {
}
/** Access to a method that passes taint from an argument. */
private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
private predicate argToMethodStep(Expr tracked, MethodCall sink) {
exists(Method m, int i |
m = sink.getMethod() and
taintPreservingArgumentToMethod(m, argToParam(sink, i)) and
@@ -375,7 +375,7 @@ private predicate taintPreservingArgumentToMethod(Method method, int arg) {
* between arguments.
*/
private predicate argToArgStep(Expr tracked, Expr sink) {
exists(MethodAccess ma, Method method, int input, int output |
exists(MethodCall ma, Method method, int input, int output |
method.(TaintPreservingCallable).transfersTaint(argToParam(ma, input), argToParam(ma, output)) and
ma.getMethod() = method and
ma.getArgument(input) = tracked and
@@ -388,7 +388,7 @@ private predicate argToArgStep(Expr tracked, Expr sink) {
* from the argument to the qualifier and `sink` is the qualifier.
*/
private predicate argToQualifierStep(Expr tracked, Expr sink) {
exists(Method m, int i, MethodAccess ma |
exists(Method m, int i, MethodCall ma |
taintPreservingArgumentToQualifier(m, argToParam(ma, i)) and
ma.getMethod() = m and
tracked = ma.getArgument(i) and
@@ -412,7 +412,7 @@ private predicate comparisonStep(Expr tracked, Expr sink) {
e.hasOperands(tracked, other)
)
or
exists(MethodAccess m | m.getMethod() instanceof EqualsMethod |
exists(MethodCall m | m.getMethod() instanceof EqualsMethod |
m = sink and
(
m.getQualifier() = tracked and m.getArgument(0) = other
@@ -429,13 +429,13 @@ private predicate comparisonStep(Expr tracked, Expr sink) {
private predicate serializationStep(Expr tracked, Expr sink) {
exists(ObjectOutputStreamVar v, VariableAssign def |
def = v.getADef() and
exists(MethodAccess ma, RValue use |
exists(MethodCall ma, VarRead use |
ma.getArgument(0) = tracked and
ma = v.getAWriteObjectMethodAccess() and
ma = v.getAWriteObjectMethodCall() and
use = ma.getQualifier() and
defUsePair(def, use)
) and
exists(RValue outputstream, ClassInstanceExpr cie |
exists(VarRead outputstream, ClassInstanceExpr cie |
cie = def.getSource() and
outputstream = cie.getArgument(0) and
adjacentUseUse(outputstream, sink)
@@ -460,23 +460,27 @@ class ObjectOutputStreamVar extends LocalVariableDecl {
result.getDestVar() = this
}
MethodAccess getAWriteObjectMethodAccess() {
/** Gets a call to `writeObject` called against this variable. */
MethodCall getAWriteObjectMethodCall() {
result.getQualifier() = this.getAnAccess() and
result.getMethod().hasName("writeObject")
}
/** DEPRECATED: Alias for `getAWriteObjectMethodCall`. */
deprecated MethodCall getAWriteObjectMethodAccess() { result = this.getAWriteObjectMethodCall() }
}
/** Flow through string formatting. */
private predicate formatStep(Expr tracked, Expr sink) {
exists(FormatterVar v, VariableAssign def |
def = v.getADef() and
exists(MethodAccess ma, RValue use |
exists(MethodCall ma, VarRead use |
ma.getAnArgument() = tracked and
ma = v.getAFormatMethodAccess() and
ma = v.getAFormatMethodCall() and
use = ma.getQualifier() and
defUsePair(def, use)
) and
exists(RValue output, ClassInstanceExpr cie |
exists(VarRead output, ClassInstanceExpr cie |
cie = def.getSource() and
output = cie.getArgument(0) and
adjacentUseUse(output, sink) and
@@ -505,7 +509,7 @@ private class FormatterVar extends LocalVariableDecl {
result.getDestVar() = this
}
MethodAccess getAFormatMethodAccess() {
MethodCall getAFormatMethodCall() {
result.getQualifier() = this.getAnAccess() and
result.getMethod().hasName("format")
}
@@ -555,7 +559,7 @@ module StringBuilderVarModule {
/**
* Gets a call that adds something to this string builder, from the argument at the given index.
*/
MethodAccess getAnInput(int arg) {
MethodCall getAnInput(int arg) {
result.getQualifier() = this.getAChainedReference() and
(
result.getMethod().getName() = "append" and arg = 0
@@ -569,19 +573,19 @@ module StringBuilderVarModule {
/**
* Gets a call that appends something to this string builder.
*/
MethodAccess getAnAppend() {
MethodCall getAnAppend() {
result.getQualifier() = this.getAChainedReference() and
result.getMethod().getName() = "append"
}
MethodAccess getNextAppend(MethodAccess append) {
MethodCall getNextAppend(MethodCall append) {
result = this.getAnAppend() and
append = this.getAnAppend() and
(
result.getQualifier() = append
or
not exists(MethodAccess chainAccess | chainAccess.getQualifier() = append) and
exists(RValue sbva1, RValue sbva2 |
not exists(MethodCall chainAccess | chainAccess.getQualifier() = append) and
exists(VarRead sbva1, VarRead sbva2 |
adjacentUseUse(sbva1, sbva2) and
append.getQualifier() = this.getAChainedReference(sbva1) and
result.getQualifier() = sbva2
@@ -592,7 +596,7 @@ module StringBuilderVarModule {
/**
* Gets a call that converts this string builder to a string.
*/
MethodAccess getToStringCall() {
MethodCall getToStringCall() {
result.getQualifier() = this.getAChainedReference() and
result.getMethod().getName() = "toString"
}
@@ -612,7 +616,7 @@ module StringBuilderVarModule {
}
}
private MethodAccess callReturningSameType(Expr ref) {
private MethodCall callReturningSameType(Expr ref) {
ref = result.getQualifier() and
result.getMethod().getReturnType() = ref.getType()
}

View File

@@ -10,6 +10,8 @@ class SsaVariable = Ssa::SsaVariable;
class Expr = J::Expr;
class Location = J::Location;
class IntegralType = J::IntegralType;
class ConstantIntegerExpr = RU::ConstantIntegerExpr;

View File

@@ -200,11 +200,11 @@ private module Impl {
* `Collection`).
*/
predicate containerSizeAccess(Expr e) {
e.(MethodAccess).getMethod() instanceof StringLengthMethod
e.(MethodCall).getMethod() instanceof StringLengthMethod
or
e.(MethodAccess).getMethod() instanceof CollectionSizeMethod
e.(MethodCall).getMethod() instanceof CollectionSizeMethod
or
e.(MethodAccess).getMethod() instanceof MapSizeMethod
e.(MethodCall).getMethod() instanceof MapSizeMethod
}
/** Holds if `e` is by definition strictly positive. */
@@ -218,7 +218,7 @@ private module Impl {
// types handled in `specificSubExprSign`.
e instanceof ArrayAccess and e.getType() instanceof NumericOrCharType
or
e instanceof MethodAccess and e.getType() instanceof NumericOrCharType
e instanceof MethodCall and e.getType() instanceof NumericOrCharType
or
e instanceof ClassInstanceExpr and e.getType() instanceof NumericOrCharType
}
@@ -267,7 +267,7 @@ private module Impl {
/** Holds if `f` can have any sign. */
predicate fieldWithUnknownSign(Field f) {
exists(ReflectiveFieldAccess rfa | rfa.inferAccessedField() = f)
exists(ReflectiveGetFieldCall rfa | rfa.inferAccessedField() = f)
}
/** Holds if `f` is accessed in an increment operation. */

View File

@@ -173,9 +173,9 @@ class LiveClass extends SourceClassOrInterface {
exists(NestedType r | r.getEnclosingType() = this | r instanceof LiveClass)
or
// An annotation on the class is reflectively accessed.
exists(ReflectiveAnnotationAccess reflectiveAnnotationAccess |
this = reflectiveAnnotationAccess.getInferredClassType() and
isLive(reflectiveAnnotationAccess.getEnclosingCallable())
exists(ReflectiveGetAnnotationCall reflectiveAnnotationCall |
this = reflectiveAnnotationCall.getInferredClassType() and
isLive(reflectiveAnnotationCall.getEnclosingCallable())
)
or
this instanceof AnonymousClass

View File

@@ -19,7 +19,7 @@ VarAccess valueAccess(EnumConstant e) {
(
exists(Call c |
c.getAnArgument() = valueFlow+(result) or
c.(MethodAccess).getQualifier() = valueFlow+(result)
c.(MethodCall).getQualifier() = valueFlow+(result)
)
or
exists(Assignment a | a.getSource() = valueFlow+(result))
@@ -47,14 +47,14 @@ predicate exception(EnumConstant e) {
)
or
// A method iterates over the values of an enum.
exists(MethodAccess values | values.getMethod().getDeclaringType() = t |
exists(MethodCall values | values.getMethod().getDeclaringType() = t |
values.getParent() instanceof EnhancedForStmt or
values.getParent().(MethodAccess).getMethod().hasName("findThisIn")
values.getParent().(MethodCall).getMethod().hasName("findThisIn")
)
or
// The `valueOf` method is called, meaning that depending on the string any constant
// could be retrieved.
exists(MethodAccess valueOf | valueOf.getMethod().getDeclaringType() = t |
exists(MethodCall valueOf | valueOf.getMethod().getDeclaringType() = t |
valueOf.getMethod().hasName("valueOf")
)
or

View File

@@ -130,7 +130,7 @@ class JUnitAnnotatedField extends ReflectivelyReadField {
*/
class ClassReflectivelyReadField extends ReflectivelyReadField {
ClassReflectivelyReadField() {
exists(ReflectiveFieldAccess fieldAccess | this = fieldAccess.inferAccessedField())
exists(ReflectiveGetFieldCall fieldAccess | this = fieldAccess.inferAccessedField())
}
}

View File

@@ -142,7 +142,7 @@ deprecated class JAXAnnotationReflectivelyConstructedClass =
class DeserializedClass extends ReflectivelyConstructedClass {
DeserializedClass() {
exists(CastingExpr cast, ReadObjectMethod readObject |
cast.getExpr().(MethodAccess).getMethod() = readObject
cast.getExpr().(MethodCall).getMethod() = readObject
|
hasDescendant(cast.getType(), this)
)
@@ -164,7 +164,7 @@ class NewInstanceCall extends EntryPoint, NewInstance {
/**
* A call to either `Class.getMethod(...)` or `Class.getDeclaredMethod(...)`.
*/
class ReflectiveMethodAccessEntryPoint extends EntryPoint, ReflectiveMethodAccess {
class ReflectiveGetMethodCallEntryPoint extends EntryPoint, ReflectiveGetMethodCall {
override Method getALiveCallable() {
result = this.inferAccessedMethod() and
// The `getMethod(...)` call must be used in a live context.
@@ -172,6 +172,9 @@ class ReflectiveMethodAccessEntryPoint extends EntryPoint, ReflectiveMethodAcces
}
}
/** DEPRECATED: Alias for `ReflectiveGetMethodCallEntryPoint`. */
deprecated class ReflectiveMethodAccessEntryPoint = ReflectiveGetMethodCallEntryPoint;
/**
* Classes that are entry points recognised by annotations.
*/

View File

@@ -19,7 +19,7 @@ private import codeql.typetracking.TypeTracking
/**
* Gets a viable dispatch target for `ma`. This is the input dispatch relation.
*/
private Method viableImpl_inp(MethodAccess ma) { result = viableImpl_v2(ma) }
private Method viableImpl_inp(MethodCall ma) { result = viableImpl_v2(ma) }
private Callable dispatchCand(Call c) {
c instanceof ConstructorCall and result = c.getCallee().getSourceDeclaration()
@@ -99,7 +99,7 @@ private predicate trackedMethodOnType(Method m, SrcRefType t) {
* by the type constructed by `cie`. Thus the dispatch from `ma` to `m` will
* only be included if `cie` flows to the qualifier of `ma`.
*/
private predicate dispatchOrigin(ClassInstanceExpr cie, MethodAccess ma, Method m) {
private predicate dispatchOrigin(ClassInstanceExpr cie, MethodCall ma, Method m) {
m = viableImpl_inp(ma) and
not m = ma.getMethod().getSourceDeclaration() and
trackedMethodOnType(m, cie.getConstructedType().getSourceDeclaration())
@@ -133,7 +133,7 @@ private module TypeTrackingSteps {
class LocalSourceNode extends RelevantNode {
LocalSourceNode() {
this.asExpr() instanceof Call or
this.asExpr() instanceof RValue or
this.asExpr() instanceof VarRead or
this instanceof DataFlow::ParameterNode or
this instanceof DataFlow::ImplicitVarargsArray or
this.asExpr() instanceof ArrayInit or
@@ -197,10 +197,10 @@ private module TypeTrackingSteps {
enum.getAnEnumConstant().getAnAssignedValue() = n1.asExpr() and
getValue.getDeclaringType() = enum and
getValue.hasName("valueOf") and
n2.asExpr().(MethodAccess).getMethod() = getValue
n2.asExpr().(MethodCall).getMethod() = getValue
)
or
exists(Variable v, MethodAccess put, MethodAccess get |
exists(Variable v, MethodCall put, MethodCall get |
put.getArgument(1) = n1.asExpr() and
put.getMethod().(MapMethod).hasName("put") and
put.getQualifier() = v.getAnAccess() and
@@ -209,12 +209,12 @@ private module TypeTrackingSteps {
n2.asExpr() = get
)
or
exists(Variable v, MethodAccess add |
exists(Variable v, MethodCall add |
add.getAnArgument() = n1.asExpr() and
add.getMethod().(CollectionMethod).hasName("add") and
add.getQualifier() = v.getAnAccess()
|
exists(MethodAccess get |
exists(MethodCall get |
get.getQualifier() = v.getAnAccess() and
get.getMethod().(CollectionMethod).hasName("get") and
n2.asExpr() = get
@@ -236,7 +236,7 @@ private module TypeTrackingSteps {
enum.getAnEnumConstant().getAnAssignedValue() = n1.asExpr() and
getValue.getDeclaringType() = enum and
getValue.hasName("values") and
n2.asExpr().(MethodAccess).getMethod() = getValue and
n2.asExpr().(MethodCall).getMethod() = getValue and
f = ContentArray()
)
or
@@ -253,7 +253,7 @@ private module TypeTrackingSteps {
exists(AssignExpr a, Variable v |
a.getSource() = n1.asExpr() and
a.getDest().(ArrayAccess).getArray() = v.getAnAccess() and
n2.asExpr() = v.getAnAccess().(RValue) and
n2.asExpr() = v.getAnAccess().(VarRead) and
f = ContentArray()
)
}
@@ -300,10 +300,10 @@ private module TypeTrackingSteps {
private predicate lambdaSource(RelevantNode n) { dispatchOrigin(n.asExpr(), _, _) }
private predicate lambdaSink(RelevantNode n) {
exists(MethodAccess ma | dispatchOrigin(_, ma, _) | n = DataFlow::getInstanceArgument(ma))
exists(MethodCall ma | dispatchOrigin(_, ma, _) | n = DataFlow::getInstanceArgument(ma))
}
private signature Method methodDispatchSig(MethodAccess ma);
private signature Method methodDispatchSig(MethodCall ma);
private module TrackLambda<methodDispatchSig/1 lambdaDispatch0> {
private Callable dispatch(Call c) {
@@ -352,7 +352,7 @@ private module TrackLambda<methodDispatchSig/1 lambdaDispatch0> {
private predicate edgePlus(PathNode n1, PathNode n2) = fastTC(edges/2)(n1, n2)
private predicate pairCand(PathNode p1, PathNode p2, Method m, MethodAccess ma) {
private predicate pairCand(PathNode p1, PathNode p2, Method m, MethodCall ma) {
exists(ClassInstanceExpr cie |
dispatchOrigin(cie, ma, m) and
p1.getNode() = DataFlow::exprNode(cie) and
@@ -367,7 +367,7 @@ private module TrackLambda<methodDispatchSig/1 lambdaDispatch0> {
* declares or inherits the tracked method `result` to the qualifier of `ma` such
* that `ma` may dispatch to `result`.
*/
Method lambdaDispatch(MethodAccess ma) {
Method lambdaDispatch(MethodCall ma) {
exists(PathNode p1, PathNode p2 |
(p1 = p2 or edgePlus(p1, p2)) and
pairCand(p1, p2, result, ma)
@@ -375,30 +375,30 @@ private module TrackLambda<methodDispatchSig/1 lambdaDispatch0> {
}
}
private Method noDisp(MethodAccess ma) { none() }
private Method noDisp(MethodCall ma) { none() }
pragma[nomagic]
private Method d1(MethodAccess ma) { result = TrackLambda<noDisp/1>::lambdaDispatch(ma) }
private Method d1(MethodCall ma) { result = TrackLambda<noDisp/1>::lambdaDispatch(ma) }
pragma[nomagic]
private Method d2(MethodAccess ma) { result = TrackLambda<d1/1>::lambdaDispatch(ma) }
private Method d2(MethodCall ma) { result = TrackLambda<d1/1>::lambdaDispatch(ma) }
pragma[nomagic]
private Method d3(MethodAccess ma) { result = TrackLambda<d2/1>::lambdaDispatch(ma) }
private Method d3(MethodCall ma) { result = TrackLambda<d2/1>::lambdaDispatch(ma) }
pragma[nomagic]
private Method d4(MethodAccess ma) { result = TrackLambda<d3/1>::lambdaDispatch(ma) }
private Method d4(MethodCall ma) { result = TrackLambda<d3/1>::lambdaDispatch(ma) }
pragma[nomagic]
private Method d5(MethodAccess ma) { result = TrackLambda<d4/1>::lambdaDispatch(ma) }
private Method d5(MethodCall ma) { result = TrackLambda<d4/1>::lambdaDispatch(ma) }
pragma[nomagic]
private Method d6(MethodAccess ma) { result = TrackLambda<d5/1>::lambdaDispatch(ma) }
private Method d6(MethodCall ma) { result = TrackLambda<d5/1>::lambdaDispatch(ma) }
/**
* Gets a viable dispatch target for `ma`. This is the output dispatch relation.
*/
Method viableImpl_out(MethodAccess ma) {
Method viableImpl_out(MethodCall ma) {
result = viableImpl_inp(ma) and
(result = d6(ma) or not dispatchOrigin(_, ma, result))
}

View File

@@ -20,7 +20,7 @@ private import semmle.code.java.dispatch.internal.Unification
/**
* Gets a viable dispatch target for `ma`. This is the input dispatch relation.
*/
private Method viableImpl_inp(MethodAccess ma) { result = viableImpl_v3(ma) }
private Method viableImpl_inp(MethodCall ma) { result = viableImpl_v3(ma) }
private Callable dispatchCand(Call c) {
c instanceof ConstructorCall and result = c.getCallee().getSourceDeclaration()
@@ -118,7 +118,7 @@ private predicate step(Node n1, Node n2) {
exists(AssignExpr a, Field v |
a.getSource() = n1.asExpr() and
a.getDest().(ArrayAccess).getArray() = v.getAnAccess() and
n2.asExpr() = v.getAnAccess().(RValue)
n2.asExpr() = v.getAnAccess().(VarRead)
)
or
exists(AssignExpr a |
@@ -193,7 +193,7 @@ private predicate source(RefType t, ObjNode n) {
* Holds if `n` is the qualifier of an `Object.toString()` call.
*/
private predicate sink(ObjNode n) {
exists(MethodAccess toString |
exists(MethodCall toString |
toString.getQualifier() = n.asExpr() and
toString.getMethod() instanceof ToStringMethod
) and
@@ -231,7 +231,7 @@ private predicate objType(ObjNode n, RefType t) {
)
}
private VirtualMethodAccess objectToString(ObjNode n) {
private VirtualMethodCall objectToString(ObjNode n) {
result.getQualifier() = n.asExpr() and sink(n)
}
@@ -239,16 +239,16 @@ private VirtualMethodAccess objectToString(ObjNode n) {
* Holds if `ma` is an `Object.toString()` call taking possibly improved type
* bounds into account.
*/
predicate objectToStringCall(VirtualMethodAccess ma) { ma = objectToString(_) }
predicate objectToStringCall(VirtualMethodCall ma) { ma = objectToString(_) }
/**
* Holds if the qualifier of the `Object.toString()` call `ma` might have type `t`.
*/
private predicate objectToStringQualType(MethodAccess ma, RefType t) {
private predicate objectToStringQualType(MethodCall ma, RefType t) {
exists(ObjNode n | ma = objectToString(n) and objType(n, t))
}
private Method viableImplObjectToString(MethodAccess ma) {
private Method viableImplObjectToString(MethodCall ma) {
exists(Method def, RefType t |
objectToStringQualType(ma, t) and
def = ma.getMethod() and
@@ -265,7 +265,7 @@ private Method viableImplObjectToString(MethodAccess ma) {
* The set of dispatch targets for `Object.toString()` calls are reduced based
* on possible data flow from objects of more specific types to the qualifier.
*/
Method viableImpl_out(MethodAccess ma) {
Method viableImpl_out(MethodCall ma) {
result = viableImpl_inp(ma) and
(
result = viableImplObjectToString(ma) or

View File

@@ -15,7 +15,7 @@ private import semmle.code.java.dispatch.internal.Unification
* A conservative analysis that returns a single method - if we can establish
* one - that will be the target of the virtual dispatch.
*/
Method exactVirtualMethod(MethodAccess c) {
Method exactVirtualMethod(MethodCall c) {
// If there are multiple potential implementations, return nothing.
implCount(c, 1) and
result = viableImpl(c)
@@ -31,7 +31,7 @@ Callable exactCallable(Call c) {
c instanceof ConstructorCall and result = c.getCallee()
}
private predicate implCount(MethodAccess m, int c) { strictcount(viableImpl(m)) = c }
private predicate implCount(MethodCall m, int c) { strictcount(viableImpl(m)) = c }
/** Gets a viable implementation of the target of the given `Call`. */
Callable viableCallable(Call c) {
@@ -44,7 +44,7 @@ Callable viableCallable(Call c) {
class VirtCalledSrcMethod extends SrcMethod {
pragma[nomagic]
VirtCalledSrcMethod() {
exists(VirtualMethodAccess ma | ma.getMethod().getSourceDeclaration() = this)
exists(VirtualMethodCall ma | ma.getMethod().getSourceDeclaration() = this)
}
}
@@ -52,7 +52,7 @@ cached
private module Dispatch {
/** Gets a viable implementation of the method called in the given method access. */
cached
Method viableImpl(MethodAccess ma) { result = ObjFlow::viableImpl_out(ma) }
Method viableImpl(MethodCall ma) { result = ObjFlow::viableImpl_out(ma) }
/**
* Holds if `m` is a viable implementation of the method called in `ma` for
@@ -60,7 +60,7 @@ private module Dispatch {
* the dispatch type is likely to yield implausible dispatch targets.
*/
cached
predicate lowConfidenceDispatchTarget(MethodAccess ma, Method m) {
predicate lowConfidenceDispatchTarget(MethodCall ma, Method m) {
m = viableImpl(ma) and lowConfidenceDispatch(ma)
}
@@ -70,13 +70,13 @@ private module Dispatch {
* Gets a viable implementation of the method called in the given method access.
*/
cached
Method viableImpl_v3(MethodAccess ma) { result = DispatchFlow::viableImpl_out(ma) }
Method viableImpl_v3(MethodCall ma) { result = DispatchFlow::viableImpl_out(ma) }
/**
* Holds if the best type bounds for the qualifier of `ma` are likely to
* contain implausible dispatch targets.
*/
private predicate lowConfidenceDispatch(VirtualMethodAccess ma) {
private predicate lowConfidenceDispatch(VirtualMethodCall ma) {
exists(RefType t | hasQualifierType(ma, t, false) |
lowConfidenceDispatchType(t.getSourceDeclaration())
) and
@@ -121,7 +121,7 @@ private module Dispatch {
* Gets a viable implementation of the method called in the given method access.
*/
cached
Method viableImpl_v2(MethodAccess ma) {
Method viableImpl_v2(MethodCall ma) {
result = viableImpl_v2_cand(pragma[only_bind_into](ma)) and
exists(Method def, RefType t, boolean exact |
qualUnionType(pragma[only_bind_into](ma), pragma[only_bind_into](t),
@@ -141,7 +141,7 @@ private module Dispatch {
not qualUnionType(ma, _, _)
}
private predicate qualUnionType(VirtualMethodAccess ma, RefType t, boolean exact) {
private predicate qualUnionType(VirtualMethodCall ma, RefType t, boolean exact) {
exprUnionTypeFlow(ma.getQualifier(), t, exact)
}
@@ -150,7 +150,7 @@ private module Dispatch {
private module Unification_v2 =
MkUnification<unificationTargetLeft_v2/1, unificationTargetRight/1>;
private Method viableImpl_v2_cand(MethodAccess ma) {
private Method viableImpl_v2_cand(MethodCall ma) {
result = viableImpl_v1(ma) and
(
exists(Method def, RefType t, boolean exact |
@@ -170,7 +170,7 @@ private module Dispatch {
)
}
private predicate qualType(VirtualMethodAccess ma, RefType t, boolean exact) {
private predicate qualType(VirtualMethodCall ma, RefType t, boolean exact) {
exprTypeFlow(ma.getQualifier(), t, exact)
}
@@ -185,7 +185,7 @@ private module Dispatch {
* Gets a viable implementation of the method called in the given method access.
*/
cached
Method viableImpl_v1(MethodAccess source) {
Method viableImpl_v1(MethodCall source) {
result = viableImpl_v1_cand(source) and
not impossibleDispatchTarget(source, result)
}
@@ -193,7 +193,7 @@ private module Dispatch {
/**
* Holds if `source` cannot dispatch to `tgt` due to a negative `instanceof` guard.
*/
private predicate impossibleDispatchTarget(MethodAccess source, Method tgt) {
private predicate impossibleDispatchTarget(MethodCall source, Method tgt) {
tgt = viableImpl_v1_cand(source) and
exists(InstanceOfExpr ioe, BaseSsaVariable v, Expr q, RefType t |
source.getQualifier() = q and
@@ -208,9 +208,9 @@ private module Dispatch {
/**
* Gets a viable implementation of the method called in the given method access.
*/
private Method viableImpl_v1_cand(MethodAccess source) {
private Method viableImpl_v1_cand(MethodCall source) {
not result.isAbstract() and
if source instanceof VirtualMethodAccess
if source instanceof VirtualMethodCall
then
exists(VirtCalledSrcMethod def, RefType t, boolean exact |
source.getMethod().getSourceDeclaration() = def and
@@ -242,7 +242,7 @@ private module Dispatch {
not e instanceof FunctionalExpr and result = e.getType()
}
private predicate hasQualifierType(VirtualMethodAccess ma, RefType t, boolean exact) {
private predicate hasQualifierType(VirtualMethodCall ma, RefType t, boolean exact) {
exists(Expr src | src = ma.getQualifier() |
// If we have a qualifier, then we take its type.
exists(RefType srctype | srctype = getPreciseType(src) |
@@ -264,9 +264,9 @@ private module Dispatch {
not exists(ma.getQualifier()) and
exact = false and
(
ma.isOwnMethodAccess() and t = ma.getEnclosingCallable().getDeclaringType()
ma.isOwnMethodCall() and t = ma.getEnclosingCallable().getDeclaringType()
or
ma.isEnclosingMethodAccess(t)
ma.isEnclosingMethodCall(t)
)
}

View File

@@ -16,7 +16,7 @@ private predicate runner(Method m, int n, Method runmethod) {
(
m.isNative()
or
exists(Parameter p, MethodAccess ma, int j |
exists(Parameter p, MethodCall ma, int j |
p = m.getParameter(n) and
ma.getEnclosingCallable() = m and
runner(pragma[only_bind_into](ma.getMethod().getSourceDeclaration()),
@@ -31,7 +31,7 @@ private predicate runner(Method m, int n, Method runmethod) {
* through a functional interface. The argument is traced backwards through
* casts and variable assignments.
*/
private Expr getRunnerArgument(MethodAccess ma, Method runmethod) {
private Expr getRunnerArgument(MethodCall ma, Method runmethod) {
exists(Method runner, int param |
runner(runner, param, runmethod) and
viableImpl_v2(ma) = runner and
@@ -50,7 +50,7 @@ private Expr getRunnerArgument(MethodAccess ma, Method runmethod) {
* Gets a method that can be invoked through a functional interface as an
* argument to `ma`.
*/
Method getRunnerTarget(MethodAccess ma) {
Method getRunnerTarget(MethodCall ma) {
exists(Expr action, Method runmethod | action = getRunnerArgument(ma, runmethod) |
action.(FunctionalExpr).asMethod().getSourceDeclaration() = result
or

View File

@@ -23,8 +23,8 @@ Expr getSystemProperty(string propertyName) {
result = getSystemPropertyFromSpringProperties(propertyName)
}
private MethodAccess getSystemPropertyFromSystem(string propertyName) {
result.(MethodAccessSystemGetProperty).hasCompileTimeConstantGetPropertyName(propertyName)
private MethodCall getSystemPropertyFromSystem(string propertyName) {
result.(MethodCallSystemGetProperty).hasCompileTimeConstantGetPropertyName(propertyName)
or
result.getMethod().hasName("lineSeparator") and propertyName = "line.separator"
}
@@ -34,7 +34,7 @@ private MethodAccess getSystemPropertyFromSystem(string propertyName) {
* - `System.getProperties().getProperty(...)`
* - `System.getProperties().get(...)`
*/
private MethodAccess getSystemPropertyFromSystemGetProperties(string propertyName) {
private MethodCall getSystemPropertyFromSystemGetProperties(string propertyName) {
exists(Method getMethod |
getMethod instanceof PropertiesGetMethod
or
@@ -42,7 +42,7 @@ private MethodAccess getSystemPropertyFromSystemGetProperties(string propertyNam
result.getMethod() = getMethod
) and
result.getArgument(0).(CompileTimeConstantExpr).getStringValue() = propertyName and
localExprFlowPlusInitializers(any(MethodAccess m |
localExprFlowPlusInitializers(any(MethodCall m |
m.getMethod().getDeclaringType() instanceof TypeSystem and
m.getMethod().hasName("getProperties")
), result.getQualifier())
@@ -156,7 +156,7 @@ private FieldAccess getSystemPropertyFromApacheSystemUtils(string propertyName)
)
}
private MethodAccess getSystemPropertyFromApacheFileUtils(string propertyName) {
private MethodCall getSystemPropertyFromApacheFileUtils(string propertyName) {
exists(Method m |
result.getMethod() = m and
m.getDeclaringType().hasQualifiedName("org.apache.commons.io", "FileUtils")
@@ -167,7 +167,7 @@ private MethodAccess getSystemPropertyFromApacheFileUtils(string propertyName) {
)
}
private MethodAccess getSystemPropertyFromGuava(string propertyName) {
private MethodCall getSystemPropertyFromGuava(string propertyName) {
exists(EnumConstant ec |
ec.getDeclaringType().hasQualifiedName("com.google.common.base", "StandardSystemProperty") and
// Example: `StandardSystemProperty.JAVA_IO_TMPDIR.value()`
@@ -177,10 +177,10 @@ private MethodAccess getSystemPropertyFromGuava(string propertyName) {
)
or
// Example: `System.getProperty(StandardSystemProperty.JAVA_IO_TMPDIR.key())`
exists(MethodAccess keyMa |
exists(MethodCall keyMa |
localExprFlowPlusInitializers(ec.getAnAccess(), keyMa.getQualifier()) and
keyMa.getMethod().hasName("key") and
localExprFlowPlusInitializers(keyMa, result.(MethodAccessSystemGetProperty).getArgument(0))
localExprFlowPlusInitializers(keyMa, result.(MethodCallSystemGetProperty).getArgument(0))
)
|
ec.hasName("JAVA_VERSION") and propertyName = "java.version"
@@ -241,7 +241,7 @@ private MethodAccess getSystemPropertyFromGuava(string propertyName) {
)
}
private MethodAccess getSystemPropertyFromOperatingSystemMXBean(string propertyName) {
private MethodCall getSystemPropertyFromOperatingSystemMXBean(string propertyName) {
exists(Method m |
m = result.getMethod() and
m.getDeclaringType().hasQualifiedName("java.lang.management", "OperatingSystemMXBean")
@@ -254,7 +254,7 @@ private MethodAccess getSystemPropertyFromOperatingSystemMXBean(string propertyN
)
}
private MethodAccess getSystemPropertyFromSpringProperties(string propertyName) {
private MethodCall getSystemPropertyFromSpringProperties(string propertyName) {
exists(Method m |
m = result.getMethod() and
m.getDeclaringType().hasQualifiedName("org.springframework.core", "SpringProperties") and

View File

@@ -60,10 +60,10 @@ class AssertionMethod extends Method {
AssertionMethod() { assertionMethod(this, _) }
/** Gets a call to the assertion method. */
MethodAccess getACheck() { result.getMethod().getSourceDeclaration() = this }
MethodCall getACheck() { result.getMethod().getSourceDeclaration() = this }
/** Gets a call to the assertion method with `checkedArg` as argument. */
MethodAccess getACheck(Expr checkedArg) {
MethodCall getACheck(Expr checkedArg) {
result = this.getACheck() and checkedArg = result.getAnArgument()
}
}

View File

@@ -24,7 +24,7 @@ class FastJsonParseMethod extends Method {
/**
* A call to `ParserConfig.setSafeMode`.
*/
class FastJsonSetSafeMode extends MethodAccess {
class FastJsonSetSafeMode extends MethodCall {
FastJsonSetSafeMode() {
exists(Method m |
this.getMethod() = m and

View File

@@ -44,7 +44,7 @@ class ObjectMapperReadMethod extends Method {
}
/** A call that enables the default typing in `ObjectMapper`. */
class EnableJacksonDefaultTyping extends MethodAccess {
class EnableJacksonDefaultTyping extends MethodCall {
EnableJacksonDefaultTyping() {
this.getMethod().getDeclaringType() instanceof ObjectMapper and
this.getMethod().hasName("enableDefaultTyping")
@@ -54,7 +54,7 @@ class EnableJacksonDefaultTyping extends MethodAccess {
/** A qualifier of a call to one of the methods in `ObjectMapper` that deserialize data. */
class ObjectMapperReadQualifier extends DataFlow::ExprNode {
ObjectMapperReadQualifier() {
exists(MethodAccess ma | ma.getQualifier() = this.asExpr() |
exists(MethodCall ma | ma.getQualifier() = this.asExpr() |
ma.getMethod() instanceof ObjectMapperReadMethod
)
}
@@ -63,7 +63,7 @@ class ObjectMapperReadQualifier extends DataFlow::ExprNode {
/** A source that sets a type validator. */
class SetPolymorphicTypeValidatorSource extends DataFlow::ExprNode {
SetPolymorphicTypeValidatorSource() {
exists(MethodAccess ma, Method m | m = ma.getMethod() |
exists(MethodCall ma, Method m | m = ma.getMethod() |
(
m.getDeclaringType() instanceof ObjectMapper and
m.hasName("setPolymorphicTypeValidator")
@@ -83,7 +83,7 @@ class SetPolymorphicTypeValidatorSource extends DataFlow::ExprNode {
* if passed to an unsafely-configured `ObjectMapper`'s `readValue` method.
*/
predicate createJacksonJsonParserStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
exists(MethodAccess ma, Method m | m = ma.getMethod() |
exists(MethodCall ma, Method m | m = ma.getMethod() |
(m.getDeclaringType() instanceof ObjectMapper or m.getDeclaringType() instanceof JsonFactory) and
m.hasName("createParser") and
ma.getArgument(0) = fromNode.asExpr() and
@@ -98,14 +98,14 @@ predicate createJacksonJsonParserStep(DataFlow::Node fromNode, DataFlow::Node to
* if passed to an unsafely-configured `ObjectMapper`'s `treeToValue` method.
*/
predicate createJacksonTreeNodeStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
exists(MethodAccess ma, Method m | m = ma.getMethod() |
exists(MethodCall ma, Method m | m = ma.getMethod() |
m.getDeclaringType() instanceof ObjectMapper and
m.hasName("readTree") and
ma.getArgument(0) = fromNode.asExpr() and
ma = toNode.asExpr()
)
or
exists(MethodAccess ma, Method m | m = ma.getMethod() |
exists(MethodCall ma, Method m | m = ma.getMethod() |
m.getDeclaringType() instanceof JsonParser and
m.hasName("readValueAsTree") and
ma.getQualifier() = fromNode.asExpr() and
@@ -138,7 +138,7 @@ private predicate hasFieldWithJsonTypeAnnotation(RefType type) {
* Holds if `call` is a method call to a Jackson deserialization method such as `ObjectMapper.readValue(String, Class)`,
* and the target deserialized class has a field with a `JsonTypeInfo` annotation that enables polymorphic typing.
*/
predicate hasArgumentWithUnsafeJacksonAnnotation(MethodAccess call) {
predicate hasArgumentWithUnsafeJacksonAnnotation(MethodCall call) {
call.getMethod() instanceof ObjectMapperReadMethod and
exists(RefType argType, int i | i > 0 and argType = call.getArgument(i).getType() |
hasJsonTypeInfoAnnotation(argType.(ParameterizedType).getATypeArgument())

View File

@@ -437,7 +437,7 @@ private predicate isXssSafeContentTypeExpr(Expr e) { isXssSafeContentType(getCon
private DataFlow::Node getABuilderWithExplicitContentType(Expr contentType) {
// Base case: ResponseBuilder.type(contentType)
result.asExpr() =
any(MethodAccess ma |
any(MethodCall ma |
ma.getCallee().hasQualifiedName(getAJaxRsPackage("core"), "Response$ResponseBuilder", "type") and
contentType = ma.getArgument(0)
)
@@ -451,7 +451,7 @@ private DataFlow::Node getABuilderWithExplicitContentType(Expr contentType) {
or
// Base case: Variant[.VariantListBuilder].mediaTypes(...)
result.asExpr() =
any(MethodAccess ma |
any(MethodCall ma |
ma.getCallee()
.hasQualifiedName(getAJaxRsPackage("core"), ["Variant", "Variant$VariantListBuilder"],
"mediaTypes") and
@@ -460,7 +460,7 @@ private DataFlow::Node getABuilderWithExplicitContentType(Expr contentType) {
or
// Recursive case: propagate through variant list building:
result.asExpr() =
any(MethodAccess ma |
any(MethodCall ma |
(
ma.getType()
.(RefType)
@@ -475,14 +475,14 @@ private DataFlow::Node getABuilderWithExplicitContentType(Expr contentType) {
or
// Recursive case: propagate through a List.get operation
result.asExpr() =
any(MethodAccess ma |
any(MethodCall ma |
ma.getMethod().hasQualifiedName("java.util", "List<Variant>", "get") and
ma.getQualifier() = getABuilderWithExplicitContentType(contentType).asExpr()
)
or
// Recursive case: propagate through Response.ResponseBuilder operations, including the `variant(...)` operation.
result.asExpr() =
any(MethodAccess ma |
any(MethodCall ma |
ma.getType().(RefType).hasQualifiedName(getAJaxRsPackage("core"), "Response$ResponseBuilder") and
[ma.getQualifier(), ma.getArgument(0)] =
getABuilderWithExplicitContentType(contentType).asExpr()
@@ -518,7 +518,7 @@ private class SanitizedResponseBuilder extends XssSanitizer {
this = getASanitizedBuilder()
or
this.asExpr() =
any(MethodAccess ma |
any(MethodCall ma |
ma.getMethod().hasQualifiedName(getAJaxRsPackage("core"), "Response", "ok") and
(
// e.g. Response.ok(sanitizeMe, new Variant("application/json", ...))
@@ -542,19 +542,19 @@ private class SanitizedResponseBuilder extends XssSanitizer {
private class VulnerableEntity extends XssSinkBarrier {
VulnerableEntity() {
this.asExpr() =
any(MethodAccess ma |
any(MethodCall ma |
(
// Vulnerable content-type already set:
ma.getQualifier() = getAVulnerableBuilder().asExpr()
or
// Vulnerable content-type set in the future:
getAVulnerableBuilder().asExpr().(MethodAccess).getQualifier*() = ma
getAVulnerableBuilder().asExpr().(MethodCall).getQualifier*() = ma
) and
ma.getMethod().hasName("entity")
).getArgument(0)
or
this.asExpr() =
any(MethodAccess ma |
any(MethodCall ma |
(
isXssVulnerableContentTypeExpr(ma.getArgument(1))
or

View File

@@ -33,7 +33,7 @@ class JsonIoReadObjectMethod extends Method {
/**
* A call to `Map.put` method, set the value of the `USE_MAPS` key to `true`.
*/
class JsonIoUseMapsSetter extends MethodAccess {
class JsonIoUseMapsSetter extends MethodCall {
JsonIoUseMapsSetter() {
this.getMethod().getDeclaringType().getASourceSupertype*() instanceof MapType and
this.getMethod().hasName("put") and
@@ -51,14 +51,14 @@ deprecated class SafeJsonIoConfig extends DataFlow2::Configuration {
SafeJsonIoConfig() { this = "UnsafeDeserialization::SafeJsonIoConfig" }
override predicate isSource(DataFlow::Node src) {
exists(MethodAccess ma |
exists(MethodCall ma |
ma instanceof JsonIoUseMapsSetter and
src.asExpr() = ma.getQualifier()
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
exists(MethodCall ma |
ma.getMethod() instanceof JsonIoJsonToJavaMethod and
sink.asExpr() = ma.getArgument(1)
)
@@ -75,14 +75,14 @@ deprecated class SafeJsonIoConfig extends DataFlow2::Configuration {
*/
module SafeJsonIoConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) {
exists(MethodAccess ma |
exists(MethodCall ma |
ma instanceof JsonIoUseMapsSetter and
src.asExpr() = ma.getQualifier()
)
}
predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
exists(MethodCall ma |
ma.getMethod() instanceof JsonIoJsonToJavaMethod and
sink.asExpr() = ma.getArgument(1)
)

View File

@@ -76,7 +76,7 @@ class KryoReadObjectMethod extends Method {
/**
* A call to `Kryo.setRegistrationRequired` that enables white-listing.
*/
class KryoEnableWhiteListing extends MethodAccess {
class KryoEnableWhiteListing extends MethodCall {
KryoEnableWhiteListing() {
exists(Method m |
m = this.getMethod() and

View File

@@ -17,14 +17,17 @@ class MockitoVerifyMethod extends Method {
}
/**
* A MethodAccess which is called as part of a Mockito verification setup.
* A MethodCall which is called as part of a Mockito verification setup.
*/
class MockitoVerifiedMethodAccess extends MethodAccess {
MockitoVerifiedMethodAccess() {
this.getQualifier().(MethodAccess).getMethod() instanceof MockitoVerifyMethod
class MockitoVerifiedMethodCall extends MethodCall {
MockitoVerifiedMethodCall() {
this.getQualifier().(MethodCall).getMethod() instanceof MockitoVerifyMethod
}
}
/** DEPRECATED: Alias for `MockitoVerifiedMethodCall`. */
deprecated class MockitoVerifiedMethodAccess = MockitoVerifiedMethodCall;
/**
* A type that can be mocked by Mockito.
*/
@@ -75,9 +78,7 @@ class MockitoInitedTest extends Class {
m.calls*(initMocks)
)
or
exists(MethodAccess call | call.getCallee() = initMocks |
call.getArgument(0).getType() = this
)
exists(MethodCall call | call.getCallee() = initMocks | call.getArgument(0).getType() = this)
)
}
}
@@ -383,12 +384,12 @@ class MockitoMockMethod extends Method {
class MockitoMockedObject extends Expr {
MockitoMockedObject() {
this.(MethodAccess).getMethod() instanceof MockitoMockMethod
this.(MethodCall).getMethod() instanceof MockitoMockMethod
or
this.(VarAccess).getVariable().getAnAssignedValue() instanceof MockitoMockedObject
or
exists(ReturnStmt ret |
this.(MethodAccess).getMethod() = ret.getEnclosingCallable() and
this.(MethodCall).getMethod() = ret.getEnclosingCallable() and
ret.getResult() instanceof MockitoMockedObject
)
}

View File

@@ -114,7 +114,7 @@ class MyBatisInjectionSink extends DataFlow::Node {
private class MyBatisProviderStep extends TaintTracking::AdditionalValueStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodAccess ma, Annotation a, Method providerMethod |
exists(MethodCall ma, Annotation a, Method providerMethod |
exists(int i |
ma.getArgument(pragma[only_bind_into](i)) = n1.asExpr() and
providerMethod.getParameter(pragma[only_bind_into](i)) = n2.asParameter()

View File

@@ -16,7 +16,7 @@ class SeleniumPageFactory extends Class {
/**
* A call to the Selenium `PageFactory.initElements` method, to construct a page object.
*/
class SeleniumInitElementsAccess extends MethodAccess {
class SeleniumInitElementsAccess extends MethodCall {
SeleniumInitElementsAccess() {
this.getMethod().getDeclaringType() instanceof SeleniumPageFactory and
this.getMethod().hasName("initElements")

View File

@@ -345,7 +345,7 @@ predicate isServletRequestMethod(Method m) {
}
/** Holds if `ma` is a call that gets a request parameter. */
predicate isRequestGetParamMethod(MethodAccess ma) {
predicate isRequestGetParamMethod(MethodCall ma) {
ma.getMethod() instanceof ServletRequestGetParameterMethod or
ma.getMethod() instanceof ServletRequestGetParameterMapMethod or
ma.getMethod() instanceof HttpServletRequestGetQueryStringMethod

View File

@@ -53,7 +53,7 @@ private class SafeYaml extends ClassInstanceExpr {
}
/** A call to a parse method of `Yaml`. */
private class SnakeYamlParse extends MethodAccess {
private class SnakeYamlParse extends MethodCall {
SnakeYamlParse() {
exists(Method m |
m.getDeclaringType() instanceof Yaml and

View File

@@ -2,7 +2,7 @@
private import semmle.code.java.dataflow.FlowSummary
private class CollectCall extends MethodAccess {
private class CollectCall extends MethodCall {
CollectCall() {
this.getMethod()
.getSourceDeclaration()
@@ -10,7 +10,7 @@ private class CollectCall extends MethodAccess {
}
}
private class Collector extends MethodAccess {
private class Collector extends MethodCall {
Collector() {
this.getMethod().getDeclaringType().hasQualifiedName("java.util.stream", "Collectors")
}

View File

@@ -27,7 +27,7 @@ class XStreamReadObjectMethod extends Method {
/**
* A call to `XStream.addPermission(NoTypePermission.NONE)`, which enables white-listing.
*/
class XStreamEnableWhiteListing extends MethodAccess {
class XStreamEnableWhiteListing extends MethodCall {
XStreamEnableWhiteListing() {
exists(Method m |
m = this.getMethod() and

View File

@@ -15,7 +15,7 @@ private import semmle.code.java.dataflow.FlowSteps
*/
private class AsyncTaskExecuteAdditionalValueStep extends AdditionalTaintStep {
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
exists(ExecuteAsyncTaskMethodAccess ma, AsyncTaskRunInBackgroundMethod m |
exists(ExecuteAsyncTaskMethodCall ma, AsyncTaskRunInBackgroundMethod m |
DataFlow::getInstanceArgument(ma).getType() = m.getDeclaringType()
|
node1.asExpr() = ma.getParamsArgument() and
@@ -76,8 +76,8 @@ private class AsyncTaskInit extends Callable {
}
/** A call to the `execute` or `executeOnExecutor` methods of the `android.os.AsyncTask` class. */
private class ExecuteAsyncTaskMethodAccess extends MethodAccess {
ExecuteAsyncTaskMethodAccess() {
private class ExecuteAsyncTaskMethodCall extends MethodCall {
ExecuteAsyncTaskMethodCall() {
this.getMethod().hasName(["execute", "executeOnExecutor"]) and
this.getMethod().getDeclaringType().getSourceDeclaration().getASourceSupertype*() instanceof
AsyncTask

View File

@@ -8,7 +8,7 @@ import java
* A call to a live literal method.
* This always returns a constant expression and can be considered as such.
*/
class LiveLiteral extends MethodAccess {
class LiveLiteral extends MethodCall {
LiveLiteral() {
this.getMethod() instanceof LiveLiteralMethod and
not this.getEnclosingCallable() instanceof LiveLiteralMethod
@@ -25,7 +25,7 @@ class LiveLiteral extends MethodAccess {
* This predicate gets the constant value held by the private field.
*/
CompileTimeConstantExpr getValue() {
exists(MethodAccess getterCall, VarAccess va |
exists(MethodCall getterCall, VarAccess va |
methodReturns(this.getMethod(), getterCall) and
methodReturns(getterCall.getMethod(), va) and
result = va.getVariable().getInitializer()

View File

@@ -154,7 +154,7 @@ class AndroidBundle extends Class {
*/
class ExplicitIntent extends Expr {
ExplicitIntent() {
exists(MethodAccess ma, Method m |
exists(MethodCall ma, Method m |
ma.getMethod() = m and
m.getDeclaringType() instanceof TypeIntent and
m.hasName(["setPackage", "setClass", "setClassName", "setComponent"]) and
@@ -237,8 +237,8 @@ private class NewIntent extends ClassInstanceExpr {
}
/** A call to a method that starts an Android component. */
private class StartComponentMethodAccess extends MethodAccess {
StartComponentMethodAccess() {
private class StartComponentMethodCall extends MethodCall {
StartComponentMethodCall() {
this.getMethod().overrides*(any(StartActivityMethod m)) or
this.getMethod().overrides*(any(StartServiceMethod m)) or
this.getMethod().overrides*(any(SendBroadcastMethod m))
@@ -263,11 +263,11 @@ private class StartComponentMethodAccess extends MethodAccess {
}
/**
* Holds if `src` reaches the intent argument `arg` of `StartComponentMethodAccess`
* Holds if `src` reaches the intent argument `arg` of `StartComponentMethodCall`
* through intra-procedural steps.
*/
private predicate reaches(Expr src, Argument arg) {
any(StartComponentMethodAccess ma).getIntentArg() = arg and
any(StartComponentMethodCall ma).getIntentArg() = arg and
src = arg
or
exists(Expr mid, BaseSsa::BaseSsaVariable ssa, BaseSsa::BaseSsaUpdate upd |
@@ -298,7 +298,7 @@ private predicate reaches(Expr src, Argument arg) {
*/
private class StartActivityIntentStep extends AdditionalValueStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(StartComponentMethodAccess startActivity, MethodAccess getIntent |
exists(StartComponentMethodCall startActivity, MethodCall getIntent |
startActivity.getMethod().overrides*(any(StartActivityMethod m)) and
getIntent.getMethod().overrides*(any(AndroidGetIntentMethod m)) and
startActivity.targetsComponentType(getIntent.getReceiverType()) and
@@ -309,11 +309,11 @@ private class StartActivityIntentStep extends AdditionalValueStep {
}
/**
* Holds if `targetType` is targeted by an existing `StartComponentMethodAccess` call
* Holds if `targetType` is targeted by an existing `StartComponentMethodCall` call
* and it's identified by `id`.
*/
private predicate isTargetableType(AndroidComponent targetType, string id) {
exists(StartComponentMethodAccess ma | ma.targetsComponentType(targetType)) and
exists(StartComponentMethodCall ma | ma.targetsComponentType(targetType)) and
targetType.getQualifiedName() = id
}
@@ -327,7 +327,7 @@ private class StartActivitiesSyntheticCallable extends SyntheticCallable {
)
}
override StartComponentMethodAccess getACall() {
override StartComponentMethodCall getACall() {
result.getMethod().hasName("startActivities") and
result.targetsComponentType(targetType)
}
@@ -396,7 +396,7 @@ private class RequiredComponentStackForStartActivities extends RequiredSummaryCo
*/
private class SendBroadcastReceiverIntentStep extends AdditionalValueStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(StartComponentMethodAccess sendBroadcast, Method onReceive |
exists(StartComponentMethodCall sendBroadcast, Method onReceive |
sendBroadcast.getMethod().overrides*(any(SendBroadcastMethod m)) and
onReceive.overrides*(any(AndroidReceiveIntentMethod m)) and
sendBroadcast.targetsComponentType(onReceive.getDeclaringType()) and
@@ -413,7 +413,7 @@ private class SendBroadcastReceiverIntentStep extends AdditionalValueStep {
*/
private class StartServiceIntentStep extends AdditionalValueStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(StartComponentMethodAccess startService, Method serviceIntent |
exists(StartComponentMethodCall startService, Method serviceIntent |
startService.getMethod().overrides*(any(StartServiceMethod m)) and
serviceIntent.overrides*(any(AndroidServiceIntentMethod m)) and
startService.targetsComponentType(serviceIntent.getDeclaringType()) and

View File

@@ -37,7 +37,7 @@ class OnActivityResultIncomingIntent extends DataFlow::Node {
or
// A fragment calls `startActivityForResult`
// and the activity it belongs to defines `onActivityResult`.
exists(MethodAccess ma |
exists(MethodCall ma |
ma.getMethod().hasName(["add", "attach", "replace"]) and
ma.getMethod()
.getDeclaringType()
@@ -71,7 +71,7 @@ private module ImplicitStartActivityForResultConfig implements DataFlow::ConfigS
}
predicate isSink(DataFlow::Node sink) {
exists(MethodAccess startActivityForResult |
exists(MethodCall startActivityForResult |
startActivityForResult.getMethod().hasName("startActivityForResult") and
startActivityForResult.getMethod().getDeclaringType().getAnAncestor() instanceof
ActivityOrFragment and
@@ -83,7 +83,7 @@ private module ImplicitStartActivityForResultConfig implements DataFlow::ConfigS
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
// Wrapping the Intent in a chooser
exists(MethodAccess ma, Method m |
exists(MethodCall ma, Method m |
ma.getMethod() = m and
m.hasName("createChooser") and
m.getDeclaringType() instanceof TypeIntent

View File

@@ -8,7 +8,7 @@ class PendingIntent extends Class {
}
/** A call to a method that creates a `PendingIntent`. */
class PendingIntentCreation extends MethodAccess {
class PendingIntentCreation extends MethodCall {
PendingIntentCreation() {
exists(Method m |
this.getMethod() = m and

View File

@@ -6,7 +6,7 @@ private import semmle.code.java.dataflow.FlowSources
private class EditableToStringStep extends AdditionalTaintStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodAccess ma |
exists(MethodCall ma |
ma.getMethod().hasName("toString") and
ma.getReceiverType().getASourceSupertype*().hasQualifiedName("android.text", "Editable") and
n1.asExpr() = ma.getQualifier() and

View File

@@ -79,7 +79,7 @@ private module SafeDigesterFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeDigester }
predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
exists(MethodCall ma |
sink.asExpr() = ma.getQualifier() and ma.getMethod().getDeclaringType() instanceof Digester
)
}

View File

@@ -21,7 +21,7 @@ import semmle.code.java.frameworks.spring.Spring
/**
* A method call to a ProcessorDefinition element.
*/
class ProcessorDefinitionElement extends MethodAccess {
class ProcessorDefinitionElement extends MethodCall {
ProcessorDefinitionElement() {
this.getMethod()
.getDeclaringType()
@@ -114,7 +114,7 @@ deprecated class CamelJavaDSLBeanRefDecl = CamelJavaDslBeanRefDecl;
*
* An expression that represents a call to a bean, or particular method on a bean.
*/
class CamelJavaDslMethodDecl extends MethodAccess {
class CamelJavaDslMethodDecl extends MethodCall {
CamelJavaDslMethodDecl() {
this.getMethod()
.getDeclaringType()

View File

@@ -14,7 +14,7 @@ private module TypeLiteralToParseAsFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof TypeLiteral }
predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
exists(MethodCall ma |
ma.getAnArgument() = sink.asExpr() and
ma.getMethod() instanceof ParseAsMethod
)

View File

@@ -26,7 +26,7 @@ class GsonDeserializeMethod extends Method {
* where `T` is a concrete type implementing `Parcelable`.
*/
predicate intentFlowsToParcel(DataFlow::Node intentNode, DataFlow::Node parcelNode) {
exists(MethodAccess getParcelableExtraCall, CreateFromParcelMethod cfpm, Type createdType |
exists(MethodCall getParcelableExtraCall, CreateFromParcelMethod cfpm, Type createdType |
intentNode.asExpr() = getParcelableExtraCall.getQualifier() and
getParcelableExtraCall.getMethod() instanceof IntentGetParcelableExtraMethod and
DataFlow::localExprFlow(getParcelableExtraCall, any(Expr e | e.getType() = createdType)) and

View File

@@ -22,7 +22,7 @@ abstract class GsonDeserializableType extends Type { }
/** A type whose values are explicitly deserialized in a call to a Gson method. */
private class ExplicitlyReadGsonDeserializableType extends GsonDeserializableType {
ExplicitlyReadGsonDeserializableType() {
exists(MethodAccess ma |
exists(MethodCall ma |
// A call to a Gson read method...
ma.getMethod() instanceof GsonReadValueMethod and
// ...where `this` is used in the final argument, indicating that this type will be deserialized.

View File

@@ -16,7 +16,7 @@ class HudsonWebMethod extends Method {
private class HudsonUtilXssSanitizer extends XssSanitizer {
HudsonUtilXssSanitizer() {
this.asExpr()
.(MethodAccess)
.(MethodCall)
.getMethod()
// Not including xmlEscape because it only accounts for >, <, and &.
// It does not account for ", or ', which makes it an incomplete XSS sanitizer.

View File

@@ -68,7 +68,7 @@ private class JacksonReadValueMethod extends Method, TaintPreservingCallable {
/** A type whose values are explicitly serialized in a call to a Jackson method. */
private class ExplicitlyWrittenJacksonSerializableType extends JacksonSerializableType {
ExplicitlyWrittenJacksonSerializableType() {
exists(MethodAccess ma |
exists(MethodCall ma |
// A call to a Jackson write method...
ma.getMethod() instanceof JacksonWriteValueMethod and
// ...where `this` is used in the final argument, indicating that this type will be serialized.
@@ -91,7 +91,7 @@ private module TypeLiteralToJacksonDatabindFlowConfig implements DataFlow::Confi
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof TypeLiteral }
predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma, Method m, int i |
exists(MethodCall ma, Method m, int i |
ma.getArgument(i) = sink.asExpr() and
m = ma.getMethod() and
m.getParameterType(i) instanceof TypeClass and
@@ -116,7 +116,7 @@ private class ExplicitlyReadJacksonDeserializableType extends JacksonDeserializa
ExplicitlyReadJacksonDeserializableType() {
usesType(getSourceWithFlowToJacksonDatabind().getReferencedType(), this)
or
exists(MethodAccess ma |
exists(MethodCall ma |
// A call to a Jackson read method...
ma.getMethod() instanceof JacksonReadValueMethod and
// ...where `this` is used in the final argument, indicating that this type will be deserialized.
@@ -177,7 +177,7 @@ private class JacksonDeserializedTaintStep extends AdditionalTaintStep {
* This informs Jackson to treat the annotations on the second class argument as if they were on
* the first class argument. This allows adding annotations to library classes, for example.
*/
class JacksonAddMixinCall extends MethodAccess {
class JacksonAddMixinCall extends MethodCall {
JacksonAddMixinCall() {
exists(Method m |
m = this.getMethod() and

View File

@@ -52,7 +52,7 @@ private module SafeValidatorFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeValidator }
predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
exists(MethodCall ma |
sink.asExpr() = ma.getQualifier() and
ma.getMethod().getDeclaringType() instanceof Validator
)

View File

@@ -135,7 +135,7 @@ class ForbiddenThisCallable extends ForbiddenCallable {
ThisAccess forbiddenThisUse(Callable c) {
result.getEnclosingCallable() = c and
(
exists(MethodAccess ma | ma.getAnArgument() = result) or
exists(MethodCall ma | ma.getAnArgument() = result) or
exists(ReturnStmt rs | rs.getResult() = result)
)
}

View File

@@ -3,7 +3,7 @@
import java
/** A call to Kotlin's `apply` method. */
class KotlinApply extends MethodAccess {
class KotlinApply extends MethodCall {
ExtensionMethod m;
KotlinApply() {

View File

@@ -8,7 +8,7 @@ class StringsKt extends RefType {
}
/** A call to the extension method `String.toRegex` from `kotlin.text`. */
class KtToRegex extends MethodAccess {
class KtToRegex extends MethodCall {
KtToRegex() {
this.getMethod().getDeclaringType() instanceof StringsKt and
this.getMethod().hasName("toRegex")

View File

@@ -126,7 +126,7 @@ class PlayMvcHttpRequestHeaderMethods extends Method {
/**
* Gets a reference to the `getQueryString` method.
*/
MethodAccess getAQueryStringAccess() {
MethodCall getAQueryStringAccess() {
this.hasName("getQueryString") and result = this.getAReference()
}
}
@@ -140,10 +140,10 @@ class PlayMvcResultsMethods extends Method {
/**
* Gets a reference to the `play.mvc.Results.ok` method.
*/
MethodAccess getAnOkAccess() { this.hasName("ok") and result = this.getAReference() }
MethodCall getAnOkAccess() { this.hasName("ok") and result = this.getAReference() }
/**
* Gets a reference to the `play.mvc.Results.redirect` method.
*/
MethodAccess getARedirectAccess() { this.hasName("redirect") and result = this.getAReference() }
MethodCall getARedirectAccess() { this.hasName("redirect") and result = this.getAReference() }
}

View File

@@ -307,7 +307,7 @@ class SpringModelPlainMap extends SpringModel {
SpringModelPlainMap() { this.getType() instanceof MapType }
override RefType getATypeInModel() {
exists(MethodAccess methodCall |
exists(MethodCall methodCall |
methodCall.getQualifier() = this.getAnAccess() and
methodCall.getCallee().hasName("put")
|
@@ -327,7 +327,7 @@ class SpringModelModel extends SpringModel {
}
override RefType getATypeInModel() {
exists(MethodAccess methodCall |
exists(MethodCall methodCall |
methodCall.getQualifier() = this.getAnAccess() and
methodCall.getCallee().hasName("addAttribute")
|

View File

@@ -164,14 +164,14 @@ private predicate isXssSafeContentTypeExpr(Expr e) {
private DataFlow::Node getABodyBuilderWithExplicitContentType(Expr contentType) {
result.asExpr() =
any(MethodAccess ma |
any(MethodCall ma |
ma.getCallee()
.hasQualifiedName("org.springframework.http", "ResponseEntity$BodyBuilder", "contentType") and
contentType = ma.getArgument(0)
)
or
result.asExpr() =
any(MethodAccess ma |
any(MethodCall ma |
ma.getQualifier() = getABodyBuilderWithExplicitContentType(contentType).asExpr() and
ma.getType()
.(RefType)
@@ -192,7 +192,7 @@ private DataFlow::Node getAVulnerableBodyBuilder() {
private class SanitizedBodyCall extends XSS::XssSanitizer {
SanitizedBodyCall() {
this.asExpr() =
any(MethodAccess ma |
any(MethodCall ma |
ma.getQualifier() = getASanitizedBodyBuilder().asExpr() and
ma.getCallee().hasName("body")
).getArgument(0)
@@ -210,7 +210,7 @@ private class SanitizedBodyCall extends XSS::XssSanitizer {
private class ExplicitlyVulnerableBodyArgument extends XSS::XssSinkBarrier {
ExplicitlyVulnerableBodyArgument() {
this.asExpr() =
any(MethodAccess ma |
any(MethodCall ma |
ma.getQualifier() = getAVulnerableBodyBuilder().asExpr() and
ma.getCallee().hasName("body")
).getArgument(0)

Some files were not shown because too many files have changed in this diff Show More