make use of the fact that stream_read will always read 8192 bytes for encryption stream
https://bugs.php.net/bug.php?id=21641
This commit is contained in:
parent
26e9a0dd13
commit
b39c3d4c4e
2 changed files with 71 additions and 23 deletions
|
@ -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);
|
||||
}
|
||||
$data=fread($this->source,8192);
|
||||
if(strlen($data)){
|
||||
$result=OC_Crypt::decrypt($data);
|
||||
}else{
|
||||
$result='';
|
||||
}
|
||||
if(!$this->meta['seekable']){
|
||||
$this->readBuffer=substr($result,$count);
|
||||
}
|
||||
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);
|
||||
|
|
56
apps/files_encryption/tests/stream.php
Normal file
56
apps/files_encryption/tests/stream.php
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue