Merge tag 'codeql-cli/latest' into auto/sync-main-pr

Compatible with the latest released version of the CodeQL CLI
This commit is contained in:
dilanbhalla
2025-06-02 22:04:24 +00:00
786 changed files with 103391 additions and 9586 deletions

View File

@@ -196,7 +196,6 @@ ql/java/ql/src/Security/CWE/CWE-730/RegexInjection.ql
ql/java/ql/src/Security/CWE/CWE-732/ReadingFromWorldWritableFile.ql
ql/java/ql/src/Security/CWE/CWE-749/UnsafeAndroidAccess.ql
ql/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql
ql/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql
ql/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql
ql/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql
ql/java/ql/src/Security/CWE/CWE-829/InsecureDependencyResolution.ql

View File

@@ -99,7 +99,6 @@ ql/java/ql/src/Security/CWE/CWE-730/RegexInjection.ql
ql/java/ql/src/Security/CWE/CWE-732/ReadingFromWorldWritableFile.ql
ql/java/ql/src/Security/CWE/CWE-749/UnsafeAndroidAccess.ql
ql/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql
ql/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql
ql/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql
ql/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql
ql/java/ql/src/Security/CWE/CWE-829/InsecureDependencyResolution.ql

View File

@@ -158,6 +158,7 @@ ql/java/ql/src/Security/CWE/CWE-312/CleartextStorageClass.ql
ql/java/ql/src/Security/CWE/CWE-319/HttpsUrls.ql
ql/java/ql/src/Security/CWE/CWE-319/UseSSL.ql
ql/java/ql/src/Security/CWE/CWE-319/UseSSLSocketFactories.ql
ql/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql
ql/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsComparison.ql
ql/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql
ql/java/ql/src/Security/CWE/CWE-798/HardcodedPasswordField.ql

View File

@@ -1,3 +1,10 @@
## 7.3.0
### Deprecated APIs
* The predicate `getValue()` on `SpringRequestMappingMethod` is now deprecated. Use `getAValue()` instead.
* Java now uses the shared `BasicBlock` library. This means that the names of several member predicates have been changed to align with the names used in other languages. The old predicates have been deprecated. The `BasicBlock` class itself no longer extends `ControlFlowNode` - the predicate `getFirstNode` can be used to fix any QL code that somehow relied on this.
## 7.2.0
### New Features
@@ -20,7 +27,7 @@ No user-facing changes.
### Minor Analysis Improvements
* Java extraction is now able to download Maven 3.9.x if a Maven Enforcer Plugin configuration indicates it is necessary. Maven 3.8.x is still preferred if the enforcer-plugin configuration (if any) permits it.
* Added a path injection sanitizer for calls to `java.lang.String.matches`, `java.lang.String.replace`, and `java.lang.String.replaceAll` that make sure '/', '\', '..' are not in the path.
* Added a path injection sanitizer for calls to `java.lang.String.matches`, `java.lang.String.replace`, and `java.lang.String.replaceAll` that make sure `/`, `\\`, `..` are not in the path.
### Bug Fixes
@@ -55,8 +62,8 @@ No user-facing changes.
* Deleted the deprecated `isLValue` and `isRValue` predicates from the `VarAccess` class, use `isVarWrite` and `isVarRead` respectively instead.
* Deleted the deprecated `getRhs` predicate from the `VarWrite` class, use `getASource` instead.
* Deleted the deprecated `LValue` and `RValue` classes, use `VarWrite` and `VarRead` respectively instead.
* Deleted a lot of deprecated classes ending in "*Access", use the corresponding "*Call" classes instead.
* Deleted a lot of deprecated predicates ending in "*Access", use the corresponding "*Call" predicates instead.
* Deleted a lot of deprecated classes ending in `*Access`, use the corresponding `*Call` classes instead.
* Deleted a lot of deprecated predicates ending in `*Access`, use the corresponding `*Call` predicates instead.
* Deleted the deprecated `EnvInput` and `DatabaseInput` classes from `FlowSources.qll`, use the threat models feature instead.
* Deleted some deprecated API predicates from `SensitiveApi.qll`, use the Sink classes from that file instead.

View File

@@ -5,8 +5,8 @@
* Deleted the deprecated `isLValue` and `isRValue` predicates from the `VarAccess` class, use `isVarWrite` and `isVarRead` respectively instead.
* Deleted the deprecated `getRhs` predicate from the `VarWrite` class, use `getASource` instead.
* Deleted the deprecated `LValue` and `RValue` classes, use `VarWrite` and `VarRead` respectively instead.
* Deleted a lot of deprecated classes ending in "*Access", use the corresponding "*Call" classes instead.
* Deleted a lot of deprecated predicates ending in "*Access", use the corresponding "*Call" predicates instead.
* Deleted a lot of deprecated classes ending in `*Access`, use the corresponding `*Call` classes instead.
* Deleted a lot of deprecated predicates ending in `*Access`, use the corresponding `*Call` predicates instead.
* Deleted the deprecated `EnvInput` and `DatabaseInput` classes from `FlowSources.qll`, use the threat models feature instead.
* Deleted some deprecated API predicates from `SensitiveApi.qll`, use the Sink classes from that file instead.

View File

@@ -3,7 +3,7 @@
### Minor Analysis Improvements
* Java extraction is now able to download Maven 3.9.x if a Maven Enforcer Plugin configuration indicates it is necessary. Maven 3.8.x is still preferred if the enforcer-plugin configuration (if any) permits it.
* Added a path injection sanitizer for calls to `java.lang.String.matches`, `java.lang.String.replace`, and `java.lang.String.replaceAll` that make sure '/', '\', '..' are not in the path.
* Added a path injection sanitizer for calls to `java.lang.String.matches`, `java.lang.String.replace`, and `java.lang.String.replaceAll` that make sure `/`, `\\`, `..` are not in the path.
### Bug Fixes

View File

@@ -0,0 +1,6 @@
## 7.3.0
### Deprecated APIs
* The predicate `getValue()` on `SpringRequestMappingMethod` is now deprecated. Use `getAValue()` instead.
* Java now uses the shared `BasicBlock` library. This means that the names of several member predicates have been changed to align with the names used in other languages. The old predicates have been deprecated. The `BasicBlock` class itself no longer extends `ControlFlowNode` - the predicate `getFirstNode` can be used to fix any QL code that somehow relied on this.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 7.2.0
lastReleaseVersion: 7.3.0

View File

