ExplodeEmptySeparator
error native on by defaultGroup: Probable bugs
Detect explode with a separator statically equal to the empty string.
Example
<?php
$parts=explode('',$text);Reported:
- line 2: Supply a nonempty separator.
Detection
- Report explode with a separator statically equal to the empty string.
- Resolve builtin calls and named arguments before checking the contract. Project-local callees are considered only when their bodies or immutable summaries establish the required facts. The default is enabled, with positive proof required.
- For flow-dependent conditions, require a reachable source-to-use path with no intervening invalidation. Unknown calls, ambiguous aliases or recursion cannot establish definite facts. When the proof is inconclusive, nothing is reported.
- A separator read from a variable is definite only when plain assignments are the sole way that variable can change in the scope of the call. See E3 for the writes that make it indefinite.
Exceptions (no report)
Unknown or nonempty separators and shadowed application functions are excluded.
Unresolved targets, incomplete required facts, suppressed findings and PHP versions lacking the referenced API or language feature produce no report. User declarations shadowing builtin names are not builtin contracts.
E3. No report when a variable of the separator expression, or a variable whose value was copied into it by assignment, can be rewritten behind the tracked assignments:
- it is captured by reference in a closure
uselist in the scope (including the closure that is the scope itself); - it is declared
globalin the scope; - it is the operand of
++or--(incrementing an empty string yields"1"); - it is bound by reference as an array item (
['k' => &$sep]); - the scope calls the builtin
extract(), orparse_str()with a single argument, either of which may define any local; - the call is at file level, where locals are globals, and the file declares the variable
globalin any function or mentions$GLOBALSanywhere.
The check is lexical and deliberately conservative: it does not prove that the rewriting code runs between the assignment and the call.
- it is captured by reference in a closure
Fix
No automatic fix: byte splitting, code-point splitting and grapheme splitting are different contracts.
PHP versions
Apply only on PHP versions supporting the referenced APIs and syntax (within PHP 5.3–8.5). Builtin behavior and argument contracts follow the configured PHP version. Extension-specific calls require resolved extension API symbols; do not treat same-named application functions as extension calls.
Options
None. Enable or disable this rule through normal rule configuration.
Configure
In custos.json:
{
"rules": {
"ExplodeEmptySeparator": {
"enabled": false
}
}
}Suppress
Before the statement or declaration (or the first statement of the file):
// @custos-ignore ExplodeEmptySeparator