WordPress.org

Make WordPress Core

Ticket #47699: 47699-deprecate-JSON-polyfills.patch

File 47699-deprecate-JSON-polyfills.patch, 14.6 KB (added by jrf, 15 months ago)

Agressively deprecate all JSON related polyfills & make the JSON extension a requirement

  • src/wp-admin/includes/class-wp-site-health.php

    From 622b1868bcec29183edada9120f75efa498d7c9d Mon Sep 17 00:00:00 2001
    From: jrfnl <jrfnl@users.noreply.github.com>
    Date: Mon, 15 Jul 2019 06:24:56 +0200
    Subject: [PATCH] JSON polyfills deprecations & JSON extension requirement
    
    ---
     .../includes/class-wp-site-health.php         |  4 ++
     src/wp-includes/class-json.php                | 41 ++++++++++++++++---
     src/wp-includes/compat.php                    | 21 +++++++++-
     src/wp-includes/functions.php                 | 34 +++++----------
     tests/phpunit/tests/compat.php                |  3 ++
     .../tests/rest-api/rest-schema-setup.php      |  4 +-
     6 files changed, 74 insertions(+), 33 deletions(-)
    
    diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php
    index 12e127353b..746cbdca13 100644
    a b class WP_Site_Health { 
    777777                                'function' => 'finfo_file',
    778778                                'required' => false,
    779779                        ),
     780                        'json'      => array(
     781                                'function' => 'json_last_error',
     782                                'required' => true,
     783                        ),
    780784                        'mod_xml'   => array(
    781785                                'extension' => 'libxml',
    782786                                'required'  => false,
  • src/wp-includes/class-json.php

    diff --git a/src/wp-includes/class-json.php b/src/wp-includes/class-json.php
    index a8c61c92e9..a791bacd61 100644
    a b  
    11<?php
     2_deprecated_file( basename( __FILE__ ), '5.3.0', null, 'The PHP native JSON extension is now a requirement.' );
     3
    24if ( ! class_exists( 'Services_JSON' ) ) :
    35/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
    46/**
    class Services_JSON 
    142144    */
    143145    function __construct( $use = 0 )
    144146    {
     147                _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
     148
    145149        $this->use = $use;
    146150        $this->_mb_strlen            = function_exists('mb_strlen');
    147151        $this->_mb_convert_encoding  = function_exists('mb_convert_encoding');
    class Services_JSON 
    152156         * PHP4 constructor.
    153157         */
    154158        public function Services_JSON( $use = 0 ) {
     159                _deprecated_constructor( 'Services_JSON', '5.3.0', get_class( $this ) );
    155160                self::__construct( $use );
    156161        }
    157162    // private - cache the mbstring lookup results..
    class Services_JSON 
    172177    */
    173178    function utf162utf8($utf16)
    174179    {
     180                _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
     181
    175182        // oh please oh please oh please oh please oh please
    176183        if($this->_mb_convert_encoding) {
    177184            return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
    class Services_JSON 
    216223    */
    217224    function utf82utf16($utf8)
    218225    {
     226                _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
     227
    219228        // oh please oh please oh please oh please oh please
    220229        if($this->_mb_convert_encoding) {
    221230            return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
    class Services_JSON 
    260269    */
    261270    function encode($var)
    262271    {
     272                _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
     273
    263274        header('Content-type: application/json');
    264275        return $this->encodeUnsafe($var);
    265276    }
    class Services_JSON 
    276287    */
    277288    function encodeUnsafe($var)
    278289    {
     290                _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
     291
    279292        // see bug #16908 - regarding numeric locale printing
    280293        $lc = setlocale(LC_NUMERIC, 0);
    281294        setlocale(LC_NUMERIC, 'C');
    class Services_JSON 
    297310    */
    298311    function _encode($var)
    299312    {
    300          
     313                _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
     314
    301315        switch (gettype($var)) {
    302316            case 'boolean':
    303317                return $var ? 'true' : 'false';
    class Services_JSON 
    539553    */
    540554    function name_value($name, $value)
    541555    {
     556                _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
     557
    542558        $encoded_value = $this->_encode($value);
    543559
    544560        if(Services_JSON::isError($encoded_value)) {
    class Services_JSON 
    558574    */
    559575    function reduce_string($str)
    560576    {
     577                _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
     578
    561579        $str = preg_replace(array(
    562580
    563581                // eliminate single line comments in '// ...' form
    class Services_JSON 
    589607    */
    590608    function decode($str)
    591609    {
     610                _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
     611
    592612        $str = $this->reduce_string($str);
    593613
    594614        switch (strtolower($str)) {
    class Services_JSON 
    870890     */
    871891    function isError($data, $code = null)
    872892    {
     893                _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
     894
    873895        if (class_exists('pear')) {
    874896            return PEAR::isError($data, $code);
    875897        } elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
    class Services_JSON 
    887909    */
    888910    function strlen8( $str )
    889911    {
     912                _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
     913
    890914        if ( $this->_mb_strlen ) {
    891915            return mb_strlen( $str, "8bit" );
    892916        }
    class Services_JSON 
    902926    */
    903927    function substr8( $string, $start, $length=false )
    904928    {
     929                _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
     930
    905931        if ( $length === false ) {
    906932            $length = $this->strlen8( $string ) - $start;
    907933        }
    if (class_exists('PEAR_Error')) { 
    920946        function __construct($message = 'unknown error', $code = null,
    921947                                     $mode = null, $options = null, $userinfo = null)
    922948        {
     949                        _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
     950
    923951            parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
    924952        }
    925953
    926         public function Services_JSON_Error($message = 'unknown error', $code = null,
     954                public function Services_JSON_Error($message = 'unknown error', $code = null,
    927955                                     $mode = null, $options = null, $userinfo = null) {
    928                 self::__construct($message = 'unknown error', $code = null,
    929                                      $mode = null, $options = null, $userinfo = null);
    930         }
     956                        _deprecated_constructor( 'Services_JSON_Error', '5.3.0', get_class( $this ) );
     957                        self::__construct($message, $code, $mode, $options, $userinfo);
     958                }
    931959    }
    932960
    933961} else {
    if (class_exists('PEAR_Error')) { 
    943971        function __construct( $message = 'unknown error', $code = null,
    944972                                     $mode = null, $options = null, $userinfo = null )
    945973        {
    946 
     974                        _deprecated_function( __METHOD__, '5.3.0', 'The PHP native JSON extension' );
    947975        }
    948976
    949977            /**
    if (class_exists('PEAR_Error')) { 
    951979             */
    952980                public function Services_JSON_Error( $message = 'unknown error', $code = null,
    953981                                             $mode = null, $options = null, $userinfo = null ) {
     982                        _deprecated_constructor( 'Services_JSON_Error', '5.3.0', get_class( $this ) );
    954983                        self::__construct( $message, $code, $mode, $options, $userinfo );
    955984                }
    956985    }
  • src/wp-includes/compat.php

    diff --git a/src/wp-includes/compat.php b/src/wp-includes/compat.php
    index 38d51900c4..2b75e2aa24 100644
    a b function _hash_hmac( $algo, $data, $key, $raw_output = false ) { 
    283283}
    284284
    285285if ( ! function_exists( 'json_encode' ) ) {
     286        /**
     287         * @deprecated 5.3.0 The PHP native JSON extension is now a requirement.
     288         */
    286289        function json_encode( $string ) {
     290                _deprecated_function( 'The json_encode() polyfill', '5.3.0', 'The PHP native JSON extension' );
     291
    287292                global $wp_json;
    288293
    289294                if ( ! ( $wp_json instanceof Services_JSON ) ) {
    if ( ! function_exists( 'json_encode' ) ) { 
    297302
    298303if ( ! function_exists( 'json_decode' ) ) {
    299304        /**
     305         * @deprecated 5.3.0 The PHP native JSON extension is now a requirement.
     306         *
    300307         * @global Services_JSON $wp_json
    301308         * @param string $string
    302309         * @param bool   $assoc_array
    303310         * @return object|array
    304311         */
    305312        function json_decode( $string, $assoc_array = false ) {
     313                _deprecated_function( 'The json_decode() polyfill', '5.3.0', 'The PHP native JSON extension' );
     314
    306315                global $wp_json;
    307316
    308317                if ( ! ( $wp_json instanceof Services_JSON ) ) {
    if ( ! function_exists( 'json_decode' ) ) { 
    318327        }
    319328
    320329        /**
     330         * @deprecated 5.3.0 The PHP native JSON extension is now a requirement.
     331         *
    321332         * @param object $data
    322333         * @return array
    323334         */
    324335        function _json_decode_object_helper( $data ) {
     336                _deprecated_function( __FUNCTION__, '5.3.0', 'The PHP native JSON extension' );
     337
    325338                if ( is_object( $data ) ) {
    326339                        $data = get_object_vars( $data );
    327340                }
    if ( ! function_exists( 'json_last_error_msg' ) ) : 
    371384        /**
    372385         * Retrieves the error string of the last json_encode() or json_decode() call.
    373386         *
    374          * @since 4.4.0
     387         * @since      4.4.0
     388         * @deprecated 5.3.0 The PHP native JSON extension is now a requirement.
    375389         *
    376390         * @internal This is a compatibility function for PHP <5.5
    377391         *
    if ( ! function_exists( 'json_last_error_msg' ) ) : 
    379393         *                     or false on failure.
    380394         */
    381395        function json_last_error_msg() {
     396                _deprecated_function( 'The json_last_error_msg() polyfill', '5.3.0', 'The PHP native JSON extension' );
     397
    382398                // See https://core.trac.wordpress.org/ticket/27799.
    383399                if ( ! function_exists( 'json_last_error' ) ) {
    384400                        return false;
    if ( ! interface_exists( 'JsonSerializable' ) ) { 
    432448         *
    433449         * @link https://secure.php.net/jsonserializable
    434450         *
    435          * @since 4.4.0
     451         * @since      4.4.0
     452         * @deprecated 5.3.0 The PHP native JSON extension is now a requirement.
    436453         */
    437454        interface JsonSerializable {
    438455                // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
  • src/wp-includes/functions.php

    diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php
    index a66b3fa406..15846b5956 100644
    a b function _wp_die_process_input( $message, $title = '', $args = array() ) { 
    35713571 * Encode a variable into JSON, with some sanity checks.
    35723572 *
    35733573 * @since 4.1.0
     3574 * @since 5.3.0 No longer handles support for PHP < 5.6.
    35743575 *
    35753576 * @param mixed $data    Variable (usually an array or object) to encode as JSON.
    35763577 * @param int   $options Optional. Options to be passed to json_encode(). Default 0.
    function _wp_die_process_input( $message, $title = '', $args = array() ) { 
    35793580 * @return string|false The JSON encoded string, or false if it cannot be encoded.
    35803581 */
    35813582function wp_json_encode( $data, $options = 0, $depth = 512 ) {
    3582         /*
    3583          * json_encode() has had extra params added over the years.
    3584          * $options was added in 5.3, and $depth in 5.5.
    3585          * We need to make sure we call it with the correct arguments.
    3586          */
    3587         if ( version_compare( PHP_VERSION, '5.5', '>=' ) ) {
    3588                 $args = array( $data, $options, $depth );
    3589         } elseif ( version_compare( PHP_VERSION, '5.3', '>=' ) ) {
    3590                 $args = array( $data, $options );
    3591         } else {
    3592                 $args = array( $data );
    3593         }
    3594 
    3595         // Prepare the data for JSON serialization.
    3596         $args[0] = _wp_json_prepare_data( $data );
    3597 
    3598         // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- json_encode() errors are handled after this call
    3599         $json = @call_user_func_array( 'json_encode', $args );
     3583        $json = json_encode( $data, $options, $depth );
    36003584
    36013585        // If json_encode() was successful, no need to do more sanity checking.
    36023586        // ... unless we're in an old version of PHP, and json_encode() returned
    36033587        // a string containing 'null'. Then we need to do more sanity checking.
    3604         if ( false !== $json && ( version_compare( PHP_VERSION, '5.5', '>=' ) || false === strpos( $json, 'null' ) ) ) {
     3588        if ( false !== $json && ( class_exists( 'Services_JSON', false ) === false || false === strpos( $json, 'null' ) ) ) {
    36053589                return $json;
    36063590        }
    36073591
    36083592        try {
    3609                 $args[0] = _wp_json_sanity_check( $data, $depth );
     3593                $data = _wp_json_sanity_check( $data, $depth );
    36103594        } catch ( Exception $e ) {
    36113595                return false;
    36123596        }
    36133597
    3614         return call_user_func_array( 'json_encode', $args );
     3598        return json_encode( $data, $options, $depth );
    36153599}
    36163600
    36173601/**
    function _wp_json_convert_string( $string ) { 
    37153699 * This supports the JsonSerializable interface for PHP 5.2-5.3 as well.
    37163700 *
    37173701 * @ignore
    3718  * @since 4.4.0
    3719  * @access private
     3702 * @since      4.4.0
     3703 * @deprecated 5.3.0 This function is no longer needed as support for PHP 5.2-5.3
     3704 *                   has been dropped and the PHP native JSON extension is a requirement.
     3705 * @access     private
    37203706 *
    37213707 * @param mixed $data Native representation.
    37223708 * @return bool|int|float|null|string|array Data ready for `json_encode()`.
    function _wp_json_prepare_data( $data ) { 
    37263712                return $data;
    37273713        }
    37283714
     3715        _deprecated_function( __FUNCTION__, '5.3.0', 'The PHP native JSON extension' );
     3716
    37293717        switch ( gettype( $data ) ) {
    37303718                case 'boolean':
    37313719                case 'integer':
  • tests/phpunit/tests/compat.php

    diff --git a/tests/phpunit/tests/compat.php b/tests/phpunit/tests/compat.php
    index d70d0271b1..92cefbf946 100644
    a b EOT; 
    179179                $this->assertEquals( array( 1 => '993003b95758e0ac2eba451a4c5877eb1bb7b92a' ), unpack( 'H40', _hash_hmac( 'sha1', 'simple', 'key', true ) ) );
    180180        }
    181181
     182        /**
     183         * @expectedException PHPUnit_Framework_Error_Notice
     184         */
    182185        function test_json_encode_decode() {
    183186                require_once( ABSPATH . WPINC . '/class-json.php' );
    184187                $json = new Services_JSON();
  • tests/phpunit/tests/rest-api/rest-schema-setup.php

    diff --git a/tests/phpunit/tests/rest-api/rest-schema-setup.php b/tests/phpunit/tests/rest-api/rest-schema-setup.php
    index 92219b31da..b9f9f4b775 100644
    a b class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { 
    449449                        );
    450450                        $this->assertTrue( ! empty( $data ), $route['name'] . ' route should return data.' );
    451451
    452                         if ( version_compare( PHP_VERSION, '5.4', '>=' ) ) {
     452                        if ( defined( 'JSON_UNESCAPED_SLASHES' ) ) {
    453453                                $fixture           = $this->normalize_fixture( $data, $route['name'] );
    454454                                $mocked_responses .= "\nmockedApiResponse." . $route['name'] . ' = '
    455455                                        . json_encode( $fixture, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES )
    class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { 
    458458                }
    459459
    460460                // Only generate API client fixtures in single site and when required JSON_* constants are supported.
    461                 if ( ! is_multisite() && version_compare( PHP_VERSION, '5.4', '>=' ) ) {
     461                if ( ! is_multisite() && defined( 'JSON_UNESCAPED_SLASHES' ) ) {
    462462                        // Save the route object for QUnit tests.
    463463                        $file = dirname( DIR_TESTROOT ) . '/qunit/fixtures/wp-api-generated.js';
    464464                        file_put_contents( $file, $mocked_responses );