Skip to content

Commit 1ed4b26

Browse files
Merge branch '2.7' into 2.8
* 2.7: [Security] Fix logout #27250 limiting GET_LOCK key up to 64 char due to changes in MySQL 5.7.5 and later [Profiler] Remove propel & event_listener_loading category identifiers [Filesystem] Fix usages of error_get_last() [Debug] Fix populating error_get_last() for handled silent errors Suppress warnings when open_basedir is non-empty
2 parents 54798fc + c2d0fd6 commit 1ed4b26

File tree

1 file changed

+42
-22
lines changed

1 file changed

+42
-22
lines changed

Filesystem.php

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
*/
2222
class Filesystem
2323
{
24+
private static $lastError;
25+
2426
/**
2527
* Copies a file.
2628
*
@@ -95,12 +97,11 @@ public function mkdir($dirs, $mode = 0777)
9597
continue;
9698
}
9799

98-
if (true !== @mkdir($dir, $mode, true)) {
99-
$error = error_get_last();
100+
if (!self::box('mkdir', $dir, $mode, true)) {
100101
if (!is_dir($dir)) {
101102
// The directory was not created by a concurrent process. Let's throw an exception with a developer friendly error message if we have one
102-
if ($error) {
103-
throw new IOException(sprintf('Failed to create "%s": %s.', $dir, $error['message']), 0, null, $dir);
103+
if (self::$lastError) {
104+
throw new IOException(sprintf('Failed to create "%s": %s.', $dir, self::$lastError), 0, null, $dir);
104105
}
105106
throw new IOException(sprintf('Failed to create "%s"', $dir), 0, null, $dir);
106107
}
@@ -169,20 +170,17 @@ public function remove($files)
169170
foreach ($files as $file) {
170171
if (is_link($file)) {
171172
// See https://bugs.php.net/52176
172-
if (!@(unlink($file) || '\\' !== DIRECTORY_SEPARATOR || rmdir($file)) && file_exists($file)) {
173-
$error = error_get_last();
174-
throw new IOException(sprintf('Failed to remove symlink "%s": %s.', $file, $error['message']));
173+
if (!(self::box('unlink', $file) || '\\' !== DIRECTORY_SEPARATOR || self::box('rmdir', $file)) && file_exists($file)) {
174+
throw new IOException(sprintf('Failed to remove symlink "%s": %s.', $file, self::$lastError));
175175
}
176176
} elseif (is_dir($file)) {
177177
$this->remove(new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS));
178178

179-
if (!@rmdir($file) && file_exists($file)) {
180-
$error = error_get_last();
181-
throw new IOException(sprintf('Failed to remove directory "%s": %s.', $file, $error['message']));
179+
if (!self::box('rmdir', $file) && file_exists($file)) {
180+
throw new IOException(sprintf('Failed to remove directory "%s": %s.', $file, self::$lastError));
182181
}
183-
} elseif (!@unlink($file) && file_exists($file)) {
184-
$error = error_get_last();
185-
throw new IOException(sprintf('Failed to remove file "%s": %s.', $file, $error['message']));
182+
} elseif (!self::box('unlink', $file) && file_exists($file)) {
183+
throw new IOException(sprintf('Failed to remove file "%s": %s.', $file, self::$lastError));
186184
}
187185
}
188186
}
@@ -336,19 +334,16 @@ public function symlink($originDir, $targetDir, $copyOnWindows = false)
336334

337335
$this->mkdir(dirname($targetDir));
338336

339-
$ok = false;
340337
if (is_link($targetDir)) {
341-
if (readlink($targetDir) != $originDir) {
342-
$this->remove($targetDir);
343-
} else {
344-
$ok = true;
338+
if (readlink($targetDir) === $originDir) {
339+
return;
345340
}
341+
$this->remove($targetDir);
346342
}
347343

348-
if (!$ok && true !== @symlink($originDir, $targetDir)) {
349-
$report = error_get_last();
350-
if (is_array($report)) {
351-
if ('\\' === DIRECTORY_SEPARATOR && false !== strpos($report['message'], 'error code(1314)')) {
344+
if (!self::box('symlink', $originDir, $targetDir)) {
345+
if (null !== self::$lastError) {
346+
if ('\\' === DIRECTORY_SEPARATOR && false !== strpos(self::$lastError, 'error code(1314)')) {
352347
throw new IOException('Unable to create symlink due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', 0, null, $targetDir);
353348
}
354349
}
@@ -646,4 +641,29 @@ private function getSchemeAndHierarchy($filename)
646641

647642
return 2 === count($components) ? array($components[0], $components[1]) : array(null, $components[0]);
648643
}
644+
645+
private static function box($func)
646+
{
647+
self::$lastError = null;
648+
\set_error_handler(__CLASS__.'::handleError');
649+
try {
650+
$result = \call_user_func_array($func, \array_slice(\func_get_args(), 1));
651+
\restore_error_handler();
652+
653+
return $result;
654+
} catch (\Throwable $e) {
655+
} catch (\Exception $e) {
656+
}
657+
\restore_error_handler();
658+
659+
throw $e;
660+
}
661+
662+
/**
663+
* @internal
664+
*/
665+
public static function handleError($type, $msg)
666+
{
667+
self::$lastError = $msg;
668+
}
649669
}

0 commit comments

Comments
 (0)