Skip to content

Commit

Permalink
don't believe sftp when it tells us the mtime is less than we know it is
Browse files Browse the repository at this point in the history
Signed-off-by: Robin Appelman <robin@icewind.nl>
  • Loading branch information
icewind1991 committed Aug 30, 2023
1 parent 638cbac commit 4d6d716
Showing 1 changed file with 21 additions and 4 deletions.
25 changes: 21 additions & 4 deletions apps/files_external/lib/Lib/Storage/SFTP.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,18 @@
*/
namespace OCA\Files_External\Lib\Storage;

use Icewind\Streams\CallbackWrapper;
use Icewind\Streams\IteratorDirectory;
use Icewind\Streams\RetryWrapper;
use OCP\IRequest;
use OCP\Cache\CappedMemoryCache;
use phpseclib\Net\SFTP\Stream;

/**
* Uses phpseclib's Net\SFTP class and the Net\SFTP\Stream stream wrapper to
* provide access to SFTP servers.
*/
class SFTP extends \OC\Files\Storage\Common {
class SFTP extends \OC\Files\Storage\Common {

Check notice

Code scanning / Psalm

DeprecatedInterface Note

OCP\Files\Storage is marked deprecated
private $host;
private $user;
private $root;
Expand All @@ -57,6 +59,7 @@ class SFTP extends \OC\Files\Storage\Common {
* @var \phpseclib\Net\SFTP
*/
protected $client;
private CappedMemoryCache $knownMTimes;

/**
* @param string $host protocol://server:port
Expand Down Expand Up @@ -112,6 +115,8 @@ public function __construct($params) {

$this->root = '/' . ltrim($this->root, '/');
$this->root = rtrim($this->root, '/') . '/';

$this->knownMTimes = new CappedMemoryCache();
}

/**
Expand Down Expand Up @@ -369,6 +374,7 @@ public function unlink($path) {
* {@inheritdoc}
*/
public function fopen($path, $mode) {
$path = $this->cleanPath($path);
try {
$absPath = $this->absPath($path);
switch ($mode) {
Expand All @@ -385,7 +391,13 @@ public function fopen($path, $mode) {
case 'wb':
SFTPWriteStream::register();
$context = stream_context_create(['sftp' => ['session' => $this->getConnection()]]);
return fopen('sftpwrite://' . trim($absPath, '/'), 'w', false, $context);
$fh = fopen('sftpwrite://' . trim($absPath, '/'), 'w', false, $context);
if ($fh) {
$fh = CallbackWrapper::wrap($fh, null, null, function() use ($path) {
$this->knownMTimes->set($path, time());
});
}
return $fh;
case 'a':
case 'ab':
case 'r+':
Expand Down Expand Up @@ -414,14 +426,13 @@ public function touch($path, $mtime = null) {
return false;
}
if (!$this->file_exists($path)) {
$this->getConnection()->put($this->absPath($path), '');
return $this->getConnection()->put($this->absPath($path), '');

Check notice

Code scanning / Psalm

InternalMethod Note

The method phpseclib\Net\SFTP::put is internal to phpseclib but called from OCA\Files_External\Lib\Storage\SFTP::touch
} else {
return false;
}
} catch (\Exception $e) {
return false;
}
return true;
}

/**
Expand Down Expand Up @@ -455,11 +466,17 @@ public function rename($source, $target) {
*/
public function stat($path) {
try {
$path = $this->cleanPath($path);
$stat = $this->getConnection()->stat($this->absPath($path));

$mtime = $stat ? $stat['mtime'] : -1;
$size = $stat ? $stat['size'] : 0;

// the mtime can't be less than when we last touched it
if ($knownMTime = $this->knownMTimes->get($path)) {
$mtime = max($mtime, $knownMTime);
}

return ['mtime' => $mtime, 'size' => $size, 'ctime' => -1];
} catch (\Exception $e) {
return false;
Expand Down

0 comments on commit 4d6d716

Please sign in to comment.