Make WordPress Core


Ignore:
Timestamp:
10/15/2021 10:52:43 PM (3 years ago)
Author:
hellofromTonya
Message:

FileSystem API: Fix autovivification deprecation notice in recurse_dirsize().

PHP natively allows for autovivification (auto-creation of arrays from falsey values). This feature is very useful and used in a lot of PHP projects, especially if the variable is undefined. However, there is a little oddity that allows creating an array from a false and null value.

The above quote is from the PHP 8.1 RFC and the (accepted) RFC changes the behaviour described above to deprecated auto creation of arrays from false. As it is deprecated, it _will_ still work for the time being, but as of PHP 9.0, this will become a Fatal Error, so we may as well fix it now.

The recurse_dirsize() function retrieves a transient and places it in the $directory_cache variable, but the get_transient() function in WP returns false when the transient doesn't exist, which subsequently can lead to the above mentioned deprecation notice.

By verifying that the $directory_cache variable is an array before assigning to it and initializing it to an empty array, if it's not, we prevent the deprecation notice, as well as harden the function against potentially corrupted transients where this transient would not return the expected array format, but some other variable type.

Includes adding dedicated unit tests for both the PHP 8.1 issue, as well as the hardening against corrupted transients.

Includes some girl-scouting: touching up a parameter description and some code layout.

Refs:

Follow-up to [49212], [49744].

Props jrf, hellofromTonya.
See #53635.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/functions/cleanDirsizeCache.php

    r51910 r51911  
    44 * Tests specific to the directory size caching.
    55 *
    6  * @covers ::clean_dirsize_cache
    76 * @group functions.php
    87 */
     
    1312     *
    1413     * @ticket 52241
     14     *
     15     * @covers ::clean_dirsize_cache
    1516     *
    1617     * @dataProvider data_clean_dirsize_cache_with_invalid_inputs
     
    5657     *
    5758     * @ticket 52241
     59     *
     60     * @covers ::clean_dirsize_cache
    5861     *
    5962     * @dataProvider data_clean_dirsize_cache_with_non_path_string
     
    101104        );
    102105    }
     106
     107    /**
     108     * Test the behaviour of the function when the transient doesn't exist.
     109     *
     110     * @ticket 52241
     111     * @ticket 53635
     112     *
     113     * @covers ::recurse_dirsize
     114     */
     115    public function test_recurse_dirsize_without_transient() {
     116        delete_transient( 'dirsize_cache' );
     117
     118        $size = recurse_dirsize( __DIR__ . '/fixtures' );
     119
     120        $this->assertGreaterThan( 10, $size );
     121    }
     122
     123    /**
     124     * Test the behaviour of the function when the transient does exist, but is not an array.
     125     *
     126     * In particular, this tests that no PHP TypeErrors are being thrown.
     127     *
     128     * @ticket 52241
     129     * @ticket 53635
     130     *
     131     * @covers ::recurse_dirsize
     132     */
     133    public function test_recurse_dirsize_with_invalid_transient() {
     134        set_transient( 'dirsize_cache', 'this is not a valid transient for dirsize cache' );
     135
     136        $size = recurse_dirsize( __DIR__ . '/fixtures' );
     137
     138        $this->assertGreaterThan( 10, $size );
     139    }
    103140}
Note: See TracChangeset for help on using the changeset viewer.