summaryrefslogtreecommitdiffstats
path: root/lib/private/files/stream
diff options
context:
space:
mode:
authorjknockaert <jasper@knockaert.nl>2015-04-21 14:21:53 +0200
committerBjoern Schiessle <schiessle@owncloud.com>2015-04-24 16:43:16 +0200
commit735f6cc0371f5e5c5d84a5ea4189f23104302ed1 (patch)
treea70682b7e5e51c400dfbf391944ad9b8fa3a3d45 /lib/private/files/stream
parent4334e770355df1583011c7e015b5caee48c91204 (diff)
downloadnextcloud-server-735f6cc0371f5e5c5d84a5ea4189f23104302ed1.tar.gz
nextcloud-server-735f6cc0371f5e5c5d84a5ea4189f23104302ed1.zip
fix encryption header error
When moving back the pointer to position 0 (using stream_seek), the pointer on the encrypted stream will be moved to the position immediately after the header. Reading the header again (invoked by stream_read) will cause an error, writing the header again (invoked by stream_write) will corrupt the file. Reading/writing the header should therefore happen when opening the file rather than upon read or write. Note that a side-effect of this PR is that empty files will still get an encryption header; I think that is OK, but it is different from how it was originally implemented.
Diffstat (limited to 'lib/private/files/stream')
-rw-r--r--lib/private/files/stream/encryption.php29
1 files changed, 16 insertions, 13 deletions
diff --git a/lib/private/files/stream/encryption.php b/lib/private/files/stream/encryption.php
index 910357eef45..936bcb71e71 100644
--- a/lib/private/files/stream/encryption.php
+++ b/lib/private/files/stream/encryption.php
@@ -221,15 +221,28 @@ class Encryption extends Wrapper {
|| $mode === 'w+'
|| $mode === 'wb'
|| $mode === 'wb+'
+ || $mode === 'r+'
+ || $mode === 'rb+'
) {
- // We're writing a new file so start write counter with 0 bytes
- $this->unencryptedSize = 0;
- $this->size = 0;
$this->readOnly = false;
} else {
$this->readOnly = true;
}
+ if (
+ $mode === 'w'
+ || $mode === 'w+'
+ || $mode === 'wb'
+ || $mode === 'wb+'
+ ) {
+ // We're writing a new file so start write counter with 0 bytes
+ $this->unencryptedSize = 0;
+ $this->writeHeader();
+ $this->size = $this->util->getHeaderSize();
+ } else {
+ parent::stream_read($this->util->getHeaderSize());
+ }
+
$sharePath = $this->fullPath;
if (!$this->storage->file_exists($this->internalPath)) {
$sharePath = dirname($sharePath);
@@ -250,11 +263,6 @@ class Encryption extends Wrapper {
$result = '';
- // skip the header if we read the file from the beginning
- if ($this->position === 0) {
- parent::stream_read($this->util->getHeaderSize());
- }
-
// $count = min($count, $this->unencryptedSize - $this->position);
while ($count > 0) {
$remainingLength = $count;
@@ -281,11 +289,6 @@ class Encryption extends Wrapper {
public function stream_write($data) {
- if ($this->position === 0) {
- $this->writeHeader();
- $this->size = $this->util->getHeaderSize();
- }
-
$length = 0;
// loop over $data to fit it in 6126 sized unencrypted blocks
while (strlen($data) > 0) {