diff --git a/core/includes/common.inc b/core/includes/common.inc
index 4229d52..2b365db 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -2932,7 +2932,7 @@ function drupal_get_css($css = NULL, $skip_alter = FALSE) {
   foreach ($css as $key => $item) {
     if ($item['type'] == 'file') {
       // If defined, force a unique basename for this file.
-      $basename = isset($item['basename']) ? $item['basename'] : basename($item['data']);
+      $basename = isset($item['basename']) ? $item['basename'] : drupal_basename($item['data']);
       if (isset($previous_item[$basename])) {
         // Remove the previous item that shared the same base name.
         unset($css[$previous_item[$basename]]);
diff --git a/core/includes/file.inc b/core/includes/file.inc
index 6e6611f..60ee8d5 100644
--- a/core/includes/file.inc
+++ b/core/includes/file.inc
@@ -770,7 +770,7 @@ function file_copy(stdClass $source, $destination = NULL, $replace = FILE_EXISTS
     $file = clone $source;
     $file->fid = NULL;
     $file->uri = $uri;
-    $file->filename = basename($uri);
+    $file->filename = drupal_basename($uri);
     // If we are replacing an existing file re-use its database record.
     if ($replace == FILE_EXISTS_REPLACE) {
       $existing_files = file_load_multiple(array(), array('uri' => $uri));
@@ -783,7 +783,7 @@ function file_copy(stdClass $source, $destination = NULL, $replace = FILE_EXISTS
     // If we are renaming around an existing file (rather than a directory),
     // use its basename for the filename.
     elseif ($replace == FILE_EXISTS_RENAME && is_file($destination)) {
-      $file->filename = basename($destination);
+      $file->filename = drupal_basename($destination);
     }
 
     $file = file_save($file);
@@ -867,14 +867,14 @@ function file_unmanaged_copy($source, $destination = NULL, $replace = FILE_EXIST
 
   // Build a destination URI if necessary.
   if (!isset($destination)) {
-    $destination = file_build_uri(basename($source));
+    $destination = file_build_uri(drupal_basename($source));
   }
 
 
   // Prepare the destination directory.
   if (file_prepare_directory($destination)) {
     // The destination is already a directory, so append the source basename.
-    $destination = file_stream_wrapper_uri_normalize($destination . '/' . basename($source));
+    $destination = file_stream_wrapper_uri_normalize($destination . '/' . drupal_basename($source));
   }
   else {
     // Perhaps $destination is a dir/file?
@@ -950,7 +950,7 @@ function file_destination($destination, $replace) {
         break;
 
       case FILE_EXISTS_RENAME:
-        $basename = basename($destination);
+        $basename = drupal_basename($destination);
         $directory = drupal_dirname($destination);
         $destination = file_create_filename($basename, $directory);
         break;
@@ -1025,7 +1025,7 @@ function file_move(stdClass $source, $destination = NULL, $replace = FILE_EXISTS
     // If we are renaming around an existing file (rather than a directory),
     // use its basename for the filename.
     elseif ($replace == FILE_EXISTS_RENAME && is_file($destination)) {
-      $file->filename = basename($destination);
+      $file->filename = drupal_basename($destination);
     }
 
     $file = file_save($file);
@@ -1443,7 +1443,7 @@ function file_save_upload($source, $validators = array(), $destination = FALSE,
   $file = new stdClass();
   $file->uid      = $user->uid;
   $file->status   = 0;
-  $file->filename = trim(basename($_FILES['files']['name'][$source]), '.');
+  $file->filename = trim(drupal_basename($_FILES['files']['name'][$source]), '.');
   $file->uri      = $_FILES['files']['tmp_name'][$source];
   $file->filemime = file_get_mimetype($file->filename);
   $file->filesize = $_FILES['files']['size'][$source];
@@ -1841,7 +1841,7 @@ function file_save_data($data, $destination = NULL, $replace = FILE_EXISTS_RENAM
     $file = new stdClass();
     $file->fid = NULL;
     $file->uri = $uri;
-    $file->filename = basename($uri);
+    $file->filename = drupal_basename($uri);
     $file->filemime = file_get_mimetype($file->uri);
     $file->uid      = $user->uid;
     $file->status   = FILE_STATUS_PERMANENT;
@@ -1857,7 +1857,7 @@ function file_save_data($data, $destination = NULL, $replace = FILE_EXISTS_RENAM
     // If we are renaming around an existing file (rather than a directory),
     // use its basename for the filename.
     elseif ($replace == FILE_EXISTS_RENAME && is_file($destination)) {
-      $file->filename = basename($destination);
+      $file->filename = drupal_basename($destination);
     }
 
     return file_save($file);
@@ -2261,6 +2261,35 @@ function drupal_dirname($uri) {
 }
 
 /**
+ * Gets the filename from a given path.
+ *
+ * PHP's basename() does not properly support streams or filenames beginning
+ * with a non-US-ASCII character.
+ *
+ * @see http://bugs.php.net/bug.php?id=37738
+ * @see basename()
+ *
+ * @ingroup php_wrappers
+ */
+function drupal_basename($uri, $suffix = NULL) {
+  $separators = '/';
+  if (DIRECTORY_SEPARATOR != '/') {
+    // For Windows OS add special separator.
+    $separators .= DIRECTORY_SEPARATOR;
+  }
+  // Remove right-most slashes when $uri points to directory.
+  $uri = rtrim($uri, $separators);
+  // Returns the trailing part of the $uri starting after one of the directory
+  // separators.
+  $filename = preg_match('@[^' . preg_quote($separators, '@') . ']+$@', $uri, $matches) ? $matches[0] : '';
+  // Cuts off a suffix from the filename.
+  if ($suffix) {
+    $filename = preg_replace('@' . preg_quote($suffix) . '$@', '', $filename);
+  }
+  return $filename;
+}
+
+/**
  * Creates a directory using Drupal's default mode.
  *
  * PHP's mkdir() does not respect Drupal's default permissions mode. If a mode
@@ -2356,7 +2385,7 @@ function drupal_tempnam($directory, $prefix) {
     $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme);
 
     if ($filename = tempnam($wrapper->getDirectoryPath(), $prefix)) {
-      return $scheme . '://' . basename($filename);
+      return $scheme . '://' . drupal_basename($filename);
     }
     else {
       return FALSE;
diff --git a/core/includes/filetransfer/filetransfer.inc b/core/includes/filetransfer/filetransfer.inc
index aa7ebe4..af7dbdd 100644
--- a/core/includes/filetransfer/filetransfer.inc
+++ b/core/includes/filetransfer/filetransfer.inc
@@ -212,7 +212,7 @@ abstract class FileTransfer {
    */
   protected function copyDirectoryJailed($source, $destination) {
     if ($this->isDirectory($destination)) {
-      $destination = $destination . '/' . basename($source);
+      $destination = $destination . '/' . drupal_basename($source);
     }
     $this->createDirectory($destination);
     foreach (new RecursiveIteratorIterator(new SkipDotsRecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST) as $filename => $file) {
@@ -303,7 +303,7 @@ abstract class FileTransfer {
     $chroot = '';
     while (count($parts)) {
       $check = implode($parts, '/');
-      if ($this->isFile($check . '/' . basename(__FILE__))) {
+      if ($this->isFile($check . '/' . drupal_basename(__FILE__))) {
         // Remove the trailing slash.
         return substr($chroot, 0, -1);
       }
diff --git a/core/includes/stream_wrappers.inc b/core/includes/stream_wrappers.inc
index 650d94d..d38c445 100644
--- a/core/includes/stream_wrappers.inc
+++ b/core/includes/stream_wrappers.inc
@@ -317,7 +317,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
     }
 
     $extension = '';
-    $file_parts = explode('.', basename($uri));
+    $file_parts = explode('.', drupal_basename($uri));
 
     // Remove the first part: a full filename should not match an extension.
     array_shift($file_parts);
@@ -377,7 +377,7 @@ abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface
     $realpath = realpath($path);
     if (!$realpath) {
       // This file does not yet exist.
-      $realpath = realpath(dirname($path)) . '/' . basename($path);
+      $realpath = realpath(dirname($path)) . '/' . drupal_basename($path);
     }
     $directory = realpath($this->getDirectoryPath());
     if (!$realpath || !$directory || strpos($realpath, $directory) !== 0) {
diff --git a/core/includes/updater.inc b/core/includes/updater.inc
index 363c6eb..9801629 100644
--- a/core/includes/updater.inc
+++ b/core/includes/updater.inc
@@ -141,7 +141,7 @@ class Updater {
       return FALSE;
     }
     foreach ($info_files as $info_file) {
-      if (drupal_substr($info_file->filename, 0, -5) == basename($directory)) {
+      if (drupal_substr($info_file->filename, 0, -5) == drupal_basename($directory)) {
         // Info file Has the same name as the directory, return it.
         return $info_file->uri;
       }
@@ -163,7 +163,7 @@ class Updater {
    *   The name of the project.
    */
   public static function getProjectName($directory) {
-    return basename($directory);
+    return drupal_basename($directory);
   }
 
   /**
diff --git a/core/modules/color/color.module b/core/modules/color/color.module
index 7665631..4f0fc2e 100644
--- a/core/modules/color/color.module
+++ b/core/modules/color/color.module
@@ -86,7 +86,7 @@ function _color_html_alter(&$vars) {
       foreach ($color_paths as $color_path) {
         // Color module currently requires unique file names to be used,
         // which allows us to compare different file paths.
-        if (basename($old_path) == basename($color_path)) {
+        if (drupal_basename($old_path) == drupal_basename($color_path)) {
           // Replace the path to the new css file.
           // This keeps the order of the stylesheets intact.
           $vars['css'][$old_path]['data'] = $color_path;
@@ -362,7 +362,7 @@ function color_scheme_form_submit($form, &$form_state) {
 
   // Copy over neutral images.
   foreach ($info['copy'] as $file) {
-    $base = basename($file);
+    $base = drupal_basename($file);
     $source = $paths['source'] . $file;
     $filepath = file_unmanaged_copy($source, $paths['target'] . $base);
     $paths['map'][$file] = $base;
@@ -404,7 +404,7 @@ function color_scheme_form_submit($form, &$form_state) {
 
       // Rewrite stylesheet with new colors.
       $style = _color_rewrite_stylesheet($theme, $info, $paths, $palette, $style);
-      $base_file = basename($file);
+      $base_file = drupal_basename($file);
       $css[] = $paths['target'] . $base_file;
       _color_save_stylesheet($paths['target'] . $base_file, $style, $paths);
     }
@@ -544,7 +544,7 @@ function _color_render_images($theme, &$info, &$paths, $palette) {
   // Cut out slices.
   foreach ($info['slices'] as $file => $coord) {
     list($x, $y, $width, $height) = $coord;
-    $base = basename($file);
+    $base = drupal_basename($file);
     $image = drupal_realpath($paths['target'] . $base);
 
     // Cut out slice.
diff --git a/core/modules/file/tests/file.test b/core/modules/file/tests/file.test
index 59f6e0c..b7343bf 100644
--- a/core/modules/file/tests/file.test
+++ b/core/modules/file/tests/file.test
@@ -761,6 +761,9 @@ class FileFieldDisplayTestCase extends FileFieldTestCase {
     $instance = field_info_instance('node', $field_name, $type_name);
 
     $test_file = $this->getTestFile('text');
+    // Coping a file to test uploads with non-latin filenames.
+    $filename = drupal_dirname($test_file->uri) . '/текстовый файл.txt';
+    $test_file = file_copy($test_file, $filename);
 
     // Create a new node with the uploaded file.
     $nid = $this->uploadNodeFile($test_file, $field_name, $type_name);
diff --git a/core/modules/image/image.test b/core/modules/image/image.test
index a29b4f3..42509f8 100644
--- a/core/modules/image/image.test
+++ b/core/modules/image/image.test
@@ -192,7 +192,7 @@ class ImageStylesPathAndUrlUnitTest extends DrupalWebTestCase {
     $this->assertNotIdentical(FALSE, $original_uri, t('Created the generated image file.'));
 
     // Get the URL of a file that has not been generated and try to create it.
-    $generated_uri = $scheme . '://styles/' . $this->style_name . '/' . $scheme . '/'. basename($original_uri);
+    $generated_uri = $scheme . '://styles/' . $this->style_name . '/' . $scheme . '/'. drupal_basename($original_uri);
     $this->assertFalse(file_exists($generated_uri), t('Generated file does not exist.'));
     $generate_url = image_style_url($this->style_name, $original_uri);
 
@@ -940,7 +940,7 @@ class ImageDimensionsUnitTest extends DrupalWebTestCase {
 
     // Create a style.
     $style = image_style_save(array('name' => 'test'));
-    $generated_uri = 'public://styles/test/public/'. basename($original_uri);
+    $generated_uri = 'public://styles/test/public/'. drupal_basename($original_uri);
     $url = image_style_url('test', $original_uri);
 
     $variables = array(
diff --git a/core/modules/locale/locale.bulk.inc b/core/modules/locale/locale.bulk.inc
index 45a31bd..16d7e21 100644
--- a/core/modules/locale/locale.bulk.inc
+++ b/core/modules/locale/locale.bulk.inc
@@ -231,7 +231,7 @@ function locale_translate_batch_import($filepath, &$context) {
   // The filename is either {langcode}.po or {prefix}.{langcode}.po, so
   // we can extract the language code to use for the import from the end.
   if (preg_match('!(/|\.)([^\./]+)\.po$!', $filepath, $langcode)) {
-    $file = (object) array('filename' => basename($filepath), 'uri' => $filepath);
+    $file = (object) array('filename' => drupal_basename($filepath), 'uri' => $filepath);
     _locale_import_read_po('db-store', $file, LOCALE_IMPORT_KEEP, $langcode[2]);
     $context['results'][] = $filepath;
   }
diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php
index 9d993d4..de16463 100644
--- a/core/modules/simpletest/drupal_web_test_case.php
+++ b/core/modules/simpletest/drupal_web_test_case.php
@@ -1631,7 +1631,16 @@ class DrupalWebTestCase extends DrupalTestCase {
    *   An header.
    */
   protected function curlHeaderCallback($curlHandler, $header) {
-    $this->headers[] = $header;
+    // Header fields can be extended over multiple lines by preceding each
+    // extra line with at least one SP or HT. They should be joined on receive.
+    // Details are in RFC2616 section 4.
+    if ($header[0] == ' ' || $header[0] == "\t") {
+      // Normalize whitespace between chucks.
+      $this->headers[] = array_pop($this->headers) . ' ' . trim($header);
+    }
+    else {
+      $this->headers[] = $header;
+    }
 
     // Errors are being sent via X-Drupal-Assertion-* headers,
     // generated by _drupal_log_error() in the exact form required
diff --git a/core/modules/simpletest/simpletest.pages.inc b/core/modules/simpletest/simpletest.pages.inc
index e65c4d4..dc4bc4f 100644
--- a/core/modules/simpletest/simpletest.pages.inc
+++ b/core/modules/simpletest/simpletest.pages.inc
@@ -254,7 +254,7 @@ function simpletest_result_form($form, &$form_state, $test_id) {
       $row = array();
       $row[] = $assertion->message;
       $row[] = $assertion->message_group;
-      $row[] = basename($assertion->file);
+      $row[] = drupal_basename($assertion->file);
       $row[] = $assertion->line;
       $row[] = $assertion->function;
       $row[] = simpletest_result_status_image($assertion->status);
diff --git a/core/modules/simpletest/tests/common.test b/core/modules/simpletest/tests/common.test
index 8406ec8..a50e4bd 100644
--- a/core/modules/simpletest/tests/common.test
+++ b/core/modules/simpletest/tests/common.test
@@ -2148,7 +2148,7 @@ class DrupalErrorCollectionUnitTest extends DrupalWebTestCase {
   function assertError($error, $group, $function, $file, $message = NULL) {
     $this->assertEqual($error['group'], $group, t("Group was %group", array('%group' => $group)));
     $this->assertEqual($error['caller']['function'], $function, t("Function was %function", array('%function' => $function)));
-    $this->assertEqual(basename($error['caller']['file']), $file, t("File was %file", array('%file' => $file)));
+    $this->assertEqual(drupal_basename($error['caller']['file']), $file, t("File was %file", array('%file' => $file)));
     if (isset($message)) {
       $this->assertEqual($error['message'], $message, t("Message was %message", array('%message' => $message)));
     }
diff --git a/core/modules/simpletest/tests/file.test b/core/modules/simpletest/tests/file.test
index 7496902..a369a44 100644
--- a/core/modules/simpletest/tests/file.test
+++ b/core/modules/simpletest/tests/file.test
@@ -198,7 +198,9 @@ class FileTestCase extends DrupalWebTestCase {
    */
   function createFile($filepath = NULL, $contents = NULL, $scheme = NULL) {
     if (!isset($filepath)) {
-      $filepath = $this->randomName();
+      // Prefix with non-latin characters to ensure that all file-related
+      // tests work with international filenames.
+      $filepath = 'Файл для тестирования ' . $this->randomName();
     }
     if (!isset($scheme)) {
       $scheme = file_default_scheme();
@@ -214,7 +216,7 @@ class FileTestCase extends DrupalWebTestCase {
 
     $file = new stdClass();
     $file->uri = $filepath;
-    $file->filename = basename($file->uri);
+    $file->filename = drupal_basename($file->uri);
     $file->filemime = 'text/plain';
     $file->uid = 1;
     $file->timestamp = REQUEST_TIME;
@@ -372,11 +374,11 @@ class FileValidatorTest extends DrupalWebTestCase {
 
     $this->image = new stdClass();
     $this->image->uri = 'core/misc/druplicon.png';
-    $this->image->filename = basename($this->image->uri);
+    $this->image->filename = drupal_basename($this->image->uri);
 
     $this->non_image = new stdClass();
     $this->non_image->uri = 'core/misc/jquery.js';
-    $this->non_image->filename = basename($this->non_image->uri);
+    $this->non_image->filename = drupal_basename($this->non_image->uri);
   }
 
   /**
@@ -539,7 +541,7 @@ class FileUnmanagedSaveDataTest extends FileTestCase {
     // Provide a filename.
     $filepath = file_unmanaged_save_data($contents, 'public://asdf.txt', FILE_EXISTS_REPLACE);
     $this->assertTrue($filepath, t('Unnamed file saved correctly.'));
-    $this->assertEqual('asdf.txt', basename($filepath), t('File was named correctly.'));
+    $this->assertEqual('asdf.txt', drupal_basename($filepath), t('File was named correctly.'));
     $this->assertEqual($contents, file_get_contents($filepath), t('Contents of the file are correct.'));
     $this->assertFilePermissions($filepath, variable_get('file_chmod_file', 0664));
   }
@@ -666,7 +668,7 @@ class FileSaveUploadTest extends FileHookTestCase {
     $this->drupalPost('file-test/upload', $edit, t('Submit'));
     $this->assertResponse(200, t('Received a 200 response for posted test file.'));
     $this->assertRaw(t('You WIN!'));
-    $this->assertTrue(is_file('temporary://' . $dir . '/' . trim(basename($image3_realpath))));
+    $this->assertTrue(is_file('temporary://' . $dir . '/' . trim(drupal_basename($image3_realpath))));
 
     // Check that file_load_multiple() with no arguments returns FALSE.
     $this->assertFalse(file_load_multiple(), t('No files were loaded.'));
@@ -2202,7 +2204,7 @@ class FileSaveDataTest extends FileHookTestCase {
     $this->assertTrue($result, t('Unnamed file saved correctly.'));
 
     $this->assertEqual(file_default_scheme(), file_uri_scheme($result->uri), t("File was placed in Drupal's files directory."));
-    $this->assertEqual($result->filename, basename($result->uri), t("Filename was set to the file's basename."));
+    $this->assertEqual($result->filename, drupal_basename($result->uri), t("Filename was set to the file's basename."));
     $this->assertEqual($contents, file_get_contents($result->uri), t('Contents of the file are correct.'));
     $this->assertEqual($result->filemime, 'application/octet-stream', t('A MIME type was set.'));
     $this->assertEqual($result->status, FILE_STATUS_PERMANENT, t("The file's status was set to permanent."));
@@ -2220,11 +2222,14 @@ class FileSaveDataTest extends FileHookTestCase {
   function testWithFilename() {
     $contents = $this->randomName(8);
 
-    $result = file_save_data($contents, 'public://' . 'asdf.txt');
+    // Using filename with non-latin characters.
+    $filename = 'Текстовый файл.txt';
+
+    $result = file_save_data($contents, 'public://' . $filename);
     $this->assertTrue($result, t('Unnamed file saved correctly.'));
 
     $this->assertEqual('public', file_uri_scheme($result->uri), t("File was placed in Drupal's files directory."));
-    $this->assertEqual('asdf.txt', basename($result->uri), t('File was named correctly.'));
+    $this->assertEqual($filename, drupal_basename($result->uri), t('File was named correctly.'));
     $this->assertEqual($contents, file_get_contents($result->uri), t('Contents of the file are correct.'));
     $this->assertEqual($result->filemime, 'text/plain', t('A MIME type was set.'));
     $this->assertEqual($result->status, FILE_STATUS_PERMANENT, t("The file's status was set to permanent."));
@@ -2336,7 +2341,10 @@ class FileDownloadTest extends FileTestCase {
     // Test generating an URL to a created file.
     $file = $this->createFile();
     $url = file_create_url($file->uri);
-    $this->assertEqual($GLOBALS['base_url'] . '/' . file_stream_wrapper_get_instance_by_scheme('public')->getDirectoryPath() . '/' . $file->filename, $url, t('Correctly generated a URL for a created file.'));
+    // URLs can't contain characters outside the ASCII set so $filename has to be
+    // encoded.
+    $filename = $GLOBALS['base_url'] . '/' . file_stream_wrapper_get_instance_by_scheme('public')->getDirectoryPath() . '/' . rawurlencode($file->filename);
+    $this->assertEqual($filename, $url, t('Correctly generated a URL for a created file.'));
     $this->drupalHead($url);
     $this->assertResponse(200, t('Confirmed that the generated URL is correct by downloading the created file.'));
 
@@ -2356,16 +2364,20 @@ class FileDownloadTest extends FileTestCase {
     // Set file downloads to private so handler functions get called.
 
     // Create a file.
-    $file = $this->createFile(NULL, NULL, 'private');
+    $contents = $this->randomName(8);
+    $file = $this->createFile(NULL, $contents, 'private');
     $url  = file_create_url($file->uri);
 
     // Set file_test access header to allow the download.
     file_test_set_return('download', array('x-foo' => 'Bar'));
-    $this->drupalHead($url);
+    $this->drupalGet($url);
     $headers = $this->drupalGetHeaders();
-    $this->assertEqual($headers['x-foo'] , 'Bar', t('Found header set by file_test module on private download.'));
+    $this->assertEqual($headers['x-foo'], 'Bar', t('Found header set by file_test module on private download.'));
     $this->assertResponse(200, t('Correctly allowed access to a file when file_test provides headers.'));
 
+    // Test that the file transfered correctly.
+    $this->assertEqual($contents, $this->content, t('Contents of the file are correct.'));
+
     // Deny access to all downloads via a -1 header.
     file_test_set_return('download', -1);
     $this->drupalHead($url);
@@ -2602,7 +2614,7 @@ class FileMimeTypeTest extends DrupalWebTestCase {
    * Test mapping of mimetypes from filenames.
    */
   public function testFileMimeTypeDetection() {
-    $prefix = 'simpletest://';
+    $prefix = 'public://';
 
     $test_case = array(
       'test.jar' => 'application/java-archive',
diff --git a/core/modules/simpletest/tests/file_test.module b/core/modules/simpletest/tests/file_test.module
index b3c43e0..1b11316 100644
--- a/core/modules/simpletest/tests/file_test.module
+++ b/core/modules/simpletest/tests/file_test.module
@@ -138,7 +138,7 @@ function _file_test_form_submit(&$form, &$form_state) {
 /**
  * Reset/initialize the history of calls to the file_* hooks.
  *
- * @see file_test_get_calls() 
+ * @see file_test_get_calls()
  * @see file_test_reset()
  */
 function file_test_reset() {
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index f4261e1..7c6e801 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -3421,12 +3421,12 @@ function system_image_toolkits() {
 function system_retrieve_file($url, $destination = NULL, $managed = FALSE, $replace = FILE_EXISTS_RENAME) {
   $parsed_url = parse_url($url);
   if (!isset($destination)) {
-    $path = file_build_uri(basename($parsed_url['path']));
+    $path = file_build_uri(drupal_basename($parsed_url['path']));
   }
   else {
     if (is_dir(drupal_realpath($destination))) {
       // Prevent URIs with triple slashes when glueing parts together.
-      $path = str_replace('///', '//', "$destination/") . basename($parsed_url['path']);
+      $path = str_replace('///', '//', "$destination/") . drupal_basename($parsed_url['path']);
     }
     else {
       $path = $destination;
diff --git a/core/modules/system/system.test b/core/modules/system/system.test
index 6cf203d..5c04afa 100644
--- a/core/modules/system/system.test
+++ b/core/modules/system/system.test
@@ -2240,7 +2240,7 @@ class RetrieveFileTestCase extends DrupalWebTestCase {
   function testFileRetrieving() {
     // Test 404 handling by trying to fetch a randomly named file.
     drupal_mkdir($sourcedir = 'public://' . $this->randomName());
-    $filename = $this->randomName();
+    $filename = 'Файл для тестирования ' . $this->randomName();
     $url = file_create_url($sourcedir . '/' . $filename);
     $retrieved_file = system_retrieve_file($url);
     $this->assertFalse($retrieved_file, t('Non-existent file not fetched.'));
@@ -2248,7 +2248,12 @@ class RetrieveFileTestCase extends DrupalWebTestCase {
     // Actually create that file, download it via HTTP and test the returned path.
     file_put_contents($sourcedir . '/' . $filename, 'testing');
     $retrieved_file = system_retrieve_file($url);
-    $this->assertEqual($retrieved_file, 'public://' . $filename, t('Sane path for downloaded file returned (public:// scheme).'));
+
+    // URLs could not contains characters outside the ASCII set so $filename
+    // has to be encoded.
+    $encoded_filename = rawurlencode($filename);
+
+    $this->assertEqual($retrieved_file, 'public://' . $encoded_filename, t('Sane path for downloaded file returned (public:// scheme).'));
     $this->assertTrue(is_file($retrieved_file), t('Downloaded file does exist (public:// scheme).'));
     $this->assertEqual(filesize($retrieved_file), 7, t('File size of downloaded file is correct (public:// scheme).'));
     file_unmanaged_delete($retrieved_file);
@@ -2256,7 +2261,7 @@ class RetrieveFileTestCase extends DrupalWebTestCase {
     // Test downloading file to a different location.
     drupal_mkdir($targetdir = 'temporary://' . $this->randomName());
     $retrieved_file = system_retrieve_file($url, $targetdir);
-    $this->assertEqual($retrieved_file, "$targetdir/$filename", t('Sane path for downloaded file returned (temporary:// scheme).'));
+    $this->assertEqual($retrieved_file, "$targetdir/$encoded_filename", t('Sane path for downloaded file returned (temporary:// scheme).'));
     $this->assertTrue(is_file($retrieved_file), t('Downloaded file does exist (temporary:// scheme).'));
     $this->assertEqual(filesize($retrieved_file), 7, t('File size of downloaded file is correct (temporary:// scheme).'));
     file_unmanaged_delete($retrieved_file);
diff --git a/core/modules/update/update.manager.inc b/core/modules/update/update.manager.inc
index 59858eb..d9fd86f 100644
--- a/core/modules/update/update.manager.inc
+++ b/core/modules/update/update.manager.inc
@@ -816,7 +816,7 @@ function update_manager_file_get($url) {
 
   // Check the cache and download the file if needed.
   $cache_directory = _update_manager_cache_directory();
-  $local = $cache_directory . '/' . basename($parsed_url['path']);
+  $local = $cache_directory . '/' . drupal_basename($parsed_url['path']);
 
   if (!file_exists($local) || update_delete_file_if_stale($local)) {
     return system_retrieve_file($url, $local, FALSE, FILE_EXISTS_REPLACE);
diff --git a/core/modules/update/update.module b/core/modules/update/update.module
index 6da47c0..ee1a94b 100644
--- a/core/modules/update/update.module
+++ b/core/modules/update/update.module
@@ -695,14 +695,14 @@ function update_verify_update_archive($project, $archive_file, $directory) {
   }
 
   if (empty($files)) {
-    $errors[] = t('%archive_file does not contain any .info files.', array('%archive_file' => basename($archive_file)));
+    $errors[] = t('%archive_file does not contain any .info files.', array('%archive_file' => drupal_basename($archive_file)));
   }
   elseif (!$compatible_project) {
     $errors[] = format_plural(
       count($incompatible),
       '%archive_file contains a version of %names that is not compatible with Drupal !version.',
       '%archive_file contains versions of modules or themes that are not compatible with Drupal !version: %names',
-      array('!version' => DRUPAL_CORE_COMPATIBILITY, '%archive_file' => basename($archive_file), '%names' => implode(', ', $incompatible))
+      array('!version' => DRUPAL_CORE_COMPATIBILITY, '%archive_file' => drupal_basename($archive_file), '%names' => implode(', ', $incompatible))
     );
   }
 
