diff --git a/controller/ApiController.php b/controller/ApiController.php index 4b9d446..13528dd 100644 --- a/controller/ApiController.php +++ b/controller/ApiController.php @@ -41,6 +41,15 @@ Class ApiController extends Controller { return $this->renderJson($params); } + private function getParentDir($realpath) { + $realpath = preg_replace('/\/$/', '', $realpath); + $arr = explode('/', $realpath); + if (count($arr) < 2) {return $realpath;} + + array_pop($arr); + return implode('/', $arr); + } + //判断父目录是否合法 protected function isParentDirectoryValid($parentDir) { if (empty($parentDir) || strpos($parentDir, '../') !== false) { @@ -48,6 +57,7 @@ Class ApiController extends Controller { } $valid = true; + $parentDir = preg_replace('/^\//', '', $parentDir); $target = __DIR__ . '/../www/' . FSC::$app['config']['content_directory'] . "/{$parentDir}"; if (!is_dir($target)) { $valid = false; @@ -241,19 +251,35 @@ Class ApiController extends Controller { } $fromDir = $this->post('from', ''); + $fromParent = $this->getParentDir($fromDir); $toDir = $this->post('to', ''); + $toParent = $this->getParentDir($toDir); $maxDirLen = 50; if (empty($fromDir) || mb_strlen($fromDir, 'utf-8') > $maxDirLen || empty($toDir) || mb_strlen($toDir, 'utf-8') > $maxDirLen) { $err = "目录名不能为空且最长 {$maxDirLen} 个字符"; return $this->renderJson(compact('code', 'msg', 'err', 'data'), $this->httpStatus['notAllowed']); - }else if ($this->isParentDirectoryValid($fromDir) == false) { //目录合法性检查 - $err = "目录{$fromDir}不存在"; + }else if ($this->isParentDirectoryValid($fromParent) == false) { //父目录合法性检查 + $err = "被移动目录{$fromParent}不存在"; return $this->renderJson(compact('code', 'msg', 'err', 'data'), $this->httpStatus['notAllowed']); - }else if ($this->isParentDirectoryValid($toDir) == false) { //目录合法性检查 - $err = "目录{$toDir}不存在"; + }else if ($this->isParentDirectoryValid($toParent) == false) { //父目录合法性检查 + $err = "目标目录{$toParent}不存在"; return $this->renderJson(compact('code', 'msg', 'err', 'data'), $this->httpStatus['notAllowed']); } + //如果from是一个文件,而to是目录 + if (preg_match('/\.\w+$/', $fromDir) && ( + preg_match('/\/$/', $toDir) || preg_match('/\/[^\.]+$/', $toDir) + ) + ) { + if ($this->isParentDirectoryValid($toDir) == false) { //父目录合法性检查 + $err = "目标目录{$toDir}不存在"; + return $this->renderJson(compact('code', 'msg', 'err', 'data'), $this->httpStatus['notAllowed']); + } + + $fromFile = str_replace("{$fromParent}/", '', $fromDir); + $toDir = preg_match('/\/$/', $toDir) ? "{$toDir}{$fromFile}" : "{$toDir}/{$fromFile}"; + } + $target = __DIR__ . '/../www/' . FSC::$app['config']['content_directory']; try { $res = rename("{$target}/{$fromDir}", "{$target}/{$toDir}");