Problem
wp-includes/pomo/po.php calls @ini_set( 'auto_detect_line_endings', 1 ) which triggers a PHP 8.1+ deprecation notice (E_DEPRECATED). WordPress silences it with @, but custom error handlers (e.g. Sentry) still capture it.
The setting will be removed entirely in PHP 9.0, so this needs a proper fix.
Purpose of auto_detect_line_endings
The ini setting makes fgets() recognize standalone \r (classic Mac line endings) in addition to \n and \r\n. This matters for old PO/MO translation files that may still use \r line endings.
Existing read_line() behavior
The current read_line() method (line ~467) already normalizes \r\n to \n:
$line = ( "\r\n" === substr( $line, -2 ) ) ? rtrim( $line, "\r\n" ) . "\n" : $line;
But it does not handle standalone \r, which is what auto_detect_line_endings was still needed for.
Proposed fix
Replace the @ini_set call with manual line-ending detection in read_line():
- After
fgets(), check if the line contains \r
- If
\r is followed by \n → normalize \r\n to \n (existing behavior)
- If
\r is standalone → split the line at \r, add \n, and fseek() to rewind the file pointer so the next fgets() picks up from the right position
$line = fgets( $f );
// Normalize line endings: handle \r\n and standalone \r (old Mac).
$r = strpos( $line, "\r" );
if ( false !== $r ) {
if ( "\n" === ( $line[ $r + 1 ] ?? '' ) ) {
// \r\n line ending — normalize to \n.
$line = rtrim( $line, "\r\n" ) . "\n";
} else {
// Standalone \r — fgets didn't recognize it as line ending.
// Take content up to \r, rewind the file pointer past the rest.
$rewind = strlen( $line ) - $r - 1;
$line = substr( $line, 0, $r ) . "\n";
if ( $rewind > 0 ) {
fseek( $f, -$rewind, SEEK_CUR );
}
}
}
Prior art
The approach in PR WordPress#7256 is functionally correct but has a dead-code branch. The condition strlen($line) === $r + 1 && "\r\n" === substr($line, $r) can never be true — if \r is the last character (strlen === $r + 1), then substr($line, $r) is just "\r", never "\r\n". The else branch handles both \r\n and \r cases by always using fseek, which works but is less efficient for the common \r\n case.
The fix proposed above separates the two cases cleanly: \r\n is handled with simple string normalization (no seeking), and standalone \r uses fseek only when necessary.
Problem
wp-includes/pomo/po.phpcalls@ini_set( 'auto_detect_line_endings', 1 )which triggers a PHP 8.1+ deprecation notice (E_DEPRECATED). WordPress silences it with@, but custom error handlers (e.g. Sentry) still capture it.The setting will be removed entirely in PHP 9.0, so this needs a proper fix.
Purpose of
auto_detect_line_endingsThe ini setting makes
fgets()recognize standalone\r(classic Mac line endings) in addition to\nand\r\n. This matters for old PO/MO translation files that may still use\rline endings.Existing
read_line()behaviorThe current
read_line()method (line ~467) already normalizes\r\nto\n:But it does not handle standalone
\r, which is whatauto_detect_line_endingswas still needed for.Proposed fix
Replace the
@ini_setcall with manual line-ending detection inread_line():fgets(), check if the line contains\r\ris followed by\n→ normalize\r\nto\n(existing behavior)\ris standalone → split the line at\r, add\n, andfseek()to rewind the file pointer so the nextfgets()picks up from the right positionPrior art
Notes on the existing PR WordPress#7256
The approach in PR WordPress#7256 is functionally correct but has a dead-code branch. The condition
strlen($line) === $r + 1 && "\r\n" === substr($line, $r)can never be true — if\ris the last character (strlen === $r + 1), thensubstr($line, $r)is just"\r", never"\r\n". The else branch handles both\r\nand\rcases by always usingfseek, which works but is less efficient for the common\r\ncase.The fix proposed above separates the two cases cleanly:
\r\nis handled with simple string normalization (no seeking), and standalone\rusesfseekonly when necessary.