rectorphp/rector · error · InvalidEregException
a literal null byte in the regex
Error message
a literal null byte in the regex
What it means
_ere2pcre_escape() refuses to emit a literal NUL byte: when a pattern character is "\x00", EregToPcreTransformer throws InvalidEregException('a literal null byte in the regex') (EregToPcreTransformer.php:241). A raw null byte cannot appear safely in a PCRE pattern string, so the ereg-to-preg conversion is aborted instead of producing a broken pattern.
Source
Thrown at rules/Php70/EregToPcreTransformer.php:241
}
if (ord($a) > ord($b)) {
$errorMessage = sprintf('an invalid character range %d-%d"', (int) $a, (int) $b);
throw new InvalidEregException($errorMessage);
}
$cls .= $this->_ere2pcre_escape($a) . '-' . $this->_ere2pcre_escape($b);
++$i;
} else {
$cls .= $this->_ere2pcre_escape($a);
}
}
$start = \false;
} while ($i < $l && $s[$i] !== ']');
return [$cls, $i];
}
private function _ere2pcre_escape(string $content): string
{
if ($content === "\x00") {
throw new InvalidEregException('a literal null byte in the regex');
}
if (strpos('\^$.[]|()?*+{}-/', $content) !== \false) {
return '\\' . $content;
}
return $content;
}
/**
* @param array<int, mixed> $r
*/
private function processCurlyBracket(string $s, int $i, array &$r, int $rr): int
{
$ii = strpos($s, '}', $i);
if ($ii === \false) {
throw new InvalidEregException('"{" does not have a matching "}"');
}
$start = $i + 1;
$length = $ii - ($i + 1);
$bound = Strings::substring($s, $start, $length);View on GitHub (pinned to 408fcb0ff1)
Solutions
- Remove the raw NUL byte from the literal in the file Rector reported.
- If matching a NUL separator is intentional, rewrite that call by hand to str_replace/explode with chr(0) or a preg pattern using an escaped sequence, instead of relying on rector's ereg conversion.
- Re-run rector; preflight-scan ereg/split literals for "\x00" (grep -P '"\x00"|\x00') before bulk migrations.
Example fix
// before - literal NUL byte inside the pattern (shown as \x00)
ereg("a\x00b", $subject);
// after - handle binary separator explicitly, no raw NUL in the regex
explode("\x00", $subject); // or preg_match('/a\x00b/', $subject) written by hand Defensive patterns
Strategy: validation
Validate before calling
if (strpos($pattern, "\x00") !== false) {
throw new InvalidArgumentException('pattern contains a literal null byte; rewrite the call without ereg');
} Try / catch
try {
$pcre = $eregToPcreTransformer->transform($pattern, $ignoreCase);
} catch (InvalidEregException $e) {
// raw NUL in the pattern — remove it or handle binary splitting outside regex
continue;
} Prevention
- Never embed raw "\x00" bytes in regex literals; use explode/str_replace with chr(0) for NUL-separated data.
- Scan migrated files for NUL bytes (grep -P '\x00') before running rector over them.
- Treat binary data and regex as separate concerns during PHP 7 migrations.
When it happens
Trigger: Rector (Php70 set / EregToPregMatchRector, target PHP >= 7.0) encounters an ereg-family call whose string-literal pattern contains an actual "\x00" byte — e.g. source written as "a\x00b" (double-quoted, real NUL), or a binary/legacy file where a NUL ended up inside the literal. Applies both in normal atoms and inside character classes, since _ere2pcre_escape() is used for both.
Common situations: Code migrated from binary-processing scripts (fixed-width records separated by NUL) where ereg/split was fed "\x00"-separated patterns; literals corrupted by an encoding conversion or editor that inserted NULs; copy-paste of binary data into pattern strings.
Related errors
- unescaped metacharacter ")"
- "[" does not have a matching "]"
- unescaped metacharacter "%s"
- an invalid escape sequence at the end
- empty regular expression or branch
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/d1cf16ffefd1bb5c.
Report an issue: GitHub.