Expand description
Intra-procedural assignment + expression flow.
Walks a lowered statement body and propagates ValueFlow
facts (FLOW-001) through assignments and expressions inside a
single routine. The pass is deliberately a may-analysis
over a flat statement list: it does not model branch joins
precisely (that needs a CFG, scheduled for a later pass) —
it conservatively merges every assignment’s RHS flow into the
LHS via ValueSet::join, which is sound for taint /
string-shape over-approximation.
Taint is use-def transitive: an RHS that references a local
already tainted earlier in the body inherits that taint, so
laundering through intermediates (v_tmp := p_user; v_sql := v_tmp;) cannot escape the analysis. The walk is
iterated to a fixpoint over the finite taint lattice so a name
tainted only on a later pass (e.g. across a loop back-edge) is
still captured.
Outputs a FlowEnv mapping each assigned name to its
accumulated ValueFlow. SAST consumes this to answer “does
tainted input reach a dynamic-SQL sink without a cleanser?”.
§/oracle evidence
DATABASE-REFERENCE.mdPL/SQL Language Reference — the assignment + parameter-mode chapters define how a value enters / moves through a routine.LOW-LEVEL-CATALOGS.mdSupplied Package Buckets —DBMS_ASSERTis the cleanser that resets a name’s taint.
Structs§
- FlowEnv
- Per-routine flow environment: name (upper-cased) → flow.
- Taint
Sources - Names referenced inside an expression that look like
parameters/binds the caller flagged as tainted. The caller
passes the set of tainted source names (e.g. public IN
parameters); any reference to one taints the expression’s
flow with
UserInput.
Functions§
- analyze_
flow - Run intra-procedural flow over
stmts.sourcesdeclares which bare names are tainted on entry (public params, binds). - analyze_
flow_ bounded - Depth-bounded variant of
analyze_flow. Returns the flow environment plus a [RecursionOutcome] recording whether (and how often) a nested re-lowered body was abandoned at the recursion-depth cap rather than walked unbounded. The caller is responsible for emitting an honest typed diagnostic whenoutcome.limit_hit(R13 — never silently truncate, never stack-overflow on a non-shrinking malformed slice).