Skip to main content

Module flow_intra

Module flow_intra 

Source
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.md PL/SQL Language Reference — the assignment + parameter-mode chapters define how a value enters / moves through a routine.
  • LOW-LEVEL-CATALOGS.md Supplied Package Buckets — DBMS_ASSERT is the cleanser that resets a name’s taint.

Structs§

FlowEnv
Per-routine flow environment: name (upper-cased) → flow.
TaintSources
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. sources declares 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 when outcome.limit_hit (R13 — never silently truncate, never stack-overflow on a non-shrinking malformed slice).