Re: [Boost-bugs] [Boost C++ Libraries] #10900: read_symlink fails to correctly read NTFS junctions

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #10900: read_symlink fails to correctly read NTFS junctions
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-05-30 14:59:26


#10900: read_symlink fails to correctly read NTFS junctions
-------------------------------------------------+------------------------
  Reporter: Benjamin Kummer-Hardt <benjamin@…> | Owner: bemandawes
      Type: Bugs | Status: assigned
 Milestone: To Be Determined | Component: filesystem
   Version: Boost 1.57.0 | Severity: Problem
Resolution: | Keywords:
-------------------------------------------------+------------------------

Comment (by anonymous):

 test case is already on file libs/filesystem/src/operations.cpp around
 line 139. But I'll provide another (for a system with Windows 7 or above,
 volumes C: and D:)
 Start by creating a directory symlink [Users] in volume D: pointing to
 [C:\Users]:

 D:\>mklink /D Users C:\Users

 Create a simple program to resolve path dot:

 //app.cpp
 ...
 cout << boost::filesystem::canonical(".") << '\n\n';
 ...

 Compile and run the program from the symlink

 D:\Users\Public\Documents>app.exe

 The code will burn CPU trapped in the loop at line 813 of operations.cpp,
 trying to resolve the symlink (internal temp buffer "C:/\\Users")

 At line 1508, from where REPARSE_DATA_BUFFER is used, PrintNameOffset and
 PrintNameLength values are the same to both sub struct
 SymbolicLinkReparseBuffer and MountPointReparseBuffer.

 The values fails when applied to SymbolicLinkReparseBuffer.PathBuffer. But
 works right on MountPointReparseBuffer.PathBuffer.

 With this (example only) change:

 {{{

 if (!error(::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT,
           0, 0, info.buf, sizeof(info), &sz, 0) == 0 ? BOOST_ERRNO : 0, p,
 ec,
           "boost::filesystem::read_symlink" ))
       symlink_path.assign(
 +
 static_cast<wchar_t*>(info.rdb.MountPointReparseBuffer.PathBuffer)
 + + info.rdb.MountPointReparseBuffer.PrintNameOffset /
 sizeof(wchar_t),
 +
 static_cast<wchar_t*>(info.rdb.MountPointReparseBuffer.PathBuffer)
 + + info.rdb.MountPointReparseBuffer.PrintNameOffset /
 sizeof(wchar_t)
 + + info.rdb.MountPointReparseBuffer.PrintNameLength /
 sizeof(wchar_t));
 -
 static_cast<wchar_t*>(info.rdb.SymbolicLinkReparseBuffer.PathBuffer)
 - +
 info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(wchar_t),
 -
 static_cast<wchar_t*>(info.rdb.SymbolicLinkReparseBuffer.PathBuffer)
 - +
 info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(wchar_t)
 - +
 info.rdb.SymbolicLinkReparseBuffer.PrintNameLength/sizeof(wchar_t));
 }}}


 Output is correct: "C:/Users\Public\Documents"

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/10900#comment:3>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:18 UTC