This is an archive of the discontinued LLVM Phabricator instance.

[15/N] [libcxx] Implement the canonical function for windows
ClosedPublic

Authored by mstorsjo on Nov 10 2020, 8:36 AM.

Details

Diff Detail

Event Timeline

mstorsjo created this revision.Nov 10 2020, 8:36 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 10 2020, 8:36 AM
Herald added 1 blocking reviewer(s): Restricted Project. · View Herald Transcript
mstorsjo updated this revision to Diff 305082.Nov 13 2020, 3:45 AM
mstorsjo added a reviewer: amccarth.

Rebased on top of updated patches.

amccarth requested changes to this revision.Dec 3 2020, 2:56 PM
amccarth added inline comments.
libcxx/src/filesystem/operations.cpp
863

This return value needs to be checked more carefully.

If the final path is longer than the buffer, then GetFinalPathNameByHandleW will return the actual length needed, which will convince this if statement that the call succeeded when it didn't, and then we'll process the uninitialized buffer.

How can the final path require a buffer longer than MAX_PATH? Two ways:

  1. The function always returns the \\?\ prefix, so a path that (with it's terminating L'\0') is exactly MAX_PATH will require MAX_PATH+4 when the prefix is added.
  1. MAX_PATH applies to most Windows APIs, but not to the actual filesystem. It's possible to have a final path that's longer than MAX_PATH (especially since it's using the \\?\ prefix). If we don't think it's worth handling those, fine, but we'd need to detect that case so that we can return an error. (A common way this happens is when the user uses subst to replace a long prefix with a fictitious drive letter. This is, in fact, how we get certain LLDB source paths under the MAX_PATH limit on some of the Windows build bots.)
This revision now requires changes to proceed.Dec 3 2020, 2:56 PM
mstorsjo added inline comments.Dec 4 2020, 4:05 AM
libcxx/src/filesystem/operations.cpp
863

Thanks, good catch. Will update with a stack buffer that should fit all practical cases (MAX_PATH+10) and fall back on dynamic allocation if that wasn't big enough.

mstorsjo updated this revision to Diff 309509.Dec 4 2020, 4:07 AM

Check the return value of GetFinalPathNameFromHandleW if it overflowed the buffer size and handle it appropriately.

amccarth accepted this revision.Dec 11 2020, 2:28 PM

LGTM.

mstorsjo updated this revision to Diff 317581.Jan 19 2021, 8:25 AM

Made a new realpath posix-like helper for windows, change explicit char to path::value_type in calling code.

ldionne set the repository for this revision to rG LLVM Github Monorepo.Jan 28 2021, 3:18 PM
mstorsjo removed rG LLVM Github Monorepo as the repository for this revision.Jan 29 2021, 4:33 AM
mstorsjo updated this revision to Diff 320103.Jan 29 2021, 4:37 AM
mstorsjo set the repository for this revision to rG LLVM Github Monorepo.

Rebased, retriggering CI.

Compared to the older version that @amccarth approved, this is a little bit reworked to fit into the POSIX realpath() interface, which means it returns a malloc() allocated buffer, so the end of the function uses a bit of memmove/wcscpy to assemble paths, instead of the slightly simpler version before (when operating on the level of the __canonical function that returns a std::filesystem::path).

This touches the existing code a little bit to just change char into path::value_type, and add the detail:: prefix on the calls to realpath().

amccarth accepted this revision.Jan 29 2021, 10:45 AM

The changes to provide realpath on Windows looks right. Since it's relying on a system call, it would be difficult to create tests for the \\?\ and UNC cases. I'm assuming the more mainstream cases will be tested by existing tests. So LGTM.

ldionne accepted this revision.Feb 2 2021, 12:30 PM
This revision is now accepted and ready to land.Feb 2 2021, 12:30 PM
This revision was automatically updated to reflect the committed changes.