Make WordPress Core

Changeset 59105


Ignore:
Timestamp:
09/27/2024 05:51:49 PM (9 months ago)
Author:
hellofromTonya
Message:

Code Modernization: Fix trigger_error() with E_USER_ERROR deprecation 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:

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

Props jrf.
See #62061.

Location:
trunk
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/Text/Diff.php

    r59070 r59105  
    261261    {
    262262        if (serialize($from_lines) != serialize($this->getOriginal())) {
    263             trigger_error("Reconstructed original does not match", E_USER_ERROR);
     263            throw new Text_Exception("Reconstructed original does not match");
    264264        }
    265265        if (serialize($to_lines) != serialize($this->getFinal())) {
    266             trigger_error("Reconstructed final does not match", E_USER_ERROR);
     266            throw new Text_Exception("Reconstructed final does not match");
    267267        }
    268268
    269269        $rev = $this->reverse();
    270270        if (serialize($to_lines) != serialize($rev->getOriginal())) {
    271             trigger_error("Reversed original does not match", E_USER_ERROR);
     271            throw new Text_Exception("Reversed original does not match");
    272272        }
    273273        if (serialize($from_lines) != serialize($rev->getFinal())) {
    274             trigger_error("Reversed final does not match", E_USER_ERROR);
     274            throw new Text_Exception("Reversed final does not match");
    275275        }
    276276
     
    278278        foreach ($this->_edits as $edit) {
    279279            if ($prevtype !== null && $edit instanceof $prevtype) {
    280                 trigger_error("Edit sequence is non-optimal", E_USER_ERROR);
     280                throw new Text_Exception("Edit sequence is non-optimal");
    281281            }
    282282            $prevtype = get_class($edit);
  • trunk/src/wp-includes/wp-diff.php

    r47198 r59105  
    1616    /** Text_Diff_Renderer_inline class */
    1717    require ABSPATH . WPINC . '/Text/Diff/Renderer/inline.php';
     18    /** Text_Exception class */
     19    require ABSPATH . WPINC . '/Text/Exception.php';
    1820}
    1921
  • trunk/tests/phpunit/tests/diff/Text_Diff_Check_Test.php

    r59070 r59105  
    2424    public static function set_up_before_class() {
    2525        require_once ABSPATH . 'wp-includes/Text/Diff.php';
     26        require_once ABSPATH . 'wp-includes/Text/Exception.php';
    2627    }
    2728
     
    3536        $this->assertTrue( $diff->_check( self::FILE_A, self::FILE_B ) );
    3637    }
     38
     39    public function test_check_throws_exception_when_from_is_not_same_as_original() {
     40        $this->expectException( Text_Exception::class );
     41        $this->expectExceptionMessage( 'Reconstructed original does not match' );
     42
     43        $diff = new Text_Diff( 'auto', array( self::FILE_A, self::FILE_B ) );
     44        $diff->_check( self::FILE_B, self::FILE_B );
     45    }
     46
     47    public function test_check_throws_exception_when_to_is_not_same_as_final() {
     48        $this->expectException( Text_Exception::class );
     49        $this->expectExceptionMessage( 'Reconstructed final does not match' );
     50
     51        $diff = new Text_Diff( 'auto', array( self::FILE_A, self::FILE_B ) );
     52        $diff->_check( self::FILE_A, self::FILE_A );
     53    }
    3754}
Note: See TracChangeset for help on using the changeset viewer.