Skip to content

CurlMultiSuccessAssumedPerTransfer ​

warning native on by default

Group: Probable bugs

Successful multi-transfer execution does not establish that each request succeeded. Inspect the completion result for every added transfer.

Example ​

php
<?php
function bad(){$h=curl_multi_init();curl_multi_add_handle($h,curl_init());if(curl_multi_exec($h,$running)===CURLM_OK && !$running){return true;}}

Reported:

  • line 2: Inspect each completed transfer result.

Detection ​

  • A curl_multi_exec result compared to CURLM_OK and completed running count guards unconditional true return, with no curl_multi_info_read inspection on that handle. Match complete function-local transfer lifecycle, not arbitrary success-named consumers.
  • Require at least one resolved curl_multi_add_handle on the same locally initialized multi handle before execution. Empty multi handles are valid and excluded. The handle must be held in a plain local variable.
  • D1b. Before the guarding if, every use of that variable must be either the target of a plain assignment or a direct argument of a resolved lifecycle builtin: curl_multi_add_handle, curl_multi_exec, curl_multi_select, curl_multi_setopt or curl_multi_errno. These drive the handle without exposing per-transfer results and without detaching transfers.
  • 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.
  • Any other use of the handle variable before the guarding if drops the report, because the code receiving the handle may inspect or change the transfers: passing it to a user function, method, static method, constructor, dynamic callee or any builtin outside the D1b list (including curl_multi_info_read, curl_multi_remove_handle and curl_multi_close), spreading it, copying it to another variable, binding it by reference, storing it in a property or array, capturing it in a closure or arrow function, or reaching it by name through a variable variable, compact() or get_defined_vars().
  • 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": {
    "CurlMultiSuccessAssumedPerTransfer": {
      "enabled": false
    }
  }
}

Suppress ​

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

php
// @custos-ignore CurlMultiSuccessAssumedPerTransfer

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