Issues

ZF-11911: Long cache ids cause the file backend to produce too long file names

Issue Type: Bug Created: 2011-11-25T11:10:08.000+0000 Last Updated: 2012-02-26T18:43:11.000+0000 Status: Closed Fix version(s): Reporter: David Fuhr (davidfuhr) Assignee: Marc Bennewitz (private) (mabe) Tags: - Zend_Cache

Related issues: Attachments:

Description

We are generating our cache ids partly dynamic. In some cases they can be very long. If the get too long the file backend fails saving them as it creates the file names using the ids.

Different file systems have different length limits: http://en.wikipedia.org/wiki/…

This could be fixed on application level, but i believe it is better to fix this on framework level as the limitations on length are backend specific.

I've created a patch against the trunk (r24565) which introduces a new config option ("max_file_length"). This enables automatic file name shortening using the hashed cache id (to minimize the risk of id collisions). The option is disabled by default to keep BC. I suggest to set it to 255 as this seems to be the limit for most of the common file systems (ext2/3/4, ntfs, jfs, xfs, btrfs, ...).

A test case to reproduce the problem is also included.

<pre class="literal">
### Eclipse Workspace Patch 1.0
#P ZendFramework-trunk
Index: library/Zend/Cache/Backend/File.php
===================================================================
--- library/Zend/Cache/Backend/File.php (Revision 24565)
+++ library/Zend/Cache/Backend/File.php (Arbeitskopie)
@@ -96,6 +96,7 @@
         'hashed_directory_umask' => 0700,
         'file_name_prefix' => 'zend_cache',
         'cache_file_umask' => 0600,
+        'max_file_length' => null,
         'metadatas_array_max_size' => 100
     );
 
@@ -863,6 +864,15 @@
     {
         $prefix = $this->_options['file_name_prefix'];
         $result = $prefix . '---' . $id;
+        
+        if (null !== $this->_options['max_file_length']) {
+            $path = $this->_path($result);
+            if (strlen($path . $result) > $this->_options['max_file_length']) {
+                $idHash = md5($result);
+                $result = substr($result, 0, $this->_options['max_file_length'] - strlen($path) - strlen($idHash)) . $idHash;
+            }
+        }
+        
         return $result;
     }
 
Index: tests/Zend/Cache/FileBackendTest.php
===================================================================
--- tests/Zend/Cache/FileBackendTest.php    (Revision 24565)
+++ tests/Zend/Cache/FileBackendTest.php    (Arbeitskopie)
@@ -120,7 +120,20 @@
         $res = $this->_instance->save('data to cache', 'foo', array('tag1', 'tag2'));
         $this->assertFalse($res);
     }
-
+    
+    /**
+     * Tests if long file names are prevented
+     *
+     * Depending on the FS there are different limits for the maximum file
+     * name length. Most FS' limit is 255 bytes or characters.
+     *
+     * @link <a href="http://en.wikipedia.org/wiki/Comparison_of_file_systems#Limits">http://en.wikipedia.org/wiki/…</a>
+     */
+    public function testSaveWithVeryLongCacheId()
+    {
+        $cacheId = str_pad('', 300, 'a');
+        $this->_instance->setOption('max_file_length', 255);
+        $res = $this->_instance->save('data to cache', $cacheId);
+        $this->assertTrue($res);
+    }
 }
-
-

Comments

Posted by Adam Lundrigan (adamlundrigan) on 2011-11-30T14:06:53.000+0000

You will need to sign and submit a CLA before we can include your suggested fix in Zend Framework. See here: http://framework.zend.com/wiki/display/…

Posted by David Fuhr (davidfuhr) on 2011-12-21T08:39:23.000+0000

CLA is singed end sent.

Posted by Marc Bennewitz (private) (mabe) on 2012-01-08T15:29:44.000+0000

The way you go doesn't work because it's changing the cache ids and methods like getIds no longer works as expected.

You can simply hash the cache id in your application before calling the cache.

On ZF2 you can get information about the backend how long the key can be.

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts