SqliteResultUsedAfterFinalize
error native on by defaultGroup: Probable bugs
Read the SQLite result before finalizing it.
Example
php
<?php
function f(SQLite3Result $r) { if($r->finalize()){ $r->fetchArray(); } }
function g(SQLite3 $db) { $r = $db->query('select 1'); $r->finalize(); return $r->fetchArray(); }Reported:
- line 2: Read the SQLite result before finalizing it.
- line 3: Read the SQLite result before finalizing it.
Detection
- After SQLite3Result finalize on a proven local receiver, fetchArray, reset, columnName, columnType or numColumns is called on that same result without reassignment. Report the invalid use. finalize cannot fail, so its return value does not have to be tested. Two shapes prove that finalize ran first: a finalize call in an expression statement of the same or an enclosing statement list that always executes before the use, including when its result is stored (
$ok = $r->finalize();); or a use inside the body of anifwhose condition is the finalize call itself or its comparison withtrue(==or===, either operand order). - Resolve builtin functions, extension classes, constants and method receivers, including aliases and supported named arguments. Inspect reachable operations in one lexical scope with bounded local flow.
- Emit one finding per violating operation. Never infer policy from names or comments. When the proof is inconclusive, nothing is reported.
Exceptions (no report)
- Exclude shadowed or unresolved symbols, incomplete code, unknown required constants, ambiguous receiver identity and unsupported versions. Reassignment, escaping aliases, and unknown calls invalidate dependent flow facts.
- A finalize call that may be skipped proves nothing: one inside a conditional statement that does not contain the use, on the right of a short-circuit or null-coalescing operator, in a ternary branch, in a
matcharm, in the arguments, array key or dynamic member name of a null-safe chain, in atryblock that the use follows, or in a nested closure. - No report when the receiver is a by-reference parameter: any call can replace the result behind it.
- Both @custos-ignore SqliteResultUsedAfterFinalize and @noinspection SqliteResultUsedAfterFinalize suppress this native rule.
Fix
None. A safe repair requires choosing values, error handling, or application behavior.
PHP versions
Apply throughout PHP 5.3–8.5 only where the extension API and syntax exist. Do not flag API unavailability through this rule.
Options
None. Use normal rule configuration to enable or disable the inspection.
Configure
In custos.json:
json
{
"rules": {
"SqliteResultUsedAfterFinalize": {
"enabled": false
}
}
}Suppress
Before the statement or declaration (or the first statement of the file):
php
// @custos-ignore SqliteResultUsedAfterFinalize