@ -621,17 +621,20 @@ class View {
* @param string|resource $data
* @return bool|mixed
* @throws LockedException
* @throws InvalidPathException When path is not within the expected root
*/
public function file_put_contents($path, $data) {
if (is_resource($data)) { //not having to deal with streams in file_put_contents makes life easier
if (!is_resource($data)) {
//not having to deal with streams in file_put_contents makes life easier
$hooks = $this->file_exists($path) ? ['update', 'write'] : ['create', 'write'];
return $this->basicOperation('file_put_contents', $path, $hooks, $data);
} else {
$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
if (Filesystem::isValidPath($path)
& & !Filesystem::isFileBlacklisted($path)
) {
$path = $this->getRelativePath($absolutePath);
if ($path === null) {
throw new InvalidPathException("Path $absolutePath is not in the expected root");
}
$this->verifyPath(dirname($path), basename($path));
$this->lockFile($path, ILockingProvider::LOCK_SHARED);
@ -671,15 +674,8 @@ class View {
$this->unlockFile($path, ILockingProvider::LOCK_SHARED);
return $result;
} else {
$this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
return false;
}
} else {
return false;
}
} else {
$hooks = $this->file_exists($path) ? ['update', 'write'] : ['create', 'write'];
return $this->basicOperation('file_put_contents', $path, $hooks, $data);
}
}
@ -735,20 +731,21 @@ class View {
$absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($target));
$targetParts = explode('/', $absolutePath2);
$targetUser = $targetParts[1] ?? null;
$result = false;
if (
Filesystem::isValidPath($target)
& & Filesystem::isValidPath($source)
& & !Filesystem::isFileBlacklisted($target)
) {
if (!Filesystem::isValidPath($source) || !Filesystem::isValidPath($target)) {
return false;
}
$source = $this->getRelativePath($absolutePath1);
$target = $this->getRelativePath($absolutePath2);
$exists = $this->file_exists($target);
if ($source == null || $target == null) {
return false;
}
$this->verifyPath(dirname($target), basename($target));
$result = false;
$this->lockFile($source, ILockingProvider::LOCK_SHARED, true);
try {
$this->lockFile($target, ILockingProvider::LOCK_SHARED, true);
@ -772,8 +769,6 @@ class View {
}
}
if ($run) {
$this->verifyPath(dirname($target), basename($target));
$manager = Filesystem::getMountManager();
$mount1 = $this->getMount($source);
$mount2 = $this->getMount($target);
@ -856,7 +851,6 @@ class View {
$this->unlockFile($source, ILockingProvider::LOCK_SHARED, true);
$this->unlockFile($target, ILockingProvider::LOCK_SHARED, true);
}
}
return $result;
}
@ -872,26 +866,27 @@ class View {
public function copy($source, $target, $preserveMtime = false) {
$absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($source));
$absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($target));
$result = false;
if (
Filesystem::isValidPath($target)
& & Filesystem::isValidPath($source)
& & !Filesystem::isFileBlacklisted($target)
) {
if (!Filesystem::isValidPath($source) || !Filesystem::isValidPath($target)) {
return false;
}
$source = $this->getRelativePath($absolutePath1);
$target = $this->getRelativePath($absolutePath2);
if ($source == null || $target == null) {
return false;
}
$run = true;
$this->verifyPath(dirname($target), basename($target));
$this->lockFile($target, ILockingProvider::LOCK_SHARED);
$this->lockFile($source, ILockingProvider::LOCK_SHARED);
$lockTypePath1 = ILockingProvider::LOCK_SHARED;
$lockTypePath2 = ILockingProvider::LOCK_SHARED;
$result = false;
try {
$run = true;
$exists = $this->file_exists($target);
if ($this->shouldEmitHooks()) {
\OC_Hook::emit(
@ -944,11 +939,8 @@ class View {
}
}
} catch (\Exception $e) {
$this->unlockFile($target, $lockTypePath2);
$this->unlockFile($source, $lockTypePath1);
throw $e;
}
} finally {
$this->unlockFile($target, $lockTypePath2);
$this->unlockFile($source, $lockTypePath1);
}
@ -1132,14 +1124,18 @@ class View {
private function basicOperation(string $operation, string $path, array $hooks = [], $extraParam = null) {
$postFix = (substr($path, -1) === '/') ? '/' : '';
$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
if (Filesystem::isValidPath($path)
& & !Filesystem::isFileBlacklisted($path)
) {
if (!Filesystem::isValidPath($path)) {
return false;
}
$path = $this->getRelativePath($absolutePath);
if ($path == null) {
return false;
}
$this->verifyPath(dirname($path), basename($path));
if (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks)) {
// always a shared lock during pre-hooks so the hook can read the file
$this->lockFile($path, ILockingProvider::LOCK_SHARED);
@ -1218,7 +1214,6 @@ class View {
} else {
$this->unlockFile($path, ILockingProvider::LOCK_SHARED);
}
}
return null;
}