Make WordPress Core

Changeset 54142


Ignore:
Timestamp:
09/13/2022 03:56:28 PM (2 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.