--- a/wp/wp-admin/includes/class-wp-filesystem-ftpext.php Thu Sep 29 08:06:27 2022 +0200
+++ b/wp/wp-admin/includes/class-wp-filesystem-ftpext.php Fri Sep 05 18:40:08 2025 +0200
@@ -40,7 +40,7 @@
// This class uses the timeout on a per-connection basis, others use it on a per-action basis.
if ( ! defined( 'FS_TIMEOUT' ) ) {
- define( 'FS_TIMEOUT', 240 );
+ define( 'FS_TIMEOUT', 4 * MINUTE_IN_SECONDS );
}
if ( empty( $opt['port'] ) ) {
@@ -358,13 +358,20 @@
}
/**
- * Moves a file.
+ * Moves a file or directory.
+ *
+ * After moving files or directories, OPcache will need to be invalidated.
+ *
+ * If moving a directory fails, `copy_dir()` can be used for a recursive copy.
+ *
+ * Use `move_dir()` for moving directories with OPcache invalidation and a
+ * fallback to `copy_dir()`.
*
* @since 2.5.0
*
- * @param string $source Path to the source file.
- * @param string $destination Path to the destination file.
- * @param bool $overwrite Optional. Whether to overwrite the destination file if it exists.
+ * @param string $source Path to the source file or directory.
+ * @param string $destination Path to the destination file or directory.
+ * @param bool $overwrite Optional. Whether to overwrite the destination if it exists.
* Default false.
* @return bool True on success, false on failure.
*/
@@ -412,14 +419,25 @@
* Checks if a file or directory exists.
*
* @since 2.5.0
+ * @since 6.3.0 Returns false for an empty path.
*
- * @param string $file Path to file or directory.
- * @return bool Whether $file exists or not.
+ * @param string $path Path to file or directory.
+ * @return bool Whether $path exists or not.
*/
- public function exists( $file ) {
- $list = ftp_nlist( $this->link, $file );
+ public function exists( $path ) {
+ /*
+ * Check for empty path. If ftp_nlist() receives an empty path,
+ * it checks the current working directory and may return true.
+ *
+ * See https://core.trac.wordpress.org/ticket/33058.
+ */
+ if ( '' === $path ) {
+ return false;
+ }
- if ( empty( $list ) && $this->is_dir( $file ) ) {
+ $list = ftp_nlist( $this->link, $path );
+
+ if ( empty( $list ) && $this->is_dir( $path ) ) {
return true; // File is an empty directory.
}
@@ -475,10 +493,10 @@
*
* @since 2.5.0
*
- * @param string $file Path to file or directory.
- * @return bool Whether $file is writable.
+ * @param string $path Path to file or directory.
+ * @return bool Whether $path is writable.
*/
- public function is_writable( $file ) {
+ public function is_writable( $path ) {
return true;
}
@@ -515,7 +533,9 @@
* @return int|false Size of the file in bytes on success, false on failure.
*/
public function size( $file ) {
- return ftp_size( $this->link, $file );
+ $size = ftp_size( $this->link, $file );
+
+ return ( $size > -1 ) ? $size : false;
}
/**
@@ -582,7 +602,24 @@
/**
* @param string $line
- * @return array
+ * @return array {
+ * Array of file information.
+ *
+ * @type string $name Name of the file or directory.
+ * @type string $perms *nix representation of permissions.
+ * @type string $permsn Octal representation of permissions.
+ * @type string|false $number File number as a string, or false if not available.
+ * @type string|false $owner Owner name or ID, or false if not available.
+ * @type string|false $group File permissions group, or false if not available.
+ * @type string|false $size Size of file in bytes as a string, or false if not available.
+ * @type string|false $lastmodunix Last modified unix timestamp as a string, or false if not available.
+ * @type string|false $lastmod Last modified month (3 letters) and day (without leading 0), or
+ * false if not available.
+ * @type string|false $time Last modified time, or false if not available.
+ * @type string $type Type of resource. 'f' for file, 'd' for directory, 'l' for link.
+ * @type array|false $files If a directory and `$recursive` is true, contains another array of files.
+ * False if unable to list directory contents.
+ * }
*/
public function parselisting( $line ) {
static $is_windows = null;
@@ -692,18 +729,28 @@
* @param bool $recursive Optional. Whether to recursively include file details in nested directories.
* Default false.
* @return array|false {
- * Array of files. False if unable to list directory contents.
+ * Array of arrays containing file information. False if unable to list directory contents.
+ *
+ * @type array ...$0 {
+ * Array of file information. Note that some elements may not be available on all filesystems.
*
- * @type string $name Name of the file or directory.
- * @type string $perms *nix representation of permissions.
- * @type string $permsn Octal representation of permissions.
- * @type string $owner Owner name or ID.
- * @type int $size Size of file in bytes.
- * @type int $lastmodunix Last modified unix timestamp.
- * @type mixed $lastmod Last modified month (3 letter) and day (without leading 0).
- * @type int $time Last modified time.
- * @type string $type Type of resource. 'f' for file, 'd' for directory.
- * @type mixed $files If a directory and `$recursive` is true, contains another array of files.
+ * @type string $name Name of the file or directory.
+ * @type string $perms *nix representation of permissions.
+ * @type string $permsn Octal representation of permissions.
+ * @type int|string|false $number File number. May be a numeric string. False if not available.
+ * @type string|false $owner Owner name or ID, or false if not available.
+ * @type string|false $group File permissions group, or false if not available.
+ * @type int|string|false $size Size of file in bytes. May be a numeric string.
+ * False if not available.
+ * @type int|string|false $lastmodunix Last modified unix timestamp. May be a numeric string.
+ * False if not available.
+ * @type string|false $lastmod Last modified month (3 letters) and day (without leading 0), or
+ * false if not available.
+ * @type string|false $time Last modified time, or false if not available.
+ * @type string $type Type of resource. 'f' for file, 'd' for directory, 'l' for link.
+ * @type array|false $files If a directory and `$recursive` is true, contains another array of
+ * files. False if unable to list directory contents.
+ * }
* }
*/
public function dirlist( $path = '.', $include_hidden = true, $recursive = false ) {
@@ -752,12 +799,13 @@
$dirlist[ $entry['name'] ] = $entry;
}
- $ret = array();
+ $path = trailingslashit( $path );
+ $ret = array();
foreach ( (array) $dirlist as $struc ) {
if ( 'd' === $struc['type'] ) {
if ( $recursive ) {
- $struc['files'] = $this->dirlist( $path . '/' . $struc['name'], $include_hidden, $recursive );
+ $struc['files'] = $this->dirlist( $path . $struc['name'], $include_hidden, $recursive );
} else {
$struc['files'] = array();
}