Skip to content

Commit b80aa65

Browse files
committed
Merge pull request #98927 from fire/warn-file-case-mismatch
Warn on filesystem case mismatch
2 parents 297ceda + c09731c commit b80aa65

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

drivers/unix/file_access_unix.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@
4141
#include <sys/types.h>
4242
#include <unistd.h>
4343

44+
#if defined(TOOLS_ENABLED)
45+
#include <limits.h>
46+
#include <stdlib.h>
47+
#endif
48+
4449
void FileAccessUnix::check_errors() const {
4550
ERR_FAIL_NULL_MSG(f, "File must be opened before use.");
4651

@@ -87,6 +92,22 @@ Error FileAccessUnix::open_internal(const String &p_path, int p_mode_flags) {
8792
}
8893
}
8994

95+
#if defined(TOOLS_ENABLED)
96+
if (p_mode_flags & READ) {
97+
String real_path = get_real_path();
98+
if (real_path != path) {
99+
// Don't warn on symlinks, since they can be used to simply share addons on multiple projects.
100+
if (real_path.to_lower() == path.to_lower()) {
101+
// The File system is case insensitive, but other platforms can be sensitive to it
102+
// To ease cross-platform development, we issue a warning if users try to access
103+
// a file using the wrong case (which *works* on Windows and macOS, but won't on other
104+
// platforms).
105+
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));
106+
}
107+
}
108+
}
109+
#endif
110+
90111
if (is_backup_save_enabled() && (p_mode_flags == WRITE)) {
91112
save_path = path;
92113
// Create a temporary file in the same directory as the target file.
@@ -173,6 +194,26 @@ String FileAccessUnix::get_path_absolute() const {
173194
return path;
174195
}
175196

197+
#if defined(TOOLS_ENABLED)
198+
String FileAccessUnix::get_real_path() const {
199+
char *resolved_path = ::realpath(path.utf8().get_data(), nullptr);
200+
201+
if (!resolved_path) {
202+
return path;
203+
}
204+
205+
String result;
206+
Error parse_ok = result.parse_utf8(resolved_path);
207+
::free(resolved_path);
208+
209+
if (parse_ok != OK) {
210+
return path;
211+
}
212+
213+
return result.simplify_path();
214+
}
215+
#endif
216+
176217
void FileAccessUnix::seek(uint64_t p_position) {
177218
ERR_FAIL_NULL_MSG(f, "File must be opened before use.");
178219

drivers/unix/file_access_unix.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ class FileAccessUnix : public FileAccess {
5151

5252
void _close();
5353

54+
#if defined(TOOLS_ENABLED)
55+
String get_real_path() const; // Returns the resolved real path for the current open file.
56+
#endif
57+
5458
public:
5559
static CloseNotificationFunc close_notification_func;
5660

drivers/windows/file_access_windows.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ Error FileAccessWindows::open_internal(const String &p_path, int p_mode_flags) {
127127
}
128128

129129
#ifdef TOOLS_ENABLED
130-
// Windows is case insensitive, but all other platforms are sensitive to it
130+
// Windows is case insensitive in the default configuration, but other platforms can be sensitive to it
131131
// To ease cross-platform development, we issue a warning if users try to access
132132
// a file using the wrong case (which *works* on Windows, but won't on other
133133
// platforms), we only check for relative paths, or paths in res:// or user://,

0 commit comments

Comments
 (0)