Skip to content
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Python: Exclude sources in functions with unclear returns
A common source of FPs is when the flow inside a function depends on
some argument to the function. In this case, if a non-container class is
being returned in _some_ branch, we behave as if it _always_ is
returned, leading to false positives where the code is actually safe
because the argument to the function prevents the bad return from being
executed.
  • Loading branch information
tausbn committed Apr 14, 2026
commit 01a9bec7df4a75d64cb589850f6b1f8f82958922
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,22 @@ module ClassInstanceFlow<ClassInstanceFlowSig Sig> {
node = DataFlow::BarrierGuard<isinstanceGuard/3>::getABarrierNode()
}

/**
* Holds if `call` is inside a branch that is guarded by a condition
* depending on a parameter of the enclosing function. In such cases,
* the instantiation is contextual — it only happens for certain argument
* values — and we cannot determine from the call site whether it will
* actually execute.
*/
private predicate parameterGuardedCall(CallNode call) {
exists(ConditionBlock guard, DataFlow::ParameterNode param, DataFlow::Node guardSubExpr |
guard.controls(call.getBasicBlock(), _) and
param.getScope() = call.getScope() and
guardSubExpr.asCfgNode() = guard.getLastNode().getAChild*() and
DataFlow::localFlow(param, guardSubExpr)
)
}

predicate isAdditionalFlowStep(
DataFlow::Node nodeFrom, FlowState stateFrom, DataFlow::Node nodeTo, FlowState stateTo
) {
Expand All @@ -109,7 +125,11 @@ module ClassInstanceFlow<ClassInstanceFlowSig Sig> {
nodeTo.asCfgNode() = call and
// Exclude decorator applications, where the result is a proxy
// rather than a typical instance.
not call.getNode() = any(FunctionExpr fe).getADecoratorCall()
not call.getNode() = any(FunctionExpr fe).getADecoratorCall() and
// Exclude instantiations guarded by parameter-dependent conditions,
// since we cannot determine from the call site whether the guard
// will be satisfied.
not parameterGuardedCall(call)
)
}
}
Expand Down
Loading