@@ -353,7 +353,7 @@ module JCAModel {
else result instanceof KeyOpAlg::TUnknownKeyOperationAlgorithmType
}
override string getKeySizeFixed() {
override int getKeySizeFixed() {
none() // TODO: implement to handle variants such as AES-128
}
@@ -611,6 +611,8 @@ module JCAModel {
}
class CipherOperationInstance extends Crypto::KeyOperationInstance instanceof CipherOperationCall {
CipherOperationInstance() { not this.isIntermediate() }
override Crypto::KeyOperationSubtype getKeyOperationSubtype() {
if CipherFlowAnalysisImpl::hasInit(this)
then result = CipherFlowAnalysisImpl::getInitFromUse(this, _, _).getCipherOperationModeType()
@@ -1102,7 +1104,7 @@ module JCAModel {
KeyGeneratorFlowAnalysisImpl::getInitFromUse(this, _, _).getKeySizeArg() = result.asExpr()
}
override string getKeySizeFixed() { none() }
override int getKeySizeFixed() { none() }
}
class KeyGeneratorCipherAlgorithm extends CipherStringLiteralAlgorithmInstance {
@@ -1308,7 +1310,7 @@ module JCAModel {
result.asExpr() = this.getKeySpecInstantiation().(PBEKeySpecInstantiation).getKeyLengthArg()
}
override string getKeySizeFixed() { none() }
override int getKeySizeFixed() { none() }
override string getOutputKeySizeFixed() { none() }
@@ -1604,13 +1606,8 @@ module JCAModel {
else result = Crypto::OtherEllipticCurveType()
}
override string getKeySize() {
exists(int keySize |
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getRawEllipticCurveName(), keySize,
_)
|
result = keySize.toString()
)
override int getKeySize() {
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getRawEllipticCurveName(), result, _)
}
EllipticCurveAlgorithmValueConsumer getConsumer() { result = consumer }

View File

@@ -1,11 +1,12 @@
name: codeql/java-all
version: 7.2.0
version: 7.3.0
groups: java
dbscheme: config/semmlecode.dbscheme
extractor: java
library: true
upgrades: upgrades
dependencies:
codeql/controlflow: ${workspace}
codeql/dataflow: ${workspace}
codeql/dataflowstack: ${workspace}
codeql/mad: ${workspace}

View File

@@ -4,91 +4,128 @@
import java
import Dominance
private import codeql.controlflow.BasicBlock as BB
cached
private module BasicBlockStage {
cached
predicate ref() { any() }
private module Input implements BB::InputSig<Location> {
import SuccessorType
cached
predicate backref() {
(exists(any(BasicBlock bb).getABBSuccessor()) implies any()) and
(exists(any(BasicBlock bb).getNode(_)) implies any()) and
(exists(any(BasicBlock bb).length()) implies any())
/** Hold if `t` represents a conditional successor type. */
predicate successorTypeIsCondition(SuccessorType t) { none() }
/** A delineated part of the AST with its own CFG. */
class CfgScope = Callable;
/** The class of control flow nodes. */
class Node = ControlFlowNode;
/** Gets the CFG scope in which this node occurs. */
CfgScope nodeGetCfgScope(Node node) { node.getEnclosingCallable() = result }
private Node getASpecificSuccessor(Node node, SuccessorType t) {
node.(ConditionNode).getABranchSuccessor(t.(BooleanSuccessor).getValue()) = result
or
node.getAnExceptionSuccessor() = result and t instanceof ExceptionSuccessor
}
/** Gets an immediate successor of this node. */
Node nodeGetASuccessor(Node node, SuccessorType t) {
result = getASpecificSuccessor(node, t)
or
node.getASuccessor() = result and
t instanceof NormalSuccessor and
not result = getASpecificSuccessor(node, _)
}
/**
* Holds if `node` represents an entry node to be used when calculating
* dominance.
*/
predicate nodeIsDominanceEntry(Node node) {
exists(Stmt entrystmt | entrystmt = node.asStmt() |
exists(Callable c | entrystmt = c.getBody())
or
// This disjunct is technically superfluous, but safeguards against extractor problems.
entrystmt instanceof BlockStmt and
not exists(entrystmt.getEnclosingCallable()) and
not entrystmt.getParent() instanceof Stmt
)
}
/**
* Holds if `node` represents an exit node to be used when calculating
* post dominance.
*/
predicate nodeIsPostDominanceExit(Node node) { node instanceof ControlFlow::ExitNode }
}
private module BbImpl = BB::Make<Location, Input>;
import BbImpl
/** Holds if the dominance relation is calculated for `bb`. */
predicate hasDominanceInformation(BasicBlock bb) {
exists(BasicBlock entry |
Input::nodeIsDominanceEntry(entry.getFirstNode()) and entry.getASuccessor*() = bb
)
}
/**
* A control-flow node that represents the start of a basic block.
*
* A basic block is a series of nodes with no control-flow branching, which can
* often be treated as a unit in analyses.
* A basic block, that is, a maximal straight-line sequence of control flow nodes
* without branches or joins.
*/
class BasicBlock extends ControlFlowNode {
cached
BasicBlock() {
BasicBlockStage::ref() and
not exists(this.getAPredecessor()) and
exists(this.getASuccessor())
or
strictcount(this.getAPredecessor()) > 1
or
exists(ControlFlowNode pred | pred = this.getAPredecessor() |
strictcount(pred.getASuccessor()) > 1
)
}
class BasicBlock extends BbImpl::BasicBlock {
/** Gets the immediately enclosing callable whose body contains this node. */
Callable getEnclosingCallable() { result = this.getScope() }
/** Gets an immediate successor of this basic block. */
cached
BasicBlock getABBSuccessor() {
BasicBlockStage::ref() and
result = this.getLastNode().getASuccessor()
}
/**
* Holds if this basic block dominates basic block `bb`.
*
* That is, all paths reaching `bb` from the entry point basic block must
* go through this basic block.
*/
predicate dominates(BasicBlock bb) { super.dominates(bb) }
/** Gets an immediate predecessor of this basic block. */
BasicBlock getABBPredecessor() { result.getABBSuccessor() = this }
/**
* DEPRECATED: Use `getASuccessor` instead.
*
* Gets an immediate successor of this basic block.
*/
deprecated BasicBlock getABBSuccessor() { result = this.getASuccessor() }
/** Gets a control-flow node contained in this basic block. */
ControlFlowNode getANode() { result = this.getNode(_) }
/**
* DEPRECATED: Use `getAPredecessor` instead.
*
* Gets an immediate predecessor of this basic block.
*/
deprecated BasicBlock getABBPredecessor() { result.getASuccessor() = this }
/** Gets the control-flow node at a specific (zero-indexed) position in this basic block. */
cached
ControlFlowNode getNode(int pos) {
BasicBlockStage::ref() and
result = this and
pos = 0
or
exists(ControlFlowNode mid, int mid_pos | pos = mid_pos + 1 |
this.getNode(mid_pos) = mid and
mid.getASuccessor() = result and
not result instanceof BasicBlock
)
}
/**
* DEPRECATED: Use `strictlyDominates` instead.
*
* Holds if this basic block strictly dominates `node`.
*/
deprecated predicate bbStrictlyDominates(BasicBlock node) { this.strictlyDominates(node) }
/** Gets the first control-flow node in this basic block. */
ControlFlowNode getFirstNode() { result = this }
/**
* DEPRECATED: Use `dominates` instead.
*
* Holds if this basic block dominates `node`. (This is reflexive.)
*/
deprecated predicate bbDominates(BasicBlock node) { this.dominates(node) }
/** Gets the last control-flow node in this basic block. */
ControlFlowNode getLastNode() { result = this.getNode(this.length() - 1) }
/**
* DEPRECATED: Use `strictlyPostDominates` instead.
*
* Holds if this basic block strictly post-dominates `node`.
*/
deprecated predicate bbStrictlyPostDominates(BasicBlock node) { this.strictlyPostDominates(node) }
/** Gets the number of control-flow nodes contained in this basic block. */
cached
int length() {
BasicBlockStage::ref() and
result = strictcount(this.getANode())
}
/** Holds if this basic block strictly dominates `node`. */
predicate bbStrictlyDominates(BasicBlock node) { bbStrictlyDominates(this, node) }
/** Holds if this basic block dominates `node`. (This is reflexive.) */
predicate bbDominates(BasicBlock node) { bbDominates(this, node) }
/** Holds if this basic block strictly post-dominates `node`. */
predicate bbStrictlyPostDominates(BasicBlock node) { bbStrictlyPostDominates(this, node) }
/** Holds if this basic block post-dominates `node`. (This is reflexive.) */
predicate bbPostDominates(BasicBlock node) { bbPostDominates(this, node) }
/**
* DEPRECATED: Use `postDominates` instead.
*
* Holds if this basic block post-dominates `node`. (This is reflexive.)
*/
deprecated predicate bbPostDominates(BasicBlock node) { this.postDominates(node) }
}
/** A basic block that ends in an exit node. */

View File

@@ -8,91 +8,75 @@ import java
* Predicates for basic-block-level dominance.
*/
/** Entry points for control-flow. */
private predicate flowEntry(BasicBlock entry) {
exists(Stmt entrystmt | entrystmt = entry.getFirstNode().asStmt() |
exists(Callable c | entrystmt = c.getBody())
or
// This disjunct is technically superfluous, but safeguards against extractor problems.
entrystmt instanceof BlockStmt and
not exists(entry.getEnclosingCallable()) and
not entrystmt.getParent() instanceof Stmt
)
}
/** The successor relation for basic blocks. */
private predicate bbSucc(BasicBlock pre, BasicBlock post) { post = pre.getABBSuccessor() }
/** The immediate dominance relation for basic blocks. */
cached
predicate bbIDominates(BasicBlock dom, BasicBlock node) =
idominance(flowEntry/1, bbSucc/2)(_, dom, node)
/** Holds if the dominance relation is calculated for `bb`. */
predicate hasDominanceInformation(BasicBlock bb) {
exists(BasicBlock entry | flowEntry(entry) and bbSucc*(entry, bb))
/**
* DEPRECATED: Use `BasicBlock::immediatelyDominates` instead.
*
* The immediate dominance relation for basic blocks.
*/
deprecated predicate bbIDominates(BasicBlock dom, BasicBlock node) {
dom.immediatelyDominates(node)
}
/** Exit points for basic-block control-flow. */
private predicate bbSink(BasicBlock exit) { exit.getLastNode() instanceof ControlFlow::ExitNode }
/** Reversed `bbSucc`. */
private predicate bbPred(BasicBlock post, BasicBlock pre) { post = pre.getABBSuccessor() }
private predicate bbPred(BasicBlock post, BasicBlock pre) { post = pre.getASuccessor() }
/** The immediate post-dominance relation on basic blocks. */
cached
predicate bbIPostDominates(BasicBlock dominator, BasicBlock node) =
deprecated predicate bbIPostDominates(BasicBlock dominator, BasicBlock node) =
idominance(bbSink/1, bbPred/2)(_, dominator, node)
/** Holds if `dom` strictly dominates `node`. */
predicate bbStrictlyDominates(BasicBlock dom, BasicBlock node) { bbIDominates+(dom, node) }
/** Holds if `dom` dominates `node`. (This is reflexive.) */
predicate bbDominates(BasicBlock dom, BasicBlock node) {
bbStrictlyDominates(dom, node) or dom = node
/**
* DEPRECATED: Use `BasicBlock::strictlyDominates` instead.
*
* Holds if `dom` strictly dominates `node`.
*/
deprecated predicate bbStrictlyDominates(BasicBlock dom, BasicBlock node) {
dom.strictlyDominates(node)
}
/** Holds if `dom` strictly post-dominates `node`. */
predicate bbStrictlyPostDominates(BasicBlock dom, BasicBlock node) { bbIPostDominates+(dom, node) }
/**
* DEPRECATED: Use `BasicBlock::dominates` instead.
*
* Holds if `dom` dominates `node`. (This is reflexive.)
*/
deprecated predicate bbDominates(BasicBlock dom, BasicBlock node) { dom.dominates(node) }
/** Holds if `dom` post-dominates `node`. (This is reflexive.) */
predicate bbPostDominates(BasicBlock dom, BasicBlock node) {
bbStrictlyPostDominates(dom, node) or dom = node
/**
* DEPRECATED: Use `BasicBlock::strictlyPostDominates` instead.
*
* Holds if `dom` strictly post-dominates `node`.
*/
deprecated predicate bbStrictlyPostDominates(BasicBlock dom, BasicBlock node) {
dom.strictlyPostDominates(node)
}
/**
* DEPRECATED: Use `BasicBlock::postDominates` instead.
*
* Holds if `dom` post-dominates `node`. (This is reflexive.)
*/
deprecated predicate bbPostDominates(BasicBlock dom, BasicBlock node) { dom.postDominates(node) }
/**
* The dominance frontier relation for basic blocks.
*
* This is equivalent to:
*
* ```
* bbDominates(x, w.getABBPredecessor()) and not bbStrictlyDominates(x, w)
* x.dominates(w.getAPredecessor()) and not x.strictlyDominates(w)
* ```
*/
predicate dominanceFrontier(BasicBlock x, BasicBlock w) {
x = w.getABBPredecessor() and not bbIDominates(x, w)
x = w.getAPredecessor() and not x.immediatelyDominates(w)
or
exists(BasicBlock prev | dominanceFrontier(prev, w) |
bbIDominates(x, prev) and
not bbIDominates(x, w)
x.immediatelyDominates(prev) and
not x.immediatelyDominates(w)
)
}
/**
* Holds if `(bb1, bb2)` is an edge that dominates `bb2`, that is, all other
* predecessors of `bb2` are dominated by `bb2`. This implies that `bb1` is the
* immediate dominator of `bb2`.
*
* This is a necessary and sufficient condition for an edge to dominate anything,
* and in particular `dominatingEdge(bb1, bb2) and bb2.bbDominates(bb3)` means
* that the edge `(bb1, bb2)` dominates `bb3`.
*/
predicate dominatingEdge(BasicBlock bb1, BasicBlock bb2) {
bbIDominates(bb1, bb2) and
bb1.getABBSuccessor() = bb2 and
forall(BasicBlock pred | pred = bb2.getABBPredecessor() and pred != bb1 | bbDominates(bb2, pred))
}
/*
* Predicates for expression-level dominance.
*/
@@ -102,7 +86,7 @@ predicate iDominates(ControlFlowNode dominator, ControlFlowNode node) {
exists(BasicBlock bb, int i | dominator = bb.getNode(i) and node = bb.getNode(i + 1))
or
exists(BasicBlock dom, BasicBlock bb |
bbIDominates(dom, bb) and
dom.immediatelyDominates(bb) and
dominator = dom.getLastNode() and
node = bb.getFirstNode()
)
@@ -112,7 +96,7 @@ predicate iDominates(ControlFlowNode dominator, ControlFlowNode node) {
pragma[inline]
predicate strictlyDominates(ControlFlowNode dom, ControlFlowNode node) {
// This predicate is gigantic, so it must be inlined.
bbStrictlyDominates(dom.getBasicBlock(), node.getBasicBlock())
dom.getBasicBlock().strictlyDominates(node.getBasicBlock())
or
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i < j)
}
@@ -121,7 +105,7 @@ predicate strictlyDominates(ControlFlowNode dom, ControlFlowNode node) {
pragma[inline]
predicate dominates(ControlFlowNode dom, ControlFlowNode node) {
// This predicate is gigantic, so it must be inlined.
bbStrictlyDominates(dom.getBasicBlock(), node.getBasicBlock())
dom.getBasicBlock().strictlyDominates(node.getBasicBlock())
or
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i <= j)
}
@@ -130,7 +114,7 @@ predicate dominates(ControlFlowNode dom, ControlFlowNode node) {
pragma[inline]
predicate strictlyPostDominates(ControlFlowNode dom, ControlFlowNode node) {
// This predicate is gigantic, so it must be inlined.
bbStrictlyPostDominates(dom.getBasicBlock(), node.getBasicBlock())
dom.getBasicBlock().strictlyPostDominates(node.getBasicBlock())
or
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i > j)
}
@@ -139,7 +123,7 @@ predicate strictlyPostDominates(ControlFlowNode dom, ControlFlowNode node) {
pragma[inline]
predicate postDominates(ControlFlowNode dom, ControlFlowNode node) {
// This predicate is gigantic, so it must be inlined.
bbStrictlyPostDominates(dom.getBasicBlock(), node.getBasicBlock())
dom.getBasicBlock().strictlyPostDominates(node.getBasicBlock())
or
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i >= j)
}

View File

@@ -23,7 +23,7 @@ class ConditionBlock extends BasicBlock {
/** Gets a `true`- or `false`-successor of the last node of this basic block. */
BasicBlock getTestSuccessor(boolean testIsTrue) {
result = this.getConditionNode().getABranchSuccessor(testIsTrue)
result.getFirstNode() = this.getConditionNode().getABranchSuccessor(testIsTrue)
}
/*
@@ -68,7 +68,7 @@ class ConditionBlock extends BasicBlock {
exists(BasicBlock succ |
succ = this.getTestSuccessor(testIsTrue) and
dominatingEdge(this, succ) and
succ.bbDominates(controlled)
succ.dominates(controlled)
)
}
}
@@ -145,7 +145,7 @@ private predicate isNonFallThroughPredecessor(SwitchCase sc, ControlFlowNode pre
* Evaluating a switch case to true corresponds to taking that switch case, and
* evaluating it to false corresponds to taking some other branch.
*/
class Guard extends ExprParent {
final class Guard extends ExprParent {
Guard() {
this.(Expr).getType() instanceof BooleanType and not this instanceof BooleanLiteral
or
@@ -272,6 +272,15 @@ class Guard extends ExprParent {
preconditionControls(this, controlled, branch)
}
/**
* Holds if this guard evaluating to `branch` controls the control-flow
* branch edge from `bb1` to `bb2`. That is, following the edge from
* `bb1` to `bb2` implies that this guard evaluated to `branch`.
*/
predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) {
guardControlsBranchEdge_v3(this, bb1, bb2, branch)
}
/**
* Holds if this guard evaluating to `branch` directly or indirectly controls
* the block `controlled`. That is, the evaluation of `controlled` is
@@ -287,7 +296,7 @@ private predicate switchCaseControls(SwitchCase sc, BasicBlock bb) {
// Pattern cases are handled as condition blocks
not sc instanceof PatternCase and
caseblock.getFirstNode() = sc.getControlFlowNode() and
caseblock.bbDominates(bb) and
caseblock.dominates(bb) and
// Check we can't fall through from a previous block:
forall(ControlFlowNode pred | pred = sc.getControlFlowNode().getAPredecessor() |
isNonFallThroughPredecessor(sc, pred)
@@ -300,14 +309,14 @@ private predicate preconditionBranchEdge(
) {
conditionCheckArgument(ma, _, branch) and
bb1.getLastNode() = ma.getControlFlowNode() and
bb2 = bb1.getLastNode().getANormalSuccessor()
bb2.getFirstNode() = bb1.getLastNode().getANormalSuccessor()
}
private predicate preconditionControls(MethodCall ma, BasicBlock controlled, boolean branch) {
exists(BasicBlock check, BasicBlock succ |
preconditionBranchEdge(ma, check, succ, branch) and
dominatingEdge(check, succ) and
succ.bbDominates(controlled)
succ.dominates(controlled)
)
}
@@ -351,6 +360,51 @@ private predicate guardControls_v3(Guard guard, BasicBlock controlled, boolean b
)
}
pragma[nomagic]
private predicate guardControlsBranchEdge_v2(
Guard guard, BasicBlock bb1, BasicBlock bb2, boolean branch
) {
guard.hasBranchEdge(bb1, bb2, branch)
or
exists(Guard g, boolean b |
guardControlsBranchEdge_v2(g, bb1, bb2, b) and
implies_v2(g, b, guard, branch)
)
}
pragma[nomagic]
private predicate guardControlsBranchEdge_v3(
Guard guard, BasicBlock bb1, BasicBlock bb2, boolean branch
) {
guard.hasBranchEdge(bb1, bb2, branch)
or
exists(Guard g, boolean b |
guardControlsBranchEdge_v3(g, bb1, bb2, b) and
implies_v3(g, b, guard, branch)
)
}
/** INTERNAL: Use `Guard` instead. */
final class Guard_v2 extends Guard {
/**
* Holds if this guard evaluating to `branch` controls the control-flow
* branch edge from `bb1` to `bb2`. That is, following the edge from
* `bb1` to `bb2` implies that this guard evaluated to `branch`.
*/
predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) {
guardControlsBranchEdge_v2(this, bb1, bb2, branch)
}
/**
* Holds if this guard evaluating to `branch` directly or indirectly controls
* the block `controlled`. That is, the evaluation of `controlled` is
* dominated by this guard evaluating to `branch`.
*/
predicate controls(BasicBlock controlled, boolean branch) {
guardControls_v2(this, controlled, branch)
}
}
private predicate equalityGuard(Guard g, Expr e1, Expr e2, boolean polarity) {
exists(EqualityTest eqtest |
eqtest = g and

View File

@@ -47,7 +47,7 @@ private predicate callAlwaysPerformsAction(Call call, ActionConfiguration conf)
private predicate actionDominatesExit(Callable callable, ActionConfiguration conf) {
exists(ExitBlock exit |
exit.getEnclosingCallable() = callable and
actionBlock(conf).bbDominates(exit)
actionBlock(conf).dominates(exit)
)
}
@@ -56,12 +56,12 @@ private BasicBlock nonDominatingActionBlock(ActionConfiguration conf) {
exists(ExitBlock exit |
result = actionBlock(conf) and
exit.getEnclosingCallable() = result.getEnclosingCallable() and
not result.bbDominates(exit)
not result.dominates(exit)
)
}
private class JoinBlock extends BasicBlock {
JoinBlock() { 2 <= strictcount(this.getABBPredecessor()) }
JoinBlock() { 2 <= strictcount(this.getAPredecessor()) }
}
/**
@@ -72,8 +72,8 @@ private predicate postActionBlock(BasicBlock bb, ActionConfiguration conf) {
bb = nonDominatingActionBlock(conf)
or
if bb instanceof JoinBlock
then forall(BasicBlock pred | pred = bb.getABBPredecessor() | postActionBlock(pred, conf))
else postActionBlock(bb.getABBPredecessor(), conf)
then forall(BasicBlock pred | pred = bb.getAPredecessor() | postActionBlock(pred, conf))
else postActionBlock(bb.getAPredecessor(), conf)
}
/** Holds if every path through `callable` goes through at least one action node. */

View File

@@ -0,0 +1,72 @@
/**
* Provides different types of control flow successor types.
*/
import java
private import codeql.util.Boolean
private newtype TSuccessorType =
TNormalSuccessor() or
TBooleanSuccessor(Boolean branch) or
TExceptionSuccessor()
/** The type of a control flow successor. */
class SuccessorType extends TSuccessorType {
/** Gets a textual representation of successor type. */
string toString() { result = "SuccessorType" }
}
/** A normal control flow successor. */
class NormalSuccessor extends SuccessorType, TNormalSuccessor { }
/**
* An exceptional control flow successor.
*
* This marks control flow edges that are taken when an exception is thrown.
*/
class ExceptionSuccessor extends SuccessorType, TExceptionSuccessor { }
/**
* A conditional control flow successor.
*
* This currently only includes boolean successors (`BooleanSuccessor`).
*/
class ConditionalSuccessor extends SuccessorType, TBooleanSuccessor {
/** Gets the Boolean value of this successor. */
boolean getValue() { this = TBooleanSuccessor(result) }
}
/**
* A Boolean control flow successor.
*
* For example, this program fragment:
*
* ```java
* if (x < 0)
* return 0;
* else
* return 1;
* ```
*
* has a control flow graph containing Boolean successors:
*
* ```
* if
* |
* x < 0
* / \
* / \
* / \
* true false
* | \
* return 0 return 1
* ```
*/
class BooleanSuccessor = ConditionalSuccessor;
/**
* A nullness control flow successor. This is currently unused for Java.
*/
class NullnessSuccessor extends ConditionalSuccessor {
NullnessSuccessor() { none() }
}

View File

@@ -209,7 +209,7 @@ class UnreachableBasicBlock extends BasicBlock {
or
// This block is not reachable in the CFG, and is not the entrypoint in a callable, an
// expression in an assert statement, or a catch clause.
forall(BasicBlock bb | bb = this.getABBPredecessor() | bb instanceof UnreachableBasicBlock) and
forall(BasicBlock bb | bb = this.getAPredecessor() | bb instanceof UnreachableBasicBlock) and
not exists(Callable c | c.getBody().getControlFlowNode() = this.getFirstNode()) and
not this.getFirstNode().asExpr().getEnclosingStmt() instanceof AssertStmt and
not this.getFirstNode().asStmt() instanceof CatchClause
@@ -219,11 +219,10 @@ class UnreachableBasicBlock extends BasicBlock {
// Not accessible from the switch expression
unreachableCaseBlock = constSwitchStmt.getAFailingCase().getBasicBlock() and
// Not accessible from the successful case
not constSwitchStmt.getMatchingCase().getBasicBlock().getABBSuccessor*() =
unreachableCaseBlock
not constSwitchStmt.getMatchingCase().getBasicBlock().getASuccessor*() = unreachableCaseBlock
|
// Blocks dominated by an unreachable case block are unreachable
unreachableCaseBlock.bbDominates(this)
unreachableCaseBlock.dominates(this)
)
}
}

View File

@@ -239,7 +239,7 @@ SsaVariable getADefinition(SsaVariable v, boolean fromBackEdge) {
exists(SsaVariable inp, BasicBlock bb, boolean fbe |
v.(SsaPhiNode).hasInputFromBlock(inp, bb) and
result = getADefinition(inp, fbe) and
(if v.getBasicBlock().bbDominates(bb) then fromBackEdge = true else fromBackEdge = fbe)
(if v.getBasicBlock().dominates(bb) then fromBackEdge = true else fromBackEdge = fbe)
)
}
@@ -290,10 +290,10 @@ private predicate guardImpliesEqual(Guard guard, boolean branch, SsaVariable v,
)
}
private ControlFlowNode getAGuardBranchSuccessor(Guard g, boolean branch) {
result = g.(Expr).getControlFlowNode().(ConditionNode).getABranchSuccessor(branch)
private BasicBlock getAGuardBranchSuccessor(Guard g, boolean branch) {
result.getFirstNode() = g.(Expr).getControlFlowNode().(ConditionNode).getABranchSuccessor(branch)
or
result = g.(SwitchCase).getControlFlowNode() and branch = true
result.getFirstNode() = g.(SwitchCase).getControlFlowNode() and branch = true
}
/**
@@ -306,7 +306,7 @@ private predicate guardControlsPhiBranch(
guard.directlyControls(upd.getBasicBlock(), branch) and
upd.getDefiningExpr().(VariableAssign).getSource() = e and
upd = phi.getAPhiInput() and
guard.getBasicBlock().bbStrictlyDominates(phi.getBasicBlock())
guard.getBasicBlock().strictlyDominates(phi.getBasicBlock())
}
/**
@@ -331,7 +331,7 @@ private predicate conditionalAssign(SsaVariable v, Guard guard, boolean branch,
forall(SsaVariable other | other != upd and other = phi.getAPhiInput() |
guard.directlyControls(other.getBasicBlock(), branch.booleanNot())
or
other.getBasicBlock().bbDominates(guard.getBasicBlock()) and
other.getBasicBlock().dominates(guard.getBasicBlock()) and
not other.isLiveAtEndOfBlock(getAGuardBranchSuccessor(guard, branch))
)
)

View File

@@ -17,7 +17,7 @@ private predicate valueFlowStepSsa(SsaVariable v, SsaReadPosition pos, Expr e, i
exists(Guard guard, boolean testIsTrue |
pos.hasReadOfVar(v) and
guard = eqFlowCond(v, e, delta, true, testIsTrue) and
guardDirectlyControlsSsaRead(guard, pos, testIsTrue)
guardControlsSsaRead(guard, pos, testIsTrue)
)
}

View File

@@ -298,9 +298,9 @@ private predicate impossibleEdge(BasicBlock bb1, BasicBlock bb2) {
private predicate leavingFinally(BasicBlock bb1, BasicBlock bb2, boolean normaledge) {
exists(TryStmt try, BlockStmt finally |
try.getFinally() = finally and
bb1.getABBSuccessor() = bb2 and
bb1.getEnclosingStmt().getEnclosingStmt*() = finally and
not bb2.getEnclosingStmt().getEnclosingStmt*() = finally and
bb1.getASuccessor() = bb2 and
bb1.getFirstNode().getEnclosingStmt().getEnclosingStmt*() = finally and
not bb2.getFirstNode().getEnclosingStmt().getEnclosingStmt*() = finally and
if bb1.getLastNode().getANormalSuccessor() = bb2.getFirstNode()
then normaledge = true
else normaledge = false
@@ -339,7 +339,7 @@ private predicate nullVarStep(
midssa.isLiveAtEndOfBlock(mid) and
not ensureNotNull(midssa).getBasicBlock() = mid and
not assertFail(mid, _) and
bb = mid.getABBSuccessor() and
bb = mid.getASuccessor() and
not impossibleEdge(mid, bb) and
not exists(boolean branch | nullGuard(midssa, branch, false).hasBranchEdge(mid, bb, branch)) and
not (leavingFinally(mid, bb, true) and midstoredcompletion = true) and

View File

@@ -209,26 +209,20 @@ module Sem implements Semantic<Location> {
class BasicBlock = J::BasicBlock;
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getABBSuccessor() }
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
private predicate id(ExprParent x, ExprParent y) { x = y }
private predicate idOfAst(ExprParent x, int y) = equivalenceRelation(id/2)(x, y)
private predicate idOf(BasicBlock x, int y) { idOfAst(x.getAstNode(), y) }
private predicate idOf(BasicBlock x, int y) { idOfAst(x.getFirstNode().getAstNode(), y) }
int getBlockId1(BasicBlock bb) { idOf(bb, result) }
final private class FinalGuard = GL::Guard;
class Guard extends FinalGuard {
class Guard extends GL::Guard_v2 {
Expr asExpr() { result = this }
}
predicate implies_v2(Guard g1, boolean b1, Guard g2, boolean b2) {
GL::implies_v2(g1, b1, g2, b2)
}
class Type = J::Type;
class IntegerType extends J::IntegralType {

View File

@@ -19,8 +19,6 @@ predicate ssaUpdateStep = U::ssaUpdateStep/3;
predicate valueFlowStep = U::valueFlowStep/3;
predicate guardDirectlyControlsSsaRead = U::guardDirectlyControlsSsaRead/3;
predicate guardControlsSsaRead = U::guardControlsSsaRead/3;
predicate eqFlowCond = U::eqFlowCond/5;

View File

@@ -321,14 +321,14 @@ private module Input implements TypeFlowInput<Location> {
*/
private predicate instanceofDisjunct(InstanceOfExpr ioe, BasicBlock bb, BaseSsaVariable v) {
ioe.getExpr() = v.getAUse() and
strictcount(bb.getABBPredecessor()) > 1 and
strictcount(bb.getAPredecessor()) > 1 and
exists(ConditionBlock cb | cb.getCondition() = ioe and cb.getTestSuccessor(true) = bb)
}
/** Holds if `bb` is disjunctively guarded by multiple `instanceof` tests on `v`. */
private predicate instanceofDisjunction(BasicBlock bb, BaseSsaVariable v) {
strictcount(InstanceOfExpr ioe | instanceofDisjunct(ioe, bb, v)) =
strictcount(bb.getABBPredecessor())
strictcount(bb.getAPredecessor())
}
/**
@@ -338,7 +338,7 @@ private module Input implements TypeFlowInput<Location> {
predicate instanceofDisjunctionGuarded(TypeFlowNode n, RefType t) {
exists(BasicBlock bb, InstanceOfExpr ioe, BaseSsaVariable v, VarAccess va |
instanceofDisjunction(bb, v) and
bb.bbDominates(va.getBasicBlock()) and
bb.dominates(va.getBasicBlock()) and
va = v.getAUse() and
instanceofDisjunct(ioe, bb, v) and
t = ioe.getSyntacticCheckedType() and

View File

@@ -145,7 +145,7 @@ private module BaseSsaImpl {
/** Holds if `v` has an implicit definition at the entry, `b`, of the callable. */
predicate hasEntryDef(BaseSsaSourceVariable v, BasicBlock b) {
exists(LocalScopeVariable l, Callable c |
v = TLocalVar(c, l) and c.getBody().getControlFlowNode() = b
v = TLocalVar(c, l) and c.getBody().getBasicBlock() = b
|
l instanceof Parameter or
l.getCallable() != c
@@ -157,15 +157,14 @@ private import BaseSsaImpl
private module SsaInput implements SsaImplCommon::InputSig<Location> {
private import java as J
private import semmle.code.java.controlflow.Dominance as Dom
class BasicBlock = J::BasicBlock;
class ControlFlowNode = J::ControlFlowNode;
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { Dom::bbIDominates(result, bb) }
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) }
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getABBSuccessor() }
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
class SourceVariable = BaseSsaSourceVariable;

View File

@@ -83,12 +83,12 @@ private module CaptureInput implements VariableCapture::InputSig<Location> {
class ControlFlowNode = J::ControlFlowNode;
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { bbIDominates(result, bb) }
BasicBlock getABasicBlockSuccessor(BasicBlock bb) {
result = bb.(J::BasicBlock).getABBSuccessor()
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) {
result.(J::BasicBlock).immediatelyDominates(bb)
}
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.(J::BasicBlock).getASuccessor() }
//TODO: support capture of `this` in lambdas
class CapturedVariable instanceof LocalScopeVariable {
CapturedVariable() {

View File

@@ -40,14 +40,14 @@ private module ThisFlow {
private int lastRank(BasicBlock b) { result = max(int rankix | thisRank(_, b, rankix)) }
private predicate blockPrecedesThisAccess(BasicBlock b) { thisAccess(_, b.getABBSuccessor*(), _) }
private predicate blockPrecedesThisAccess(BasicBlock b) { thisAccess(_, b.getASuccessor*(), _) }
private predicate thisAccessBlockReaches(BasicBlock b1, BasicBlock b2) {
thisAccess(_, b1, _) and b2 = b1.getABBSuccessor()
thisAccess(_, b1, _) and b2 = b1.getASuccessor()
or
exists(BasicBlock mid |
thisAccessBlockReaches(b1, mid) and
b2 = mid.getABBSuccessor() and
b2 = mid.getASuccessor() and
not thisAccess(_, mid, _) and
blockPrecedesThisAccess(b2)
)

View File

@@ -144,13 +144,13 @@ private predicate certainVariableUpdate(TrackedVar v, ControlFlowNode n, BasicBl
pragma[nomagic]
private predicate hasEntryDef(TrackedVar v, BasicBlock b) {
exists(LocalScopeVariable l, Callable c |
v = TLocalVar(c, l) and c.getBody().getControlFlowNode() = b
v = TLocalVar(c, l) and c.getBody().getBasicBlock() = b
|
l instanceof Parameter or
l.getCallable() != c
)
or
v instanceof SsaSourceField and v.getEnclosingCallable().getBody().getControlFlowNode() = b
v instanceof SsaSourceField and v.getEnclosingCallable().getBody().getBasicBlock() = b
}
/** Holds if `n` might update the locally tracked variable `v`. */
@@ -165,15 +165,14 @@ private predicate uncertainVariableUpdate(TrackedVar v, ControlFlowNode n, Basic
private module SsaInput implements SsaImplCommon::InputSig<Location> {
private import java as J
private import semmle.code.java.controlflow.Dominance as Dom
class BasicBlock = J::BasicBlock;
class ControlFlowNode = J::ControlFlowNode;
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { Dom::bbIDominates(result, bb) }
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) }
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getABBSuccessor() }
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
class SourceVariable = SsaSourceVariable;
@@ -655,16 +654,7 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
def instanceof SsaUncertainImplicitUpdate
}
class Guard extends Guards::Guard {
/**
* Holds if the control flow branching from `bb1` is dependent on this guard,
* and that the edge from `bb1` to `bb2` corresponds to the evaluation of this
* guard to `branch`.
*/
predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) {
super.hasBranchEdge(bb1, bb2, branch)
}
}
class Guard = Guards::Guard;
/** Holds if the guard `guard` directly controls block `bb` upon evaluating to `branch`. */
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock bb, boolean branch) {

View File

@@ -4,7 +4,6 @@ module Private {
private import semmle.code.java.dataflow.RangeUtils as RU
private import semmle.code.java.controlflow.Guards as G
private import semmle.code.java.controlflow.BasicBlocks as BB
private import semmle.code.java.controlflow.internal.GuardsLogic as GL
private import SsaReadPositionCommon
class BasicBlock = BB::BasicBlock;
@@ -15,7 +14,7 @@ module Private {
class Expr = J::Expr;
class Guard = G::Guard;
class Guard = G::Guard_v2;
class ConstantIntegerExpr = RU::ConstantIntegerExpr;
@@ -101,29 +100,17 @@ module Private {
}
}
/**
* Holds if `guard` directly controls the position `controlled` with the
* value `testIsTrue`.
*/
pragma[nomagic]
predicate guardDirectlyControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
guard.directlyControls(controlled.(SsaReadPositionBlock).getBlock(), testIsTrue)
or
exists(SsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
guard.directlyControls(controlledEdge.getOrigBlock(), testIsTrue) or
guard.hasBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(), testIsTrue)
)
}
/**
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
*/
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
guardDirectlyControlsSsaRead(guard, controlled, testIsTrue)
guard.controls(controlled.(SsaReadPositionBlock).getBlock(), testIsTrue)
or
exists(Guard guard0, boolean testIsTrue0 |
GL::implies_v2(guard0, testIsTrue0, guard, testIsTrue) and
guardControlsSsaRead(guard0, controlled, testIsTrue0)
exists(SsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
guard.controls(controlledEdge.getOrigBlock(), testIsTrue) or
guard
.controlsBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(),
testIsTrue)
)
}

View File

@@ -7,13 +7,12 @@ module Private {
private import semmle.code.java.dataflow.SSA as Ssa
private import semmle.code.java.controlflow.Guards as G
private import SsaReadPositionCommon
private import semmle.code.java.controlflow.internal.GuardsLogic as GL
private import Sign
import Impl
class ConstantIntegerExpr = RU::ConstantIntegerExpr;
class Guard = G::Guard;
class Guard = G::Guard_v2;
class SsaVariable = Ssa::SsaVariable;
@@ -170,31 +169,17 @@ module Private {
predicate ssaRead = RU::ssaRead/2;
/**
* Holds if `guard` directly controls the position `controlled` with the
* value `testIsTrue`.
*/
pragma[nomagic]
private predicate guardDirectlyControlsSsaRead(
Guard guard, SsaReadPosition controlled, boolean testIsTrue
) {
guard.directlyControls(controlled.(SsaReadPositionBlock).getBlock(), testIsTrue)
or
exists(SsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
guard.directlyControls(controlledEdge.getOrigBlock(), testIsTrue) or
guard.hasBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(), testIsTrue)
)
}
/**
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
*/
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
guardDirectlyControlsSsaRead(guard, controlled, testIsTrue)
guard.controls(controlled.(SsaReadPositionBlock).getBlock(), testIsTrue)
or
exists(Guard guard0, boolean testIsTrue0 |
GL::implies_v2(guard0, testIsTrue0, guard, testIsTrue) and
guardControlsSsaRead(guard0, controlled, testIsTrue0)
exists(SsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
guard.controls(controlledEdge.getOrigBlock(), testIsTrue) or
guard
.controlsBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(),
testIsTrue)
)
}
}

View File

@@ -19,7 +19,7 @@ private predicate id(BB::ExprParent x, BB::ExprParent y) { x = y }
private predicate idOfAst(BB::ExprParent x, int y) = equivalenceRelation(id/2)(x, y)
private predicate idOf(BasicBlock x, int y) { idOfAst(x.getAstNode(), y) }
private predicate idOf(BasicBlock x, int y) { idOfAst(x.getFirstNode().getAstNode(), y) }
private int getId(BasicBlock bb) { idOf(bb, result) }

View File

@@ -153,8 +153,16 @@ class SpringRequestMappingMethod extends SpringControllerMethod {
result = this.getProducesExpr().(CompileTimeConstantExpr).getStringValue()
}
/** Gets the "value" @RequestMapping annotation value, if present. */
string getValue() { result = requestMappingAnnotation.getStringValue("value") }
/** DEPRECATED: Use `getAValue()` instead. */
deprecated string getValue() { result = requestMappingAnnotation.getStringValue("value") }
/**
* Gets a "value" @RequestMapping annotation string value, if present.
*
* If the annotation element is defined with an array initializer, then the result will be one of the
* elements of that array. Otherwise, the result will be the single expression used as value.
*/
string getAValue() { result = requestMappingAnnotation.getAStringArrayValue("value") }
/** Gets the "method" @RequestMapping annotation value, if present. */
string getMethodValue() {

View File

@@ -24,6 +24,6 @@ private class SslProceedCall extends MethodCall {
/** Holds if `m` trusts all certificates by calling `SslErrorHandler.proceed` unconditionally. */
predicate trustsAllCerts(OnReceivedSslErrorMethod m) {
exists(SslProceedCall pr | pr.getQualifier().(VarAccess).getVariable() = m.handlerArg() |
pr.getBasicBlock().bbPostDominates(m.getBody().getBasicBlock())
pr.getBasicBlock().postDominates(m.getBody().getBasicBlock())
)
}

View File

@@ -21,7 +21,7 @@ private module ValidationMethod<DataFlow::guardChecksSig/3 validationGuard> {
validationMethod(ma.getMethod(), pos) and
ma.getArgument(pos) = rv and
adjacentUseUseSameVar(rv, result.asExpr()) and
ma.getBasicBlock().bbDominates(result.asExpr().getBasicBlock())
ma.getBasicBlock().dominates(result.asExpr().getBasicBlock())
)
}

View File

@@ -168,7 +168,7 @@ private class FullyDecodesUrlBarrier extends DataFlow::Node {
exists(Variable v, Expr e | this.asExpr() = v.getAnAccess() |
fullyDecodesUrlGuard(e) and
e = v.getAnAccess() and
e.getBasicBlock().bbDominates(this.asExpr().getBasicBlock())
e.getBasicBlock().dominates(this.asExpr().getBasicBlock())
)
}
}

View File

@@ -40,16 +40,16 @@ private predicate validatedAccess(VarAccess va) {
guardcall.getControlFlowNode() = node
|
exists(BasicBlock succ |
succ = node.getANormalSuccessor() and
succ.getFirstNode() = node.getANormalSuccessor() and
dominatingEdge(node.getBasicBlock(), succ) and
succ.bbDominates(va.getBasicBlock())
succ.dominates(va.getBasicBlock())
)
or
exists(BasicBlock bb, int i |
bb.getNode(i) = node and
bb.getNode(i + 1) = node.getANormalSuccessor()
|
bb.bbStrictlyDominates(va.getBasicBlock()) or
bb.strictlyDominates(va.getBasicBlock()) or
bb.getNode(any(int j | j > i)).asExpr() = va
)
)

View File

@@ -1,3 +1,9 @@
## 1.5.1
### Minor Analysis Improvements
* The query `java/hardcoded-credential-api-call` has been removed from all query suites.
## 1.5.0
### Query Metadata Changes

View File

@@ -99,8 +99,8 @@ predicate failedLock(LockType t, BasicBlock lockblock, BasicBlock exblock) {
)
) and
(
lock.getAnExceptionSuccessor() = exblock or
lock.(ConditionNode).getAFalseSuccessor() = exblock
lock.getAnExceptionSuccessor() = exblock.getFirstNode() or
lock.(ConditionNode).getAFalseSuccessor() = exblock.getFirstNode()
)
)
}
@@ -113,7 +113,7 @@ predicate heldByCurrentThreadCheck(LockType t, BasicBlock checkblock, BasicBlock
exists(ConditionBlock conditionBlock |
conditionBlock.getCondition() = t.getIsHeldByCurrentThreadAccess()
|
conditionBlock.getBasicBlock() = checkblock and
conditionBlock = checkblock and
conditionBlock.getTestSuccessor(false) = falsesucc
)
}
@@ -133,7 +133,7 @@ predicate variableLockStateCheck(LockType t, BasicBlock checkblock, BasicBlock f
conditionBlock.getTestSuccessor(true) = t.getUnlockAccess().getBasicBlock() and
conditionBlock.getCondition() = v
|
conditionBlock.getBasicBlock() = checkblock and
conditionBlock = checkblock and
conditionBlock.getTestSuccessor(false) = falsesucc
)
}
@@ -145,9 +145,7 @@ predicate variableLockStateCheck(LockType t, BasicBlock checkblock, BasicBlock f
predicate blockIsLocked(LockType t, BasicBlock src, BasicBlock b, int locks) {
lockUnlockBlock(t, b, locks) and src = b and locks > 0
or
exists(BasicBlock pred, int predlocks, int curlocks, int failedlock |
pred = b.getABBPredecessor()
|
exists(BasicBlock pred, int predlocks, int curlocks, int failedlock | pred = b.getAPredecessor() |
// The number of net locks from the `src` block to the predecessor block `pred` is `predlocks`.
blockIsLocked(t, src, pred, predlocks) and
// The recursive call ensures that at least one lock is held, so do not consider the false

View File

@@ -18,6 +18,6 @@ where
iteration = inner.getAnIterationVariable() and
iteration = outer.getAnIterationVariable() and
inner.getEnclosingStmt+() = outer and
inner.getBasicBlock().getABBSuccessor+() = outer.getCondition().getBasicBlock()
inner.getBasicBlock().getASuccessor+() = outer.getCondition().getBasicBlock()
select inner.getCondition(), "Nested for statement uses loop variable $@ of enclosing $@.",
iteration, iteration.getName(), outer, "for statement"

View File

@@ -18,6 +18,7 @@ public class Test {
String s1 = "test";
s1 = s1.replaceAll("t", "x"); // NON_COMPLIANT
s1 = s1.replaceAll(".*", "x"); // COMPLIANT
s1 = s1.replace("t", "x"); // COMPLIANT
}
}

View File

@@ -4,7 +4,7 @@
* @kind path-problem
* @problem.severity error
* @security-severity 9.8
* @precision medium
* @precision low
* @id java/hardcoded-credential-api-call
* @tags security
* external/cwe/cwe-798

View File

@@ -37,7 +37,7 @@ predicate overwritten(VariableUpdate upd) {
bb1.getNode(i) = upd.getControlFlowNode() and
bb2.getNode(j) = overwrite.getControlFlowNode()
|
bb1.getABBSuccessor+() = bb2
bb1.getASuccessor+() = bb2
or
bb1 = bb2 and i < j
)

View File

@@ -14,7 +14,7 @@ private predicate blockInSwitch(SwitchStmt s, BasicBlock b) {
private predicate switchCaseControlFlow(SwitchStmt switch, BasicBlock b1, BasicBlock b2) {
blockInSwitch(switch, b1) and
b1.getABBSuccessor() = b2 and
b1.getASuccessor() = b2 and
blockInSwitch(switch, b2)
}

View File

@@ -0,0 +1,5 @@
## 1.5.1
### Minor Analysis Improvements
* The query `java/hardcoded-credential-api-call` has been removed from all query suites.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.5.0
lastReleaseVersion: 1.5.1

View File

@@ -13,7 +13,7 @@ import semmle.code.java.dataflow.SSA
class SsaConvertibleReadAccess extends VarRead {
SsaConvertibleReadAccess() {
this.getEnclosingCallable().getBody().getBasicBlock().getABBSuccessor*() = this.getBasicBlock() and
this.getEnclosingCallable().getBody().getBasicBlock().getASuccessor*() = this.getBasicBlock() and
(
not exists(this.getQualifier())
or

View File

@@ -1,5 +1,5 @@
name: codeql/java-queries
version: 1.5.0
version: 1.5.1
groups:
- java
- queries

View File

@@ -10,5 +10,5 @@ import internal.CaptureModels
import SummaryModels
from DataFlowSummaryTargetApi api, string flow
where flow = ContentSensitive::captureFlow(api, _)
where flow = ContentSensitive::captureFlow(api, _, _, _, _)
select flow order by flow

View File

@@ -16,7 +16,7 @@ import PartialFlow::PartialPathGraph
int explorationLimit() { result = 3 }
module PartialFlow = Heuristic::PropagateFlow::FlowExplorationFwd<explorationLimit/0>;
module PartialFlow = Heuristic::PropagateTaintFlow::FlowExplorationFwd<explorationLimit/0>;
from
PartialFlow::PartialPathNode source, PartialFlow::PartialPathNode sink,

View File

@@ -12,16 +12,15 @@ import java
import semmle.code.java.dataflow.DataFlow
import utils.modelgenerator.internal.CaptureModels
import SummaryModels
import Heuristic
import PropagateFlow::PathGraph
import Heuristic::PropagateTaintFlow::PathGraph
from
PropagateFlow::PathNode source, PropagateFlow::PathNode sink, DataFlowSummaryTargetApi api,
DataFlow::Node p, DataFlow::Node returnNodeExt
Heuristic::PropagateTaintFlow::PathNode source, Heuristic::PropagateTaintFlow::PathNode sink,
DataFlowSummaryTargetApi api, DataFlow::Node p, DataFlow::Node returnNodeExt
where
PropagateFlow::flowPath(source, sink) and
Heuristic::PropagateTaintFlow::flowPath(source, sink) and
p = source.getNode() and
returnNodeExt = sink.getNode() and
exists(captureThroughFlow0(api, p, returnNodeExt))
Heuristic::captureThroughFlow0(api, p, returnNodeExt)
select sink.getNode(), source, sink, "There is flow from $@ to the $@.", source.getNode(),
"parameter", sink.getNode(), "return value"

View File

@@ -92,7 +92,7 @@ module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig<Locatio
string qualifierString() { result = "Argument[this]" }
string parameterAccess(J::Parameter p) {
string parameterApproximateAccess(J::Parameter p) {
if
p.getType() instanceof J::Array and
not isPrimitiveTypeUsedForBulkData(p.getType().(J::Array).getElementType())
@@ -103,20 +103,20 @@ module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig<Locatio
else result = "Argument[" + p.getPosition() + "]"
}
string parameterContentAccess(J::Parameter p) { result = "Argument[" + p.getPosition() + "]" }
string parameterExactAccess(J::Parameter p) { result = "Argument[" + p.getPosition() + "]" }
class InstanceParameterNode = DataFlow::InstanceParameterNode;
bindingset[c]
string paramReturnNodeAsOutput(Callable c, ParameterPosition pos) {
result = parameterAccess(c.getParameter(pos))
string paramReturnNodeAsApproximateOutput(Callable c, ParameterPosition pos) {
result = parameterApproximateAccess(c.getParameter(pos))
or
result = qualifierString() and pos = -1
}
bindingset[c]
string paramReturnNodeAsContentOutput(Callable c, ParameterPosition pos) {
result = parameterContentAccess(c.getParameter(pos))
string paramReturnNodeAsExactOutput(Callable c, ParameterPosition pos) {
result = parameterExactAccess(c.getParameter(pos))
or
result = qualifierString() and pos = -1
}

View File

@@ -1,6 +1,6 @@
import default
import java
import semmle.code.java.controlflow.Dominance
from BasicBlock b, BasicBlock b2
where bbStrictlyDominates(b, b2)
where b.strictlyDominates(b2)
select b, b2

View File

@@ -1,5 +1,5 @@
import default
import java
from BasicBlock b, BasicBlock b2
where b.getABBSuccessor() = b2
where b.getASuccessor() = b2
select b, b2

View File

@@ -16,6 +16,6 @@ predicate dominanceCounterExample(ControlFlowNode entry, ControlFlowNode dom, Co
from Callable c, ControlFlowNode dom, ControlFlowNode node
where
(strictlyDominates(dom, node) or bbStrictlyDominates(dom, node)) and
strictlyDominates(dom, node) and
dominanceCounterExample(c.getBody().getControlFlowNode(), dom, node)
select c, dom, node

View File

@@ -1,6 +1,6 @@
import default
import java
import semmle.code.java.controlflow.Dominance
from BasicBlock b, BasicBlock b2
where bbStrictlyDominates(b, b2)
where b.strictlyDominates(b2)
select b, b2

View File

@@ -1,5 +1,5 @@
import default
import java
from BasicBlock b, BasicBlock b2
where b.getABBSuccessor() = b2
where b.getASuccessor() = b2
select b, b2

View File

@@ -16,6 +16,6 @@ predicate dominanceCounterExample(ControlFlowNode entry, ControlFlowNode dom, Co
from Callable c, ControlFlowNode dom, ControlFlowNode node
where
(strictlyDominates(dom, node) or bbStrictlyDominates(dom, node)) and
strictlyDominates(dom, node) and
dominanceCounterExample(c.getBody().getControlFlowNode(), dom, node)
select c, dom, node

View File

@@ -1,6 +1,6 @@
import default
import java
import semmle.code.java.controlflow.Dominance
from BasicBlock b, BasicBlock b2
where bbStrictlyDominates(b, b2)
where b.strictlyDominates(b2)
select b, b2

View File

@@ -1,5 +1,5 @@
import default
import java
from BasicBlock b, BasicBlock b2
where b.getABBSuccessor() = b2
where b.getASuccessor() = b2
select b, b2

View File

@@ -16,6 +16,6 @@ predicate dominanceCounterExample(ControlFlowNode entry, ControlFlowNode dom, Co
from Callable c, ControlFlowNode dom, ControlFlowNode node
where
(strictlyDominates(dom, node) or bbStrictlyDominates(dom, node)) and
strictlyDominates(dom, node) and
dominanceCounterExample(c.getBody().getControlFlowNode(), dom, node)
select c, dom, node

View File

@@ -0,0 +1,18 @@
import java
import utils.test.InlineExpectationsTest
private import semmle.code.java.frameworks.spring.SpringController
module TestRequestController implements TestSig {
string getARelevantTag() { result = "RequestMappingURL" }
predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "RequestMappingURL" and
exists(SpringRequestMappingMethod m |
m.getLocation() = location and
element = m.toString() and
value = "\"" + m.getAValue() + "\""
)
}
}
import MakeTest<TestRequestController>

View File

@@ -32,92 +32,93 @@ import org.springframework.web.bind.annotation.SessionAttribute;
public class Test {
static void sink(Object o) {}
static void sink(Object o) {
}
@Controller
static class NotTaintedTest {
@RequestMapping("/")
public void get(WebRequest src) {
public void get(WebRequest src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(NativeWebRequest src) {
public void get(NativeWebRequest src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(ServletRequest src) {
public void get(ServletRequest src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(HttpSession src) {
public void get(HttpSession src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(PushBuilder src) {
public void get(PushBuilder src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(Principal src) {
public void get(Principal src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(HttpMethod src) {
public void get(HttpMethod src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(Locale src) {
public void get(Locale src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(TimeZone src) {
public void get(TimeZone src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(ZoneId src) {
public void get(ZoneId src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(OutputStream src) {
public void get(OutputStream src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(Writer src) {
public void get(Writer src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(RedirectAttributes src) {
public void get(RedirectAttributes src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(Errors src) {
public void get(Errors src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(SessionStatus src) {
public void get(SessionStatus src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(UriComponentsBuilder src) {
public void get(UriComponentsBuilder src) { // $ RequestMappingURL="/"
sink(src);
}
@RequestMapping("/")
public void get(Pageable src) {
public void get(Pageable src) { // $ RequestMappingURL="/"
sink(src);
}
}
@@ -125,62 +126,62 @@ public class Test {
@Controller
static class ExplicitlyTaintedTest {
@RequestMapping("/")
public void get(InputStream src) {
public void get(InputStream src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
@RequestMapping("/")
public void get(Reader src) {
public void get(Reader src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
@RequestMapping("/")
public void matrixVariable(@MatrixVariable Object src) {
public void matrixVariable(@MatrixVariable Object src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
@RequestMapping("/")
public void requestParam(@RequestParam Object src) {
public void requestParam(@RequestParam Object src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
@RequestMapping("/")
public void requestHeader(@RequestHeader Object src) {
public void requestHeader(@RequestHeader Object src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
@RequestMapping("/")
public void cookieValue(@CookieValue Object src) {
public void cookieValue(@CookieValue Object src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
@RequestMapping("/")
public void requestPart(@RequestPart Object src) {
public void requestPart(@RequestPart Object src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
@RequestMapping("/")
public void pathVariable(@PathVariable Object src) {
public void pathVariable(@PathVariable Object src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
@RequestMapping("/")
public void requestBody(@RequestBody Object src) {
public void requestBody(@RequestBody Object src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
@RequestMapping("/")
public void get(HttpEntity src) {
public void get(HttpEntity src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
@RequestMapping("/")
public void requestAttribute(@RequestAttribute Object src) {
public void requestAttribute(@RequestAttribute Object src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
@RequestMapping("/")
public void sessionAttribute(@SessionAttribute Object src) {
public void sessionAttribute(@SessionAttribute Object src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
}
@@ -191,13 +192,20 @@ public class Test {
}
@RequestMapping("/")
public void get(String src) {
public void get(String src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
@RequestMapping("/")
public void get1(Pojo src) {
public void get1(Pojo src) { // $ RequestMappingURL="/"
sink(src); // $hasValueFlow
}
}
@Controller
static class MultipleValuesTest {
@RequestMapping({"/a", "/b"})
public void get(WebRequest src) { // $ RequestMappingURL="/a" RequestMappingURL="/b"
}
}
}

View File

@@ -3,5 +3,6 @@ public class Test {
String s1 = "test";
s1 = s1.replaceAll("t", "x"); // $ Alert // NON_COMPLIANT
s1 = s1.replaceAll(".*", "x"); // COMPLIANT
s1 = s1.replace("t", "x"); // COMPLIANT
}
}

View File

@@ -4,7 +4,7 @@ import SummaryModels
import utils.test.InlineMadTest
module InlineMadTestConfig implements InlineMadTestConfigSig {
string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c, _) }
string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c, _, _, _, _) }
string getKind() { result = "contentbased-summary" }
}

View File

@@ -4,7 +4,7 @@ import SummaryModels
import utils.test.InlineMadTest
module InlineMadTestConfig implements InlineMadTestConfigSig {
string getCapturedModel(Callable c) { result = Heuristic::captureFlow(c) }
string getCapturedModel(Callable c) { result = Heuristic::captureFlow(c, _) }
string getKind() { result = "heuristic-summary" }
}

View File

@@ -4,7 +4,7 @@ public final class FinalClass {
private static final String C = "constant";
// heuristic-summary=p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=p;FinalClass;false;returnsInput;(String);;Argument[0];ReturnValue;value;dfc-generated
public String returnsInput(String input) {
return input;

View File

@@ -24,7 +24,7 @@ public final class ImmutablePojo {
return x;
}
// heuristic-summary=p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;value;df-generated
// heuristic-summary=p;ImmutablePojo;false;or;(String);;Argument[this];ReturnValue;taint;df-generated
// contentbased-summary=p;ImmutablePojo;false;or;(String);;Argument[0];ReturnValue;value;dfc-generated
// contentbased-summary=p;ImmutablePojo;false;or;(String);;Argument[this].SyntheticField[p.ImmutablePojo.value];ReturnValue;value;dfc-generated

View File

@@ -10,7 +10,7 @@ public class Inheritance {
}
public class AImplBasePrivateImpl extends BasePrivate {
// heuristic-summary=p;Inheritance$AImplBasePrivateImpl;true;id;(String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;Inheritance$AImplBasePrivateImpl;true;id;(String);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=p;Inheritance$AImplBasePrivateImpl;true;id;(String);;Argument[0];ReturnValue;value;dfc-generated
@Override
public String id(String s) {
@@ -19,7 +19,7 @@ public class Inheritance {
}
public class AImplBasePublic extends BasePublic {
// heuristic-summary=p;Inheritance$BasePublic;true;id;(String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;Inheritance$BasePublic;true;id;(String);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=p;Inheritance$BasePublic;true;id;(String);;Argument[0];ReturnValue;value;dfc-generated
@Override
public String id(String s) {
@@ -60,7 +60,7 @@ public class Inheritance {
}
public class BImpl extends B {
// heuristic-summary=p;Inheritance$IPublic1;true;id;(String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;Inheritance$IPublic1;true;id;(String);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=p;Inheritance$IPublic1;true;id;(String);;Argument[0];ReturnValue;value;dfc-generated
@Override
public String id(String s) {
@@ -69,7 +69,7 @@ public class Inheritance {
}
public class CImpl extends C {
// heuristic-summary=p;Inheritance$C;true;id;(String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;Inheritance$C;true;id;(String);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=p;Inheritance$C;true;id;(String);;Argument[0];ReturnValue;value;dfc-generated
@Override
public String id(String s) {
@@ -78,7 +78,7 @@ public class Inheritance {
}
public class DImpl extends D {
// heuristic-summary=p;Inheritance$IPublic2;true;id;(String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;Inheritance$IPublic2;true;id;(String);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=p;Inheritance$IPublic2;true;id;(String);;Argument[0];ReturnValue;value;dfc-generated
@Override
public String id(String s) {
@@ -87,7 +87,7 @@ public class Inheritance {
}
public class EImpl extends E {
// heuristic-summary=p;Inheritance$EImpl;true;id;(String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;Inheritance$EImpl;true;id;(String);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=p;Inheritance$EImpl;true;id;(String);;Argument[0];ReturnValue;value;dfc-generated
@Override
public String id(String s) {

View File

@@ -9,14 +9,14 @@ public class InnerClasses {
}
public class CaptureMe {
// heuristic-summary=p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=p;InnerClasses$CaptureMe;true;yesCm;(String);;Argument[0];ReturnValue;value;dfc-generated
public String yesCm(String input) {
return input;
}
}
// heuristic-summary=p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=p;InnerClasses;true;yes;(String);;Argument[0];ReturnValue;value;dfc-generated
public String yes(String input) {
return input;

View File

@@ -2,7 +2,7 @@ package p;
public class MultiPaths {
// heuristic-summary=p;MultiPaths;true;cond;(String,String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;MultiPaths;true;cond;(String,String);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=p;MultiPaths;true;cond;(String,String);;Argument[0];ReturnValue;value;dfc-generated
public String cond(String x, String other) {
if (x == other) {

View File

@@ -16,7 +16,7 @@ class MultipleImpl2 {
}
public class Impl2 implements IInterface {
// heuristic-summary=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=p;MultipleImpl2$IInterface;true;m;(Object);;Argument[0];ReturnValue;value;dfc-generated
public Object m(Object value) {
return value;

View File

@@ -9,7 +9,7 @@ public class MultipleImpls {
}
public static class Strat1 implements Strategy {
// heuristic-summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=p;MultipleImpls$Strategy;true;doSomething;(String);;Argument[0];ReturnValue;value;dfc-generated
public String doSomething(String value) {
return value;

View File

@@ -7,7 +7,7 @@ import java.util.List;
public class ParamFlow {
// heuristic-summary=p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;value;df-generated
// contentbased-summary=p;ParamFlow;true;returnsInput;(String);;Argument[0];ReturnValue;value;dfc-generated
public String returnsInput(String input) {
return input;
@@ -18,8 +18,8 @@ public class ParamFlow {
return input.length();
}
// heuristic-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;taint;df-generated
// heuristic-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;taint;df-generated
// heuristic-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;value;df-generated
// heuristic-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;value;df-generated
// contentbased-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[0];ReturnValue;value;dfc-generated
// contentbased-summary=p;ParamFlow;true;returnMultipleParameters;(String,String);;Argument[1];ReturnValue;value;dfc-generated
public String returnMultipleParameters(String one, String two) {

View File

@@ -40,8 +40,8 @@ public class Sources {
return socketStream();
}
// source=p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[0].ArrayElement;remote;df-generated
// source=p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[1].Element;remote;df-generated
// source=p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[0];remote;df-generated
// source=p;Sources;true;sourceToParameter;(InputStream[],List);;Argument[1];remote;df-generated
// neutral=p;Sources;sourceToParameter;(InputStream[],List);summary;df-generated
public void sourceToParameter(InputStream[] streams, List<InputStream> otherStreams)
throws IOException {