-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Windows platform file access to allow file sharing with external programs #51430
Conversation
Short explanation on sharing modes:
I debated instead changing it to |
I'm not very fond of the presence of the cosmetic changes in the same commit, but looks good to me overall. |
I have no problem seperating those to a second commit if you want :) Just didn't bother because it was only 9 lines. |
This restores Windows platform file handling back to open files non-exlusively by default, as was the case before October 2018. (See godotengine@b902a2f) Back then, while fixing warnings for MSVC, the function used for opening files was changed from _wfopen() to _wfopen_s() as suggsted by the warning C4996. ("This function may be unsafe, consider using _wfopen_s instead.") This new function 1. did parameter validation and thus avoided some possible security issues due to nil pointers or wrongly terminated strings 2. it also changed the default file sharing for opened files from _SH_DENYNO (which was the implicit default for the previous _wfopen()) to _SH_SECURE. _SH_DENYNO means every opened file could be opened by other calls (like is the default on other operating systems). _SH_SECURE means if the file is opened with READ access, others can still read the same file, but if it is opened with WRITE access, others can't open it at all, not even to read. This led to rarely occuring bugs on Windows, i.e. due to random access by Antivirus processes, or Godot/Windows not closing a file handle fast enough while trying to open it again elsewhere (i.e. project.godot, instead showing the Project manager, or saving shaders/debugging the game). What this PR does it change the file access to a third method, _wfsopen(). This is still secure, doing parameter validation and thus avoids the warning, but it allows us to actually SET the file sharing parameter. And we set it to _SH_DENYNO, as it was implicitely before the change. (And as it currently is on all non-Windows platforms, where file sharing restrictions don't exist by default.) Warning C4996 should really have been pointing this out. It should've been _wfsopen() all along. Let's hope this banishes those annoying, rare errors for all eternity. Fixes godotengine#28036.
I think it's OK in this case as it's indeed just a few lines. For more substantial changes keeping them separate is good practice indeed. |
24239c9
to
be8c665
Compare
be8c665
to
a5c179e
Compare
Seperated cosmetic changes into a second commit, added a dot :) |
Thanks! |
MinGW (9.0.0, GCC 11.2.0) build on macOS fails with |
Fixed by #51470. |
Cherry-picked for 3.4. |
Follow-up to godotengine#51430. (cherry picked from commit cb52f2c)
Cherry-picked for 3.3.3. |
Follow-up to godotengine#51430. (cherry picked from commit cb52f2c)
Follow-up to godotengine#51430. (cherry picked from commit cb52f2c)
This restores Windows platform file handling back to open files non-exlusively by default, as was the case before October 2018. (See b902a2f)
It seems back then it was unintentionally changed while fixing warnings.
This is fixed by changing the open call from
_wfopen_s()
to_wfsopen()
, thus being able to set the file sharing constant to_SH_DENYNO
while still preserving security features of_wfopen_s()
, like parameter validation, meaning the warning stays fixed.Fixes #28036.
I tested this change on Windows as extensively as I could and found no issues.
Details
Back then, while fixing warnings for MSVC, the function used for opening files was changed from
_wfopen()
to_wfopen_s()
as suggested by the warningC4996
. ("This function may be unsafe, consider using _wfopen_s instead."
)This new function
_SH_DENYNO
(which was the implicit default for the previous_wfopen()
) to_SH_SECURE
._SH_DENYNO
means every opened file could be opened by other calls (like is the default on other operating systems)._SH_SECURE
means if the file is opened with READ access, others can still read the same file (but not write to it), but if it is opened with WRITE access, others can't open it at all, not even to read.As this file sharing access is implied as default, not a parameter for either function, it seems this change was neither intended nor noticed.
This led to rarely occuring bugs on Windows, i.e. due to random access by Antivirus processes, or Godot/Windows not closing a file handle fast enough while trying to open it again elsewhere (i.e.
project.godot
, instead showing the Project Manager, or saving shaders/debugging the game).What this PR does is change the file access to a third method,
_wfsopen()
. This is still secure, doing parameter validation and thus avoids the warning, but it allows us to actually SET the file sharing parameter. And we set it to_SH_DENYNO
, as it was implicitely before the change. (And as it currently is on all non-Windows platforms, where file sharing restrictions don't exist by default.)Warning
C4996
should really have been pointing this out. It should've been_wfsopen()
all along. Let's hope this banishes those annoying, rare errors for all eternity.The only interesting lines are 116 and 316, changing the function used for opening in
FileAccessWindows::_open()
andFileAccessWindows::file_exists()
respectively, everything else are formatting fixes.Links:
_wfopen() docs
_wfopen_s() docs
_wfsopen() docs