Description
Describe the bug
Environment: with Long Paths DISABLED. Yuck. But test will probably still work due to lack of longPathAware manifest.
__std_fs_get_stats calls GetFileAttributesExW() on a filename that exists, but is too long,
this function returns that it does not exist, and that is the result.
Line 868 in 8e9f4ee
However, if the parent path is UNDER the limit by a few characters, and the filename is OVER the limit,
then you can use directory_iterator{parent_dir} to retrieve the details of the filename (and will say it exists),
but, if you call directory_entry{filename}, it will tell you the file does not exist.
Instead, if the filename is too long because of the legacy limits, then please, throw the exception. Don't say the query was successful and the file does not exist.
It is problematic that directory_iterator will still work, but, whatever, this is still better.
Command-line test case
C:\Temp>type test_stat_long.cpp
#include <iostream>
#include <filesystem>
#include <fstream>
int main()
{
try {
std::filesystem::path short_base_folder { "c:/Temp/short" };
std::filesystem::path long_base_folder { "c:/Temp/long long long long long long long long long" };
std::filesystem::path subfolders { "long long long long long long/long long long long long long/long long long long long long/long long long long long long/long long long long long long/long long long long long long/final long" };
std::filesystem::path short_folder { short_base_folder / subfolders };
std::filesystem::path long_folder { long_base_folder / subfolders };
std::filesystem::create_directories(short_folder);
std::filesystem::path fn { "long_long_file_name_the_file.txt" };
std::filesystem::path fn_short_path = short_folder / fn;
std::filesystem::path fn_long_path = long_folder / fn;
std::ofstream out;
out.exceptions(std::ios::badbit | std::ios::failbit);
out.open(fn_short_path, std::ios::binary);
out << "Hello world\n";
out.close();
std::filesystem::rename(short_base_folder, long_base_folder);
for ( std::filesystem::directory_entry entry : std::filesystem::directory_iterator { long_folder } )
std::cout << "Iterator, file: " << entry.path().generic_string() << "\nFile exists? " << (int)entry.exists() << std::endl << std::endl;
std::filesystem::directory_entry entry { fn_long_path };
std::cout << "Direct: File exists? " << (int)entry.exists() << std::endl;
return 0;
}
catch (std::exception & e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
catch (...) {
std::cerr << "Unknown Exception" << std::endl;
}
return 1;
}
C:\Temp>cl /EHsc /W4 /WX /std:c++latest .\test_stat_long.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.43.34810 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
/std:c++latest is provided as a preview of language features from the latest C++
working draft, and we're eager to hear about bugs and suggestions for improvements.
However, note that these features are provided as-is without support, and subject
to changes or removal as the working draft evolves. See
https://go.microsoft.com/fwlink/?linkid=2045807 for details.
test_stat_long.cpp
Microsoft (R) Incremental Linker Version 14.43.34810.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:test_stat_long.exe
test_stat_long.obj
C:\Temp>.\test_stat_long.exe
Iterator, file: c:/Temp/long long long long long long long long long/long long long long long long/long long long long long long/long long long long long long/long long long long long long/long long long long long long/long long long long long long/final long/long_long_file_name_the_file.txt
File exists? 1
Direct: File exists? 0
Expected behavior
If long-paths were enabled in the registry, and the program had a manifest for longPathAware=true,
then I would expect "File exists? 1".
In this case, with long-paths disabled and no program manifest,
I would expect directory_entry to throw a filesystem_error(filename_too_long)
STL version
- Visual Studio version
Microsoft Visual Studio Community 2022 (64-bit) - Current
Version 17.13.6
```