Esempio n. 1
0
	/**
	 * read block to file
	 */
	protected function readCache() {
		// cache should always be empty string when this function is called
		// don't try to fill the cache when trying to write at the end of the unencrypted file when it coincides with new block
		if ($this->cache === '' && !($this->position === $this->unencryptedSize && ($this->position % $this->unencryptedBlockSize) === 0)) {
			// Get the data from the file handle
			$data = parent::stream_read($this->util->getBlockSize());
			$this->cache = $this->encryptionModule->decrypt($data);
		}
	}
Esempio n. 2
0
 /**
  * read block to file
  */
 protected function readCache()
 {
     // cache should always be empty string when this function is called
     // don't try to fill the cache when trying to write at the end of the unencrypted file when it coincides with new block
     if ($this->cache === '' && !($this->position === $this->unencryptedSize && $this->position % $this->unencryptedBlockSize === 0)) {
         // Get the data from the file handle
         $data = parent::stream_read($this->util->getBlockSize());
         $position = (int) floor($this->position / $this->unencryptedBlockSize);
         $numberOfChunks = (int) ($this->unencryptedSize / $this->unencryptedBlockSize);
         if ($numberOfChunks === $position) {
             $position .= 'end';
         }
         $this->cache = $this->encryptionModule->decrypt($data, $position);
     }
 }
Esempio n. 3
0
	/**
	 * calculate the unencrypted size
	 *
	 * @param string $path internal path relative to the storage root
	 * @param int $size size of the physical file
	 * @param int $unencryptedSize size of the unencrypted file
	 *
	 * @return int calculated unencrypted size
	 */
	protected function fixUnencryptedSize($path, $size, $unencryptedSize) {

		$headerSize = $this->getHeaderSize($path);
		$header = $this->getHeader($path);
		$encryptionModule = $this->getEncryptionModule($path);

		$stream = $this->storage->fopen($path, 'r');

		// if we couldn't open the file we return the old unencrypted size
		if (!is_resource($stream)) {
			$this->logger->error('Could not open ' . $path . '. Recalculation of unencrypted size aborted.');
			return $unencryptedSize;
		}

		$newUnencryptedSize = 0;
		$size -= $headerSize;
		$blockSize = $this->util->getBlockSize();

		// if a header exists we skip it
		if ($headerSize > 0) {
			fread($stream, $headerSize);
		}

		// fast path, else the calculation for $lastChunkNr is bogus
		if ($size === 0) {
			return 0;
		}

		$signed = (isset($header['signed']) && $header['signed'] === 'true') ? true : false;
		$unencryptedBlockSize = $encryptionModule->getUnencryptedBlockSize($signed);

		// 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/ $blockSize)-1;
		// calculate last chunk position
		$lastChunkPos = ($lastChunkNr * $blockSize);
		// try to fseek to the last chunk, if it fails we have to read the whole file
		if (@fseek($stream, $lastChunkPos, SEEK_CUR) === 0) {
			$newUnencryptedSize += $lastChunkNr * $unencryptedBlockSize;
		}

		$lastChunkContentEncrypted='';
		$count = $blockSize;

		while ($count > 0) {
			$data=fread($stream, $blockSize);
			$count=strlen($data);
			$lastChunkContentEncrypted .= $data;
			if(strlen($lastChunkContentEncrypted) > $blockSize) {
				$newUnencryptedSize += $unencryptedBlockSize;
				$lastChunkContentEncrypted=substr($lastChunkContentEncrypted, $blockSize);
			}
		}

		fclose($stream);

		// we have to decrypt the last chunk to get it actual size
		$encryptionModule->begin($this->getFullPath($path), $this->uid, 'r', $header, []);
		$decryptedLastChunk = $encryptionModule->decrypt($lastChunkContentEncrypted);
		$decryptedLastChunk .= $encryptionModule->end($this->getFullPath($path));

		// calc the real file size with the size of the last chunk
		$newUnencryptedSize += strlen($decryptedLastChunk);

		$this->updateUnencryptedSize($this->getFullPath($path), $newUnencryptedSize);

		// write to cache if applicable
		$cache = $this->storage->getCache();
		if ($cache) {
			$entry = $cache->get($path);
			$cache->update($entry['fileid'], ['size' => $newUnencryptedSize]);
		}

		return $newUnencryptedSize;
	}