[VD:localFS] _extract() more quickly and safety

This commit is contained in:
nao-pon
2015-03-18 20:35:18 +09:00
parent 441021a7d8
commit 531266bcba
+29 -28
View File
@@ -630,6 +630,7 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
if ($name != '.' && $name != '..') {
$p = $path.DIRECTORY_SEPARATOR.$name;
if (is_link($p) || !$this->nameAccepted($name)) {
$this->setError(elFinder::ERROR_SAVE, $name);
return true;
}
if (is_dir($p) && $this->_findSymlinks($p)) {
@@ -660,13 +661,16 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
if ($this->quarantine) {
$dir = $this->quarantine.DIRECTORY_SEPARATOR.str_replace(' ', '_', microtime()).basename($path);
$dir = $this->quarantine.DIRECTORY_SEPARATOR.md5(basename($path).mt_rand());
$archive = $dir.DIRECTORY_SEPARATOR.basename($path);
if (!@mkdir($dir)) {
return false;
}
// insurance unexpected shutdown
register_shutdown_function(array(&$this, 'delTree'), realpath($dir));
chmod($dir, 0777);
// copy in quarantine
@@ -695,30 +699,26 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
// find symlinks
$symlinks = $this->_findSymlinks($dir);
// remove arc copy
//$this->remove($dir);
$this->delTree($dir, false);
if ($symlinks) {
return $this->setError(elFinder::ERROR_ARC_SYMLINKS);
$this->delTree($dir);
return $this->setError(array_merge($this->error, array(elFinder::ERROR_ARC_SYMLINKS)));
}
// check max files size
if ($this->options['maxArcFilesSize'] > 0 && $this->options['maxArcFilesSize'] < $this->archiveSize) {
$this->delTree($dir);
return $this->setError(elFinder::ERROR_ARC_MAXSIZE);
}
// archive contains one item - extract in archive dir
if (count($ls) == 1) {
$this->_unpack($path, $arc);
$result = dirname($path).DIRECTORY_SEPARATOR.$ls[0];
$src = $dir.DIRECTORY_SEPARATOR.$ls[0];
if (count($ls) === 1 && is_file($src)) {
$name = $ls[0];
} else {
// for several files - create new directory
// create unique name for directory
$src = $dir;
$name = basename($path);
if (preg_match('/\.((tar\.(gz|bz|bz2|z|lzo))|cpio\.gz|ps\.gz|xcf\.(gz|bz2)|[a-z0-9]{1,4})$/i', $name, $m)) {
$name = substr($name, 0, strlen($name)-strlen($m[0]));
@@ -727,18 +727,17 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
if (file_exists($test) || is_link($test)) {
$name = $this->uniqueName(dirname($path), $name, '-', false);
}
$result = dirname($path).DIRECTORY_SEPARATOR.$name;
$archive = $result.DIRECTORY_SEPARATOR.basename($path);
if (!$this->_mkdir(dirname($path), $name) || !copy($path, $archive)) {
return false;
}
$this->_unpack($archive, $arc);
@unlink($archive);
}
$result = dirname($path).DIRECTORY_SEPARATOR.$name;
if (! @rename($src, $result)) {
$this->delTree($dir);
return false;
}
is_dir($dir) && $this->delTree($dir);
return file_exists($result) ? $result : false;
}
}
@@ -788,13 +787,15 @@ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver {
* @return boolean
* @author Naoki Sawada
*/
protected function delTree($localpath) {
foreach (array_diff(scandir($localpath), array('.', '..')) as $file) {
@set_time_limit(30);
$path = $localpath . '/' . $file;
(is_dir($path)) ? $this->delTree($path) : @unlink($path);
public function delTree($localpath) {
if (is_dir($localpath)) {
foreach (array_diff(scandir($localpath), array('.', '..')) as $file) {
@set_time_limit(30);
$path = $localpath . '/' . $file;
(is_dir($path)) ? $this->delTree($path) : @unlink($path);
}
return rmdir($localpath);
}
return rmdir($localpath);
}
} // END class