]> source.dussan.org Git - nextcloud-server.git/commit
Fix truncation of files upon read when using object store and encryption.
authorAlan Meeson <alan@carefullycalculated.co.uk>
Wed, 11 Aug 2021 18:34:23 +0000 (19:34 +0100)
committerAlan Meeson <alan@carefullycalculated.co.uk>
Sat, 23 Oct 2021 14:11:23 +0000 (15:11 +0100)
commit44c332a46ef3b7d0b97039cad62840f7c8b9c82f
tree5fe6db66ce22470fbf29fd3ae64a420479bb4650
parent2b651cc0220629f7898440d1b38b622c524f7931
Fix truncation of files upon read when using object store and encryption.

When using and object store as primary storage and using the default
encryption module at the same time,  any encrypted file would be truncated
when read, and a text error message added to the end.

This was caused by a combination of the reliance of the read functions on
on knowing the unencrypted file size,  and a bug in the function which
calculated the unencrypted file size for a given file.

In order to calculate the unencrypted file size,  the function would first
skip the header block, then use fseek to skip to the last encrypted block
in the file.  Because there was a corresponence between the encrypted and
unencrypted blocks, this would also be the last encrypted block.  It would
then read the final block and decrypt it to get the unencrypted length of
the last block.  With that, the number of blocks, and the unencrypted block
size, it could calculate the unencrypted file size.

The trouble was that when using an object store, an fread call doesn't
always get you the number of bytes you asked for, even if they are
available.  To resolve this I adapted the stream_read_block function from
lib/private/Files/Streams/Encryption.php to work here.  This function
wraps the fread call in a loop and repeats until it has the entire set of
bytes that were requested,  or there are no more to get.

This fixes the imediate bug, and should (with luck) allow people to get
their encrypted files out of Nextcloud now.  (The problem was purely on
the decryption side).  In the future it would be nice to do some
refactoring here.

I have tested this with image files ranging from 1kb to 10mb using
Nextcloud version 22.1.0 (the nextcloud:22.1-apache docker image), with
sqlite and a Linode object store as the primary storage.

Signed-off-by: Alan Meeson <alan@carefullycalculated.co.uk>
lib/private/Files/Storage/Wrapper/Encryption.php