std::string/std::string_view size()/length() was cached only in the member
cache, which assign() clears. So `char* p = malloc(s.size()+1); ...; p[s.size()]`
encoded the two size() calls as DIFFERENT symbols, letting the solver find a
spurious out-of-bounds (yams object_storage_adapter.cpp dup_cstr, plugin_host_services_shim).
Route zero-arg const size()/length() through the assignment-surviving
string-length cache (string_lengths_), so both calls resolve to one length
symbol: the final write lands exactly at the end (in-bounds), while a genuine
size()+1 write still fires.
Adds positive/negative oob tests; full suite 137/137.
- int-overflow: unsigned wrap is defined, not UB — split to
fold.unsigned-wrap so signed-UB findings aren't drowned; on by
default (--report-unsigned-wrap=false opts out)
- use-after-free: model return/throw as path-terminating so
`delete p; return;` in an error branch can't poison the fall-through
- oob-access: real sizeof for complete structs (was 1); recognize
std::min/clamp/modulo index bounds
- memory-leak: static-storage singletons + return-to-caller are
caller-owned, not leaks
YAMS scan: UAF 4→0, struct-OOB ~10→0, singleton-leak ~15→0,
min/modulo-bound OOB →0. 137/137 tests pass.
- Verified seedInterproceduralContext() pipeline: SecurityWalker calls it
before TraverseDecl, OOBObserver scans all call sites for ConstantArrayType
- OOB observer consumes param_buffer_sizes_ for ParmVarDecl base variables
- Test added for interprocedural buffer-bound detection
- encoder.cpp: extract VarDecl from ArraySubscriptExpr base when
trackedArrayVar returns null (covers ParmVarDecls like 'output')
- test_oob_access.cpp: test interprocedural buffer propagation
(decode_base64 receiving decoded[256] via pointer parameter)
- Root cause: validate_auth is summarized, preventing inline walk.
Mitigation tracked in docs/internal/interprocedural-notes.md
- SizeInfo struct: buffer_name, capacity, index_expr for OOB findings
- path_trace: vector of branch/call events from SafetyObserver
- counterexample: Z3 model key=value pairs for SAT findings
- variable_name, sink_function: named context for LLM steering
- Serialized in FindingEvidence + SARIF properties