Skip to content

SplFixedArrayIndexOutOfBounds ​

error native on by default PHP ≥ 5.3

Group: Probable bugs

Use an index within the fixed array size.

Example ​

Finding:

php
<?php
$a = new SplFixedArray(3); $a[3] = "outside";

Reported:

  • line 2: Use an index within the fixed array size.

Detection ​

  • Track literal nonnegative size from new SplFixedArray, fromArray and setSize. Report read/write/unset of a proven integer index below zero or greater than/equal to size. For fromArray, preserved indices determine size; with preserveKeys=false use element count.
  • 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.
  • The size stays proven only while every earlier mention of the receiver is inert: an offset access, a named builtin method call, its own plain assignment, by-value foreach, isset/empty, clone, or a direct argument of a read-only builtin such as count or var_dump. A setSize call counts only when it runs on every path to the access; a conditional one, or one later in a loop that also contains the access, removes proof. When the access is inside a loop, every mention anywhere in the outermost enclosing loop is treated as earlier.
  • A receiver that is not a plain local variable (a property, for instance) additionally loses proof when any method call on another receiver, user function call, static call or instantiation of a non-builtin class, or include/require appears before the access.
  • An element unset does not discard a fromArray allocation: the unset itself and later accesses are still checked, provided no setSize follows the allocation.

Exceptions (no report) ​

  • Unknown sizes/indices and guarded in-range paths are excluded. Do not use ordinary PHP array bounds for SplFixedArray.
  • Exclude shadowed builtin symbols, unresolved required types, incomplete syntax and unsupported PHP versions.
  • Existence probes never throw and are not reported: an out-of-range offset that is an operand of isset() or empty(), or the left operand of ??, including when it is the base of a longer offset or property chain in that position (isset($a[9][0]), $a[9]->name ?? null). The probe does not extend to an index expression, a method call on the element or the right operand of ??, and ??= is still reported because it writes the offset.
  • No report once the receiver may have been resized or replaced out of sight: captured by a closure use or mentioned in an arrow function, copied or referenced into another variable, passed to a user function, method, constructor or callback-invoking builtin, iterated by reference, unset as a whole, or called through a dynamic method name.
  • A size passed through an unpacked argument (new SplFixedArray(...$args)) is unknown: no report.

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

Suppress ​

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

php
// @custos-ignore SplFixedArrayIndexOutOfBounds

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