Skip to content

Commit

Permalink
Code Modernization: Fix trigger_error() with E_USER_ERROR deprecation…
Browse files Browse the repository at this point in the history
… in Text_Diff::_check().

PHP 8.4 deprecates the use of `trigger_errror()` with `E_USER_ERROR` as the error level, as there are a number of gotchas to this way of creating a `Fatal Error` (`finally` blocks not executing, destructors not executing). The recommended replacements are either to use exceptions or to do a hard `exit`.

This is an unmaintained external dependency; thus, the fix is made in the WP specific copy of the dependency.

Now, there were basically three options:
* Silence the deprecation until PHP 9.0 and delay properly solving this until then.
    This would lead to an awkward solution, as prior to PHP 8.0, error silencing would apply to all errors, while, as of PHP 8.0, it will no longer apply to fatal errors.
    It also would only buy us some time and wouldn't actually solve anything.
* Use `exit($status)`.
    This would make the code untestable and would disable handling of these errors via custom error handlers, which makes this an undesirable solution.
* Throw an exception.
    This makes for the most elegant solution with the least BC-breaking impact.

The third option is implemented which:
* Introduces a new `Text_Exception` class.
* Starts using that in the `Text_Diff::_check()` method in all applicable places.
* Adds tests for the first two error conditions.

References:
* https://wiki.php.net/rfc/deprecations_php_8_4#deprecate_passing_e_user_error_to_trigger_error
* https://www.php.net/manual/en/migration80.incompatible.php

Follow-up to [59070], [52978], [7747].

Props jrf.
See #62061.

git-svn-id: https://develop.svn.wordpress.org/trunk@59105 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
hellofromtonya committed Sep 27, 2024
1 parent 2550224 commit 9a9ca41
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 5 deletions.
10 changes: 5 additions & 5 deletions src/wp-includes/Text/Diff.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,24 +260,24 @@ static function _getTempDir()
function _check($from_lines, $to_lines)
{
if (serialize($from_lines) != serialize($this->getOriginal())) {
trigger_error("Reconstructed original does not match", E_USER_ERROR);
throw new Text_Exception("Reconstructed original does not match");
}
if (serialize($to_lines) != serialize($this->getFinal())) {
trigger_error("Reconstructed final does not match", E_USER_ERROR);
throw new Text_Exception("Reconstructed final does not match");
}

$rev = $this->reverse();
if (serialize($to_lines) != serialize($rev->getOriginal())) {
trigger_error("Reversed original does not match", E_USER_ERROR);
throw new Text_Exception("Reversed original does not match");
}
if (serialize($from_lines) != serialize($rev->getFinal())) {
trigger_error("Reversed final does not match", E_USER_ERROR);
throw new Text_Exception("Reversed final does not match");
}

$prevtype = null;
foreach ($this->_edits as $edit) {
if ($prevtype !== null && $edit instanceof $prevtype) {
trigger_error("Edit sequence is non-optimal", E_USER_ERROR);
throw new Text_Exception("Edit sequence is non-optimal");
}
$prevtype = get_class($edit);
}
Expand Down
11 changes: 11 additions & 0 deletions src/wp-includes/Text/Exception.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
/**
* Exception for errors from the Text_Diff package.
*
* {@internal This is a WP native addition to the external Text_Diff package.}
*
* @package WordPress
* @subpackage Text_Diff
*/

class Text_Exception extends Exception {}
2 changes: 2 additions & 0 deletions src/wp-includes/wp-diff.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
require ABSPATH . WPINC . '/Text/Diff/Renderer.php';
/** Text_Diff_Renderer_inline class */
require ABSPATH . WPINC . '/Text/Diff/Renderer/inline.php';
/** Text_Exception class */
require ABSPATH . WPINC . '/Text/Exception.php';
}

require ABSPATH . WPINC . '/class-wp-text-diff-renderer-table.php';
Expand Down
17 changes: 17 additions & 0 deletions tests/phpunit/tests/diff/Text_Diff_Check_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ final class Text_Diff_Check_Test extends WP_UnitTestCase {

public static function set_up_before_class() {
require_once ABSPATH . 'wp-includes/Text/Diff.php';
require_once ABSPATH . 'wp-includes/Text/Exception.php';
}

/**
Expand All @@ -34,4 +35,20 @@ public function test_check_passes_when_passed_same_input() {
$diff = new Text_Diff( 'auto', array( self::FILE_A, self::FILE_B ) );
$this->assertTrue( $diff->_check( self::FILE_A, self::FILE_B ) );
}

public function test_check_throws_exception_when_from_is_not_same_as_original() {
$this->expectException( Text_Exception::class );
$this->expectExceptionMessage( 'Reconstructed original does not match' );

$diff = new Text_Diff( 'auto', array( self::FILE_A, self::FILE_B ) );
$diff->_check( self::FILE_B, self::FILE_B );
}

public function test_check_throws_exception_when_to_is_not_same_as_final() {
$this->expectException( Text_Exception::class );
$this->expectExceptionMessage( 'Reconstructed final does not match' );

$diff = new Text_Diff( 'auto', array( self::FILE_A, self::FILE_B ) );
$diff->_check( self::FILE_A, self::FILE_A );
}
}

0 comments on commit 9a9ca41

Please sign in to comment.