]> source.dussan.org Git - nextcloud-server.git/commitdiff
make use of the fact that stream_read will always read 8192 bytes for encryption...
authorRobin Appelman <icewind@owncloud.com>
Tue, 17 Apr 2012 21:10:14 +0000 (23:10 +0200)
committerRobin Appelman <icewind@owncloud.com>
Wed, 18 Apr 2012 18:54:28 +0000 (20:54 +0200)
https://bugs.php.net/bug.php?id=21641

apps/files_encryption/lib/cryptstream.php
apps/files_encryption/tests/stream.php [new file with mode: 0644]

index 86583096f1dbeaba4273dad36bfd2eb829550da7..21fa38e4b5989699cac69deabac9feaf41d9c89c 100644 (file)
@@ -64,29 +64,19 @@ class OC_CryptStream{
        }
        
        public function stream_read($count){
-               $pos=0;
-               $currentPos=ftell($this->source);
-               $offset=$currentPos%8192;
-               $result='';
-               if($offset>0){
-                       if($this->meta['seekable']){
-                               fseek($this->source,-$offset,SEEK_CUR);//if seeking isnt supported the internal read buffer will be used
-                       }else{
-                               $pos=strlen($this->readBuffer);
-                               $result=$this->readBuffer;
-                       }
+               //$count will always be 8192 https://bugs.php.net/bug.php?id=21641
+               //This makes this function a lot simpler but will breake everything the moment it's fixed
+               if($count!=8192){
+                       OC_Log::write('files_encryption','php bug 21641 no longer holds, decryption will not work',OC_Log::FATAL);
+                       die();
                }
-               while($count>$pos){
-                       $data=fread($this->source,8192);
-                       $pos+=8192;
-                       if(strlen($data)){
-                               $result.=OC_Crypt::decrypt($data);
-                       }
-               }
-               if(!$this->meta['seekable']){
-                       $this->readBuffer=substr($result,$count);
+               $data=fread($this->source,8192);
+               if(strlen($data)){
+                       $result=OC_Crypt::decrypt($data);
+               }else{
+                       $result='';
                }
-               return substr($result,0,$count);
+               return $result;
        }
        
        public function stream_write($data){
@@ -107,8 +97,10 @@ class OC_CryptStream{
                                $oldPos=ftell($this->source);
                                $encryptedBlock=fread($this->source,8192);
                                fseek($this->source,$oldPos);
-                               $block=OC_Crypt::decrypt($encryptedBlock);
-                               $data.=substr($block,strlen($data));
+                               if($encryptedBlock){
+                                       $block=OC_Crypt::decrypt($encryptedBlock);
+                                       $data.=substr($block,strlen($data));
+                               }
                        }
                        $encrypted=OC_Crypt::encrypt(substr($data,0,8192));
                        fwrite($this->source,$encrypted);
diff --git a/apps/files_encryption/tests/stream.php b/apps/files_encryption/tests/stream.php
new file mode 100644 (file)
index 0000000..578b091
--- /dev/null
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class Test_CryptStream extends UnitTestCase {
+       private $tmpFiles=array();
+       
+       function testStream(){
+               $stream=$this->getStream('test1','w');
+               fwrite($stream,'foobar');
+               fclose($stream);
+
+               $stream=$this->getStream('test1','r');
+               $data=fread($stream,6);
+               fclose($stream);
+               $this->assertEqual('foobar',$data);
+
+               $file=OC::$SERVERROOT.'/3rdparty/MDB2.php';
+               $source=fopen($file,'r');
+               $target=$this->getStream('test2','w');
+               OC_Helper::streamCopy($source,$target);
+               fclose($target);
+               fclose($source);
+
+               $stream=$this->getStream('test2','r');
+               $data=stream_get_contents($stream);
+               $original=file_get_contents($file);
+               $this->assertEqual(strlen($original),strlen($data));
+               $this->assertEqual($original,$data);
+       }
+
+       /**
+        * get a cryptstream to a temporary file
+        * @param string $id
+        * @param string $mode
+        * @return resource
+        */
+       function getStream($id,$mode){
+               if($id===''){
+                       $id=uniqid();
+               }
+               if(!isset($this->tmpFiles[$id])){
+                       $file=OC_Helper::tmpFile();
+                       $this->tmpFiles[$id]=$file;
+               }else{
+                       $file=$this->tmpFiles[$id];
+               }
+               $stream=fopen($file,$mode);
+               OC_CryptStream::$sourceStreams[$id]=array('path'=>'dummy','stream'=>$stream);
+               return fopen('crypt://streams/'.$id,$mode);
+       }
+}