FileTruncatedBeforeLock
warning native on by defaultGroup: Probable bugs
Detect fopen in w/w+ variants followed by exclusive flock on the same identity.
Example
php
<?php
function bad($path) { $h = fopen($path, 'wb'); if ($h !== false) { flock($h, LOCK_EX); fclose($h); } }
function unlockOnly($path) { $h = fopen($path, 'w'); fwrite($h, 'x'); flock($h, LOCK_UN); fclose($h); }
function sharedOnly($path) { $h = fopen($path, 'w'); flock($h, LOCK_SH); fclose($h); }Reported:
- line 2: Acquire the lock before truncating the file.
Detection
- Report fopen in w/w+ variants followed by exclusive flock on the same identity. The lock is exclusive only when the
flockoperation (second argument, or namedoperation) is proven to beLOCK_EX, optionally combined withLOCK_NBthrough bitwise or. The operation may be written with the constants, with their integer values, or through a local holding such a value. - Resolve builtin calls and named arguments before checking the contract. Project-local callees are considered only when their bodies or immutable summaries establish the required facts. The default is enabled, with positive proof required.
- For flow-dependent conditions, require a reachable source-to-use path with no intervening invalidation. Unknown calls, ambiguous aliases, recursion or analysis-budget exhaustion cannot establish definite facts.
Exceptions (no report)
- Nontruncating modes, already-held established locks, unrelated handles and unknown modes are excluded.
- Unresolved targets, incomplete required facts, suppressed findings and PHP versions lacking the referenced API or language feature produce no report. User declarations shadowing builtin names are not builtin contracts.
- A later
flockthat only requests a shared lock (LOCK_SH) or releases one (LOCK_UN), with or withoutLOCK_NB, is not an exclusive lock and produces no report. The same holds when the operation is missing, dynamic or only partly known.
Fix
No automatic fix: changing mode also requires correctly positioned truncation and failure checks.
PHP versions
Apply only on PHP versions supporting the referenced APIs and syntax (within PHP 5.3–8.5). Builtin behavior and argument contracts follow the configured PHP version. Extension-specific calls require resolved extension API symbols; do not treat same-named application functions as extension calls.
Options
None. Enable or disable this rule through normal rule configuration.
Configure
In custos.json:
json
{
"rules": {
"FileTruncatedBeforeLock": {
"enabled": false
}
}
}Suppress
Before the statement or declaration (or the first statement of the file):
php
// @custos-ignore FileTruncatedBeforeLock