rework getFileSize

This commit is contained in:
jknockaert 2014-10-19 22:27:15 +02:00
parent 245ae7e071
commit e318858152

View file

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