The filesystem used by Windows, NTFS, does not support the user-group-other/read-write-execute paradigm that is used on Linux, BSD etc.
On Windows, the PHP functions chmod(), fileperms() etc. tries to emulate the Linux paradigm, but the emulation is rather limited. See this comment for some background info.
The limitations in the emulation cause some tests to fail on Windows. These tests test some permission mask, e.g. 0775, but one Windows the three octets are always the same and reflect the 'user' permission, so the value returned by fileperms() is 0777 and not 0775.
This patch makes the tests pass on Windows while testing as much as possible. It has been tested with Windows XP.
Comment | File | Size | Author |
---|---|---|---|
#48 | 443286-stream-wrapper-windows.patch | 3.83 KB | Damien Tournoud |
#45 | 443286-45.patch | 16.35 KB | scor |
#39 | 443286-03.patch | 17.99 KB | webkenny |
#29 | 443286-step-1_0-reroll.patch | 17.89 KB | drifter |
#26 | 443286-step-1.patch | 16.95 KB | Damien Tournoud |
Comments
Comment #1
cburschkaChecking the operating system when you really have to make assumptions about the file system is not ideal, but unfortunately I didn't find a way to check the file system directly. This may be the best you can do.
I'm a bit rusty on bit-wise operations, but I hope that this change only relaxes the constraints. NTFS may be the default, but you can also use FAT and even (with added drivers) EXT2 on Windows. The check should still pass in that case.
(There's also the case of using an NTFS volume on Linux, which could be possible on dual-booting machines. But I think we don't need to cover all the edge cases.)
Comment #3
c960657 CreditAttribution: c960657 commentedReroll.
Comment #5
c960657 CreditAttribution: c960657 commentedTest bot problems.
Comment #7
c960657 CreditAttribution: c960657 commentedTest bot problems.
Comment #8
drewish CreditAttribution: drewish commentedSeems sane to me. I don't have a Windows box to test this on though. And I really do like the change from 511 to 0777... not sure why I did the decimal version.
Comment #9
drewish CreditAttribution: drewish commentedmeant to bump the status as well.
Comment #10
webchickOther than perhaps in some book somewhere, I've never in my life seen the
|=
operator, nor the>>
operator. We need way, way more comments here to explain what is going on. And a summary would be nice as well for people who don't care about the details. Like, "This forces the normal Unix permissions to Windows's read/write equivalents" or "This drops the group and other bits from the permission, as the user is the only important thing" or whatever it's doing.The comments atm tell me some of what, but not enough, and not any of the why. :)
I do like the consistency of using 0777 though. So +1 to that!
Comment #11
c960657 CreditAttribution: c960657 commentedI made the comments a bit more elaborate and got rid of the
&=
and!=
operators. I haven't tested this version of the patch on Windows (my Windows box isn't configured with a web server ATM).Comment #12
drewish CreditAttribution: drewish commentedah, yeah that's a lot more readable. if we can get this tested on a windows box it looks rtbc.
Comment #14
sunThe comment looks outdated now?
I'm on Windows, I can test.
I'm on crack. Are you, too?
Comment #15
c960657 CreditAttribution: c960657 commentedI'm not sure what you by “outdated”? The mentioned line does the same as before - the number is just specified in a different way.
Comment #16
drewish CreditAttribution: drewish commentedsun, you are on crack... that or you need to review the documentation for integers ;)
0777 == 511. the leading 0 causes php to interpret the number as octal, just like a leading 0x causes it to be interpreted as hexadecimal.
Comment #17
mr.baileysMarked #315520: assertFilePermissions() not working on Windows as a duplicate of this one.
Comment #18
c960657 CreditAttribution: c960657 commentedReroll. Includes a fix for #701500: Cannot download files with 8bit filenames on Windows.
With this patch all file tests pass on Windows.
Comment #19
mr.baileysMarked #753250: Simpletest file permission exceptions on Windows test platform as a duplicate (does contain some additional info)
Comment #20
Damien Tournoud CreditAttribution: Damien Tournoud commentedRaising to critical, as file handling is severely broken on Windows + IIS.
Here is a reroll, with a few additions:
This makes the File tests (and related tests) pass on IIS. At last. We really need a test environment for Windows + IIS.
Comment #22
Damien Tournoud CreditAttribution: Damien Tournoud commentedNeeds work anyway because:
- The idea of storing UTF-8 data over another encoding is just a hack (and this "other encoding" is not necessarily Windows-1252, it can be any encoding depending of the server configuration).
- The current patch provides no migration path for existing files.
- Changing the external URLs of files to match our lame way of storing them is just... not elegant.
The root of the problem is known: PHP on Windows doesn't use the proper API to access the files. It uses the legacy one instead of the Unicode version. I'm currently investigating if it would be possible to workaround that using a custom stream wrapper.
Comment #23
c960657 CreditAttribution: c960657 commentedHow do you configure PHP/Windows to make 8-bit characters map to another encoding than Windows-1252?
Comment #24
Damien Tournoud CreditAttribution: Damien Tournoud commented@c960657: the problem is not Windows, it's PHP. Windows stores filenames in UTF-16 (on NTFS), but PHP uses the old (locale-aware) API to access the filesystem, instead of the newer Unicode API. That's where the actual encoding conversion takes place.
Comment #25
Damien Tournoud CreditAttribution: Damien Tournoud commentedGiven that there is no clear way forward for the support of Unicode files on Windows, I suggest we first focus on fixing the issue regarding the clean-up of directories containing read-only files. This issue is simple to fix, and make a lot of unrelated tests fail (for example: "Import feeds from OPML functionality" in the test suite of the Aggregator module).
This (somewhat simple) patch should already make the situation a lot better. Let's get it in.
Comment #26
Damien Tournoud CreditAttribution: Damien Tournoud commentedThe same patch minus the changes to
web.config
, that I don't want there.Comment #27
YesCT CreditAttribution: YesCT commented#26: 443286-step-1.patch queued for re-testing.
Comment #29
drifter CreditAttribution: drifter commentedRerolling #26
Comment #30
rfayThere's no reason I understand to do an "if Windows" in the delete cases. The logic is the same. Why can't we just chmod whether or not we're on Windows and simplify the code?
The comments need a link to the PHP issue.
We need a test for this so that it doesn't come back to haunt us (assuming we get testing going on Win). I think the big risk here is that we'll rip this out later because we just don't understand it.
It's very hard to like this at all. It's an API change. It's intrusive. It's hard to let people know about. It's hard to maintain. We're changing core code and adding an API to support an obscure Windows PHP issue that nobody will understand down the line.
Changing the title, as this is *not* critical if this is just about tests on Windows. It probably *is* critical if it's about all file handling on Windows. But if it's just about tests, let's downgrade it.
Powered by Dreditor.
Comment #31
rfayI just took a quick look at the issues marked as dups in #17, 18, and 19.
We need a clear statement of what we're going to address in this issue, and the rest needs to be put in another issue. So many things have been marked as dups and they'll be lost if we don't get this straightened out. I see at least:
If we're going to try to address a list of issues, let's get them listed carefully, with an example of how to demonstrate each so we can do decent tests.
Comment #32
Damien Tournoud CreditAttribution: Damien Tournoud commentedJust clarifying a little bit more:
Comment #33
mikeytown2 CreditAttribution: mikeytown2 commentedlooking at #29
We might want to have a link to this inside the code comments?
http://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
I have a similar function in the boost module so I don't try to create bad filenames on windows. If this was in core, it would probably be a nice thing; otherwise we will be shipping something I can not rely on as a module maintainer and will thus have to create my own version of the same function.
make this into a function since it is used in more then 1 place
Powered by Dreditor.
@rfay
This would be for performance reasons, if we can avoid hitting the filesystem then that is a major plus. Always chmod-ing a file before deletion will make it slower. Taking the idea from #818818: Race Condition when using file_save_data FILE_EXISTS_REPLACE we could attempt the delete and if it fails then chmod and attempt the delete again; like this
Is there anyway we can get rid of the
if ($context)
in this function? Makes the code harder to read. http://php.net/unlinkComment #34
andypostFor windows only 0200 mask has meaning (readable) so chmod(0200, $file) is enough to make it writable
About unicode - I have to use transliteration module on every site where users can upload any files because russian letters 'Ё' 'ё' 'я' are not supported on linux. So only possibles way to work with user files are urlencode() or transliterate them.
Comment #35
andypostRelated issue about permissions #857300: Make drupal_install_mkdir should use octal numbers
Comment #36
webkenny CreditAttribution: webkenny commented#29: 443286-step-1_0-reroll.patch queued for re-testing.
Comment #37
webkenny CreditAttribution: webkenny commentedThis patch doesn't apply cleanly to the latest HEAD revision.
Comment #39
webkenny CreditAttribution: webkenny commentedRe-roll attached. I am a big fan of the addition of
drupal_unlink
- It introduces lower level file handling to the API for modules that may want to make use of unlink instead offile_delete
.I can also confirm this does, in fact, work on IIS7 (Windows 7, 64-Bit) thought it would be nice to get some older builds of IIS in the mix here.
Comment #40
sunThis wasn't reviewed / RTBC yet, as far as I can see.
Comment #41
webkenny CreditAttribution: webkenny commented@sun, Thanks. You are right. Still needs review. My tests pass but others need to have a peek.
Comment #42
Dries CreditAttribution: Dries commentedI hate the fact that we need to work around OS-difference. This is a PHP bug, IMO.
I don't have a Windows machine so I can't really test it but webkenny (who is sitting next to me) ran the tests on Windows.
As far as I can tell this is ready. Painful but ready. I won't commit it yet so we leave some more time for reviews.
Comment #43
sunStrange wrapping. Can we write this on one line, please?
Trailing white-space.
Should be drupal_chmod(), no?
Do we have to alter the Archive_Tar library?
Powered by Dreditor.
Comment #44
andypostAs I pointed above ONLY 0200 (readable) make sense for WIN, 0400 useless because actually no changes happen in filesystem
Comment #45
scor CreditAttribution: scor commentedrerolling with changes suggested in #45 except:
We would not have to if it had it's own work around for WIN. What do you suggest instead, no WIN support? Per #870204: Revert coding style changes to system.tar.inc & other externally developed files, this would fall under "Only keep changes required for Drupal integration.". This should be fixed upstream in the tar library.
Comment #46
Dries CreditAttribution: Dries commentedCommitted to CVS HEAD. Great! :)
Comment #47
Damien Tournoud CreditAttribution: Damien Tournoud commentedActually, we might want to revert that. Because both rmdir() and unlink() are in the stream wrapper interface, we can do much better then this.
Comment #48
Damien Tournoud CreditAttribution: Damien Tournoud commentedThis patch (untested) might allow us to remove drupal_unlink() and drupal_rmdir().
Comment #49
scor CreditAttribution: scor commentedthere is also the filesystem permission to address in #44 which remains to be addressed
Comment #50
Dries CreditAttribution: Dries commentedNot sure the proposed alternative is 'much better'. It certainly is something we want to evaluate more (and in the mean time, the critical bug has been addressed).
Comment #51
Damien Tournoud CreditAttribution: Damien Tournoud commentedThis approach is better because we don't have to rely on everyone explicitely calling drupal_unlink() and drupal_rmdir(). If you think this is a hack, it certainly is. But it seems to work alright.
Also, with this framework we can fix other crazy issues with filesystem on Windows, e.g.: #874172: is_writable() cannot be use to determine if a directory is writable (on Windows).
Comment #52
Dries CreditAttribution: Dries commentedYep, I'm on board with all of that. As I wrote: let's continue to explore your option.
Comment #53
Dries CreditAttribution: Dries commentedI'm demoting this issue because it is no longer critical. The actual bug was fixed, the proposal in #48 is further clean-up. :-)
Comment #54
hass CreditAttribution: hass commented+
Comment #55
sun.core CreditAttribution: sun.core commentedDemoting to normal. Might still be nice to that follow-up clean-up, but as of now, there doesn't seem to be a real problem in HEAD.
Comment #56
andypostLnked issue #278425: Using basename() is not locale safe