gulrak / filesystem

An implementation of C++17 std::filesystem for C++11 /C++14/C++17/C++20 on Windows, macOS, Linux and FreeBSD.
MIT License
1.31k stars 168 forks source link

Fix directory iterator treating all files subsequent to a symlink as symlink on Windows #162

Closed Qrox closed 1 year ago

Qrox commented 1 year ago

According to microsoft documentation on the dwReserved0 member of _WIN32_FIND_DATAW,

If the dwFileAttributes member includes the FILE_ATTRIBUTE_REPARSE_POINT attribute, this member specifies the reparse point tag.

Otherwise, this value is undefined and should not be used.

reparse_tag_from_INFO uses dwReserved0 without checking the FILE_ATTRIBUTE_REPARSE_POINT attribute, which causes directory_iterator to use a stale dwReserved0 value for all files subsequent to a symlink, causing all of these files to be treated as symlink incorrectly.

This patch checks FILE_ATTRIBUTE_REPARSE_POINT before checking dwReserved0 to correctly get the symlink status of the files. Also replaced a hack that uses structure size to determine structure type with proper templates.

This patch is tested on https://github.com/CleverRaven/Cataclysm-DDA/pull/63612 and cherrypicked from that PR.

gulrak commented 1 year ago

Thank you for the fix!