Skip to content
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

Warn on filesystem case mismatch #98927

Merged
merged 1 commit into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions drivers/unix/file_access_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.");

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.");

Expand Down
4 changes: 4 additions & 0 deletions drivers/unix/file_access_unix.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion drivers/windows/file_access_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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://,
Expand Down
Loading