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:
* https://wiki.php.net/rfc/autovivification_false
* https://developer.wordpress.org/reference/functions/get_transient/

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

Props jrf, hellofromTonya.
See #53635.
Built from https://develop.svn.wordpress.org/trunk@51911


git-svn-id: http://core.svn.wordpress.org/trunk@51504 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
hellofromTonya 2021-10-15 22:53:58 +00:00
parent 82141be0d8
commit 4471c3787c
2 changed files with 11 additions and 4 deletions

View File

@ -8120,8 +8120,9 @@ function get_dirsize( $directory, $max_execution_time = null ) {
* @param string $directory Full path of a directory.
* @param string|array $exclude Optional. Full path of a subdirectory to exclude from the total,
* or array of paths. Expected without trailing slash(es).
* @param int $max_execution_time Maximum time to run before giving up. In seconds. The timeout is global
* and is measured from the moment WordPress started to load.
* @param int $max_execution_time Optional. Maximum time to run before giving up. In seconds.
* The timeout is global and is measured from the moment
* WordPress started to load.
* @param array $directory_cache Optional. Array of cached directory paths.
*
* @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout.
@ -8194,7 +8195,9 @@ function recurse_dirsize( $directory, $exclude = null, $max_execution_time = nul
}
}
if ( $max_execution_time > 0 && microtime( true ) - WP_START_TIMESTAMP > $max_execution_time ) {
if ( $max_execution_time > 0 &&
( microtime( true ) - WP_START_TIMESTAMP ) > $max_execution_time
) {
// Time exceeded. Give up instead of risking a fatal timeout.
$size = null;
break;
@ -8205,6 +8208,10 @@ function recurse_dirsize( $directory, $exclude = null, $max_execution_time = nul
}
}
if ( ! is_array( $directory_cache ) ) {
$directory_cache = array();
}
$directory_cache[ $directory ] = $size;
// Only write the transient on the top level call and not on recursive calls.

View File

@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '5.9-alpha-51910';
$wp_version = '5.9-alpha-51911';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.