updated core to 7.73

This commit is contained in:
2020-09-24 17:04:08 +02:00
parent 084d28842a
commit 7d87153100
524 changed files with 25194 additions and 7745 deletions
+250 -100
View File
@@ -273,7 +273,9 @@ function file_default_scheme() {
* The normalized URI.
*/
function file_stream_wrapper_uri_normalize($uri) {
$scheme = file_uri_scheme($uri);
// Inline file_uri_scheme() function call for performance reasons.
$position = strpos($uri, '://');
$scheme = $position ? substr($uri, 0, $position) : FALSE;
if ($scheme && file_stream_wrapper_valid_scheme($scheme)) {
$target = file_uri_target($uri);
@@ -470,8 +472,11 @@ function file_ensure_htaccess() {
* @param $private
* FALSE indicates that $directory should be an open and public directory.
* The default is TRUE which indicates a private and protected directory.
* @param $force_overwrite
* Set to TRUE to attempt to overwrite the existing .htaccess file if one is
* already present. Defaults to FALSE.
*/
function file_create_htaccess($directory, $private = TRUE) {
function file_create_htaccess($directory, $private = TRUE, $force_overwrite = FALSE) {
if (file_uri_scheme($directory)) {
$directory = file_stream_wrapper_uri_normalize($directory);
}
@@ -480,19 +485,12 @@ function file_create_htaccess($directory, $private = TRUE) {
}
$htaccess_path = $directory . '/.htaccess';
if (file_exists($htaccess_path)) {
if (file_exists($htaccess_path) && !$force_overwrite) {
// Short circuit if the .htaccess file already exists.
return;
}
if ($private) {
// Private .htaccess file.
$htaccess_lines = "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006\nDeny from all\nOptions None\nOptions +FollowSymLinks";
}
else {
// Public .htaccess file.
$htaccess_lines = "SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006\nOptions None\nOptions +FollowSymLinks";
}
$htaccess_lines = file_htaccess_lines($private);
// Write the .htaccess file.
if (file_put_contents($htaccess_path, $htaccess_lines)) {
@@ -504,6 +502,59 @@ function file_create_htaccess($directory, $private = TRUE) {
}
}
/**
* Returns the standard .htaccess lines that Drupal writes to file directories.
*
* @param $private
* (Optional) Set to FALSE to return the .htaccess lines for an open and
* public directory. The default is TRUE, which returns the .htaccess lines
* for a private and protected directory.
*
* @return
* A string representing the desired contents of the .htaccess file.
*
* @see file_create_htaccess()
*/
function file_htaccess_lines($private = TRUE) {
$lines = <<<EOF
# Turn off all options we don't need.
Options None
Options +FollowSymLinks
# Set the catch-all handler to prevent scripts from being executed.
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<Files *>
# Override the handler again if we're run later in the evaluation list.
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
</Files>
# If we know how to do it safely, disable the PHP engine entirely.
<IfModule mod_php5.c>
php_flag engine off
</IfModule>
<IfModule mod_php7.c>
php_flag engine off
</IfModule>
EOF;
if ($private) {
$lines = <<<EOF
# Deny all requests from Apache 2.4+.
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
# Deny all requests from Apache 2.0-2.2.
<IfModule !mod_authz_core.c>
Deny from all
</IfModule>
EOF
. "\n\n" . $lines;
}
return $lines;
}
/**
* Loads file objects from the database.
*
@@ -586,7 +637,11 @@ function file_save(stdClass $file) {
module_invoke_all('entity_update', $file, 'file');
}
// Clear internal properties.
unset($file->original);
// Clear the static loading cache.
entity_get_controller('file')->resetCache(array($file->fid));
return $file;
}
@@ -719,10 +774,11 @@ function file_usage_delete(stdClass $file, $module, $type = NULL, $id = NULL, $c
* stored in the database. This is a powerful function that in many ways
* performs like an advanced version of copy().
* - Checks if $source and $destination are valid and readable/writable.
* - Checks that $source is not equal to $destination; if they are an error
* is reported.
* - If file already exists in $destination either the call will error out,
* replace the file or rename the file based on the $replace parameter.
* - If the $source and $destination are equal, the behavior depends on the
* $replace parameter. FILE_EXISTS_REPLACE will error out. FILE_EXISTS_RENAME
* will rename the file until the $destination is unique.
* - Adds the new file to the files database. If the source file is a
* temporary file, the resulting file will also be a temporary file. See
* file_save_upload() for details on temporary files.
@@ -817,10 +873,11 @@ function file_valid_uri($uri) {
* This is a powerful function that in many ways performs like an advanced
* version of copy().
* - Checks if $source and $destination are valid and readable/writable.
* - Checks that $source is not equal to $destination; if they are an error
* is reported.
* - If file already exists in $destination either the call will error out,
* replace the file or rename the file based on the $replace parameter.
* - If the $source and $destination are equal, the behavior depends on the
* $replace parameter. FILE_EXISTS_REPLACE will error out. FILE_EXISTS_RENAME
* will rename the file until the $destination is unique.
* - Provides a fallback using realpaths if the move fails using stream
* wrappers. This can occur because PHP's copy() function does not properly
* support streams if safe_mode or open_basedir are enabled. See
@@ -846,7 +903,6 @@ function file_valid_uri($uri) {
*/
function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
$original_source = $source;
$original_destination = $destination;
// Assert that the source file actually exists.
if (!file_exists($source)) {
@@ -940,8 +996,15 @@ function file_build_uri($path) {
* @return
* The destination filepath, or FALSE if the file already exists
* and FILE_EXISTS_ERROR is specified.
*
* @throws RuntimeException
* Thrown if the filename contains invalid UTF-8.
*/
function file_destination($destination, $replace) {
$basename = drupal_basename($destination);
if (!drupal_validate_utf8($basename)) {
throw new RuntimeException(sprintf("Invalid filename '%s'", $basename));
}
if (file_exists($destination)) {
switch ($replace) {
case FILE_EXISTS_REPLACE:
@@ -949,7 +1012,6 @@ function file_destination($destination, $replace) {
break;
case FILE_EXISTS_RENAME:
$basename = drupal_basename($destination);
$directory = drupal_dirname($destination);
$destination = file_create_filename($basename, $directory);
break;
@@ -1108,10 +1170,10 @@ function file_munge_filename($filename, $extensions, $alerts = TRUE) {
// Allow potentially insecure uploads for very savvy users and admin
if (!variable_get('allow_insecure_uploads', 0)) {
// Remove any null bytes. See http://php.net/manual/en/security.filesystem.nullbytes.php
// Remove any null bytes. See http://php.net/manual/security.filesystem.nullbytes.php
$filename = str_replace(chr(0), '', $filename);
$whitelist = array_unique(explode(' ', trim($extensions)));
$whitelist = array_unique(explode(' ', strtolower(trim($extensions))));
// Split the filename up by periods. The first part becomes the basename
// the last part the final extension.
@@ -1124,7 +1186,7 @@ function file_munge_filename($filename, $extensions, $alerts = TRUE) {
// of allowed extensions.
foreach ($filename_parts as $filename_part) {
$new_filename .= '.' . $filename_part;
if (!in_array($filename_part, $whitelist) && preg_match("/^[a-zA-Z]{2,5}\d?$/", $filename_part)) {
if (!in_array(strtolower($filename_part), $whitelist) && preg_match("/^[a-zA-Z]{2,5}\d?$/", $filename_part)) {
$new_filename .= '_';
}
}
@@ -1165,11 +1227,20 @@ function file_unmunge_filename($filename) {
* @return
* File path consisting of $directory and a unique filename based off
* of $basename.
*
* @throws RuntimeException
* Thrown if the $basename is not valid UTF-8 or another error occurs
* stripping control characters.
*/
function file_create_filename($basename, $directory) {
$original = $basename;
// Strip control characters (ASCII value < 32). Though these are allowed in
// some filesystems, not many applications handle them well.
$basename = preg_replace('/[\x00-\x1F]/u', '_', $basename);
if (preg_last_error() !== PREG_NO_ERROR) {
throw new RuntimeException(sprintf("Invalid filename '%s'", $original));
}
if (substr(PHP_OS, 0, 3) == 'WIN') {
// These characters are not allowed in Windows filenames
$basename = str_replace(array(':', '*', '?', '"', '<', '>', '|'), '_', $basename);
@@ -1256,6 +1327,7 @@ function file_delete(stdClass $file, $force = FALSE) {
if (file_unmanaged_delete($file->uri)) {
db_delete('file_managed')->condition('fid', $file->fid)->execute();
db_delete('file_usage')->condition('fid', $file->fid)->execute();
entity_get_controller('file')->resetCache();
return TRUE;
}
return FALSE;
@@ -1365,8 +1437,9 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) {
* Temporary files are periodically cleaned. To make the file a permanent file,
* assign the status and use file_save() to save the changes.
*
* @param $source
* A string specifying the filepath or URI of the uploaded file to save.
* @param $form_field_name
* A string that is the associative array key of the upload form element in
* the form array.
* @param $validators
* An optional, associative array of callback functions used to validate the
* file. See file_validate() for a full discussion of the array format.
@@ -1377,9 +1450,9 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) {
* (Beware: this is not safe and should only be allowed for trusted users, if
* at all).
* @param $destination
* A string containing the URI $source should be copied to.
* This must be a stream wrapper URI. If this value is omitted, Drupal's
* temporary files scheme will be used ("temporary://").
* A string containing the URI that the file should be copied to. This must
* be a stream wrapper URI. If this value is omitted, Drupal's temporary
* files scheme will be used ("temporary://").
* @param $replace
* Replace behavior when the destination file already exists:
* - FILE_EXISTS_REPLACE: Replace the existing file.
@@ -1397,45 +1470,45 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) {
* - source: Path to the file before it is moved.
* - destination: Path to the file after it is moved (same as 'uri').
*/
function file_save_upload($source, $validators = array(), $destination = FALSE, $replace = FILE_EXISTS_RENAME) {
function file_save_upload($form_field_name, $validators = array(), $destination = FALSE, $replace = FILE_EXISTS_RENAME) {
global $user;
static $upload_cache;
// Return cached objects without processing since the file will have
// already been processed and the paths in _FILES will be invalid.
if (isset($upload_cache[$source])) {
return $upload_cache[$source];
if (isset($upload_cache[$form_field_name])) {
return $upload_cache[$form_field_name];
}
// Make sure there's an upload to process.
if (empty($_FILES['files']['name'][$source])) {
if (empty($_FILES['files']['name'][$form_field_name])) {
return NULL;
}
// Check for file upload errors and return FALSE if a lower level system
// error occurred. For a complete list of errors:
// See http://php.net/manual/en/features.file-upload.errors.php.
switch ($_FILES['files']['error'][$source]) {
// See http://php.net/manual/features.file-upload.errors.php.
switch ($_FILES['files']['error'][$form_field_name]) {
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
drupal_set_message(t('The file %file could not be saved, because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $_FILES['files']['name'][$source], '%maxsize' => format_size(file_upload_max_size()))), 'error');
drupal_set_message(t('The file %file could not be saved, because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $_FILES['files']['name'][$form_field_name], '%maxsize' => format_size(file_upload_max_size()))), 'error');
return FALSE;
case UPLOAD_ERR_PARTIAL:
case UPLOAD_ERR_NO_FILE:
drupal_set_message(t('The file %file could not be saved, because the upload did not complete.', array('%file' => $_FILES['files']['name'][$source])), 'error');
drupal_set_message(t('The file %file could not be saved, because the upload did not complete.', array('%file' => $_FILES['files']['name'][$form_field_name])), 'error');
return FALSE;
case UPLOAD_ERR_OK:
// Final check that this is a valid upload, if it isn't, use the
// default error handler.
if (is_uploaded_file($_FILES['files']['tmp_name'][$source])) {
if (is_uploaded_file($_FILES['files']['tmp_name'][$form_field_name])) {
break;
}
// Unknown error
default:
drupal_set_message(t('The file %file could not be saved. An unknown error has occurred.', array('%file' => $_FILES['files']['name'][$source])), 'error');
drupal_set_message(t('The file %file could not be saved. An unknown error has occurred.', array('%file' => $_FILES['files']['name'][$form_field_name])), 'error');
return FALSE;
}
@@ -1443,10 +1516,10 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
$file = new stdClass();
$file->uid = $user->uid;
$file->status = 0;
$file->filename = trim(drupal_basename($_FILES['files']['name'][$source]), '.');
$file->uri = $_FILES['files']['tmp_name'][$source];
$file->filename = trim(drupal_basename($_FILES['files']['name'][$form_field_name]), '.');
$file->uri = $_FILES['files']['tmp_name'][$form_field_name];
$file->filemime = file_get_mimetype($file->filename);
$file->filesize = $_FILES['files']['size'][$source];
$file->filesize = $_FILES['files']['size'][$form_field_name];
$extensions = '';
if (isset($validators['file_validate_extensions'])) {
@@ -1479,9 +1552,9 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
// rename filename.php.foo and filename.php to filename.php.foo.txt and
// filename.php.txt, respectively). Don't rename if 'allow_insecure_uploads'
// evaluates to TRUE.
if (!variable_get('allow_insecure_uploads', 0) && preg_match('/\.(php|pl|py|cgi|asp|js)(\.|$)/i', $file->filename) && (substr($file->filename, -4) != '.txt')) {
if (!variable_get('allow_insecure_uploads', 0) && preg_match('/\.(php|phar|pl|py|cgi|asp|js)(\.|$)/i', $file->filename) && (substr($file->filename, -4) != '.txt')) {
$file->filemime = 'text/plain';
$file->uri .= '.txt';
// The destination filename will also later be used to create the URI.
$file->filename .= '.txt';
// The .txt extension may not be in the allowed list of extensions. We have
// to add it here or else the file upload will fail.
@@ -1503,20 +1576,26 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
return FALSE;
}
$file->source = $source;
$file->source = $form_field_name;
// A URI may already have a trailing slash or look like "public://".
if (substr($destination, -1) != '/') {
$destination .= '/';
}
$file->destination = file_destination($destination . $file->filename, $replace);
try {
$file->destination = file_destination($destination . $file->filename, $replace);
}
catch (RuntimeException $e) {
drupal_set_message(t('The file %source could not be uploaded because the name is invalid.', array('%source' => $form_field_name)), 'error');
return FALSE;
}
// If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and
// there's an existing file so we need to bail.
if ($file->destination === FALSE) {
drupal_set_message(t('The file %source could not be uploaded because a file by that name already exists in the destination %directory.', array('%source' => $source, '%directory' => $destination)), 'error');
drupal_set_message(t('The file %source could not be uploaded because a file by that name already exists in the destination %directory.', array('%source' => $form_field_name, '%directory' => $destination)), 'error');
return FALSE;
}
// Add in our check of the the file name length.
// Add in our check of the file name length.
$validators['file_validate_name_length'] = array();
// Call the validation functions specified by this function's caller.
@@ -1531,7 +1610,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
else {
$message .= ' ' . array_pop($errors);
}
form_set_error($source, $message);
form_set_error($form_field_name, $message);
return FALSE;
}
@@ -1539,8 +1618,8 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
// directory. This overcomes open_basedir restrictions for future file
// operations.
$file->uri = $file->destination;
if (!drupal_move_uploaded_file($_FILES['files']['tmp_name'][$source], $file->uri)) {
form_set_error($source, t('File upload error. Could not move uploaded file.'));
if (!drupal_move_uploaded_file($_FILES['files']['tmp_name'][$form_field_name], $file->uri)) {
form_set_error($form_field_name, t('File upload error. Could not move uploaded file.'));
watchdog('file', 'Upload error. Could not move uploaded file %file to destination %destination.', array('%file' => $file->filename, '%destination' => $file->uri));
return FALSE;
}
@@ -1559,8 +1638,22 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
// If we made it this far it's safe to record this file in the database.
if ($file = file_save($file)) {
// Track non-public files in the session if they were uploaded by an
// anonymous user. This allows modules such as the File module to only
// grant view access to the specific anonymous user who uploaded the file.
// See file_file_download().
// The 'file_public_schema' variable is used to allow other publicly
// accessible file schemes to be treated the same as the public:// scheme
// provided by Drupal core and to avoid adding unnecessary data to the
// session (and the resulting bypass of the page cache) in those cases. For
// security reasons, only schemes that are completely publicly accessible,
// with no download restrictions, should be added to this variable. See
// file_managed_file_value().
if (!$user->uid && !in_array($destination_scheme, variable_get('file_public_schema', array('public')))) {
$_SESSION['anonymous_allowed_file_ids'][$file->fid] = $file->fid;
}
// Add file to the cache.
$upload_cache[$source] = $file;
$upload_cache[$form_field_name] = $file;
return $file;
}
return FALSE;
@@ -1686,8 +1779,6 @@ function file_validate_extensions(stdClass $file, $extensions) {
/**
* Checks that the file's size is below certain limits.
*
* This check is not enforced for the user #1.
*
* @param $file
* A Drupal file object.
* @param $file_limit
@@ -1705,20 +1796,17 @@ function file_validate_extensions(stdClass $file, $extensions) {
*/
function file_validate_size(stdClass $file, $file_limit = 0, $user_limit = 0) {
global $user;
$errors = array();
// Bypass validation for uid = 1.
if ($user->uid != 1) {
if ($file_limit && $file->filesize > $file_limit) {
$errors[] = t('The file is %filesize exceeding the maximum file size of %maxsize.', array('%filesize' => format_size($file->filesize), '%maxsize' => format_size($file_limit)));
}
// Save a query by only calling file_space_used() when a limit is provided.
if ($user_limit && (file_space_used($user->uid) + $file->filesize) > $user_limit) {
$errors[] = t('The file is %filesize which would exceed your disk quota of %quota.', array('%filesize' => format_size($file->filesize), '%quota' => format_size($user_limit)));
}
if ($file_limit && $file->filesize > $file_limit) {
$errors[] = t('The file is %filesize exceeding the maximum file size of %maxsize.', array('%filesize' => format_size($file->filesize), '%maxsize' => format_size($file_limit)));
}
// Save a query by only calling file_space_used() when a limit is provided.
if ($user_limit && (file_space_used($user->uid) + $file->filesize) > $user_limit) {
$errors[] = t('The file is %filesize which would exceed your disk quota of %quota.', array('%filesize' => format_size($file->filesize), '%quota' => format_size($user_limit)));
}
return $errors;
}
@@ -1747,7 +1835,7 @@ function file_validate_is_image(stdClass $file) {
/**
* Verifies that image dimensions are within the specified maximum and minimum.
*
* Non-image files will be ignored. If a image toolkit is available the image
* Non-image files will be ignored. If an image toolkit is available the image
* will be scaled to fit within the desired maximum dimensions.
*
* @param $file
@@ -1956,23 +2044,7 @@ function file_download() {
$target = implode('/', $args);
$uri = $scheme . '://' . $target;
if (file_stream_wrapper_valid_scheme($scheme) && file_exists($uri)) {
// Let other modules provide headers and controls access to the file.
// module_invoke_all() uses array_merge_recursive() which merges header
// values into a new array. To avoid that and allow modules to override
// headers instead, use array_merge() to merge the returned arrays.
$headers = array();
foreach (module_implements('file_download') as $module) {
$function = $module . '_file_download';
$result = $function($uri);
if ($result == -1) {
// Throw away the headers received so far.
$headers = array();
break;
}
if (isset($result) && is_array($result)) {
$headers = array_merge($headers, $result);
}
}
$headers = file_download_headers($uri);
if (count($headers)) {
file_transfer($uri, $headers);
}
@@ -1984,6 +2056,69 @@ function file_download() {
drupal_exit();
}
/**
* Retrieves headers for a private file download.
*
* Calls all module implementations of hook_file_download() to retrieve headers
* for files by the module that originally provided the file. The presence of
* returned headers indicates the current user has access to the file.
*
* @param $uri
* The URI for the file whose headers should be retrieved.
*
* @return
* If access is allowed, headers for the file, suitable for passing to
* file_transfer(). If access is not allowed, an empty array will be returned.
*
* @see file_transfer()
* @see file_download_access()
* @see hook_file_download()
*/
function file_download_headers($uri) {
// Let other modules provide headers and control access to the file.
// module_invoke_all() uses array_merge_recursive() which merges header
// values into a new array. To avoid that and allow modules to override
// headers instead, use array_merge() to merge the returned arrays.
$headers = array();
foreach (module_implements('file_download') as $module) {
$function = $module . '_file_download';
$result = $function($uri);
if ($result == -1) {
// Throw away the headers received so far.
$headers = array();
break;
}
if (isset($result) && is_array($result)) {
$headers = array_merge($headers, $result);
}
}
return $headers;
}
/**
* Checks that the current user has access to a particular file.
*
* The return value of this function hinges on the return value from
* file_download_headers(), which is the function responsible for collecting
* access information through hook_file_download().
*
* If immediately transferring the file to the browser and the headers will
* need to be retrieved, the return value of file_download_headers() should be
* used to determine access directly, so that access checks will not be run
* twice.
*
* @param $uri
* The URI for the file whose access should be retrieved.
*
* @return
* Boolean TRUE if access is allowed. FALSE if access is not allowed.
*
* @see file_download_headers()
* @see hook_file_download()
*/
function file_download_access($uri) {
return count(file_download_headers($uri)) > 0;
}
/**
* Finds all files that match a given mask in a given directory.
@@ -2019,9 +2154,33 @@ function file_download() {
* 'filename', and 'name' members corresponding to the matching files.
*/
function file_scan_directory($dir, $mask, $options = array(), $depth = 0) {
// Default nomask option.
$nomask = '/(\.\.?|CVS)$/';
// Overrides the $nomask variable accordingly if $options['nomask'] is set.
//
// Allow directories specified in settings.php to be ignored. You can use this
// to not check for files in common special-purpose directories. For example,
// node_modules and bower_components. Ignoring irrelevant directories is a
// performance boost.
if (!isset($options['nomask'])) {
$ignore_directories = variable_get(
'file_scan_ignore_directories',
array()
);
foreach ($ignore_directories as $index => $ignore_directory) {
$ignore_directories[$index] = preg_quote($ignore_directory, '/');
}
if (!empty($ignore_directories)) {
$nomask = '/^(\.\.?)|CVS|' . implode('|', $ignore_directories) . '$/';
}
}
// Merge in defaults.
$options += array(
'nomask' => '/(\.\.?|CVS)$/',
'nomask' => $nomask,
'callback' => 0,
'recurse' => TRUE,
'key' => 'uri',
@@ -2177,7 +2336,7 @@ function drupal_chmod($uri, $mode = NULL) {
* @param $uri
* A URI or pathname.
* @param $context
* Refer to http://php.net/manual/en/ref.stream.php
* Refer to http://php.net/manual/ref.stream.php
*
* @return
* Boolean TRUE on success, or FALSE on failure.
@@ -2199,29 +2358,21 @@ function drupal_unlink($uri, $context = NULL) {
}
/**
* Returns the absolute local filesystem path of a stream URI.
* Resolves the absolute filepath of a local URI or filepath.
*
* This function was originally written to ease the conversion of 6.x code to
* use 7.x stream wrappers. However, it assumes that every URI may be resolved
* to an absolute local filesystem path, and this assumption fails when stream
* wrappers are used to support remote file storage. Remote stream wrappers
* may implement the realpath method by always returning FALSE. The use of
* drupal_realpath() is discouraged, and is slowly being removed from core
* functions where possible.
* The use of drupal_realpath() is discouraged, because it does not work for
* remote URIs. Except in rare cases, URIs should not be manually resolved.
*
* Only use this function if you know that the stream wrapper in the URI uses
* the local file system, and you need to pass an absolute path to a function
* that is incompatible with stream URIs.
*
* @param $uri
* A stream wrapper URI or a filesystem path, possibly including one or more
* symbolic links.
* @param string $uri
* A stream wrapper URI or a filepath, possibly including one or more symbolic
* links.
*
* @return
* The absolute local filesystem path (with no symbolic links), or FALSE on
* failure.
*
* @todo This function is deprecated, and should be removed wherever possible.
* @return string|false
* The absolute local filepath (with no symbolic links), or FALSE on failure.
*
* @see DrupalStreamWrapperInterface::realpath()
* @see http://php.net/manual/function.realpath.php
@@ -2318,7 +2469,7 @@ function drupal_basename($uri, $suffix = NULL) {
* @param $recursive
* Default to FALSE.
* @param $context
* Refer to http://php.net/manual/en/ref.stream.php
* Refer to http://php.net/manual/ref.stream.php
*
* @return
* Boolean TRUE on success, or FALSE on failure.
@@ -2349,7 +2500,7 @@ function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) {
* @param $uri
* A URI or pathname.
* @param $context
* Refer to http://php.net/manual/en/ref.stream.php
* Refer to http://php.net/manual/ref.stream.php
*
* @return
* Boolean TRUE on success, or FALSE on failure.
@@ -2474,7 +2625,6 @@ function file_directory_temp() {
* An associative array of headers, as expected by file_transfer().
*/
function file_get_content_headers($file) {
$name = mime_header_encode($file->filename);
$type = mime_header_encode($file->filemime);
return array(