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 <[email protected]>
  • Loading branch information
icewind1991 committed Aug 31, 2023
1 parent 638cbac commit 847f6f5
Showing 1 changed file with 20 additions and 3 deletions.
23 changes: 20 additions & 3 deletions apps/files_external/lib/Lib/Storage/SFTP.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@
*/
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;

/**
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 847f6f5

Please sign in to comment.