Skip to content

ProcessPipesDrainedSequentially ​

warning native off by default

Group: Probable bugs

Reading a child's stdout and stderr sequentially can deadlock when the other pipe fills. Drain both output pipes concurrently. This inspection is disabled by default because the intended policy or use can vary.

Example ​

php
<?php
$p=proc_open("worker",[1=>["pipe","w"],2=>["pipe","w"]],$pipes);$stdout=stream_get_contents($pipes[1]);$stderr=stream_get_contents($pipes[2]);

Reported:

  • line 2: Drain process output pipes concurrently.

Detection ​

  • Resolved proc_open descriptors declare stdout and stderr as separate output pipes; parent performs blocking stream_get_contents on pipes[1] then pipes[2]. No nonblocking mode/select/concurrent draining. Require owned pipe array and no reassignment.
  • The initial supported proof is three adjacent statements: proc_open, blocking stdout read, blocking stderr read, using the same simple pipes-array name and literal descriptor indices.
  • Resolve builtin functions, classes, constants and methods; user-defined lookalikes are excluded. Follow only bounded local proof in one lexical scope.
  • Emit one finding per violating operation, not per supporting evidence statement. When the proof is inconclusive, nothing is reported.

Exceptions (no report) ​

  • Do not report unresolved or shadowed builtin names, unknown values, or incomplete receiver/type provenance. Unknown calls, aliases escaping, and intervening writes invalidate local proof. Similar code outside the stated detection contract is not a finding.
  • Both standard suppression forms suppress this native ID.

Fix ​

None. Choosing a repair requires intent or additional runtime information.

PHP versions ​

Available throughout supported PHP 5.3–8.5 where the referenced builtin/extension is available. Respect syntax/version-specific receiver contracts; unavailable APIs are not this rule’s concern.

Configure ​

In custos.json:

json
{
  "rules": {
    "ProcessPipesDrainedSequentially": {
      "enabled": true
    }
  }
}

Suppress ​

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

php
// @custos-ignore ProcessPipesDrainedSequentially

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