ConnectTimeoutAssumedToBoundReads
warning native off by default PHP ≥ 5.3Group: Probable bugs
Set a separate timeout for stream reads. This opt-in rule applies the policy described in Detection.
Example
php
<?php
$s=fsockopen("example.test",443,$errno,$errstr,2); if ($s!==false) { fgets($s); }Reported:
- line 2: Set a separate timeout for stream reads.
Detection
- Enabled policy requires explicit bounded reads. Report fgets/fread/stream_get_contents/fgetcsv on a local/direct fsockopen or pfsockopen result whose connection timeout is a positive integer or float literal, unless a checked stream_set_timeout call on that same handle (same expression, same opening call) is known to have returned true when the read runs. Unknown origins and zero, negative, non-numeric or unknown connection timeouts are excluded. This checks per-read configuration; it does not establish an overall deadline.
- A condition proves success through its polarity: the call itself when true, also silenced (
@) or assigned in place ($ok = stream_set_timeout(...)), or a boolean holding its result while that boolean is not reassigned;!flips the polarity;&&/andwhen true and||/orwhen false prove it if either operand does;==,===,!=,!==against atrue/falseliteral on either side are reduced to the compared operand. A strict comparison with a value of another type (=== 1) never holds and proves nothing. Any other expression proves nothing. - Accepted guard positions, within the same function scope: the body of an
if/elseifwhose condition proves success when true; anelseiforelsereached only after earlier conditions of the chain that prove success when false; the right operand of&&/and(left proves success when true) or||/or(left proves success when false); the matching arm of a ternary; a loop body whose condition proves success when true; and code after an earlier statement that leaves the path whenever success is not proven: anifwhose body always leaves (return, throw, exit, break, continue), or a statement such asstream_set_timeout($s, 2) or exit;. - A read reached only when configuration failed (inverted condition, wrong branch) is reported. A bare
stream_set_timeout($h, …);statement whose result is discarded is not a guard: the policy asks for a checked configuration, so the following read is still reported. - Resolve builtin functions, extension classes, method receivers, constants and named arguments. Follow unchanged locals and aliases only within the same bounded lexical scope. Require a reachable path; merge branch facts only when all incoming paths establish them.
- Emit one finding at the violating operation, not one per evidence statement. Rebinding, writes, by-reference escape and unresolved calls that can mutate relevant state remove proof. When the proof is inconclusive, nothing is reported.
Exceptions (no report)
- Exclude shadowed builtins, unresolved receivers, incomplete syntax and unknown prerequisite facts. An extension function name alone does not prove an application function is that builtin.
- A dominating valid guard or repair described in Detection prevents the finding. Both legacy noinspection and custos-ignore forms suppress this ID.
Fix
No automatic fix. The required repair depends on error handling, data selection, lifecycle ordering or application policy.
PHP versions
Requires PHP 5.3 or later and the referenced extension API. Respect method-specific introduction versions within PHP 5.3–8.5; unsupported optional APIs cannot establish facts. Named arguments require PHP 8.0 or later.
Configure
In custos.json:
json
{
"rules": {
"ConnectTimeoutAssumedToBoundReads": {
"enabled": true
}
}
}Suppress
Before the statement or declaration (or the first statement of the file):
php
// @custos-ignore ConnectTimeoutAssumedToBoundReads