From d8030964da66dbe6b08fcd4aaf97310eb9c7177a Mon Sep 17 00:00:00 2001 From: boombatower Date: Fri, 18 Oct 2013 06:56:51 +0000 Subject: Modify drupal_move_uploaded_file() to check is_uploaded_file(), copy(), and unlink() the file to properly support stream wrappers. --- core/includes/file.inc | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/core/includes/file.inc b/core/includes/file.inc index 6065dd4..903b1bc 100644 --- a/core/includes/file.inc +++ b/core/includes/file.inc @@ -1028,7 +1028,7 @@ function file_unmanaged_delete_recursive($path, $callback = NULL) { /** * Moves an uploaded file to a new location. * - * PHP's move_uploaded_file() does not properly support streams if safe_mode + * PHP's move_uploaded_file() does not properly support streams if se * or open_basedir are enabled, so this function fills that gap. * * Compatibility: normal paths and stream wrappers. @@ -1046,20 +1046,20 @@ function file_unmanaged_delete_recursive($path, $callback = NULL) { * @ingroup php_wrappers */ function drupal_move_uploaded_file($filename, $uri) { - $result = @move_uploaded_file($filename, $uri); - // PHP's move_uploaded_file() does not properly support streams if safe_mode - // or open_basedir are enabled so if the move failed, try finding a real path - // and retry the move operation. - if (!$result) { - if ($realpath = drupal_realpath($uri)) { - $result = move_uploaded_file($filename, $realpath); - } - else { - $result = move_uploaded_file($filename, $uri); - } - } - - return $result; + // move_uploaded_file() does not support moving a file between two different + // stream wrappers. Other file handling functions like rename() have the same + // problem, but copy() works since it explicitely sends the contents to the + // new source. As such move_uploaded_file() is replaced by is_uploaded_file(), + // copy(), and unlink() the old file. Doing so also works around the + // open_basedir limitations of move_uploaded_file() while maintaining the + // functionality since copy is used internally. + // + // This also supports upload proxying during which the file may be remotely + // located and referenced by a stream wrapper. In that case $filename may be + // something like remote://... and $uri public://... which may end up on the + // same remote filesystem, but PHP does not make the distinction. Of course, + // this also means the file can be moved between two different file systems. + return is_uploaded_file($filename) && copy($filename, $uri) && unlink($filename); } /** -- 1.8.1.2