mirror of
https://github.com/godotengine/godot.git
synced 2024-11-24 05:04:10 +00:00
Warn on filesystem case mismatch
When a file is opened with a wrong case, it can work on the developer system but break on a user system with a case-sensitive filesystem. This will display a warning when it happens. CAVEATS: It will also display the warning if a symlink is in the path. Adapt warning if the file is a symlink. Avoid warning on symlinks. Fix memory leak and avoid `lstat` usage. Avoid exposing real_path when not in TOOLS_ENABLED mode.
This commit is contained in:
parent
87318a2fb7
commit
c09731c413
@ -41,6 +41,11 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(TOOLS_ENABLED)
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
void FileAccessUnix::check_errors() const {
|
||||
ERR_FAIL_NULL_MSG(f, "File must be opened before use.");
|
||||
|
||||
@ -87,6 +92,22 @@ Error FileAccessUnix::open_internal(const String &p_path, int p_mode_flags) {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(TOOLS_ENABLED)
|
||||
if (p_mode_flags & READ) {
|
||||
String real_path = get_real_path();
|
||||
if (real_path != path) {
|
||||
// Don't warn on symlinks, since they can be used to simply share addons on multiple projects.
|
||||
if (real_path.to_lower() == path.to_lower()) {
|
||||
// The File system is case insensitive, but other platforms can be sensitive to it
|
||||
// To ease cross-platform development, we issue a warning if users try to access
|
||||
// a file using the wrong case (which *works* on Windows and macOS, but won't on other
|
||||
// platforms).
|
||||
WARN_PRINT(vformat("Case mismatch opening requested file '%s', stored as '%s' in the filesystem. This file will not open when exported to other case-sensitive platforms.", path, real_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (is_backup_save_enabled() && (p_mode_flags == WRITE)) {
|
||||
save_path = path;
|
||||
// Create a temporary file in the same directory as the target file.
|
||||
@ -173,6 +194,26 @@ String FileAccessUnix::get_path_absolute() const {
|
||||
return path;
|
||||
}
|
||||
|
||||
#if defined(TOOLS_ENABLED)
|
||||
String FileAccessUnix::get_real_path() const {
|
||||
char *resolved_path = ::realpath(path.utf8().get_data(), nullptr);
|
||||
|
||||
if (!resolved_path) {
|
||||
return path;
|
||||
}
|
||||
|
||||
String result;
|
||||
Error parse_ok = result.parse_utf8(resolved_path);
|
||||
::free(resolved_path);
|
||||
|
||||
if (parse_ok != OK) {
|
||||
return path;
|
||||
}
|
||||
|
||||
return result.simplify_path();
|
||||
}
|
||||
#endif
|
||||
|
||||
void FileAccessUnix::seek(uint64_t p_position) {
|
||||
ERR_FAIL_NULL_MSG(f, "File must be opened before use.");
|
||||
|
||||
|
@ -51,6 +51,10 @@ class FileAccessUnix : public FileAccess {
|
||||
|
||||
void _close();
|
||||
|
||||
#if defined(TOOLS_ENABLED)
|
||||
String get_real_path() const; // Returns the resolved real path for the current open file.
|
||||
#endif
|
||||
|
||||
public:
|
||||
static CloseNotificationFunc close_notification_func;
|
||||
|
||||
|
@ -127,7 +127,7 @@ Error FileAccessWindows::open_internal(const String &p_path, int p_mode_flags) {
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
// Windows is case insensitive, but all other platforms are sensitive to it
|
||||
// Windows is case insensitive in the default configuration, but other platforms can be sensitive to it
|
||||
// To ease cross-platform development, we issue a warning if users try to access
|
||||
// a file using the wrong case (which *works* on Windows, but won't on other
|
||||
// platforms), we only check for relative paths, or paths in res:// or user://,
|
||||
|
Loading…
Reference in New Issue
Block a user