close

Make WordPress Core

Opened 2 weeks ago

Closed 13 days ago

#64928 closed defect (bug) (fixed)

pomo/po.php: Replace deprecated auto_detect_line_endings with manual line-ending handling

Reported by: apermo's profile apermo Owned by: sergeybiryukov's profile SergeyBiryukov
Milestone: 7.0 Priority: normal
Severity: normal Version: 5.9
Component: I18N Keywords: has-patch has-unit-tests
Focuses: Cc:

Description

Since WordPress 5.9 ([51636]), wp-includes/pomo/po.php silences the PHP 8.1 deprecation of auto_detect_line_endings with the @ operator:

@ini_set( 'auto_detect_line_endings', 1 );


The comment says to revisit this when PHP 9.0 is in alpha/beta. PHP 9.0 is still years away (PHP 8.5 is expected late 2025, 8.6 late 2026), but this is already causing real problems right now.

The actual problem


The @ suppression works for PHP's built-in error handler. But custom error handlers like Sentry, Bugsnag, Rollbar, or New Relic still receive the error — @ only sets error_reporting to 0 temporarily, and the handler has to check that itself. Many don't.

The result: this deprecation notice fires on every single request and gets logged to error tracking on every WordPress site running PHP 8.1+ with a custom error handler. That's a lot of noise, and it affects a lot of sites.

We ran into this in our production environment, where it was spamming our Sentry instance. I'm fairly sure we're not the only ones dealing with this.

The fix


PR #7256 by @akirk already has a clean solution. It's been open since August 2024 but hasn't received any reviews yet.

The approach is straightforward:

  • Remove the @ini_set( 'auto_detect_line_endings', 1 ) call
  • Handle \r line endings manually in PO::read_line() using strpos() + fseek()
  • Includes a unit test covering \r, \n, and \r\n


I've independently tested this: a 23,000-line German core translation file (de_DE.po) converted to \r-only line endings parses identically (8 headers, 4456 entries) to the original. No regressions on page loads or REST API responses.

Why not wait for PHP 9.0


Well, there are three main reasons.

First, the error tracking noise is a real problem today. Sites using Sentry or similar tools are getting this deprecation on every request in production. The only workaround is to blacklist the message in your error tracker, which is a band-aid, not a fix.

Second, the fix already exists, it's tested, and it moves the line-ending handling to where it actually belongs — PO::read_line(). That's just better code.

Third, there's a small but real performance benefit: removing the @ operator + ini_set call eliminates per-request overhead. The @ operator saves/restores error_reporting, and ini_set modifies a runtime setting. Neither is needed when the handling is done in read_line(). Not a huge deal on its own, but this runs on every request on every WordPress site. It adds up.

  • #53635 — PHP 8.1 compatibility (introduced the @ suppression in [51636])
  • #51383php-error CSS class added for suppressed errors (Alex linked his PR there, but it's a different issue)
  • PR #7256 — The patch by Alex Kirk

Disclaimer: Research, verfication and documentation with help of Claude Opus 4.6 (1M)

Change History (3)

Image

This ticket was mentioned in PR #7256 on WordPress/wordpress-develop by @akirk.


2 weeks ago
#1

In PHP 8.1, the admin_header will gets the php-error CSS class added for the suppressed notice for @ini_set( 'auto_detect_line_endings', 1 );

This adds code so that we can do without the ini setting and still handle old-style \r line-terminated files. This also adds a unit test for this.

Trac ticket:
https://core.trac.wordpress.org/ticket/64928
https://core.trac.wordpress.org/ticket/51383

#2 Image @SergeyBiryukov
2 weeks ago

  • Milestone changed from Awaiting Review to 7.0
  • Owner set to SergeyBiryukov
  • Status changed from new to reviewing

#3 Image @SergeyBiryukov
13 days ago

  • Resolution set to fixed
  • Status changed from reviewing to closed

In 62093:

Code Modernization: Replace the deprecated auto_detect_line_endings setting.

Since PHP 8.1, the auto_detect_line_endings setting is deprecated:

The auto_detect_line_endings ini setting modifies the behavior of file() and fgets() to support an isolated \r (as opposed to \n or \r\n) as a newline character. These newlines were used by “Classic” Mac OS, a system which has been discontinued in 2001, nearly two decades ago. Interoperability with such systems is no longer relevant.

Reference: PHP RFC: Deprecations for PHP 8.1: auto_detect_line_endings ini setting.

The auto_detect_line_endings ini setting has been deprecated. If necessary, handle \r line breaks manually instead.

Reference: PHP 8.1 Upgrade Notes.

This commits adds code to replace the deprecated setting and still handle old-style \r line-terminated files in PO::read_line() using strpos() + fseek(). Includes a unit test covering \r, \n, and \r\n line endings.

Follow-up to [51633], [51636].

Props akirk, apermo, westonruter, SergeyBiryukov.
Fixes #64928.

Note: See TracTickets for help on using tickets.