Skip to content

Handling of volume designators broken on windows #99

@Flamefire

Description

@Flamefire

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 and C:/tmp/real
  • Observe different results while stepping through boost source (see below)

What happens:

  • We are iterating over the path in
    for (path::iterator itr = source.begin(); itr != source.end(); ++itr)
  • The first entry is "C:"
  • This is passed into is_symlink in
    bool is_sym (is_symlink(detail::symlink_status(result, ec)));
    yielding true when in junction and false when in real!!!

Reason for that is the call to GetFileAttributesW in

DWORD attr(::GetFileAttributesW(p.c_str()));
. As described in e.g. https://stackoverflow.com/questions/38300808/why-does-getfileattributeswlc-return-file-attribute-reparse-point "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])

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions