diff --git a/Filesystem.php b/Filesystem.php index d45cb1734e..041ea30ad0 100644 --- a/Filesystem.php +++ b/Filesystem.php @@ -192,12 +192,12 @@ public function remove($files) public function chmod($files, $mode, $umask = 0000, $recursive = false) { foreach ($this->toIterator($files) as $file) { - if ($recursive && is_dir($file) && !is_link($file)) { - $this->chmod(new \FilesystemIterator($file), $mode, $umask, true); - } if (true !== @chmod($file, $mode & ~$umask)) { throw new IOException(sprintf('Failed to chmod file "%s".', $file), 0, null, $file); } + if ($recursive && is_dir($file) && !is_link($file)) { + $this->chmod(new \FilesystemIterator($file), $mode, $umask, true); + } } } diff --git a/Tests/FilesystemTest.php b/Tests/FilesystemTest.php index 6ac81299eb..7843df4353 100644 --- a/Tests/FilesystemTest.php +++ b/Tests/FilesystemTest.php @@ -483,6 +483,22 @@ public function testChmodChangesModeOfTraversableFileObject() $this->assertFilePermissions(753, $directory); } + public function testChmodChangesZeroModeOnSubdirectoriesOnRecursive() + { + $this->markAsSkippedIfChmodIsMissing(); + + $directory = $this->workspace.DIRECTORY_SEPARATOR.'directory'; + $subdirectory = $directory.DIRECTORY_SEPARATOR.'subdirectory'; + + mkdir($directory); + mkdir($subdirectory); + chmod($subdirectory, 0000); + + $this->filesystem->chmod($directory, 0753, 0000, true); + + $this->assertFilePermissions(753, $subdirectory); + } + public function testChown() { $this->markAsSkippedIfPosixIsMissing();