Skip to content

FileLockFailureUnchecked ​

warning native on by default

Group: Probable bugs

Detect a write following flock requiring an exclusive lock where acquisition success is not established.

Example ​

php
<?php
function bad($path) { $h = fopen($path, 'cb'); if ($h === false) { return; } flock($h, LOCK_EX); fwrite($h, 'next'); fclose($h); }

Reported:

  • line 2: Acquire the lock successfully before writing.

Detection ​

  • Report a write following flock requiring an exclusive lock where acquisition success is not established.

  • 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.

  • D4. Acquisition is established when the write can only run after the last flock call on the handle returned true. The result may be tested directly or through a plain local that still holds it unchanged, and the test may be negated, error-suppressed (@), or compared strictly or loosely with true or false. Accepted tests are:

    • an if, elseif or while condition whose guarded body contains the write, or the matching side of a conditional expression;
    • the right operand of &&/and (result true) or ||/or (result false) containing the write;
    • an if whose failure branch always leaves (return, throw, exit, break, continue), with the write later in the statement list that owns the if;
    • a statement of the form flock(...) or exit / || throw, with the write later in the same statement list;
    • a while or do-while retry loop repeating until the result is true and containing no break, with the write after the loop.
  • A test proves nothing, and the write is still reported, when the local was reassigned or merged from another value, when the test sits on only one path to the write (a nested conditional, another closure or function, an earlier case label), when the failure branch can continue, or when the result is combined with an unrelated condition that can let the failing side through. assert(flock(...)) is not a test by default: assertions may be compiled out. With flow.assertions enabled, a direct native flock result with effect-free arguments proves acquisition on the assumed successful path.

  • An exclusive-lock attempt inside a direct native assertion remains a possible unchecked attempt when assertion arguments may be skipped. Report a following write only while the handle has the same complete allocation identity and no intervening call makes that witness ambiguous. This witness proves no successful acquisition and does not change the common-state query used for definite operations.

Exceptions (no report) ​

  • Guarded acquisition and retry until success in any of the D4 forms, explicit unlocked best-effort contracts and unrelated handles 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.

Fix ​

No automatic fix: lock failure and retry policies are unknown.

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": {
    "FileLockFailureUnchecked": {
      "enabled": false
    }
  }
}

Suppress ​

Before the statement or declaration (or the first statement of the file):

php
// @custos-ignore FileLockFailureUnchecked

Released under the MIT License. Native rules and rules modeled on Php Inspections (EA Extended); independent clean-room implementation.