Opened 7 years ago

Last modified 6 years ago

#12108 new Bugs

boost::filesystem::canonical() enters infinite loop when current path is a directory symlink on windows

Reported by: Tony Abbott <tony.abbott@…> Owned by: Beman Dawes
Milestone: To Be Determined Component: filesystem
Version: Boost 1.60.0 Severity: Problem
Keywords: Cc:

Description

On Windows platforms, when the current path is a directory symlink, boost::filesystem::canonical() enters an infinite loop.

Verified using attached program on Windows 8.1 and Windows Server 2012.

The problem occurs because when the current path is a directory symlink then boost::filesystem::is_symlink(path("c:")) returns true.

Assuming the following paths:

myDir = c:\temp\symlink-example\dir mySym = c:\temp\symlink-example\sym -> myDir myFile = c:\temp\symlink-example\dir\hello.txt

When current path is set to mySym and canonical(myFile) is called:

  • The path components of myFile are iterated over (operations.cpp:827)
  • "c:" is the first component. It is considered a symlink and expanded (operations.cpp:844)
  • The path then becomes c:\temp\symlink-example\dir\temp\symlink-example\dir\hello.txt
  • scan is set true and the loop repeats. "c:" is again expanded. The loop repeats infinitely as the path grows longer and longer

Attachments (1)

filesystem_canonical_bug.cpp (1.9 KB ) - added by Tony Abbott <tony.abbott@…> 7 years ago.

Download all attachments as: .zip

Change History (2)

by Tony Abbott <tony.abbott@…>, 7 years ago

comment:1 by libaracy@…, 6 years ago

Will boost fix it? I have encountered similar problem.

"C:" refers to current directory on drive C according to https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx#fully_qualified_vs._relative_paths

    // this is my test code:

    system("mkdir D:\\canonical");
    system("mkdir D:\\canonical\\target");
    system("echo test > D:\\canonical\\target\\test.txt");
    system("mklink /d D:\\canonical\\link D:\\canonical\\target");

    SetCurrentDirectoryW(L"D:\\canonical\\link");
    auto x = boost::filesystem::canonical(L"D:\\canonical\\link\\test.txt");

https://svn.boost.org/trac/boost/ticket/11138 should be similar.

Note: See TracTickets for help on using tickets.