Skip to content

Commit e40e13b

Browse files
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: [https://wiki.php.net/rfc/deprecations_php_8_1#auto_detect_line_endings_ini_setting 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: [https://github.com/php/php-src/blob/1cf4fb739f7a4fa8404a4c0958f13d04eae519d4/UPGRADING#L456-L457 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. git-svn-id: https://develop.svn.wordpress.org/trunk@62093 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 9a03e90 commit e40e13b

File tree

2 files changed

+89
-12
lines changed

2 files changed

+89
-12
lines changed

src/wp-includes/pomo/po.php

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,6 @@
1313
define( 'PO_MAX_LINE_LEN', 79 );
1414
}
1515

16-
/*
17-
* The `auto_detect_line_endings` setting has been deprecated in PHP 8.1,
18-
* but will continue to work until PHP 9.0.
19-
* For now, we're silencing the deprecation notice as there may still be
20-
* translation files around which haven't been updated in a long time and
21-
* which still use the old MacOS standalone `\r` as a line ending.
22-
* This fix should be revisited when PHP 9.0 is in alpha/beta.
23-
*/
24-
@ini_set( 'auto_detect_line_endings', 1 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
25-
2616
/**
2717
* Routines for working with PO files
2818
*/
@@ -475,8 +465,31 @@ public function read_line( $f, $action = 'read' ) {
475465
$use_last_line = true;
476466
return true;
477467
}
478-
$line = $use_last_line ? $last_line : fgets( $f );
479-
$line = ( "\r\n" === substr( $line, -2 ) ) ? rtrim( $line, "\r\n" ) . "\n" : $line;
468+
469+
if ( $use_last_line ) {
470+
$line = $last_line;
471+
} else {
472+
$line = fgets( $f );
473+
if ( false === $line ) {
474+
return $line;
475+
}
476+
477+
// Handle \r-only terminated lines after the deprecation of auto_detect_line_endings in PHP 8.1.
478+
$r = strpos( $line, "\r" );
479+
if ( false !== $r ) {
480+
if ( strlen( $line ) === $r + 1
481+
&& "\r\n" === substr( $line, $r )
482+
) {
483+
$line = rtrim( $line, "\r\n" ) . "\n";
484+
} else {
485+
// The lines are terminated by just \r, so we end the line there and rewind.
486+
$rewind = strlen( $line ) - $r - 1;
487+
$line = substr( $line, 0, $r ) . "\n";
488+
fseek( $f, - $rewind, SEEK_CUR );
489+
}
490+
}
491+
}
492+
480493
$last_line = $line;
481494
$use_last_line = false;
482495
return $line;

tests/phpunit/tests/pomo/po.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,5 +338,69 @@ public function test_import_from_file_with_windows_line_endings_should_work_as_w
338338
$this->assertCount( 1, $po->entries );
339339
}
340340

341+
/**
342+
* @ticket 64928
343+
*
344+
* @dataProvider data_import_from_file_with_various_line_endings
345+
*/
346+
public function test_import_from_file_with_various_line_endings( $newline, $printable_newline ) {
347+
$import_file = $this->temp_filename();
348+
349+
$file = 'msgid ""' . $newline;
350+
$file .= 'msgstr ""' . $newline;
351+
$file .= '"Project-Id-Version: WordPress 7.0\n"' . $newline;
352+
$file .= '"Plural-Forms: nplurals=2; plural=n != 1;\n"';
353+
354+
$entries = array();
355+
for ( $i = 1; $i <= 3; $i++ ) {
356+
$file .= $newline;
357+
$file .= $newline;
358+
$line = "Entry $i";
359+
$file .= 'msgid "' . $line . '"' . $newline;
360+
$file .= 'msgstr ""';
361+
$entry = new Translation_Entry( array( 'singular' => $line ) );
362+
363+
$entries[ $entry->key() ] = $entry;
364+
}
365+
366+
file_put_contents( $import_file, $file );
367+
368+
$po = new PO();
369+
$res = $po->import_from_file( $import_file );
370+
unlink( $import_file );
371+
372+
$this->assertTrue( $res );
373+
374+
$this->assertSame(
375+
array(
376+
'Project-Id-Version' => 'WordPress 7.0',
377+
'Plural-Forms' => 'nplurals=2; plural=n != 1;',
378+
),
379+
$po->headers
380+
);
381+
382+
$this->assertEquals( $po->entries, $entries, 'Failed for ' . $printable_newline );
383+
384+
$export_file = $this->temp_filename();
385+
$po->export_to_file( $export_file );
386+
$content = file_get_contents( $export_file );
387+
unlink( $export_file );
388+
389+
$this->assertSame( str_replace( $newline, "\n", $file ), $content );
390+
}
391+
392+
/**
393+
* Data provider.
394+
*
395+
* @return array[]
396+
*/
397+
public static function data_import_from_file_with_various_line_endings() {
398+
return array(
399+
'\r' => array( "\r", '\r' ),
400+
'\n' => array( "\n", '\n' ),
401+
'\r\n' => array( "\r\n", '\r\n' ),
402+
);
403+
}
404+
341405
// TODO: Add tests for bad files.
342406
}

0 commit comments

Comments
 (0)