rework getFileSize

This commit is contained in:
jknockaert 2014-10-19 22:27:15 +02:00
parent 245ae7e071
commit e318858152
1 changed files with 46 additions and 29 deletions

View File

@ -385,14 +385,23 @@ class Util {
&& $this->isEncryptedPath($path)
) {
$offset = 0;
if ($this->containHeader($path)) {
$offset = Crypt::BLOCKSIZE;
}
$cipher = Helper::getCipher();
$realSize = 0;
// get the size from filesystem if the file contains a encryption header we
// we substract it
$size = $this->view->filesize($path) - $offset;
// get the size from filesystem
$size = $this->view->filesize($path);
// open stream
$stream = fopen($path, "r");
// if the file contains a encryption header we
// we set the cipher
// and we update the size
if ($this->containHeader($path)) {
$header = fread($stream,Crypt::BLOCKSIZE);
$cipher = Crypt::getCipher($header);
$size -= Crypt::BLOCKSIZE;
}
// fast path, else the calculation for $lastChunkNr is bogus
if ($size === 0) {
@ -403,37 +412,45 @@ class Util {
// calculate last chunk nr
// next highest is end of chunks, one subtracted is last one
// we have to read the last chunk, we can't just calculate it (because of padding etc)
$lastChunkNr = ceil($size/ Crypt::BLOCKSIZE) - 1;
$lastChunkSize = $size - ($lastChunkNr * Crypt::BLOCKSIZE);
// open stream
$stream = fopen('crypt://' . $path, "r");
$lastChunkNr = ceil($size/Crypt::BLOCKSIZE)-1;
if (is_resource($stream)) {
// calculate last chunk position
$lastChunckPos = ($lastChunkNr * Crypt::BLOCKSIZE);
$lastChunkPos = ($lastChunkNr * Crypt::BLOCKSIZE);
// seek to end
if (@fseek($stream, $lastChunckPos) === -1) {
// storage doesn't support fseek, we need a local copy
fclose($stream);
$localFile = $this->view->getLocalFile($path);
Helper::addTmpFileToMapper($localFile, $path);
$stream = fopen('crypt://' . $localFile, "r");
if (fseek($stream, $lastChunckPos) === -1) {
// if fseek also fails on the local storage, than
// there is nothing we can do
fclose($stream);
\OCP\Util::writeLog('Encryption library', 'couldn\'t determine size of "' . $path, \OCP\Util::ERROR);
return $result;
// get the content of the last chunk
$lastChunkContentEncrypted='';
$count=Crypt::BLOCKSIZE;
if (@fseek($stream, $lastChunkPos, SEEK_CUR) === 0) {
$realSize+=$lastChunkNr*6126;
while ($count>0) {
$data=fread($stream,Crypt::BLOCKSIZE);
$count=strlen($data);
$lastChunkContentEncrypted.=$data;
}
} else {
while ($count>0) {
if(strlen($lastChunkContentEncrypted)>Crypt::BLOCKSIZE) {
$realSize+=6126;
$lastChunkContentEncrypted=substr($lastChunkContentEncrypted,Crypt::BLOCKSIZE);
}
$data=fread($stream,Crypt::BLOCKSIZE);
$count=strlen($data);
$lastChunkContentEncrypted.=$data;
}
}
// get the content of the last chunk
$lastChunkContent = fread($stream, $lastChunkSize);
$session = new \OCA\Encryption\Session(new \OC\Files\View('/'));
$privateKey = $session->getPrivateKey();
$plainKeyfile = $this->decryptKeyfile($path, $privateKey);
$shareKey = Keymanager::getShareKey($this->view, $this->keyId, $this, $path);
$plainKey = Crypt::multiKeyDecrypt($plainKeyfile, $shareKey, $privateKey);
$lastChunkContent=Crypt::symmetricDecryptFileContent($lastChunkContentEncrypted, $plainKey, $cipher);
// calc the real file size with the size of the last chunk
$realSize = (($lastChunkNr * 6126) + strlen($lastChunkContent));
$realSize += strlen($lastChunkContent);
// store file size
$result = $realSize;