Make WordPress Core

Changeset 54142


Ignore:
Timestamp:
09/13/2022 03:56:28 PM (4 years ago)
Author:
SergeyBiryukov
Message:

Code Modernization: Fix autovivification from false to array in WP_Scripts::localize().

This function was previously already problematic as it does not do proper input validation, and it has already received tweaks related to PHP 8.0 in [50408] / #52534, which also introduced a _doing_it_wrong() notice and added tests.

The short of it is:

  • The function expects to receive an array for the $l10n parameter;
  • ...but silently supported the parameter being passed as a string;
  • ...and would expect PHP to gracefully handle everything else or throw appropriate warnings/errors.

In the previous fix, a _doing_it_wrong() notice was added for any non-array inputs. The function would also cause a PHP native "Cannot use a scalar value as an array" warning (PHP < 8.0) or error (PHP 8.0+) for all scalar values, except false.

PHP 8.1 deprecated autovivification from false to array, so now false starts throwing an "Automatic conversion of false to array is deprecated" notice.

By rights, the function should just throw an exception when a non-array/string input is received, but that would be a backward compatibility break.

So the current change will maintain the previous behavior, but will prevent both the "Cannot use a scalar value as an array" warning/error as well as the "Automatic conversion of false to array" deprecation notice for invalid inputs.

Invalid inputs will still receive a _doing_it_wrong() notice, which is the reason this fix is considered acceptable.

Includes:

  • Adding a test passing an empty array.
  • Adding a test to the data provider for a null input to make sure that the function will not throw a PHP 8.1 "passing null to non-nullable" notice.

This solves the following PHP 8.1 test error:

Tests_Dependencies_Scripts::test_wp_localize_script_data_formats with data set #8 (false, '[""]')
Automatic conversion of false to array is deprecated

/var/www/src/wp-includes/class.wp-scripts.php:514
/var/www/src/wp-includes/functions.wp-scripts.php:221
/var/www/tests/phpunit/tests/dependencies/scripts.php:1447
/var/www/vendor/bin/phpunit:123

Reference: PHP Manual: PHP 8.1 Deprecations: Autovivification from false.

Follow-up to [7970], [18464], [18490], [19217], [50408].

Props jrf, costdev.
See #55656.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class.wp-scripts.php

    r53366 r54142  
    502502                                '5.7.0'
    503503                        );
     504
     505                        if ( false === $l10n ) {
     506                                // This should really not be needed, but is necessary for backward compatibility.
     507                                $l10n = array( $l10n );
     508                        }
    504509                }
    505510
    506511                if ( is_string( $l10n ) ) {
    507512                        $l10n = html_entity_decode( $l10n, ENT_QUOTES, 'UTF-8' );
    508                 } else {
    509                         foreach ( (array) $l10n as $key => $value ) {
     513                } elseif ( is_array( $l10n ) ) {
     514                        foreach ( $l10n as $key => $value ) {
    510515                                if ( ! is_scalar( $value ) ) {
    511516                                        continue;
  • trunk/tests/phpunit/tests/dependencies/scripts.php

    r53360 r54142  
    14291429         * @param mixed  $l10n_data Localization data passed to wp_localize_script().
    14301430         * @param string $expected  Expected transformation of localization data.
    1431          * @param string $warning   Optional. Whether a PHP native warning/error is expected. Default false.
    1432          */
    1433         public function test_wp_localize_script_data_formats( $l10n_data, $expected, $warning = false ) {
    1434                 if ( $warning ) {
    1435                         if ( PHP_VERSION_ID < 80000 ) {
    1436                                 $this->expectWarning();
    1437                         } else {
    1438                                 $this->expectError();
    1439                         }
    1440                 }
    1441 
     1431         */
     1432        public function test_wp_localize_script_data_formats( $l10n_data, $expected ) {
    14421433                if ( ! is_array( $l10n_data ) ) {
    14431434                        $this->setExpectedIncorrectUsage( 'WP_Scripts::localize' );
     
    14611452         *     @type mixed  $l10n_data Localization data passed to wp_localize_script().
    14621453         *     @type string $expected  Expected transformation of localization data.
    1463          *     @type string $warning   Optional. Whether a PHP native warning/error is expected.
    14641454         * }
    14651455         */
     
    14721462                        array( array( 'foo' => 6.6 ), '{"foo":"6.6"}' ),
    14731463                        array( array( 'foo' => 6 ), '{"foo":"6"}' ),
     1464                        array( array(), '[]' ),
    14741465
    14751466                        // Unofficially supported format.
     
    14771468
    14781469                        // Unsupported formats.
    1479                         array( 1.5, '1.5', true ),
    1480                         array( 1, '1', true ),
     1470                        array( 1.5, '1.5' ),
     1471                        array( 1, '1' ),
    14811472                        array( false, '[""]' ),
     1473                        array( null, 'null' ),
    14821474                );
    14831475        }
Note: See TracChangeset for help on using the changeset viewer.