]> source.dussan.org Git - nextcloud-server.git/commitdiff
# This is a combination of 2 commits.
authorThomas Müller <thomas.mueller@tmit.eu>
Thu, 8 May 2014 13:19:54 +0000 (15:19 +0200)
committerThomas Müller <thomas.mueller@tmit.eu>
Wed, 28 May 2014 13:30:44 +0000 (15:30 +0200)
# The first commit's message is:

adding tests for long paths
increment path field in database up to 4000 (maximum for Oracle - otherwise we could use php's 4096)
increment version to trigger database migration
adding unit test for too long path

# This is the 2nd commit message:

fix too long path

db_structure.xml
lib/private/files/view.php
tests/lib/files/view.php
version.php

index 3cb2af287afe5175faa5498f36a83a2d4334e3fe..21ac47a781b6908e37573efe024de2d333b070ea 100644 (file)
                                <type>text</type>
                                <default></default>
                                <notnull>false</notnull>
-                               <length>512</length>
+                               <length>4000</length>
                        </field>
 
                        <field>
index 940f31fe420bc51dc83466c07b8d8bb62d0a8f51..b698d87866c0f4e6f0df092407bfbe2a1bcfdfe4 100644 (file)
@@ -29,14 +29,13 @@ use OC\Files\Cache\Updater;
 
 class View {
        private $fakeRoot = '';
-       private $internal_path_cache = array();
-       private $storage_cache = array();
 
        public function __construct($root = '') {
                $this->fakeRoot = $root;
        }
 
        public function getAbsolutePath($path = '/') {
+               $this->assertPathLength($path);
                if ($path === '') {
                        $path = '/';
                }
@@ -77,6 +76,7 @@ class View {
         * @return string
         */
        public function getRelativePath($path) {
+               $this->assertPathLength($path);
                if ($this->fakeRoot == '') {
                        return $path;
                }
@@ -208,6 +208,7 @@ class View {
        }
 
        public function readfile($path) {
+               $this->assertPathLength($path);
                @ob_end_clean();
                $handle = $this->fopen($path, 'rb');
                if ($handle) {
@@ -595,6 +596,7 @@ class View {
        }
 
        public function toTmpFile($path) {
+               $this->assertPathLength($path);
                if (Filesystem::isValidPath($path)) {
                        $source = $this->fopen($path, 'r');
                        if ($source) {
@@ -611,7 +613,7 @@ class View {
        }
 
        public function fromTmpFile($tmpFile, $path) {
-
+               $this->assertPathLength($path);
                if (Filesystem::isValidPath($path)) {
 
                        // Get directory that the file is going into
@@ -640,6 +642,7 @@ class View {
        }
 
        public function getMimeType($path) {
+               $this->assertPathLength($path);
                return $this->basicOperation('getMimeType', $path);
        }
 
@@ -669,6 +672,7 @@ class View {
        }
 
        public function free_space($path = '/') {
+               $this->assertPathLength($path);
                return $this->basicOperation('free_space', $path);
        }
 
@@ -808,6 +812,7 @@ class View {
         * @return \OC\Files\FileInfo|false
         */
        public function getFileInfo($path, $includeMountPoints = true) {
+               $this->assertPathLength($path);
                $data = array();
                if (!Filesystem::isValidPath($path)) {
                        return $data;
@@ -878,6 +883,7 @@ class View {
         * @return FileInfo[]
         */
        public function getDirectoryContent($directory, $mimetype_filter = '') {
+               $this->assertPathLength($directory);
                $result = array();
                if (!Filesystem::isValidPath($directory)) {
                        return $result;
@@ -1006,6 +1012,7 @@ class View {
         * returns the fileid of the updated file
         */
        public function putFileInfo($path, $data) {
+               $this->assertPathLength($path);
                if ($data instanceof FileInfo) {
                        $data = $data->getData();
                }
@@ -1153,4 +1160,12 @@ class View {
                }
                return null;
        }
+
+       private function assertPathLength($path) {
+               $maxLen = min(PHP_MAXPATHLEN, 4000);
+               $pathLen = strlen($path);
+               if ($pathLen > $maxLen) {
+                       throw new \OCP\Files\InvalidPathException("Path length($pathLen) exceeds max path length($maxLen): $path");
+               }
+       }
 }
index 201eb9ff6cbfcaba0ab547e653475952d441cfc8..b5e4d79235095a9e9558a81a9c3c8fea2f8df025 100644 (file)
@@ -20,6 +20,7 @@ class View extends \PHPUnit_Framework_TestCase {
         * @var \OC\Files\Storage\Storage[] $storages
         */
        private $storages = array();
+       private $user;
 
        public function setUp() {
                \OC_User::clearBackends();
@@ -569,6 +570,47 @@ class View extends \PHPUnit_Framework_TestCase {
                }
        }
 
+       public function testLongPath() {
+
+               $storage = new \OC\Files\Storage\Temporary(array());
+               \OC\Files\Filesystem::mount($storage, array(), '/');
+
+               $rootView = new \OC\Files\View('');
+
+               $longPath = '';
+               // 4000 is the maximum path length in file_cache.path
+               $folderName = 'abcdefghijklmnopqrstuvwxyz012345678901234567890123456789';
+               $depth = (4000/57);
+               foreach (range(0, $depth-1) as $i) {
+                       $longPath .= '/'.$folderName;
+                       $result = $rootView->mkdir($longPath);
+                       $this->assertTrue($result, "mkdir failed on $i - path length: " . strlen($longPath));
+
+                       $result = $rootView->file_put_contents($longPath . '/test.txt', 'lorem');
+                       $this->assertEquals(5, $result, "file_put_contents failed on $i");
+
+                       $this->assertTrue($rootView->file_exists($longPath));
+                       $this->assertTrue($rootView->file_exists($longPath . '/test.txt'));
+               }
+
+               $cache = $storage->getCache();
+               $scanner = $storage->getScanner();
+               $scanner->scan('');
+
+               $longPath = $folderName;
+               foreach (range(0, $depth-1) as $i) {
+                       $cachedFolder = $cache->get($longPath);
+                       $this->assertTrue(is_array($cachedFolder), "No cache entry for folder at $i");
+                       $this->assertEquals($folderName, $cachedFolder['name'], "Wrong cache entry for folder at $i");
+
+                       $cachedFile = $cache->get($longPath . '/test.txt');
+                       $this->assertTrue(is_array($cachedFile), "No cache entry for file at $i");
+                       $this->assertEquals('test.txt', $cachedFile['name'], "Wrong cache entry for file at $i");
+
+                       $longPath .= '/' . $folderName;
+               }
+       }
+
        public function testTouchNotSupported() {
                $storage = new TemporaryNoTouch(array());
                $scanner = $storage->getScanner();
@@ -605,4 +647,83 @@ class View extends \PHPUnit_Framework_TestCase {
                        array('/files/test', '/test'),
                );
        }
+
+       /**
+        * @dataProvider tooLongPathDataProvider
+        * @expectedException \OCP\Files\InvalidPathException
+        */
+       public function testTooLongPath($operation, $param0 = NULL) {
+
+               $longPath = '';
+               // 4000 is the maximum path length in file_cache.path
+               $folderName = 'abcdefghijklmnopqrstuvwxyz012345678901234567890123456789';
+               $depth = (4000/57);
+               foreach (range(0, $depth+1) as $i) {
+                       $longPath .= '/'.$folderName;
+               }
+
+               $storage = new \OC\Files\Storage\Temporary(array());
+               \OC\Files\Filesystem::mount($storage, array(), '/');
+
+               $rootView = new \OC\Files\View('');
+
+
+               if ($param0 === '@0') {
+                       $param0 = $longPath;
+               }
+
+               if ($operation === 'hash') {
+                       $param0 = $longPath;
+                       $longPath = 'md5';
+               }
+
+               call_user_func(array($rootView, $operation), $longPath, $param0);
+
+       }
+
+       public function tooLongPathDataProvider() {
+               return array(
+                       array('getAbsolutePath'),
+                       array('getRelativePath'),
+                       array('getMountPoint'),
+                       array('resolvePath'),
+                       array('getLocalFile'),
+                       array('getLocalFolder'),
+                       array('mkdir'),
+                       array('rmdir'),
+                       array('opendir'),
+                       array('is_dir'),
+                       array('is_file'),
+                       array('stat'),
+                       array('filetype'),
+                       array('filesize'),
+                       array('readfile'),
+                       array('isCreatable'),
+                       array('isReadable'),
+                       array('isUpdatable'),
+                       array('isDeletable'),
+                       array('isSharable'),
+                       array('file_exists'),
+                       array('filemtime'),
+                       array('touch'),
+                       array('file_get_contents'),
+                       array('unlink'),
+                       array('deleteAll'),
+                       array('toTmpFile'),
+                       array('getMimeType'),
+                       array('free_space'),
+                       array('getFileInfo'),
+                       array('getDirectoryContent'),
+                       array('getOwner'),
+                       array('getETag'),
+                       array('file_put_contents', 'ipsum'),
+                       array('rename', '@0'),
+                       array('copy', '@0'),
+                       array('fopen', 'r'),
+                       array('fromTmpFile', '@0'),
+                       array('hash'),
+                       array('hasUpdated', 0),
+                       array('putFileInfo', array()),
+               );
+       }
 }
index 079af52545408e347b1ca812f479edca6dd394fb..28ef5ea72d05b551548e8ea3fee89015006937f7 100644 (file)
@@ -3,7 +3,7 @@
 // We only can count up. The 4. digit is only for the internal patchlevel to trigger DB upgrades
 // between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
 // when updating major/minor version number.
-$OC_Version=array(6, 90, 0, 2);
+$OC_Version=array(6, 90, 0, 3);
 
 // The human readable string
 $OC_VersionString='7.0 pre alpha';