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:
Addhook_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.
Comment | File | Size | Author |
---|---|---|---|
#218 | interdiff.txt | 888 bytes | xjm |
#218 | twig-2606772-218.patch | 5.68 KB | xjm |
#210 | 2606772-error.png | 28.63 KB | mikeker |
#205 | 2606772-187-205.interdiff.txt | 2.77 KB | mikeker |
#205 | 2606772-205-shortened-hashes.patch | 5.76 KB | mikeker |
Comments
Comment #2
marcingy CreditAttribution: marcingy at Examiner.com commentedI can't recreate on a windows 10 install using xampp so this doesn't seem to be general d8 issue. Please provide more info about php etc
Comment #3
hatuhay CreditAttribution: hatuhay commentedInstallation done with
https://bitnami.com/redirect/to/75604/bitnami-drupal-8.0.0.rc2-0-dev-windows-installer.exe
Running under Apache and PHP 5.5.30
Reinstall Drupal 8 to reproduce issue.
With fresh installation, warnings still appearing, but site is up.
3b9a7135_block--system-messages-block.html.twig_1b89fea44fd124de67ee5957081934a6aa2d86b3295c1a8dd2211f15a8f19efb
folder is empty and temporary twig files that cannot be renamed, remain on\sites\default\files\php\twig
This is the complete error message:
Warning: rename(sites/default/files/php/twig/.f4c86f3b64,sites/default/files/php/twig/3b9a7135_block--system-messages-block.html.twig_1b89fea44fd124de67ee5957081934a6aa2d86b3295c1a8dd2211f15a8f19efb/f0f090b909fe6a121bae2b9d5538964c7899b4a3f361bdd3c517cc83769742fc.php): No such file or directory en Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage->save() (linea 91 de C:\Bitnami\drupal-8.0.0.rc2-0\apps\drupal\htdocs\core\lib\Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage.php).
After installing same modules first time, site crashed.
Last module enabled admin_toolbar and admin_toolbar_tools.
I am leaving office now,so no more time for testing tonight, but apparently:
Comment #4
hatuhay CreditAttribution: hatuhay commentedComment #5
star-szrI seem to recall someone mentioning an issue on Windows with file paths that are over ~255 characters, and both of those templates would be (pardon the mixed slashes, just copying and pasting things together from your error messages):
C:\Bitnami\drupal-8.0.0.rc2-0\apps\drupal\htdocs\sites/default/files/php/twig/3b9a7135_block--system-messages-block.html.twig_1b89fea44fd124de67ee5957081934a6aa2d86b3295c1a8dd2211f15a8f19efb/f0f090b909fe6a121bae2b9d5538964c7899b4a3f361bdd3c517cc83769742fc.php
259 characters
Comment #6
star-szrClosed #2604486: Error during install (Twig unable to rename a file) as a duplicate of this issue. Thanks for the report!
I'm thinking the tests would ensure our cache filepaths end up as a reasonable length.
Comment #7
star-szrAnd I think #2587101: MTimeProtectedFastFileStorage (and likely others?) can generate paths that are too long for Windows was the first report but this now has a bit more info.
Comment #8
mikeker CreditAttribution: mikeker as a volunteer commentedThe root issue is that MAX_PATH on Windows is 260 chars. That page indicates that prepending
\\?\
to an absolute path would remove the limit, but it has downsides such as not resolving..
and.
within the path.Funny, I was just starting to work on #2587101: MTimeProtectedFastFileStorage (and likely others?) can generate paths that are too long for Windows! I'll do that in this issue instead since it has more eyeballs on it.
Removing the Needs tests tag since we don't currently have Windows testing infrastructure.
Comment #9
star-szr@mikeker Thanks! I know we can't *really* test this but it's a nasty enough bug that it should have some sort of coverage I think, even if that coverage is just asserting "we don't generate super long paths".
Comment #10
mikeker CreditAttribution: mikeker as a volunteer commented@Cottser, the problem is we can limit our paths to whatever length we want, but if the site is installed at
c:\very\very\very\long\path
we'll end up over MAX_PATH anyhow. So there's not really a number we can pick to completely avoid this bug.I guess we could assert that we never have a path longer than 257 so that you could always install Drupal at
c:\
and it'll work... OK, you just watched me talk myself out of my own position. :)I think the real solution is to introduce a utility class or trait that converts paths on Windows to use the
\\?\
format and use that anyplace we usemkdir()
. But that might be too disruptive at this point. I'll try and figure out a fix for this case and we can work on generalizing it later.Comment #11
star-szrMy thought was moreso that we could truncate those hashes that we are currently generating for the Twig cache filenames to something shorter but still with enough uniqueness, and to test it do something like compile all templates and ensure none of the paths are over a certain (yes, arbitrary) length. Just ideas.
What you're talking about sounds more like it would live in or near MTimeProtectedFastFileStorage (generically useful) and is probably the proper fix. But right now D8 seems too easy to break on Windows and I'd like to fix that sooner than later, even if it's somewhat of a band-aid.
Comment #12
mikeker CreditAttribution: mikeker as a volunteer commentedFirst stab at the fix for this... FileStorage.php is a little funky so this has some cleanup in it for parts that I was already touching.
Still to do:
FileStorage:::unlink()
doesn't work correctly on Windows as\DirectoryIterator
doesn't handle Windows Unicode paths.Note that this fix relies on the path to Drupal's temp dir being less than 260 characters.
Finally, this is really a workaround a limitation in PHP -- many file functions fail with Unicode paths (those that include the '\\?\' prefix which allows us to get past the 260 char path limitation). I haven't investigated any PHP bug reports regarding this yet.
Comment #13
mikeker CreditAttribution: mikeker as a volunteer commentedAdded issue summary and tagging for RC consideration.
Comment #14
joelpittetlooks like a decent solution for an unfortunate problem
camelCase, because member variable.
leave oxford comma
Comment #15
joelpittetSorry for just nitpicks but you were mentioning how you wanted to use camelCase for OOP and I believe this is the place where we've been using it.
It would be nice to get someone else on windows who runs into this problem to give this a test as well to see if it resolves.
Comment #16
mikeker CreditAttribution: mikeker as a volunteer commented@joelpittet: Nitpicks are always welcome! Especially as we were just debating coding standards in IRC... :)
I've been playing with this a bunch over the past few days. I think the best solution is going to be a half-solution/half-workaround:
c:\temp
orc:\Mike\temp
), and then moves them to their final location(Edit: specified "on Windows" in the second bullet).
We do this complicated two-step because most PHP file functions on Windows do not support the long-path format prefixed with a '\\?\'. As far as I can tell, only
work correctly with '\\?\' prefixed long paths. Which leaves us moving directories from a long-path to a short-path, manipulating them there, and then moving them back. Ugly, ugly, ugly... But I think it'll work.
It looks like PHP 7.x has support for Unicode paths, which should fix this problem as well. I haven't had a chance to try -- if anyone has a Windows setup with PHP 7.x on it, please report back your findings!
Comment #17
greggmarshallI tried the patch on a Drupal 8.0.0 site that started on an Acquia Cloud free instance and was copied down using Dev Desktop (November 22, 2015 release). It didn't seem to resolve the issue.
That was with PHP 5.6, so I switched to PHP 7.x and that didn't help the problem.
My temporary directory is set to C:\temp so it is short. The site location is better than if it were in my user directory at C:\drupal\drupalsites\bluedroprealty-dev\docroot, The resulting path that generates the error is
C:/drupal/drupalsites/bluedroprealty-dev/docroo/sites/bluedroprealty.dev.dd/files/php/twig/.942de757b6,sites/bluedroprealty.dev.dd/files/php/twig/53c3541f_status-messages.html.twig_4d23d10f88a68b61425c7d86bd20befdf23f8c3894a63344ee4d0d903cf03069/8f90a9801d2baa495aa89536da1d39bfb0f1ba3ca19ced5e55749b4770dd0b45.php which is roughly 314 characters long.
Right now the only work around I have figured out is disable twig caching.
Comment #18
hass CreditAttribution: hass commentedI have the same problem.
Why is the filename not just a uuid? It is unique and short.
Comment #19
joelpittet@hass to help find the compiled PHP for debugging I believe was the reason. Otherwise you'd have to search for the comment in the files.
Comment #20
star-szrTo my knowledge there is currently: a hash for the service container to take deployments into account, a filename for easier debugging like @joelpittet said, and then a hash. And that's just the folder name. I still think we should consider shortening those last two hashes, not sure what the math is on if we would have a collision but seems unlikely with all the other data already in the path.
Comment #21
hass CreditAttribution: hass commentedCan you decode these hashes to useful names or how does this help with debugging?
Comment #22
star-szrThe status-messages.html.twig is the useful part (see a few posts up for an example file name).
Comment #23
hass CreditAttribution: hass commentedThat does not really answer my question.
Joel said we need the many hashes for debugging reasons. I see nothing useful from these hashes or can these decoded to something useful?
Otherwise we could just remove all hashes and use one uuid only.
This makes the filenames a lot shorter and already *unique* without adding ~5 useless hashes. Uuids are unique where random hashes may not as I know.
Comment #24
joelpittet@hass, the 3 tools I use, phpstorm, sublime, atom all have ways of fuzzy searching file names. Which allows me to get to the file quickly, which is why it helps with debugging.
Comment #25
star-szr@hass - @joelpittet never said the hashes were for debugging. Please don't put words in people's mouths. He was saying the twig template file name is good for debugging and never mentioned hashes.
To start with we used the same structure as Twig itself I'm pretty sure, and we've just tweaked it from there.
If we remove all hashes things will break badly.
Comment #26
hass CreditAttribution: hass commentedYou spread fear that thing may break, but can you prove this? Uuids are unique, nothing can fail.
And well it is possible that twig not on drupal has the same bugs.
Comment #27
star-szrThe uuid concept you're talking about hasn't so far been used in any Twig caching I've seen, whether ours or upstream. UUIDs might be worth considering over hashes, but there's more at play here.
Comment #28
catchCan we split bits of the filename out to sub-directories?
Then we'd have shorter individual filenames without losing any information.
Comment #29
greggmarshall@cottser, I understand the concerns about making changes, but as it is there is a significant operating system (at least for development) that is broken now. There has to be some way to make the file names a reasonable length so Windows doesn't choke.
Comment #30
joelpittetTemplate suggestions would make the filenames quite long and less deterministic for size. So unless we do the
'\\?\'
magic. I'm willing to concede the nice for debugging file names for a quick fix and we can add them back when we or MS fix the directory length underlying problem.I'm a bit wary about the UUID's collision points too and it's more risky to truncate those without finding out how unique we really need them. But the UUIDs aren't the problem, it's Windows directory length, the UUIDs and file names are just symptoms.
Does that sound like a decent trade?
Comment #31
star-szr@greggmarshall yes there definitely is and don't worry we understand it's broken for many people on Windows.
I am wondering why the path you shared seemingly has two sites/bluedroprealty.dd/files/php/twig in it, what's the deal with that? #17
C:/drupal/drupalsites/bluedroprealty-dev/docroo/sites/bluedroprealty.dev.dd/files/php/twig/.942de757b6,sites/bluedroprealty.dev.dd/files/php/twig/53c3541f_status-messages.html.twig_4d23d10f88a68b61425c7d86bd20befdf23f8c3894a63344ee4d0d903cf03069/8f90a9801d2baa495aa89536da1d39bfb0f1ba3ca19ced5e55749b4770dd0b45.php
I really don't want to lose the filenames in the cached Twig templates especially if we're waiting for MS to fix something in order to get it back :(
This is roughly what I'd propose, length of hashes can obviously be increased if we want, I went with the same length as the service container hash for this example:
Before
After
Comment #32
mikeker CreditAttribution: mikeker as a volunteer commentedThe hash used for the filename is necessary. It includes the containing directory's mtime() so if the files dir is compromised and someone replaces a rendered template the hash will fail since the mtime would have changed. (See Drupal/Component/PhpStorage/MTimeProtectedFastFileStorage.php:112).
I believe the hash in the directory name is there for uniqueness and may be replaced with a UUID. Need to double-check, though. Seems to me we could either use a shorter hash (SHA1 is 40-char vs 64) or just use the first, say, 20 chars of the hash and assume that's good enough (a la Git commit references).
Regardless, even with crazy template suggestions, removing the template name from the path only gets us so far. A quick option would be to limit the amount of the template name included which should give you enough for fuzzy matching in IDEs.
The main issue, imo, is two 64-character hashes eating up nearly half of Windows (pathetically small) MAX_PATH.
Comment #33
greggmarshall@costter, I'm not sure but you are right it appears to be two paths separated by a comma. I just did a quick copy and paste, perhaps I grabbed more than I had anticipated when I tried to skip the rest of the error message.
Comment #34
star-szrYup.
Comment #35
catchSo why not:
Before:
After:
53c3541f/status-messages.html.twig/4d23d10f88a68b61425c7d86bd20befdf23f8c3894a63344ee4d0d903cf03069/8f90a9801d2baa495aa89536da1d39bfb0f1ba3ca19ced5e55749b4770dd0b45.php
Comment #36
star-szr@catch I think because that doesn't solve the problem, it's not the filename length that's the issue it's the total length of the path (as far as I understand it anyway).
Comment #37
catchOh.
Comment #38
greggmarshallThat is my understanding also.
This also becomes an issue if you put your Drupal installations (even D7) inside subdirectories inside your windows "home" directory. The aggregated directories plus some really long file names for files (we have some PDFs with 150-200 character file names) puts you over the limit.
Comment #39
mikeker CreditAttribution: mikeker as a volunteer commentedFrom #35 and #36:
That's correct, the total path length must be <= 260 chars.
In #31, @Cottser says:
Agreed with the filenames. To be fair, MS fixed the issue ages ago (Windows NT, I believe) but the MAX_PATH constant remains for backward compatibility. Using the UNC-ish '\\?\' prefix (which allows for longer path and Unicode chars) would allow us up to 32k chars in path names. However, in PHP, only the four functions listed in #16 support those paths (as far as I can tell -- documentation on this is scarce). I haven't yet found an issue in the PHP buglist that directly addresses this and don't relish the idea of diving into PHP source code...
It should be pointed out that paths with Unicode characters will likely suffer from this bug as well, regardless of the path length. As far as I know, Unicode support on Windows was added only with the '\\?\' prefix. It would be great if someone could verify that...
Attached is a patch that shortens the hashes used to 10 chars and truncates the template name to 30 chars. This would help kick this problem another 100-odd characters down the road and the "proper" solution (whatever that may be) can be done in a followup. Let me know what you think about semi-solving this quick vs. solving this right.
In #38, @greggmarshall says:
Unfortunately, this patch may not help you much if you have really long filenames for user-generated content. Until a real solution is found it would be best if you could truncate those names to a predictable length and arrange your directory structure so that paths don't exceed 260 chars.
Background: the 10 and 30 char limits are somewhat arbitrary. 10 chars of a SHA256 gives us a trillion unique options which seems plenty to me to avoid collisions (git commit mentions generally use less). But since this is tweaking a security feature which hardens Twig caching, I would appreciate input from someone with a better security perspective than mine (tagging as such).
Comment #40
mikeker CreditAttribution: mikeker as a volunteer commentedComment #41
mikeker CreditAttribution: mikeker as a volunteer commentedUpdated IS with security review details.
Comment #42
catchI was going to suggest we fork the implementation for Windows, but:
- we don't have automated tests for windows, so it'd be completely untested, as opposed to changing the implementation for everyone (even if we can't verify the windows bug is fixed)
- we should not change service definitions based on Windows or not, because of #2614202: CoreServiceProvider::registerUuid() assumes all environments have the same functions available - not that we'd necessarily do that here, but reminded me of that issue anyway.
Comment #43
mikeker CreditAttribution: mikeker as a volunteer commented@catch, The patch in #12 kinda forks the Windows implementation of
MTimeProtectedFastFileStorage
. The hope was to keep the API ofMTimeProtectedFastFileStorage
the same and handle Windows oddities internally. Is that what you are/were thinking?Comment #45
star-szrI agree we should change the Twig cache filenames for everyone, not just windows.
I'm wondering (if it's feasible) if we should throw an exception in MTimeProtectedFastFileStorage on windows if we detect the filename is above the limit? Or is that a bad idea?
Comment #46
hass CreditAttribution: hass commentedHow should i handle such an exception? :-)
Comment #47
star-szrIt would just be better than the current message is what I'm getting at. This is talking about fixing Twig but MTimeProtectedFastFileStorage is used by other things, not just Twig.
Comment #48
mikeker CreditAttribution: mikeker as a volunteer commentedAs @Cottser points out,
MTimeProtectedFastFileStorage
is used for more than just Twig caching. As such we can't trim the template names there as there are valid cases where the "name" would exceed 30-chars. That was causing some of the test failures.The attached patch removes the filename trimming and makes the hash max length a protected property of
MTimeProtectedFastFileStorage
andTwigPhpStorageCache
.Sorry, I mangled things a bit and lost the easy interdiff (#2629240: Overwriting file-cached keys on Windows results in an access denied error was causing a lot of false failures). But it's a small enough patch that I'm hoping reviewers can overlook that... :)
Comment #50
mikeker CreditAttribution: mikeker as a volunteer commentedugh... Forgot the fixes to the tests.
Comment #51
star-szrThanks @mikeker! This is looking very good to me, maxlenHash could maybe be hashMaxLength or something but that's probably about all I'd change and quite minor in the end. I'm not sure what kind of tests we should add beyond the tests that have been updated.
As far as I can tell this won't pose any problems for sites running in production, as soon as they see this new code they should switch to (and generate if necessary) the shorter directory/file names.
Seeing these nice tidy short names I almost wish we could add the extension (theme/module name) to the directory but maybe later ;)
Comment #52
greggmarshallOne question, on line 86 is this line
$expected_filename = $expected_directory . '/' . substr(hash_hmac('sha256', $name, $this->secret . $directory_mtime), 0, 10) . '.php';
Is the 10 in the substr supposed to be $maxlenHash (or whatever it gets changed to)? Right now it looks like it is hard coded to be 10, which is what the constructor sets maxlenHash to.
Comment #53
star-szr@greggmarshall good question but that's in a test so I think it's fine.
Comment #54
mikeker CreditAttribution: mikeker as a volunteer commentedFrom #52:
@Cottser is correct, assuming you're referring to this line:
(Edit: Dreditor code snippet was all messed up...)
The 10 is checking that the TwigEnvironment class uses 10 chars as it's max hash length. If someone were to change that value in TwigEnvironment, they would need to update the test. If they were to inherit from TwigEnvironment, they would want to write a different test for that child class using whatever value they specify in the child class.
From #51:
I was following the pattern of
numThings
. Also I had amaxlenFilename
in there until I realized that was messing up all the cache tests and they read better when there were two of them. Anyhow, happy to change it you feel it should be or it doesn't keep with Drupal's naming scheme. Feel free to bump back to NW if you think it should be changed.Comment #55
mikeker CreditAttribution: mikeker as a volunteer commentedAdded updated about using shorter hashes to the IS. Also updated remaining tasks.
Comment #56
drupalfan2 CreditAttribution: drupalfan2 commentedThis problem still seems to be part oft drupal 8.0.1.
What can I do?
Comment #57
mikeker CreditAttribution: mikeker as a volunteer commented@DrupalFan2: at this point we need manual testing on Windows that the latest patch (currently #50) works as advertised. (Note this doesn't remove the problem -- paths in Windows can still go well over 260 chars -- it just makes it less likely to happen in a normal install). It has to be manual testing because we don't have an automated system for testing patches against Windows at this point.
It was suggested that we add automated tests to ensure that Drupal doesn't generate paths longer than a (somewhat arbitrary) limit of 240 chars. That would allow Drupal to be installed in a path such as
c:\dev\mysite
and still work. That has not been done at this point and I'm not sure if it is required to get this patch accepted.This issue also needs signoff from a security perspective that the shortened hashes do not remove the protection created by MTimeProtectedFastFileStorage.
Comment #58
acrosmanThe patch in #50 appears to be working in my current context of a shared folder on a linux virtual box on a Windows host. I agree that a review by the security team would be reassuring.
Comment #59
david_garcia CreditAttribution: david_garcia commentedThe patch looks perfectly good and tests OK.
Just a question... if hash length is defaulted to 10, why are we using the 64 character length SHA256.
Something that already gives us shorter out of the box hashes might be a better option such as MD5 (32 characters)
And to reduce the probablity of collisions due to just taking the first 10 characters, there are other approaches.
I had to resort to something similar for cache keys in the supercache module, and this is what I ended up doing to have shorter hashes with a reduced collision probability:
The idea is taken from here.
http://stackoverflow.com/questions/3763728/shorter-php-cipher-than-md5
Comment #60
dawehnerwhat about just putting that as default value on the property itself? It would be great to somewhere document what we assume for which length as part of the directory name.
Comment #61
mikeker CreditAttribution: mikeker as a volunteer commentedSorry for the delay getting back to recent comments. Based on @david_garcia's suggestion in #59, setting this back to NW.
I have some concerns about the S.O. linked to in that post. Specifically the warning on the PHP base_convert doc page that says:
In very quick testing, this warning seems to be borne out:
results in:
It seems odd that the conversion to base-32 results in a number that's 12 digits shorter than base-31 or base-33. Also, shouldn't we convert to base-36 (0-9a-z) to full utilize the characters we can use in the filesystem?
re: #60: yeah, I should've done that originally. Will do in the next patch... Thanks, @dawehner!
Comment #62
mikeker CreditAttribution: mikeker as a volunteer commentedComment #63
mikeker CreditAttribution: mikeker as a volunteer commentedThe attached patch addresses #60 and #51.
From #59:
My main concern is that MD5 (and SHA1) are broken hashing functions, but SHA256 is not (yet). Using 40 bits of a 128 bit hash has the same number of collision possibilities as using 40 bits of a 256 bit hash. But hacking the input string to return the same hash is harder (currently impossible, but who knows for how long).
I do like the idea of converting whatever hash into base-36 so as to fully use the 0-9/a-z character range we have available. But that only drops a 64-character hex string to 54 characters, or a 32-character string to 27. (Worst case scenario -- often ends up being a few characters less depending on the numeric value of the hex string). In playing with this idea, I ran into the fact that base_convert only handles about 14 digits decimal, which is 12 digits hex, adding complexity to the hashing system.
Perhaps the compromise is to truncate to 48 bits (12 hex characters) and convert to base-36 to shave off another character or two?
Comment #64
david_garcia CreditAttribution: david_garcia commentedI think current implementation is more than good.
I've also tested by using this patch as part of our build process without issues so far. Twig cache paths are well bellow the 256 limit with this patch, the longest one's I have seen are between 100 and 125 characters long.
Comment #65
alexpottDid we consider making this a constant on PhpStorageInterface? And documenting that this is used to keep total file path lengths small enough for windows. This would mean if we decided to only support some new version of windows that supported large paths we'd just have one constant to update. It also seems to me that this maxHashLength is due to the implementation. So something feels off here. What we do for cache keys - where the max length is 255 is only hash once the path is longer than. I'm wondering why we don't take a similar approach here and determine the path length of the thing we're about to write and do something if it is too long.
I'm pondering what is going to update on existing sites when they apply this patch. Should there be a hook_update_N to clear the existing twig cache files... and what does that mean for multiple web heads.
Comment #66
alexpottAlso I think we should add a hook_requirements check for windows and check the depth of the install path and issue a warning or something.
Comment #67
david_garcia CreditAttribution: david_garcia commentedI don't like this for paths because these paths might be relative to something and be mounted in Symlinks or the like. So from my application I might see that a path is < 255, but from somewhere else these path might be longer (or shorter).
Again, this is not ideal for the same reason. The path that my PHP application is seeing might not be the true path to the files. Still, what will the warning limit be? The truth is that even with the current patch it is not 100% sure that the max path length will be never exceeded, it just reduces - a lot - the probablity of that happening.
Actually windows supports long paths, even longer than *nix. It's not the version of Windows that matters, it's the PHP usage of the Windows API's.
I believe we should not be that picky and get this fixed ASAP because anyone running D8 on Windows is getting warnings out of the box. After all there are legacy - and not so legacy - parts in core that have much much more formal issues than the ones being raised here. If these warnings were being thrown on *nix I am sure that this issue would have been raised to critical a long time ago.
Comment #68
mikeker CreditAttribution: mikeker as a volunteer commented@alexpott, thank you for the review! Some comments to add to what @david_garcia wrote in #67:
Agreed, the documentation was missing. I've added that to this patch.
No, I didn't consider putting it in PhpStorageInterface -- I felt that was putting it at too abstract a level since it was only used in one implementation of that interface.
I don't think that works here.
MTimeProtectedFastFileStorage
is using the directory'smtime()
as part of the hash to ensure a file hasn't been changed maliciously. It would add a lot of complexity to determine the realpath to the filie and only hash if we're past some limit.If a
drush cr
can be assumed during the update, there will be no interruption and stale files will not be left behind in the /files/php/twig directory. If there is no cache-rebuild, then the next request will be a cache-miss for the Twig files and they will be regenerated alongside the old version of the file. From the end-user's perspective, there is no change. From the developer's perspective, we will leave old cache files lying around until the next cache-rebuild.As to multiple web heads, this is starting to get above my pay-grade... :)
I believe it won't make any difference -- if they have it working for multiple web heads to pull from a single file cache, then it should work the same as the single web head.
Comment #69
mstrelan CreditAttribution: mstrelan commentedTypo (x2):
fxiedfixedComment #70
mikeker CreditAttribution: mikeker as a volunteer commented@mstrelan, thank you for catching that. I fxied it... :)
Removing the Needs Tests tag since there are tests and there isn't a way to add a test that we don't go past 260 characters since we'll never know how deep in the file system Drupal is installed.
Comment #71
alexpott@mikeker we can know exactly how deep drupal is installed - php has a
realpath
function and this issue should be adding a warning to windows user once DRUPAL_ROOT is over 10(or whatever people think is best) deep.Comment #72
mikeker CreditAttribution: mikeker as a volunteer commented@alexpott, Fair enough, re:
realpath
. We need to keep in mind that the warning will have to be somewhat vague as we have no idea how long Twig template names will be. Currently the longest in core (excepting test templates) is 48 chars (config_translation_manage_form_element.html.twig). The cached version of that template, by default and with this patch, would reside insites/default/files/php/0123456789_config_translation_manage_form_element.html.twig_0123456789/0123456789.php
(109 chars).Caveats:
default
can be replaced withsubdomain.example.com
, with template suggestions the filename length can grow substantially, and contrib could add very long template names. (I suppose contrib could also shorten those long template names.)I'll add a install warning if
realpath
ofDRUPAL_ROOT
is > 100 chars. How does that sound? Is there any possible way to add a test for this?Comment #73
mikeker CreditAttribution: mikeker as a volunteer commented+= "on Windows."
Comment #74
mikeker CreditAttribution: mikeker as a volunteer commentedI've added an install warning if
realpath(DRUPAL_ROOT)
is greater than 100 characters on Windows only:Since this adds new strings for translation, I assume that means it's bumped to 8.1.x? (Not sure so I'm not changing it for now).
Comment #75
joelpittet8.1 yes. Got find a vm to test but 100 seems reasonable considering the core template + suggestions
Comment #76
mikeker CreditAttribution: mikeker as a volunteer commented@joelpittet, thanks for clarifying the 8.0.x vs 8.1.x.
Sorry should've mentioned that I tested this briefly on Windows10 running Apache 2.4.4, PHP 5.5, and MySQL 5.6. Two scenarios: one with Drupal root at 100-chars deep and another at 101-chars. Verified the warning show at 101 chars, and does not at 100 chars, and the install completes without issue in both situations.
With the 101-char deep install, the longest Twig cache path I saw generated was 204 chars long:
That leaves us with 56 characters of breathing room to handle a long domain name replacing
default
or some crazy template suggestion strings. I think 100 chars is a good cutoff for the warning.Comment #77
mikeker CreditAttribution: mikeker as a volunteer commentedComment #78
xjmComment #79
david_garcia CreditAttribution: david_garcia commentedComment #80
david_garcia CreditAttribution: david_garcia commentedRTBC again
Comment #81
alexpott#65 still has not been addressed. I understand the reasons given #68 but they should still be a class constant rather than a property. It is not has if this is something that should be changed mid request.
Comment #82
david_garcia CreditAttribution: david_garcia commentedSlightly different approach. I can think of a few places - at least in contrib - that would benefit from using this short hash thing.
Comment #83
alexpottI like this new approach! I think we should add comments to places where it is used as to why we're doing it here.
Drive by code style review...
Lines end with a space.
Need a new line before the @return and it needs a description.
Comment #84
david_garcia CreditAttribution: david_garcia commentedAdressed everything from #83.
Was not sure what to test, just made sure that the method does what it has to do - not how it does it.
Let's see what the testbot thinks about it.
Comment #86
alexpottFixing the test...
Comment #87
david_garcia CreditAttribution: david_garcia commentedTested this manually, everything look OK.
Thanks!
Comment #88
mikeker CreditAttribution: mikeker as a volunteer commentedThis is problematic:
base_convert
loses precision with large numbers (see #61). I was OK with it forMTimeProtectedFastStorage
because we only needed "good enough" security there. But by putting this inCrypt
, we're implying that this is good for use cases that require high precision.Maybe we can mitigate the above concern with documentation? I think we should warn users of this function that a shortened hash is at greater risk of collisions. Though it is minimal at the default $length, this function shouldn't be used to hash passwords, for example.
Comment #89
david_garcia CreditAttribution: david_garcia commentedExcept for the weird base 32 case, I'm not sure we are really affected in this use case by the limited precision of floats in PHP.
Agreed.
Comment #90
mikeker CreditAttribution: mikeker as a volunteer commentedComment #91
mikeker CreditAttribution: mikeker as a volunteer commentedAttached patch adds some docs and change the
$name
parameter to a more generic$data
since this function is no longer limited to Twig caches.Comment #92
mikeker CreditAttribution: mikeker as a volunteer commentedAlso
goes above my pay-grade. :)
I'll look into it further, but if anyone has any insights, I would love to hear it.
Comment #93
david_garcia CreditAttribution: david_garcia commentedGreat!
Comment #94
alexpottTagging with "rc target triage" to discuss with the other core committers about whether we should commit this to 8.1.x. In my mind this bug has work arounds but it might be very hard to work out what you need to do. And just installing a new module might cause the bug on an otherwise working site.
Comment #95
webchick@effulgentsia and I reviewed this patch and scanned the issue. Overall, we are comfortable promoting this to a formal rc target, but neither of us were confident in committing it outright without extra time to do a deep dive, given that 8.1.0 is less than a day away.
So removing the "triage" part of the tag, but leaving RTBC for now.
Comment #96
effulgentsia CreditAttribution: effulgentsia at Acquia commentedI'm not comfortable committing this line. This is the line for which this issue is tagged "needs security review", and in my opinion, 10 characters (
40 bits~50 bits with base36) is too little protection against arbitrary code execution on the server. Leaving at RTBC though in case another committer disagrees and wants to commit anyway.This hash doesn't have a security requirement, so I'm fine with this one being shortened. But, why do we need a hash here at all? Can we shorten it to 0?
Can we control for this, like only use the debug-friendly filename if it's shorter than say 32 (or whatever arbitrary number), but if the template name is longer, then use a 32 character hash instead (or 21 characters from the template name and a 10 character hash)? I think all core template names are less than 32, and for a few contrib ones that are longer, I don't think the loss to debuggability is all that bad, since the original name is in the contents of the file and can be found in IDEs that way. Also if the cutoff number is a setting, then people wanting to debug those long template names can increase it, especially if they're not on Windows. Note that I think we can remove the ".html.twig" portion from the name too, since that's 10 extra characters for no benefit.
Comment #97
alexpottre #96.1 @effulgentsia isn't the protection on offer not about the length but about hashing the mtimes?
Comment #98
effulgentsia CreditAttribution: effulgentsia at Acquia commentedRe #97, yeah that's a fair point. But the length matters against a brute force attack. Assuming the server has a file upload vector, could someone attempt a quadrillion uploads in order to eventually succeed? I guess I could be convinced that that's sufficiently low risk, but per #96.2 and #96.3, is it a necessary one?
Comment #99
effulgentsia CreditAttribution: effulgentsia at Acquia commentedFrom #96.2:
Oh, I see now, that's a hash of the classname, not the template name. And you can have a situation of 2 different templates with the same template name (e.g., from different themes) co-existing on the same site. So yeah, we do need a hash there. 10 characters seems more than fine to protect against that collision, since in the 1 in quadrillion case of such a collision, all that happens is you get back markup from the wrong theme, which seems like a very low severity consequence of such an unlikely event, unlike the hash in #96.1, which has a much higher severity consequence from collision.
Comment #100
catchPer #98, it would also be possible to do the shortening only on Windows if that's a concern.
I'd really like to see a review from Heine here if he has time.
Comment #101
alexpottAlso by default we use
Drupal\Component\PhpStorage\MTimeProtectedFileStorage
so even if an attacker manages to write to a file they'd need to also somehow keep the same mtime.Comment #102
alexpottWith
\Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage
if they write another file to the folder it'd break stuff... they'd have to write to the file that exists.Comment #103
mikeker CreditAttribution: mikeker as a volunteer commentedFrom #100:
Respectfully, I really don't like this idea. If the security is not good enough for Linux I believe it's not good enough for Windows as well. i don't like the idea of making Windows (even more of) a second-class citizen.
From #96 and #98:
Assuming a file upload vulnerability, an attacker would have to upload a file with the same first 50-or-so bits matching the hash within the same second as Drupal caches the template since the directory's
mtime
is the secret when creating the hash. (mtime
is granular to one second.)Comment #104
lauriiiComment #105
alexpottDiscussed @catch, @effulgentsia, @xjm , @cottser, @laurii, @joelpittet and @Wim Leers. We agreed this is a major issue because without this change windows users get unexpected errors.
Comment #106
catchWell it's a second class citizen because it can't handle reasonable file name lengths - this is more like progressive enhancement on linux, it's not penalizing Windows.
Moving back to CNR, I'd really like to see Heine's thoughts on this issue.
Comment #107
e.r.n.i.e CreditAttribution: e.r.n.i.e as a volunteer commentedWould it be possible to save (a part of) the needed hashes inside the file?
Comment #108
Deciphered CreditAttribution: Deciphered commentedThis is an issue when installing 8.2.x on Windows when using Acquia Dev Desktop, which is part of the tools set used in the First Time Sprint Workshop and Mentored sprint. As such, every windows user during the DrupalCon NOLA First time sprint will experience this issue.
Comment #109
mikeker CreditAttribution: mikeker as a volunteer commented@e.r.n.i.e: I suppose that's possible but I'm concerned about performance issues related having to open and read each file to validate the hash. Currently, we just calculate the hash and include the file. If the directory's mtime has changed then the hash will be different and the
include
will fail.Adding the full hash to the file itself will require us to open the file, parse and remove the full hash, validate the full hash, and then include the file. I'm concerned this could be a performance issue.
@Deciphered: Agreed. I would love to get this fixed before the Friday sprints.
Comment #110
ptsimard CreditAttribution: ptsimard commentedCan we only hope this is implemented sanely: http://mspoweruser.com/ntfs-260-character-windows-10/
Please MS don't mess it up.
Comment #111
Anonymous (not verified) CreditAttribution: Anonymous commentedI have the same issue with twig templates: http://drupal.stackexchange.com/questions/201705/some-templates-are-not-...
Comment #112
alexpottI honestly don't understand why we don't swap out the implementation for windows - the proposed fix still doesn't warn Windows users when a file name is too long - it just makes it less likely.
Comment #113
Anonymous (not verified) CreditAttribution: Anonymous commentedthanks for patch. Life was too easy, now we have twig..
ppl who write about brute-force attack.. pff, cache dir is protected from web access
Comment #115
david_garcia CreditAttribution: david_garcia commentedOne of the test files was moved so the patch did not apply anymore.
Made a couple of more changes:
* Crypt::shortHash now throws an Exception when $length > 50 (that is the length of the sha256 after changing base)
* Default length for Crypt::shortHash is no longer a constant in the Crypt class
Comment #116
cesarmiquel CreditAttribution: cesarmiquel as a volunteer and at easytechgreen commentedJust FYI this is not only a Windows issue: 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.
Comment #117
slasher13Tested on Windows. Works for me.
Comment #118
cilefen CreditAttribution: cilefen commentedThis sentence "Because of their variable length, for example template suggestions can arbitrarily lengthen a filename, there is no set limit beyond which Drupal will not function correctly on Windows." is missing a comma or something because it doesn't make sense. I am also not ok with "set limit" because it is vague. "Predictable root directory depth" or similar would make more sense.
Comment #119
Anonymous (not verified) CreditAttribution: Anonymous commentednvm
Comment #120
cilefen CreditAttribution: cilefen commented@yurii_2016 In the time it took to write the comment you then deleted when you asked me "ARE YOU NUTS" you could have written a patch. Just to demonstrate, this took three minutes of my time.
Comment #121
slasher13Comment #122
Anonymous (not verified) CreditAttribution: Anonymous commentedas edited says 'nvm'
i don't believe in 3 minutes. just don't lie. it should take at least 10 mins
also i do not write patches, i'm against it.
also, if you prove it is so easy why to do this https://www.drupal.org/node/2606772#comment-11776337 ? Guy has provided you a solution and after 1 year you type about comma? Omg man, thanks my last comment on Drupal.
see ya
p.s.
also it took 1 year and it will take another 6 month to commit this stuff eventually, according to my observations of drupal surroundings
Comment #123
pingwin4eg@yurii_2016 Please read the Drupal Code of Conduct carefully.
This is a collaborative work and everyone brings their best in it. But your comments are not motivating despite you think they are. They are even not useful in any kind.
P.S.:
That says it all about you as a "PHP certified engi".
Comment #124
alexpottThis parameter is not tested.
This exception is not tested.
Comment #125
mikeker CreditAttribution: mikeker as a volunteer commentedThank you @alexpott and @cilefen for the reviews.
From #118:
Yikes, not the best example of my writing skills! :) Updated to read:
From #124:
Comment #126
david_garcia CreditAttribution: david_garcia commentedThis will make the issue stall forever, and everything points to the changes being proposed here not affecting security at all.
Comment #127
alexpottElsewhere we use
if (substr(PHP_OS, 0, 3) == 'WIN') {
for this. Seefile_create_filename()
for example. This would be the first usage of php_uname() in core.We don't use annotations anymore for this see #2822837: Replace @expectedException @expectedExceptionMessage with $this->setExpectedException - also we should assert on the message too.
Comment #128
catchRe-titling since this doesn't just affect Windows per #116.
Comment #129
mikeker CreditAttribution: mikeker as a volunteer commentedThanks for the review @alexpott. I'm looking forward to hearing from the security team on this.
Yeah, I've got no idea why I used that instead of PHP_OS... I had to look it up to see what it returned! :)
Fixed along with the exepectedException change, also asserting the exception message.
Comment #133
joelpittetUnrelated test fail it looks like. Tests look to be passing, I'll rerun them.
Comment #134
david_garcia CreditAttribution: david_garcia commentedBack to what I said in #126 :)
Comment #135
david_garcia CreditAttribution: david_garcia commentedComment #136
david_garcia CreditAttribution: david_garcia commentedComment #137
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedIt's also not clear to me why the few char gain here makes it the right approach. Also - using base 36 makes the hash longer than using the existing base64 encoding, what am I missing?
It seems like this is a more a bug in Twig if we are getting very long filenames. Why not hash those (or partially like cache IDs) so we have constant lengthor a defnitive maximum length filename for all twig templates?
see \Drupal\Core\Cache\DatabaseBackend::normalizeCid()
Comment #138
alexpott@pwolanin - the hash_hmac in the original code is not replace by a simple hash.
I think mixing hash_hmac function into this method makes it easier to make mistakes. We should two methods shortHash and shortHmac so that it is clear what you want to use and why.
Comment #139
alexpottDiscussed at length with @pwolanin in #drupal-security. He pointed out that we should use \Drupal\Component\Utility\Crypt::hmacBase64() for shorter security hashes - therefore we don't lessen the security in windows or linux.
I also think it is worth separating the security change from the rest of the change here to twig. @pwolanin also made some sensible suggestion that this issue takes into account the length of the filename and hashes it once over a certain length. That way we can know the length of the all relative paths to twig files because they can't be longer. And then we can add a better check in system_requirements().
In order to separate out the security issue from the changes which are not security related I've created #2830596: MTimeProtectedFastFileStorage::getFullPath() creates really long filenames unnecessarily
Comment #140
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedThe compiled Twig files seem to have a comment specifying the original template, like:
/* core/themes/bartik/templates/form--search-block-form.html.twig */
So I do't think it's very important to have the template name in the directory name also, since a simple grep will find the filename of interest if it exists.
Comment #141
alexpottPatch attached removes the security related changes since they are being handled in #2830596: MTimeProtectedFastFileStorage::getFullPath() creates really long filenames unnecessarily and also implements the logic similar to
\Drupal\Core\Cache\DatabaseBackend::normalizeCid()
to hash the filename if it gets to long. Also even without the security changes the patch attached with result in d8 working on windows as long as the root path is not more than 100 - which is what is being checked for in system_requirements().Comment #142
alexpottWith #2830596: MTimeProtectedFastFileStorage::getFullPath() creates really long filenames unnecessarily this comes down to 48 giving us even more wiggle room.
Comment #143
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedPlease remove the added static function Crypt::shortHash()
If you want to add to core a feature of proving substrings of hashes, I'd add an optional 2nd param to \Drupal\Component\Utility\Crypt::hashBase64() to specify the number of bytes of the hash output to use.
Given that this is not a very common need - we can just take the substring in this twig code I think, rather than baking it into core.
Comment #144
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedIt can maybe be this simple?
produces a file listing like:
Comment #145
alexpott@pwolanin that looks really good to me. With this patch we're guaranteeing that with a usual set up the warning adding to system_requirements() is relevant and we're not introducing any security differences between windows and other servers.
Why 132 bits?
We need to test this shortening explicit somewhere. And we probably need a change record to announce the change in twig filenames.
Comment #146
alexpottAlso this issue should add an empty post update function to system.post_update.php to force a cache clear so that all the old twig templates are removed.
Comment #147
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedIf we assume #2830596: MTimeProtectedFastFileStorage::getFullPath() creates really long filenames unnecessarily is going to be committed first (?) we can extend the hash and name parts by a few more characters.
Here's a patch with that assumption (uses a substring of 30) plus test.
Comment #148
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedOh wait - I added an empty update function - which is the right approach? Do we always want to clear the twig cache after updates?
Comment #149
alexpott@pwolanin a post update to clear the cache is fine.
@pwolanin I wouldn't make the assumption about #2830596: MTimeProtectedFastFileStorage::getFullPath() creates really long filenames unnecessarily landing first. Also I think having extra "wiggle" room is fine too. Because of the "sites/default/files" assumption... if people are doing multisite then that is going to grow.
Comment #150
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commented@alexpott - why do we even need to clear the cache? If the expected file is not found I think Drupal just generates it.
Comment #151
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedHere's with a class const to avoid magic numbers in code.
Comment #152
alexpottWe should clean up the files cause leaving around the old files is super confusing for people.
Comment #153
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedok, then let's make sure #2830596: MTimeProtectedFastFileStorage::getFullPath() creates really long filenames unnecessarily goes in 1st (since it's really a trivial patch) and we'll add the post-update here.
Comment #154
alexpottI think this belongs in system_requirements() since sites can be moved. Also on install it should be an error not a warning.
This can be removed as the post update has been committed in the other patch.
Comment #155
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedOk, moving the requirements check. The other change doesn't show up in the interdiff since it was rebased away.
The issue summary needs to be updated too.
Comment #156
alexpottI think we should make this an error during the install and a warning post install. If we prevent install in too deep paths then people have the chance to fix it. A warning means they can continue but their site will be broken. Hmmm... actually maybe this should always be an error. Since if you move a site to a place where the directory length is greater than 100 you are still going to have problems. Not sure.
Thanks for adding the test - nice one.
Comment #157
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedok, here's making is an error and slight rewording of the comment.
Comment #158
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedComment #159
cilefen CreditAttribution: cilefen commentedThe latest work is feeling sensible to me.
"Windows supports up to 255 characters..."
Do we want to give consideration to warning on other filesystems such as mentioned in #116?
Comment #160
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commented@cilefen the issue there is the file name length not the root dir depth, so for now I think this is ok for just windows (especially since the trunation means we won't grow file names without limit).
Comment #161
alexpottAlso with windows we know we have the issue 100% of the time - any other OS we know we don't have the issue 95+% of the time so I think only doing the notice windows is totally acceptable.
Comment #162
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedNoting some impact from #2569119: Use Crypt::hashBase64(), not hash('crc32b') or sha1 for placeholder tokens which would increase the twig extension hash length.
Comment #163
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedOk, that issue we've reduced the change to a few extra chars, so it's won't undo the work here.
Comment #164
YesCT CreditAttribution: YesCT commentedI'm gonna look at this and also check what remaining tasks there might be.
Comment #165
YesCT CreditAttribution: YesCT commentedRead the whole patch, also applied it and looked at the changes in context.
Just some nits (non-commit blockers: order of use statements and comment ending with punctuation) real quick (only in lines already being changed by the patch).
Next I will update this comment
which needs updating since we removed the $hash var.
Comment #166
YesCT CreditAttribution: YesCT commentedI think just replacing $hash with $suffix works to keep the intended meaning. (made 80 char re-wrapping needed.)
next I'm going to try and verify the numbers here.
I think it's a great comment, just want to see where those come from (which will verify, and also help know when this might need to be updated, if know where they come from).
Comment #167
khaled.zaidan CreditAttribution: khaled.zaidan at Reading Room commented#166 works perfectly for me!
Comment #168
manuel.adanThe issue is focused on Windows OS, but I got the same error running drupal 8 in a docker container (that uses AUFS).
Comment #169
alexpott@manuel.adan - thanks for the new information. AUFS seems to have two limits - see http://aufs.sourceforge.net/aufs3/man.html and search for 255 - the other limit is 242. Which one is affecting you? And does the latest patch on this issue fix it for you?
Comment #170
bmcclure CreditAttribution: bmcclure as a volunteer and at Top Floor commentedI have this issue with Docker, also. I'm using Kalabox for local development of sites on Pantheon, and running into these errors regularly. Additionally, on the Pantheon platform itself we're seeing these errors sometimes it seems (likely for the same reason). I haven't had a chance to test this patch yet but when I do I'll report back.
Comment #171
manuel.adan@alexpott as you mentioned, max filename size in AUFS is 242
Currently patch from #115 works for me on docker.
Comment #172
YesCT CreditAttribution: YesCT commentedreroll. was a conflict with #2569119: Use Crypt::hashBase64(), not hash('crc32b') or sha1 for placeholder tokens ($hash is now $prefix in TwigEnvironmentTest.php)
and a testsonly patch.
Comment #173
YesCT CreditAttribution: YesCT commented@manuel.adan can you try #172 (171)?
Comment #176
mikeker CreditAttribution: mikeker as a volunteer commentedFixes the tests from #171. We were using the Twig extension hash instead of the Twig prefix.
Comment #178
cilefen CreditAttribution: cilefen commentedTypo: It should be "...longer than...". Why not "Truncate the suffix to a maximum of 51 characters."?
I am trying to understand this part of the comment, which like all comments, is an effort to be helpful when code is confusing. The maximum is 153, we are handling 51 of them right here, and we are using 138 ("as follows"). It begs the question of where the other 15 may come from.
Comment #179
Anonymous (not verified) CreditAttribution: Anonymous commentedIs there a quickfix for completely disabling the hash suffix?
Comment #180
mikeker CreditAttribution: mikeker as a volunteer commented@cilefen, thanks for the review!
First off, I updated the tests-only patch so that it fails on the added tests and not a syntax error....
I've tried rewriting the comment you mentioned so it makes more sense. However, I wasn't the one that added the comment so I'd appreciate someone ensuring I haven't lost any important details.
Comment #181
mikeker CreditAttribution: mikeker as a volunteer commentedNot exactly a "quick" fix, but the Twig cache is a service that can be replaced like any other service in D8. You could extend
TwigPhpStorageCache
and override thegenerateKey
method.Comment #184
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedAfter discussion with cilefen, it doesn't seem like enumerating all the path lengths is really useful as a code comment and will be hard to maintain. We cna add it to the change record instead.
Here's a reword to try to make the comment clearer and also reflect the change to a requirement error.
Comment #186
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedOops - actually it's 142 long now due to the prefix change in #2569119: Use Crypt::hashBase64(), not hash('crc32b') or sha1 for placeholder tokens
CI seems to have some java error.
Comment #187
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedand... off by 1. forgot the leading slash. It's 143
Comment #189
mikeker CreditAttribution: mikeker as a volunteer commentedTest failure seems unrelated -- re-queuing.
Comment #191
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedComment #192
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedGiven the docker issues, maybe we should have a requirements error on every platform at >= 100 root depth?
Or at least a requirements warning for non-Windows?
Comment #193
Anonymous (not verified) CreditAttribution: Anonymous commentedBTW: why do we need these long names anyway? Can't we just use template names?
Comment #194
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commented@ivanjros - read the comments on class MTimeProtectedFileStorage and MTimeProtectedFastFileStorage and look at related issues.
Comment #195
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commenteddiscussed with alexpott and he suggested a follow-up issue to discuss requirements on non-Windows.
Comment #196
Belba CreditAttribution: Belba commentedHi
Is there found a solution for below isue. A solution for users who dont know coding :
Warning: rename(sites/default/files/php/twig/.c8f11c368b,sites/default/files/php/twig/16fd8d9f_block--system-messages-block.html.twig_c0493f9769b7032f5275fe4f26f33947f47fbbeeeeae6956e258589eb0c5b633/43969a40fb9932c6f99be001c55d4191ef50230540825bd474d4bd1562e04377.php): The system cannot find the path specified. (code: 3) in Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage->save() (line 86 of core\lib\Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage.php).
Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage->save('16fd8d9f_block--system-messages-block.html.twig_c0493f9769b7032f5275fe4f26f33947f47fbbeeeeae6956e258589eb0c5b633', '<?php
Or maybe a solution to remove the warning, because the website is working fine.
Thanks
Comment #197
kevla CreditAttribution: kevla commentedThis has just caught me out. The patch in #187 seems to work ok. However this has stung me on a client site that insists on Windows. It's not really a good idea to run a dev version on production so I'm probably not able to deploy the patch till its released.
Are we still saying that Drupal 8.2 is compatible with Windows, despite this bug? It seems rather serious.
Comment #198
alexpottI really want to land this change because it is hard to find out about this fix - but I'm pondering whether or not we should test the depth of the public files directory since in a multi-site install these can get quite big.
Comment #199
cilefen CreditAttribution: cilefen commentedIt is mentioned in the release notes
Comment #200
kevla CreditAttribution: kevla commentedDo you not think this should be highlighted more clearer than just the release notes. Perhaps on this page https://www.drupal.org/docs/8/system-requirements/web-server
(left a comment on that to open it up)
I really would advocate saying that Drupal 8 in it's current state is not reliably compatible with Windows.
Comment #201
Anonymous (not verified) CreditAttribution: Anonymous commentedalexpott: yeah, I am storing templates in /tmp/appname/[uuid]/php/twig/..... so you can imagine the length. On Windows, this might be even longer with c:\windows\...
I understand the reason for these names but it is just so unpractical. It's like that long ass config directory name :D
---
Also I have a lot of theme suggestions so the template name itself will be "quite" long.
Maybe skipping the directories completely and using single directory with all templates could be fine?
Comment #202
cilefen CreditAttribution: cilefen commentedI am setting this to needs work for alexpott's suggestion in #198. We can't ignore multisite. Merely testing DRUPAL_ROOT and warning based on that could paint an inaccurate picture of what may happen when you install for any site directory longer than "default". Let's find the public files directory depth and base the requirements error on that.
Comment #203
cilefen CreditAttribution: cilefen commented@kevla You mentioned making a comment on https://www.drupal.org/docs/8/system-requirements/web-server but I don't see one. However, it is not clear where such a note would be best placed. The problem is OS-based, not web server based.
On the other hand, when you follow links to Download Drupal 8.2.5, you go to the release notes, and it is right there.
Comment #204
kevla CreditAttribution: kevla commentedTrue, it's hard to see where we should place a warning.
I would suggest that it's not clear enough. No one is going trawl through all those release notes just to see one tiny footnote which brings them to this huge thread. I vote that a stronger notice needs to be placed somewhere prominent. however I am in agreement with you that where to put that isn't clear with the current layout of the requirements page.
Comment #205
mikeker CreditAttribution: mikeker as a volunteer commentedChanged to measure the public files directory path length instead of Drupal root and bumped the limit to 120 characters.
This won't prevent the situation where a new, longer site is added to a shorter multi-site install. (Eg: really-long-name-goes-here.example.com is added to example.com.) I think that argues for raising the profile of this limitation as @kevla suggests.
Comment #206
cilefen CreditAttribution: cilefen commentedNevertheless, the attempt to add a new site with a long directory name will result in a requirements error.
Comment #207
mikeker CreditAttribution: mikeker as a volunteer commentedOf course. They have to go through the install for each multi-site... Don't know what I was thinking!?!
I've added "read through the installation guide and find a good place for this" to my growing post-it of things to do while tests/migrations run... :)
Comment #208
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedWe need to at least file a follow-up for a requirement warning on non-Windows too
Comment #209
alexpott@pwolanin I'm not convinced about the non windows warning at all. This would mean a warning on every site with paths > 120 and most of them are not going to have an issue. Sure we can have a followup to discuss further but I don't think it should block this issue.
Can someone please provide test evidence i.e. a screenshot that warning works on windows? I don't have a windows install to prove it :)
Comment #210
mikeker CreditAttribution: mikeker as a volunteer commented@alexpott, sorry, should've included a screenshot in #205...
With Drupal root at 101 characters deep, meaning sites/default/files (19 chars) plus the slash is 121 characters deep. Installation gives this:
I should point out that you won't even get to that if you have
$settings['extension_discovery_scan_tests'] = TRUE;
(which is part of the defaultsettings.local.php
file). Instead you'll get an uncaught exception when ExtensionDiscovery tries to readinvalid_module_name_over_the_maximum_allowed_character_length.info.yml
. I'll open a followup for that, but I wanted to make note of it here.Comment #211
mikeker CreditAttribution: mikeker as a volunteer commentedOpened #2845042: Uncaught exception SplFileInfo::openFile during installation on Windows when the Drupal root directory is greater than 88 characters to track the uncaught exception.
Comment #212
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedI think this last change looks fine - let's get it in.
Comment #213
Anonymous (not verified) CreditAttribution: Anonymous commentedSince this is just about adding a notice and not solving the issue itself, wouldn't be an idea to add settings.php setting that would allow to disable this level of security in cases where the directory structure has to be longer acceptable?
Comment #214
mikeker CreditAttribution: mikeker as a volunteer commented@ivanjaros, This does solve the underlying issue as far as we can solve it (the true root issue is the max path limitation). This patch prevents Twig cache filenames from exceeding that as well as adding the install error.
Removed the manual testing tag because of #210. Also, I've been using this patch on two projects on my localhost without issue.
Comment #216
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedsporadic test fail - queued a retest
Comment #218
xjm@wheatpenny, @pwolanin, @cilefen, and I reviewed the text for this issue. We came up with this more readable text:
Attached updates the error to this message.
120 characters is hardcoded as a magic number; should we use a constant?
Comment #219
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedGood, I like this shorter version.
Comment #220
alexpottI guess we could have a constant in system.install - the other option would be bootstrap.inc or system.module but I'm not sure about what would also need this value. If the requirements stuff was a class then this would totally make sense as a class constant.
Comment #221
pwolanin CreditAttribution: pwolanin as a volunteer and at SciShield commentedI don't think a constant is needed when this is only used in one place
Comment #222
xjmComment #223
alexpottCommitted and pushed ba455a1 to 8.4.x and 737fb7d to 8.3.x. Thanks!
Tagging for 8.3.0 release notes as committing this means that we should be able to take out the Windows warning from the release notes.
Comment #226
LittleCodingIs it possible that this fix will make it into the 8.2.x branch?
Comment #227
cilefen CreditAttribution: cilefen commentedRe #223 Well, sort-of. There are existing sites and relocated sites to consider.
Comment #228
cilefen CreditAttribution: cilefen commented@LittleCoding I started a conversation with xjm about backporting because I somehow became convinced this is critical priority (not sure how), when in fact it is major because of its limited scope and workarounds. No, we will not backport this to 8.2.x. Quoting xjm: "no further patch release is planned for 8.2.x barring critical or security fixes, so affected sites can try the patch for now and plan to upgrade to 8.3.0 April 5".
Comment #229
LittleCodingHas anyone tested with the current 8.2.x releases? (as I am asking for a current site 8.2.6 and I do see some ill effect due to this bug)
Comment #230
cilefen CreditAttribution: cilefen commentedThe most recent patch does not apply 8.2.x. A new one would need crafting.
Comment #231
mikeker CreditAttribution: mikeker as a volunteer commented@LittleCoding: I'm running this on two 8.2.x project currently (I develop on Windows) without issues for a couple months. The patch doesn't apply as is, but if you (manually) remove the changes to
TwigEnvironmentTest.php
it applies cleanly.Comment #232
LittleCoding++ @mikeker thanks for the tip!
Comment #234
xjmComment #235
mikeker CreditAttribution: mikeker as a volunteer commentedI don't think this was supposed to be moved to 8.3.x as it was committed to 8.4.x. Regardless, it's a closed issue so I don't think it matters...
Comment #236
cilefen CreditAttribution: cilefen commentedI think we usually leave it at the lowest branch it was committed to.
Comment #237
.jch CreditAttribution: .jch as a volunteer and commentedWhy is this issue closed? As of 8.6 it still exists. Continuing to apply a 2 year old patch that was targeted for a version that could be now considered deprecated is not a solution. This requires doing a diff to see if the targeted patch files have changed each update and then modifying the patch file if required.
Please do not close this issue until a permanent solution exists. It has existed since the initial release of d8 and will likely continue throughout the entire version 8 span.
Comment #238
acrosman@.jch it got marked as fixed after the patches were applied to 8.3 and 8.4, and automatically closed two weeks later. I don't see any comments indicating people having problems on new installs on versions since then. The fix does impose installation requirements to help prevent problems and a warning on the status panel, so older installs might still suffer if they aren't moved to a structure that meets those requirements. If you're having problems you think should be fixed through another patch you probably need to be more specific about the use cases not resolved by the commits above that you think need further updates.
Comment #239
cilefen CreditAttribution: cilefen commented@.jch This issue was closed when the change was commited to the development and bugfix branches that existed at the time. The code exists in 8.6.x. I do not understand what you mean about applying a patch for this to later releases. Can you explain a bit?
If memory services, the efforts here were to mitigate and warn about limited filesystems. What problems are you facing?
Comment #240
.jch CreditAttribution: .jch as a volunteer and commentedCore 8.6.1 Commerce 2.9 PHP 7.2.4 Apache 2.4.33 MySQL 5.7.22 Win10. Site completely built and maintained with composer and forced current by composer update --with-dependencies then running update.php
After navigating through any content then performing a "Flush all caches" at least half a dozen warning messages similar to the following will be generated....
This has been present since d8 was initially released and for the most part I just disregarded it as a using Win10 as a dev platform thing.
My development.services.yml contains the usual for twig...
And I place
$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml';
in settings.php so its always there if I don't want to turn on the extra stuff in settings.local.phpWhen I initially upgraded to d8.6 it blew away drupal console and was causing some other memory errors not related to taxonomy for me.
I solved that by down grading the following symfony components from 4.x and reinstalling console...
Warning: rename(sites/default/files/php/twig/.W_xUdhX-QWcpEUPO8_MobXBPW-E,sites/default/files/php/twig/5b97d8854d2e8_image-style.html.twig_DT80HYqk6Wo9CW3TWFD8uocbD/Hhs5_fA5iGL1kVSPf1A1_LZuUunvdIpCoSJroHz2Nf0.php): Access is denied. (code: 5) in Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage->save() (line 88 of E:\x64Stack\Sites\market\web\core\lib\Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage.php) #0 E:\x64Stack\Sites\market\web\core\includes\bootstrap.inc(584): _drupal_error_handler_real(2, 'rename(sites/de...', 'E:\\x64Stack\\Sit...', 88, Array) #1 [internal function]: _drupal_error_handler(2, 'rename(sites/de...', 'E:\\x64Stack\\Sit...', 88, Array) #2 E:\x64Stack\Sites\market\web\core\lib\Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage.php(88): rename('sites/default/f...', 'sites/default/f...') #3 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Template\TwigPhpStorageCache.php(111): Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage->save('5b97d8854d2e8_i...', '<?php\n\n/* core/...') #4 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Environment.php(457): Drupal\Core\Template\TwigPhpStorageCache->write('5b97d8854d2e8_i...', '<?php\n\n/* core/...') #5 E:\x64Stack\Sites\market\web\core\themes\engines\twig\twig.engine(64): Twig_Environment->loadTemplate('core/themes/cla...') #6 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Theme\ThemeManager.php(384): twig_render_template('core/themes/cla...', Array) #7 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(437): Drupal\Core\Theme\ThemeManager->render('image_style', Array) #8 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, false) #9 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Template\TwigExtension.php(490): Drupal\Core\Render\Renderer->render(Array) #10 E:\x64Stack\Sites\market\web\sites\default\files\php\twig\5b97d8854d2e8_image-formatter.html.twig_ldCGq89AyEvgQ64wQj7e87tii\WDzx56914y1dxdTKsj6F4qVyXC5tFQvW0A9P9oDXTII.php(48): Drupal\Core\Template\TwigExtension->escapeFilter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true) #11 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(432): __TwigTemplate_e18722380924e0c8e26f521294629e9763917d315cc1dd1b50aa06e078d7264b->doDisplay(Array, Array) #12 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(403): Twig_Template->displayWithErrorHandling(Array, Array) #13 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(411): Twig_Template->display(Array) #14 E:\x64Stack\Sites\market\web\core\themes\engines\twig\twig.engine(64): Twig_Template->render(Array) #15 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Theme\ThemeManager.php(384): twig_render_template('core/themes/cla...', Array) #16 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(437): Drupal\Core\Theme\ThemeManager->render('image_formatter', Array) #17 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, false) #18 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Template\TwigExtension.php(490): Drupal\Core\Render\Renderer->render(Array) #19 E:\x64Stack\Sites\market\web\sites\default\files\php\twig\5b97d8854d2e8_field.html.twig_HyD1CDgeXt4pMEmeIFrpQTXOP\VIffvtqYFMqp7wtAi3YbXR52hac_luu-h9Vr8AaHCok.php(91): Drupal\Core\Template\TwigExtension->escapeFilter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true) #20 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(432): __TwigTemplate_e82230bf48c4e8909379cf3de7ad2c36cd781acedc417cad2ac0e83358bda903->doDisplay(Array, Array) #21 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(403): Twig_Template->displayWithErrorHandling(Array, Array) #22 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(411): Twig_Template->display(Array) #23 E:\x64Stack\Sites\market\web\core\themes\engines\twig\twig.engine(64): Twig_Template->render(Array) #24 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Theme\ThemeManager.php(384): twig_render_template('core/themes/cla...', Array) #25 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(437): Drupal\Core\Theme\ThemeManager->render('field', Array) #26 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(450): Drupal\Core\Render\Renderer->doRender(Array) #27 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, false) #28 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Template\TwigExtension.php(490): Drupal\Core\Render\Renderer->render(Array) #29 E:\x64Stack\Sites\market\web\sites\default\files\php\twig\5b97d8854d2e8_media.html.twig_55Om3yZ7U9Z2TtdmubMjr36gC\XSYp3BZqdAJLaybc2mjAOgdzx9chgrQa_SUNMlfZRM8.php(60): Drupal\Core\Template\TwigExtension->escapeFilter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true) #30 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(432): __TwigTemplate_8af39d4f2eea6ad4bbd9891aafd9d7ef5aa26304cef4541d1d4306cf1ac30174->doDisplay(Array, Array) #31 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(403): Twig_Template->displayWithErrorHandling(Array, Array) #32 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(411): Twig_Template->display(Array) #33 E:\x64Stack\Sites\market\web\core\themes\engines\twig\twig.engine(64): Twig_Template->render(Array) #34 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Theme\ThemeManager.php(384): twig_render_template('core/themes/cla...', Array) #35 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(437): Drupal\Core\Theme\ThemeManager->render('media', Array) #36 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, false) #37 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Template\TwigExtension.php(490): Drupal\Core\Render\Renderer->render(Array) #38 E:\x64Stack\Sites\market\web\sites\default\files\php\twig\5b97d8854d2e8_field.html.twig_HyD1CDgeXt4pMEmeIFrpQTXOP\VIffvtqYFMqp7wtAi3YbXR52hac_luu-h9Vr8AaHCok.php(91): Drupal\Core\Template\TwigExtension->escapeFilter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true) #39 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(432): __TwigTemplate_e82230bf48c4e8909379cf3de7ad2c36cd781acedc417cad2ac0e83358bda903->doDisplay(Array, Array) #40 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(403): Twig_Template->displayWithErrorHandling(Array, Array) #41 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(411): Twig_Template->display(Array) #42 E:\x64Stack\Sites\market\web\core\themes\engines\twig\twig.engine(64): Twig_Template->render(Array) #43 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Theme\ThemeManager.php(384): twig_render_template('core/themes/cla...', Array) #44 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(437): Drupal\Core\Theme\ThemeManager->render('field', Array) #45 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(450): Drupal\Core\Render\Renderer->doRender(Array) #46 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, false) #47 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Template\TwigExtension.php(490): Drupal\Core\Render\Renderer->render(Array) #48 E:\x64Stack\Sites\market\web\sites\default\files\php\twig\5b97d8854d2e8_commerce-product.html.twi_exmHfBoRDShhmqkE7uBQoVAc3\KJHPkvo4Pk8Iw2TpdyxRnO47cpzNMQlMA_byf_InYDY.php(47): Drupal\Core\Template\TwigExtension->escapeFilter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true) #49 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(432): __TwigTemplate_04346218d9962525fd3c275d72f7c83f142553ab6bb91c9dd7977aded49ddbbf->doDisplay(Array, Array) #50 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(403): Twig_Template->displayWithErrorHandling(Array, Array) #51 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(411): Twig_Template->display(Array) #52 E:\x64Stack\Sites\market\web\core\themes\engines\twig\twig.engine(64): Twig_Template->render(Array) #53 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Theme\ThemeManager.php(384): twig_render_template('modules/contrib...', Array) #54 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(437): Drupal\Core\Theme\ThemeManager->render('commerce_produc...', Array) #55 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, false) #56 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Template\TwigExtension.php(490): Drupal\Core\Render\Renderer->render(Array) #57 E:\x64Stack\Sites\market\web\sites\default\files\php\twig\5b97d8854d2e8_views-view-unformatted.ht_xQi2yM9T-9ZEbMctKaNllJCcH\IbZxYnC-uuV8KATgrrxFdBcBZ6v-pBDcAnm1gmvyfcs.php(64): Drupal\Core\Template\TwigExtension->escapeFilter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true) #58 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(432): __TwigTemplate_6dc4d340d6641967fa4f801c3c9dc6704349157f3cf27b298edf49211cf9b993->doDisplay(Array, Array) #59 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(403): Twig_Template->displayWithErrorHandling(Array, Array) #60 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(411): Twig_Template->display(Array) #61 E:\x64Stack\Sites\market\web\core\themes\engines\twig\twig.engine(64): Twig_Template->render(Array) #62 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Theme\ThemeManager.php(384): twig_render_template('core/themes/cla...', Array) #63 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(437): Drupal\Core\Theme\ThemeManager->render('views_view_unfo...', Array) #64 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(450): Drupal\Core\Render\Renderer->doRender(Array) #65 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, false) #66 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Template\TwigExtension.php(490): Drupal\Core\Render\Renderer->render(Array) #67 E:\x64Stack\Sites\market\web\sites\default\files\php\twig\5b97d8854d2e8_views-view.html.twig_sSNBbe-nvcLwN-zRsqV6zX4U-\vIFhWUvXo3bJ6UHnqXlVnC8HgspZW-StiT0O9gV1VZM.php(114): Drupal\Core\Template\TwigExtension->escapeFilter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true) #68 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(432): __TwigTemplate_c7841218cc66a41ffd0fc3c1bb984e6a97dfe7cbfa08d27a4e662f0d88a436e5->doDisplay(Array, Array) #69 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(403): Twig_Template->displayWithErrorHandling(Array, Array) #70 E:\x64Stack\Sites\market\vendor\twig\twig\lib\Twig\Template.php(411): Twig_Template->display(Array) #71 E:\x64Stack\Sites\market\web\core\themes\engines\twig\twig.engine(64): Twig_Template->render(Array) #72 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Theme\ThemeManager.php(384): twig_render_template('core/themes/cla...', Array) #73 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(437): Drupal\Core\Theme\ThemeManager->render('views_view', Array) #74 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(450): Drupal\Core\Render\Renderer->doRender(Array) #75 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(195): Drupal\Core\Render\Renderer->doRender(Array, false) #76 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\MainContent\HtmlRenderer.php(226): Drupal\Core\Render\Renderer->render(Array, false) #77 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\Renderer.php(582): Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() #78 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\MainContent\HtmlRenderer.php(227): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #79 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\Render\MainContent\HtmlRenderer.php(117): Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch)) #80 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\EventSubscriber\MainContentViewSubscriber.php(90): Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch)) #81 [internal function]: Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #82 E:\x64Stack\Sites\market\web\core\lib\Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher)) #83 E:\x64Stack\Sites\market\vendor\symfony\http-kernel\HttpKernel.php(156): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent)) #84 E:\x64Stack\Sites\market\vendor\symfony\http-kernel\HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #85 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\StackMiddleware\Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #86 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\StackMiddleware\KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #87 E:\x64Stack\Sites\market\web\core\modules\page_cache\src\StackMiddleware\PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #88 E:\x64Stack\Sites\market\web\core\modules\page_cache\src\StackMiddleware\PageCache.php(78): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true) #89 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\StackMiddleware\ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #90 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\StackMiddleware\NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #91 E:\x64Stack\Sites\market\vendor\stack\builder\src\Stack\StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #92 E:\x64Stack\Sites\market\web\core\lib\Drupal\Core\DrupalKernel.php(665): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #93 E:\x64Stack\Sites\market\web\index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #94 {main}.
Comment #241
acrosmanBy my count the file in question has 225 characters in the full path name (196 from Drupal + 29 from the path in the references to code files), which is below the 260 character limit that triggered this issue. That implies you have another issue, or your setup have files outside web-root and therefore generating a different path from my count and potentially out past the 260.
It's worth noting the solution in this issue uses 120 characters to trigger the warning that would allow file paths of 140 characters of generated hashed. This file is 176 characters so could still generate problems on sites without triggering a warning. The warning should probably be triggered at 80 characters instead of 120. That will not solve your problem as you still need shorter system paths, and it seems unlikely we want to shorten the hashes more than was done previously.
Comment #242
.jch CreditAttribution: .jch as a volunteer and commentedd8.6.9 Apache/2.4.33 (Win64) PHP/7.2.4 Site built with composer.
Don't know why this issue continues to be closed out. It has existed since the first release of 8 and continues with 8.6.9.
The following log message is one of 6 that are generated after performing a 'flush all caches'.
I think this site was initially built with 8.3 or 8.4 and all components are up to date.
Using drush 9 and
drush cr
produces no errors on console.Comment #243
cilefen CreditAttribution: cilefen commented@.jch The error log reads “access is denied”.
Comment #244
DanChadwick CreditAttribution: DanChadwick commented@cilefen, @.jch: The error is "access is denied", but it's not clear why. This happens for me sporadically. Windows 10 64 bit, WAMP stack. At this point, it happens only once a month or so, making debugging very difficult.
There are lots of successful renames with
$full_path
151 characters long, plus another 22 characters to get to the drupal rootc:/wamp64/www/drupal8/
.The failure happened with
$full_path
actually 7 characters shorter, so this doesn't seem to be a straightforward path length issue.So some issue continues to happen intermittently on the Windows platform. The webserver runs as the administrator, and the files are marked as read-only, but the Administrators group has full access.
My installation is straightforward, except that I'm using multisite, which results in paths a few characters longer than normal.
This -- or a different issue with the same failure behavior -- is definitely not fixed. Perhaps a new issue should be created, referring to this issue.
Comment #245
M_Z CreditAttribution: M_Z commentedI also get the
rename(…php/twig/… Access denied ...
error from time to time (after flush all caches from the backend or after disabling a theme).As in #244 I use WAMP and I use a multisite Installation, too.
Comment #246
omkargaonkar CreditAttribution: omkargaonkar as a volunteer commentedI tried with all the above portions still I getting error message
Warning: rename(sites/default/files/php/twig/.bxGp3LM87WyqhvB_GD7fvh54gDc,sites/default/files/php/twig/5f71ce71a1926_input.html.twig_7yuX2-VF9y2p2EoZlLL8wT_eK/DZIhfkSvqyYPDaS7YZqMfvR5eyzdwliwpJWBYN5QuF0.php): Access is denied. (code: 5) in Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage->save() (line 88 of core\lib\Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage.php).
any suggestion on the above warning. How it can be fix.Comment #247
Sseto CreditAttribution: Sseto commented@DanChadwick and @ M_Z. I'm also getting the same issue with WAMP. Did you guys find a fix for it?
Thanks!
Comment #248
loze CreditAttribution: loze commentedI am also seeing this error on my local windows development environment. Usually happens when I open an entitybrowser modal.
Comment #249
shoebob CreditAttribution: shoebob commentedAlso seeing this error using WAMP. Appears every time I open entity browser modal.
Comment #250
smustgrave CreditAttribution: smustgrave at Mobomo commentedAlso been noticing this issue in Drupal 9.2. in Azure site.
Anyone have a working solution?
Comment #251
chrisck CreditAttribution: chrisck commentedI'm experiencing this error after flushing all caches on two different Windows setups with Drupal 9.2:
Setup 1
Windows 10
Apache
MySQL
PHP
Setup 2
Windows 10
IIS
SQL Server
PHP
Comment #252
cilefen CreditAttribution: cilefen commentedThe 8.3.0 release notes read:
@chrisck Do you see those warnings in the site status report? What is the base path of the affected site?
Comment #253
chrisck CreditAttribution: chrisck commentedHi @cilefen the Drupal root path does not exceed 100 characters on both systems and there are no warnings in the site status report.
WAMP Local Dev Environment
C:\MAMP\htdocs\dev\web
WISP Live Production Environment
\\7-chars\19-chars\drupal\web
Comment #254
cilefen CreditAttribution: cilefen commented@chrisck I count only 162 characters in the path, whereas the intrinsic limit with Windows is 260. What is the determination that the site is affected by this issue and not another issue?
Comment #255
chrisck CreditAttribution: chrisck commented@cilefen I'm not certain the site is affected by the Windows character limit issue, however I did land here from a matched search result of the error I'm receiving. #240 and #242, #244-246 with the rename function and "access is denied".
Comment #256
cilefen CreditAttribution: cilefen commentedThis issue was referenced early on but wasn’t formally linked.
Comment #257
chrisck CreditAttribution: chrisck commented@cilefen Thank you for pointing me in the right direction! The referenced issue seems more likely to be the source of error.
Comment #258
M_Z CreditAttribution: M_Z commented@chrisck / @cilefen : If I understand you right, then the "Access denied" error for WAMP / Windows users (e.g. described in comments #244, #245 and #247) will be caused by a Windows file permissions issue as described in #2629240: Overwriting file-cached keys on Windows results in an access denied error?
Does the provided patch in #2629240: Overwriting file-cached keys on Windows results in an access denied error fixes the "Access denied" error for WAMP / Windows users? And does the patch apply to D9?
Should we move further discussion to the other issue?
Comment #259
loze CreditAttribution: loze commentedI am seeing this error on WAMP
I have tried the following suggestions to no avail:
Comment #260
quietone CreditAttribution: quietone at PreviousNext commentedpublish the change record