]> source.dussan.org Git - nextcloud-server.git/commitdiff
improve tar archive backend
authorRobin Appelman <icewind@owncloud.com>
Thu, 17 May 2012 23:54:02 +0000 (01:54 +0200)
committerRobin Appelman <icewind@owncloud.com>
Thu, 17 May 2012 23:54:59 +0000 (01:54 +0200)
apps/files_archive/lib/storage.php
apps/files_archive/tests/storage.php
lib/archive/tar.php
tests/lib/filestorage.php

index 086a338db25f26543b4300133d75d67461ad6709..b8f7d4683850371f735dfac623dd7c0c15747df2 100644 (file)
@@ -89,7 +89,7 @@ class OC_Filestorage_Archive extends OC_Filestorage_Common{
                if($path==''){
                        return file_exists($this->path);
                }
-               return $this->archive->fileExists($path) or $this->archive->fileExists($path.'/');
+               return $this->archive->fileExists($path);
        }
        public function unlink($path){
                $path=$this->stripPath($path);
index 7ebcce4ac6fdc1f6c723588fc78f92e0c29b4127..74ddf22870ca12f43dc415e0dda543a5501d4709 100644 (file)
@@ -22,4 +22,18 @@ class Test_Filestorage_Archive_Zip extends Test_FileStorage {
        }
 }
 
-?>
\ No newline at end of file
+class Test_Filestorage_Archive_Tar extends Test_FileStorage {
+       /**
+        * @var string tmpDir
+        */
+       private $tmpFile;
+
+       public function setUp(){
+               $this->tmpFile=OCP\Files::tmpFile('.tar.gz');
+               $this->instance=new OC_Filestorage_Archive(array('archive'=>$this->tmpFile));
+       }
+
+       public function tearDown(){
+               unlink($this->tmpFile);
+       }
+}
index 07f0ba5bd8a44fb921ee9bb56f9b3e77c5a3e3af..4ff787798340ac0a2e547c38ca3a62e8c1bf987d 100644 (file)
@@ -12,6 +12,8 @@ class OC_Archive_TAR extends OC_Archive{
        const PLAIN=0;
        const GZIP=1;
        const BZIP=2;
+
+       private $fileList;
        
        /**
         * @var Archive_Tar tar
@@ -64,6 +66,7 @@ class OC_Archive_TAR extends OC_Archive{
                mkdir($tmpBase.$path);
                $result=$this->tar->addModify(array($tmpBase.$path),'',$tmpBase);
                rmdir($tmpBase.$path);
+               $this->fileList=false;
                return $result;
        }
        /**
@@ -84,6 +87,7 @@ class OC_Archive_TAR extends OC_Archive{
                }else{
                        $result=$this->tar->addString($path,$source);
                }
+               $this->fileList=false;
                return $result;
        }
 
@@ -103,12 +107,14 @@ class OC_Archive_TAR extends OC_Archive{
                $types=array(null,'gz','bz');
                $this->tar=new Archive_Tar($this->path,$types[self::getTarType($this->path)]);
                $this->tar->createModify(array($tmp),'',$tmp.'/');
+               $this->fileList=false;
+               return true;
        }
 
        private function getHeader($file){
                $headers=$this->tar->listContent();
                foreach($headers as $header){
-                       if($file==$header['filename'] or $file.'/'==$header['filename']){
+                       if($file==$header['filename'] or $file.'/'==$header['filename'] or '/'.$file.'/'==$header['filename'] or '/'.$file==$header['filename']){
                                return $header;
                        }
                }
@@ -144,9 +150,16 @@ class OC_Archive_TAR extends OC_Archive{
                $folderContent=array();
                $pathLength=strlen($path);
                foreach($files as $file){
+                       if(substr($file,0,1)=='/'){
+                               $file=substr($file,1);
+                       }
                        if(substr($file,0,$pathLength)==$path and $file!=$path){
-                               if(strrpos(substr($file,0,-1),'/')<=$pathLength){
-                                       $folderContent[]=substr($file,$pathLength);
+                               $result=substr($file,$pathLength);
+                               if($pos=strpos($result,'/')){
+                                       $result=substr($result,0,$pos+1);
+                               }
+                               if(array_search($result,$folderContent)===false){
+                                       $folderContent[]=$result;
                                }
                        }
                }
@@ -157,11 +170,15 @@ class OC_Archive_TAR extends OC_Archive{
         * @return array
         */
        function getFiles(){
+               if($this->fileList){
+                       return $this->fileList;
+               }
                $headers=$this->tar->listContent();
                $files=array();
                foreach($headers as $header){
                        $files[]=$header['filename'];
                }
+               $this->fileList=$files;
                return $files;
        }
        /**
@@ -183,7 +200,11 @@ class OC_Archive_TAR extends OC_Archive{
                if(!$this->fileExists($path)){
                        return false;
                }
-               $success=$this->tar->extractList(array($path),$tmp);
+               if($this->fileExists('/'.$path)){
+                       $success=$this->tar->extractList(array('/'.$path),$tmp);
+               }else{
+                       $success=$this->tar->extractList(array($path),$tmp);
+               }
                if($success){
                        rename($tmp.$path,$dest);
                }
@@ -205,7 +226,26 @@ class OC_Archive_TAR extends OC_Archive{
         * @return bool
         */
        function fileExists($path){
-               return $this->getHeader($path)!==null;
+               $files=$this->getFiles();
+               if((array_search($path,$files)!==false) or (array_search($path.'/',$files)!==false)){
+                       return true;
+               }else{
+                       $folderPath=$path;
+                       if(substr($folderPath,-1,1)!='/'){
+                               $folderPath.='/';
+                       }
+                       $pathLength=strlen($folderPath);
+                       foreach($files as $file){
+                               if(strlen($file)>$pathLength and substr($file,0,$pathLength)==$folderPath){
+                                       return true;
+                               }
+                       }
+               }
+               if(substr($path,0,1)!='/'){//not all programs agree on the use of a leading /
+                       return $this->fileExists('/'.$path);
+               }else{
+                       return false;
+               }
        }
        
        /**
@@ -217,6 +257,7 @@ class OC_Archive_TAR extends OC_Archive{
                if(!$this->fileExists($path)){
                        return false;
                }
+               $this->fileList=false;
                //no proper way to delete, extract entire archive, delete file and remake archive
                $tmp=OCP\Files::tmpFolder();
                $this->tar->extract($tmp);
index b58e28cefde7654dedf83fac9d48419c414708b3..f71b658253a9bee0e79f5645597f68318b45b16a 100644 (file)
@@ -88,6 +88,7 @@ abstract class Test_FileStorage extends UnitTestCase {
                
                //fill a file with string data
                $this->instance->file_put_contents('/lorem.txt',$sourceText);
+               $this->assertFalse($this->instance->is_dir('/lorem.txt'));
                $this->assertEqual($sourceText,$this->instance->file_get_contents('/lorem.txt'),'data returned from file_get_contents is not equal to the source data');
 
                //empty the file