mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Java: Replace global flow by local flow
This commit is contained in:
@@ -106,45 +106,42 @@ private predicate isEqualsIgnoreCaseMethodAccess(MethodAccess ma) {
|
|||||||
ma.getMethod().getDeclaringType() instanceof TypeString
|
ma.getMethod().getDeclaringType() instanceof TypeString
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A configuration to model the flow of feature flags into `Guard`s. This is used to determine whether something is guarded by such a flag. */
|
/** Holds if `source` should is considered a flag. */
|
||||||
private class FlagToGuardFlow extends DataFlow::Configuration {
|
private predicate isFlag(DataFlow::Node source) {
|
||||||
FlagToGuardFlow() { this = "FlagToGuardFlow" }
|
exists(VarAccess v | v.getVariable().getName() = getAFlagName() |
|
||||||
|
source.asExpr() = v and v.getType() instanceof FlagType
|
||||||
|
)
|
||||||
|
or
|
||||||
|
exists(StringLiteral s | s.getRepresentedString() = getAFlagName() | source.asExpr() = s)
|
||||||
|
or
|
||||||
|
exists(MethodAccess ma | ma.getMethod().getName() = getAFlagName() |
|
||||||
|
source.asExpr() = ma and
|
||||||
|
ma.getType() instanceof FlagType and
|
||||||
|
not isEqualsIgnoreCaseMethodAccess(ma)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override predicate isSource(DataFlow::Node source) {
|
/** Holds if there is flow from `node1` to `node2` either due to local flow or due to custom flow steps. */
|
||||||
exists(VarAccess v | v.getVariable().getName() = getAFlagName() |
|
private predicate flagFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||||
source.asExpr() = v and v.getType() instanceof FlagType
|
DataFlow::localFlowStep(node1, node2)
|
||||||
)
|
or
|
||||||
or
|
exists(MethodAccess ma | ma.getMethod() = any(EnvReadMethod m) |
|
||||||
exists(StringLiteral s | s.getRepresentedString() = getAFlagName() | source.asExpr() = s)
|
ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr()
|
||||||
or
|
)
|
||||||
exists(MethodAccess ma | ma.getMethod().getName() = getAFlagName() |
|
or
|
||||||
source.asExpr() = ma and
|
exists(MethodAccess ma |
|
||||||
ma.getType() instanceof FlagType and
|
ma.getMethod().hasName("parseBoolean") and
|
||||||
not isEqualsIgnoreCaseMethodAccess(ma)
|
ma.getMethod().getDeclaringType().hasQualifiedName("java.lang", "Boolean")
|
||||||
)
|
|
|
||||||
}
|
ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr()
|
||||||
|
)
|
||||||
override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof Guard }
|
|
||||||
|
|
||||||
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
|
||||||
exists(MethodAccess ma | ma.getMethod() = any(EnvReadMethod m) |
|
|
||||||
ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr()
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(MethodAccess ma |
|
|
||||||
ma.getMethod().hasName("parseBoolean") and
|
|
||||||
ma.getMethod().getDeclaringType().hasQualifiedName("java.lang", "Boolean")
|
|
||||||
|
|
|
||||||
ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets a guard that depends on a flag. */
|
/** Gets a guard that depends on a flag. */
|
||||||
private Guard getAGuard() {
|
private Guard getAGuard() {
|
||||||
exists(FlagToGuardFlow cfg, DataFlow::Node source, DataFlow::Node sink |
|
exists(DataFlow::Node source, DataFlow::Node sink |
|
||||||
cfg.hasFlow(source, sink)
|
isFlag(source) and
|
||||||
|
|
flagFlowStep*(source, sink) and
|
||||||
sink.asExpr() = result
|
sink.asExpr() = result
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user