SplObjectStorageIndirectArrayMutation
warning native on by default PHP ≥ 5.3Group: Probable bugs
Assign the modified storage value back.
Example
Finding:
php
<?php
$s = new SplObjectStorage(); $o = new stdClass(); $s[$o] = ["count" => 1]; $s[$o]["count"]++;Reported:
- line 2: Assign the modified storage value back.
Detection
- D1. Resolve SplObjectStorage offset whose most recent stored value is a proven array. Report nested offset/property-like array writes, increment/decrement or unset applied indirectly to its retrieved array. Highlight the complete mutation expression.
- Emit one finding per violating operation. Flow facts require a reachable path with no intervening mutation, escaped alias, unknown call involving the tracked value or analysis-budget exhaustion. Uncertain facts cannot prove a violation.
- D4. The proof in D1 comes from the last
$storage[$key] = <array literal>assignment that certainly ran before the mutation. It is dropped when, between that assignment and the mutation, the same storage may receive another value: a method call on the storage other than a read-only one (contains,count,current,getHash,getInfo,key,next,offsetExists,offsetGet,rewind,seek,valid), a directunset($storage[...]), an offset assignment of a value that is not a proven array under any key or on a path that may not run, or a closure capturing the storage variable, including an arrow function that mentions it. Later offset assignments of proven arrays keep the proof. Passing the key variable to an unresolved method may rebind the key and drops the correspondence with the earlier offset assignment. A resolved by-value method on another storage keeps that correspondence.
Exceptions (no report)
- Stored objects are mutable handles and are excluded. Assigning a retrieved modified array back is valid. Unknown stored type or custom offsetGet behavior is excluded. A value possibly replaced through
offsetSet(),attach()or any other mutating storage call counts as unknown (D4). - Exclude shadowed builtin symbols, unresolved required types, incomplete syntax and unsupported PHP versions.
Fix
No automatic fix. Choosing a repair requires runtime information, error-handling policy or a semantic decision.
All edits use exact byte ranges, preserve comments and evaluation order, and require syntax supported by the target PHP version. A fix must never add an evaluation or silently change unrelated arguments.
PHP versions
Minimum PHP 5.3.
Configure
In custos.json:
json
{
"rules": {
"SplObjectStorageIndirectArrayMutation": {
"enabled": false
}
}
}Suppress
Before the statement or declaration (or the first statement of the file):
php
// @custos-ignore SplObjectStorageIndirectArrayMutation