This is an archive of the discontinued LLVM Phabricator instance.

[llvm-rc] Handle driveless absolute windows paths when loading external files
ClosedPublic

Authored by mstorsjo on Dec 3 2020, 2:15 AM.

Details

Summary

When llvm-rc loads an external file, it looks for it relative to a number of include directories and the current working directory. If the path is considered absolute, llvm-rc tries to open the filename as such, and doesn't try to open it relative to other paths.

On Windows, a path name like "\dir\file" isn't considered absolute as it lacks the drive name, but by appending it on top of the search dirs, it's not found.

LLVM's sys::path::append just appends such a path (same with a properly absolute posix path) after the paths it's supposed to be relative to.

This fix doesn't handle the case if the resource script and the external file are on a different drive than the current working directory; to fix that, we'd have to make LLVM's sys::path::append handle appending fully absolute and partially absolute paths (ones lacking a drive prefix but containing a root directory), or switch to C++17's std::filesystem.

There's an existing testcase for fully absolute paths, using lit's %t to expand to an absolute path. Making a testcase for this would probably require a bit more scripting in the test file, to strip out the drive name prefix from the absolute path, and embed that into a resource script.

Diff Detail

Event Timeline

mstorsjo created this revision.Dec 3 2020, 2:15 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 3 2020, 2:15 AM
mstorsjo requested review of this revision.Dec 3 2020, 2:15 AM
thakis accepted this revision.Dec 3 2020, 6:54 AM

If you're fine with this randomly breaking one day when someone changes path handling, I think this is fine as is. It is difficult to test.

This revision is now accepted and ready to land.Dec 3 2020, 6:54 AM
thakis added a comment.Dec 3 2020, 6:55 AM

(It'd maybe be nice to have a PR that has manual repro steps and link to that in the commit message at least.)

mstorsjo added a subscriber: rnk.Dec 4 2020, 5:06 AM

If you're fine with this randomly breaking one day when someone changes path handling, I think this is fine as is. It is difficult to test.

Actually, testing should be fairly straightforward with a diff like this:

diff --git a/llvm/test/tools/llvm-rc/absolute.test b/llvm/test/tools/llvm-rc/absolute.test
index 95aff3e42440..fd8b2d68d41e 100644
--- a/llvm/test/tools/llvm-rc/absolute.test 
+++ b/llvm/test/tools/llvm-rc/absolute.test
@@ -1,3 +1,7 @@ 
 ; RUN: touch %t.manifest
 ; RUN: echo "1 24 \"%t.manifest\"" > %t.rc
 ; RUN: llvm-rc -- %t.rc
+;; On Windows, try stripping out the drive name from the absolute path,
+;; and make sure the path still is found.
+; RUN: cat %t.rc | sed 's/"[a-zA-Z]:/"/' > %t2.rc
+; RUN: llvm-rc -- %t2.rc

But can we rely on tools like sed being available on windows test setups? (I faintly remember someone summarizing what tools we can rely on being available somewhere - @rnk?) I guess it also should be possible to do that replacement with some sort of shell expansion, like ABS="%t"; ROOTLESS="${ABS#*:\\}"; echo "1 24 \"$ROOTLESS\"" > %t2.rc

mstorsjo updated this revision to Diff 310346.Dec 8 2020, 2:12 PM

Concluded that sed is one of the tools that is supposed to be available when running tests on windows, so it should be safe to add a test that uses it.

rnk accepted this revision.Dec 9 2020, 12:09 PM

lgtm

llvm/test/tools/llvm-rc/absolute.test
6

Yep, it's available.