You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
rename fails on Windows PHP 8.1 if the target file is being executed #7910
PHP Warning: rename(newfile.php,C:\Users\John\projects\test\bug.php): Access is denied (code: 5) in C:\Users\John\projects\test\bug.php on line 6
Warning: rename(newfile.php,C:\Users\John\projects\test\bug.php): Access is denied (code: 5) in C:\Users\John\projects\test\bug.php on line 6
bool(false)
Note that on Composer 2 we now use copy on Windows (to get around potential permission issues in UAC protected locations) and this still works on PHP 8.1, but Composer 1 uses rename (as do all non-Windows platforms on all Composer versions).
The file is opened in FILE_SHARE_DELETE mode, but apparently, moving an opened source file is possible, while moving to an opened destination file is not:
C:\php-sdk\phpdev\vs16\x64
$ echo foo>foo
C:\php-sdk\phpdev\vs16\x64
$ echo bar>bar
C:\php-sdk\phpdev\vs16\x64
$ type movefile.c
#include <Windows.h>
int main(void)
{
HANDLE file = CreateFileA(
"bar",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
BOOL res = MoveFileExA(
"foo",
"bar",
MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED);
printf("%d", res);
return 0;
}
C:\php-sdk\phpdev\vs16\x64
$ cl movefile.c
Microsoft (R) C/C++-Optimierungscompiler Version 19.29.30138 für x64
Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.
movefile.c
Microsoft (R) Incremental Linker Version 14.29.30138.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:movefile.exe
movefile.obj
C:\php-sdk\phpdev\vs16\x64
$ movefile.exe
0
C:\php-sdk\phpdev\vs16\x64
$ type foo
foo
C:\php-sdk\phpdev\vs16\x64
$ type bar
bar
I think we either need to close the script file right after compilation, or accept that this is just not supported on Windows. I'd prefer to do the former, unless there is a good reason to keep the script file open.
Thanks for the demo. That makes sense (I should have thought about it a bit more).
I'd prefer to do the former, unless there is a good reason to keep the script file open.
Let's hope there isn't. I appreciate your time and involvement in this. Moving to Github issues has made PHP bugs a lot more interesting and compelling - for me anyway.
Reacted by Jordi Boggiano, Christoph M. Becker, Ryan Jentzsch and Jakob Schumann
In the meantime, here's the rector config I use to circumvent the issue:
// rector.php$rectorConfig->paths([
__DIR__ . '/src',
__DIR__ . '/vendor/symfony/',
__DIR__ . '/vendor/doctrine/',
// Add any dependency that causes issues, adding the whole vendor directory might be too much on your PC
]);
$rectorConfig->ruleWithConfiguration(RenameFunctionRector::class, [
'rename' => 'windows_rename_fix',
]);
Does this relate to the fact that in PHP 8 (8.1.27, 8.2.16, 8.3.3), on Windows, unlink() cannot delete a currently running script? Since PHP 7 (7.4.33) doesn't have this problem, I guess it's a regression?
I'm not sure if I could reproduce it as it was very "random" as to when the problem would occur, and I don't currently have access to the repo that had the issue
I'm not sure if I could reproduce it as it was very "random" as to when the problem would occur, and I don't currently have access to the repo that had the issue
The problem is reproducible in 100% of cases when updating GravCMS on Windows with PHP 8+ (on PHP 7 everything is fine).
That's interesting as my use case was Symfony's entity classes (or something related) cache and getting to hit the bug mid-request (i.e. when the file would be open/read prior to being replaced) was complex
Activity
cmb69 commentedon Jan 7, 2022
The regression is apparently caused by c732ab4. I shall have a look.
johnstevenson commentedon Jan 8, 2022
Hey thanks. It seems like the file is locked, because cmd.exe
movealso fails when we call it as part of our UAC elevation stuff.cmb69 commentedon Jan 8, 2022
The file is not locked in a strict sense, but the handle is kept open after compilation, and that prevents the file to be renamed on Windows.
johnstevenson commentedon Jan 8, 2022
Ah, so presumably the file has not been opened with
FILE_SHARE_DELETEaccess.cmb69 commentedon Jan 8, 2022
The file is opened in
FILE_SHARE_DELETEmode, but apparently, moving an opened source file is possible, while moving to an opened destination file is not:I think we either need to close the script file right after compilation, or accept that this is just not supported on Windows. I'd prefer to do the former, unless there is a good reason to keep the script file open.
johnstevenson commentedon Jan 8, 2022
Thanks for the demo. That makes sense (I should have thought about it a bit more).
Let's hope there isn't. I appreciate your time and involvement in this. Moving to Github issues has made PHP bugs a lot more interesting and compelling - for me anyway.
Fix phpGH-7910: rename fails on Windows if the target is being executed
3 remaining items
Fix phpGH-7910: rename fails on Windows if the target is being executed
johnstevenson commentedon Jan 25, 2023
@cmb69 Apologies for the BUMP, but it would be good if this could be fixed.
Voltra commentedon Feb 7, 2023
This also happens (sometimes) when files are being cached using Symfony or Laravel's default cache and filesystem adapters
(Happens on 7.4.26 too, from Wamp 3.2.6)
Voltra commentedon Mar 10, 2023
In the meantime, here's the rector config I use to circumvent the issue:
And I add the
monkey_patch.phpin theautoload.filesarray in my composer.jsonlufog commentedon Mar 11, 2024
Does this relate to the fact that in PHP 8 (8.1.27, 8.2.16, 8.3.3), on Windows, unlink() cannot delete a currently running script? Since PHP 7 (7.4.33) doesn't have this problem, I guess it's a regression?
nicolas-grekas commentedon Jul 5, 2024
Is this issue still relevant? Didn't @cmb69 fix it in c7f24d9?
nicolas-grekas commentedon Jul 5, 2024
Ah, yes, #9351 is still opened as draft. Would be could is someone could take over!
Voltra commentedon Jul 5, 2024
I'm not sure if I could reproduce it as it was very "random" as to when the problem would occur, and I don't currently have access to the repo that had the issue
gggeek commentedon Jul 26, 2024
@nicolas-grekas I dont have MS build tooling installed any more, but I can help testing #9351 as long as there are prebuilt binaries I can download...
lufog commentedon Jul 26, 2024
The problem is reproducible in 100% of cases when updating GravCMS on Windows with PHP 8+ (on PHP 7 everything is fine).
Voltra commentedon Jul 26, 2024
That's interesting as my use case was Symfony's entity classes (or something related) cache and getting to hit the bug mid-request (i.e. when the file would be open/read prior to being replaced) was complex
johnstevenson commentedon Jul 27, 2024
See #7910 (comment)
Voltra commentedon Aug 14, 2024
Using my current WAMP setup, here are the PHP versions that suffer from the bug:
Here are the versions that don't: