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

Issues with saving files in case-insensitive file systems #52231

Open
YuriSizov opened this issue Aug 29, 2021 · 4 comments
Open

Issues with saving files in case-insensitive file systems #52231

YuriSizov opened this issue Aug 29, 2021 · 4 comments

Comments

@YuriSizov
Copy link
Contributor

YuriSizov commented Aug 29, 2021

Godot version

3.3, master (7368004)

System information

Windows 10

Issue description

While working on #52189 I've run into several issues regarding case sensitivity or lack thereof on Windows (probably applies to macOS as well).

Windows, being case-insensitive by default, is pretty tolerant to replacing res://aaa/file.tres with res://AaA/file.tres. It will still open or save the file and won't complain about it. The problem is, we have no way to know if the actual path in the file system is different from what we imagine it is. There are several ways a user can run into this situation, and as a result they may have a resource/scene with its path set to a value that is not actually correct, but that would still work on Windows.

To solve this we need to be able to "sanitize" paths by the means of the OS or the FS, letting them handle the inconsistencies, and we also may need a dedicated method to fetch a valid case-sensitive path from the given path.

These can then be utilized in the resource and scene saving logic of the editor to make sure that these resources know their correct paths.

Interestingly we already have a case for a warning on Windows, but I was unable to trigger it on master even with blatantly mismatched paths. It just didn't go past the invalid handle check.

#ifdef TOOLS_ENABLED
	// Windows is case insensitive, but all other platforms are 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).
	if (p_mode_flags == READ) {
		WIN32_FIND_DATAW d;
		HANDLE f = FindFirstFileW((LPCWSTR)(path.utf16().get_data()), &d);
		if (f != INVALID_HANDLE_VALUE) {
			String fname = String::utf16((const char16_t *)(d.cFileName));
			if (fname != String()) {
				String base_file = path.get_file();
				if (base_file != fname && base_file.findn(fname) == 0) {
					WARN_PRINT("Case mismatch opening requested file '" + base_file + "', stored as '" + fname + "' in the filesystem. This file will not open when exported to other case-sensitive platforms.");
				}
			}
			FindClose(f);
		}
	}
#endif

Another option here may be to completely enforce case insensitivity so there is no way to create files with conflicting names on any platform.

Steps to reproduce

One example would be to use a loophole in FileDialog and input the incorrectly-cased directory name into the "File" field when saving a scene. See #52230

Minimal reproduction project

No response

@YuriSizov
Copy link
Contributor Author

cc @mhilbrunner
You were interested in looking into this case insensitivity issue 🙂

@L2750558108
Copy link
Contributor

Will this (https://stackoverflow.com/questions/3644863/how-do-i-get-the-correct-case-of-a-path) helps?
Maybe it's possible to get the case-correct file path locally by going through each level of directories (although this can be cumbersome, there should at least be a solution, shouldn't there)

image
(Some of the qt functions need to be replaced)

@AThousandShips
Copy link
Member

@L2750558108 Thank you! Was roughly thinking this and will see if I can't make a few experiments along these lines to fix

@KoBeWi
Copy link
Member

KoBeWi commented Jul 10, 2023

I was able to trigger the warning using MRP from #79298:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants