Problem/Motivation
A D8 install can easily generate extremely lengthy file/directory names when caching Twig templates.
On some scenarios, the maximum length for a path might be limited by the OS:
- Windows has a maximum path length of 260 characters. Can read more here.
- If you are in Linux and have the filesystem where you have the site mounted using eCryptfs and its configured to encrypt filenames as well as the file content you will experience this same issue. You can read a little about this limitation here.
To reproduce this issue on Windows, add the following to settings.php
.
$settings['file_public_path'] = 'sites/default/files/0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-01'; // That's a 255-char dir name.
Proposed resolution
Update as of #144 going with option #3
Option #3: Trigger a requirement error on windows if the Drupal root is deeper than 100 characters. Use our existing base64 hash and hmac functions so the hashes are half as long to start. Truncate the human-readable template name portion and hash portion of the to a maximum length so the directory names can never be longer than 51 characters. The cache file name itself has already been shortened to 47 characters using the bas64 hmac in the split-off child issue #2830596: MTimeProtectedFastFileStorage::getFullPath() creates really long filenames unnecessarily
Update: as of #39, options #2 is the preferred solution.
Option #1: Use the Unicode path prefix (\\?\
) on Windows to avoid the 260 character limit (pushes the limit to around 32k which is well above Linux's limit of 4k characters). Unfortunately, PHP's support of these pathnames is limited. (see #16) which would require a much more disruptive fix.
Option #2: Use shorter hashes while retaining the "uniqueness" of these directory and file names. However, the filename hash contains the filemtime()
of the containing directory. If, for example, file uploads were compromised and malicious code added to a cached Twig template, the containing directory's filemtime
would change and the hash would not match. Using shorter hashes could potentially increase the risk of a compromised file still passing the hash test. (Security review requested).
Also, option #2 does not solve the underlying problem, but hopefully gives us some breathing room. Currently, there are two 64-character hashes in each cached Twig template.
Remaining tasks
As of #12:
- not needed since we're using option #2:
FileStorage::unlink does not work with the Unicode prefix - Needs security review to ensure that shortened hashs still give enough "uniqueness" for MTimeProtectedFastFileStorage
- Needs tests to assert that generated files do no exceed a (somewhat arbitrary) limit
- Done:
Add hook_requirements
to warn users when installing Drupal on Windows with a long path name.
User interface changes
Adds a new warning when installing Drupal on Windows at a path > 100 characters.
API changes
With option #2, none.
Data model changes
None.