-
Notifications
You must be signed in to change notification settings - Fork 164
Description
I noticed the problem when using canonical
when I'm currently in a directory with a junction point.
To reproduce:
- Create junction point:
mklink /J C:/tmp/junction C:/tmp/real
- Put an executable into
C:/tmp/real
which calls e.g.canonical("C:/tmp/real")
- Execute once form within
C:/tmp/junction
andC:/tmp/real
- Observe different results while stepping through boost source (see below)
What happens:
- We are iterating over the path in
Line 888 in b0a0fde
for (path::iterator itr = source.begin(); itr != source.end(); ++itr) - The first entry is
"C:"
- This is passed into
is_symlink
inLine 901 in b0a0fde
bool is_sym (is_symlink(detail::symlink_status(result, ec))); junction
and false when inreal
!!!
Reason for that is the call to GetFileAttributesW
in
Line 1901 in b0a0fde
DWORD attr(::GetFileAttributesW(p.c_str())); |
"C:"
does not mean "the drive C" but "the current working directory on drive C" (https://docs.microsoft.com/de-de/windows/desktop/FileIO/naming-a-file)
If a file name begins with only a disk designator but not the backslash after the colon, it is interpreted as a relative path to the current directory on the drive with the specified letter.
This is a very serious issue as it returns wrong results in unexpected ways.
I'm not sure how to fix this. Maybe iteration should not return the "root_name" but the "root_path" first? Or the root_name on windows shall include the slash if given?
I'm afraid there was a mistake when defining the decomposition table (https://www.boost.org/doc/libs/1_68_0/libs/filesystem/doc/reference.html#path-decomposition-table): for c:
vs c:\
(vs c:/
?): the (back)slash after the colon has to be treated as part of the first element or the meaning is significantly altered. (I'm not 100% sure that C:\
is the same as C:/
but it seems like [GetFileAttributesW
returns the same])