diff options
author | jknockaert <jasper@knockaert.nl> | 2015-04-21 14:21:53 +0200 |
---|---|---|
committer | Bjoern Schiessle <schiessle@owncloud.com> | 2015-04-24 16:43:16 +0200 |
commit | 735f6cc0371f5e5c5d84a5ea4189f23104302ed1 (patch) | |
tree | a70682b7e5e51c400dfbf391944ad9b8fa3a3d45 /lib/private/files/stream | |
parent | 4334e770355df1583011c7e015b5caee48c91204 (diff) | |
download | nextcloud-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.php | 29 |
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) { |