diff --git a/core/lib/Drupal/Core/File/FileSystem.php b/core/lib/Drupal/Core/File/FileSystem.php index 076bc066d85851f8632cf681e7112bf9ee2b019b..a2fafbb60dae681d9ab50e16014a893fa146ee12 100644 --- a/core/lib/Drupal/Core/File/FileSystem.php +++ b/core/lib/Drupal/Core/File/FileSystem.php @@ -181,8 +181,10 @@ public function mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) { // If recursive, create each missing component of the parent directory // individually and set the mode explicitly to override the umask. if ($recursive) { - // Ensure the path is using DIRECTORY_SEPARATOR. - $uri = str_replace('/', DIRECTORY_SEPARATOR, $uri); + // Ensure the path is using DIRECTORY_SEPARATOR, and trim off any trailing + // slashes because they can throw off the loop when creating the parent + // directories. + $uri = rtrim(str_replace('/', DIRECTORY_SEPARATOR, $uri), DIRECTORY_SEPARATOR); // Determine the components of the path. $components = explode(DIRECTORY_SEPARATOR, $uri); // If the filepath is absolute the first component will be empty as there diff --git a/core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php b/core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php index 774bd7c0e2b25fcd22fa69d298a260a3b1d311c3..d7e7c382f6efb5784c6e33556fce51bcc4a579ee 100644 --- a/core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php +++ b/core/tests/Drupal/KernelTests/Core/File/DirectoryTest.php @@ -161,4 +161,17 @@ function testFileDirectoryTemp() { $this->assertEqual($config->get('path.temporary'), $tmp_directory); } + /** + * Tests directory creation. + */ + public function testDirectoryCreation() { + /** @var \Drupal\Core\File\FileSystemInterface $file_system */ + $file_system = $this->container->get('file_system'); + + // mkdir() recursion should work with or without a trailing slash. + $dir = $this->siteDirectory . '/files'; + $this->assertTrue($file_system->mkdir($dir . '/foo/bar', 0775, TRUE)); + $this->assertTrue($file_system->mkdir($dir . '/foo/baz/', 0775, TRUE)); + } + }