summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPirama Arumuga Nainar <pirama@google.com>2017-08-21 20:49:44 +0000
committerPirama Arumuga Nainar <pirama@google.com>2017-08-21 20:49:44 +0000
commit3d48bb5fc2eb6316fa16a3f48cdf2c8df3ed217d (patch)
treec61d91123cf28c19eacab253f1cc7dcd3ca08622
parent08a38fe71e607505dd07c66e4fec6c3c4aff99f4 (diff)
downloadbcm5719-llvm-3d48bb5fc2eb6316fa16a3f48cdf2c8df3ed217d.tar.gz
bcm5719-llvm-3d48bb5fc2eb6316fa16a3f48cdf2c8df3ed217d.zip
[Support, Windows] Handle long paths with unix separators
Summary: The function widenPath() for Windows also normalizes long path names by iterating over the path's components and calling append(). The assumption during the iteration that separators are not returned by the iterator doesn't hold because the iterators do return a separator when the path has a drive name. Handle this case by ignoring separators during iteration. Reviewers: rnk Subscribers: danalbert, srhines Differential Revision: https://reviews.llvm.org/D36752 llvm-svn: 311382
-rw-r--r--llvm/lib/Support/Windows/Path.inc11
-rw-r--r--llvm/unittests/Support/Path.cpp15
2 files changed, 22 insertions, 4 deletions
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index 8dac0e4482b..f82a6bc07bd 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -94,13 +94,16 @@ std::error_code widenPath(const Twine &Path8,
return EC;
FullPath.append(CurPath);
}
- // Traverse the requested path, canonicalizing . and .. as we go (because
- // the \\?\ prefix is documented to treat them as real components).
- // The iterators don't report separators and append() always attaches
- // preferred_separator so we don't need to call native() on the result.
+ // Traverse the requested path, canonicalizing . and .. (because the \\?\
+ // prefix is documented to treat them as real components). Ignore
+ // separators, which can be returned from the iterator if the path has a
+ // drive name. We don't need to call native() on the result since append()
+ // always attaches preferred_separator.
for (llvm::sys::path::const_iterator I = llvm::sys::path::begin(Path8Str),
E = llvm::sys::path::end(Path8Str);
I != E; ++I) {
+ if (I->size() == 1 && is_separator((*I)[0]))
+ continue;
if (I->size() == 1 && *I == ".")
continue;
if (I->size() == 2 && *I == "..")
diff --git a/llvm/unittests/Support/Path.cpp b/llvm/unittests/Support/Path.cpp
index f1c8e7f1bdc..4de2e648259 100644
--- a/llvm/unittests/Support/Path.cpp
+++ b/llvm/unittests/Support/Path.cpp
@@ -699,6 +699,21 @@ TEST_F(FileSystemTest, CreateDir) {
ThisDir = path::parent_path(ThisDir);
}
+ // Also verify that paths with Unix separators are handled correctly.
+ std::string LongPathWithUnixSeparators(TestDirectory.str());
+ // Add at least one subdirectory to TestDirectory, and replace slashes with
+ // backslashes
+ do {
+ LongPathWithUnixSeparators.append("/DirNameWith19Charss");
+ } while (LongPathWithUnixSeparators.size() < 260);
+ std::replace(LongPathWithUnixSeparators.begin(),
+ LongPathWithUnixSeparators.end(),
+ '\\', '/');
+ ASSERT_NO_ERROR(fs::create_directories(Twine(LongPathWithUnixSeparators)));
+ // cleanup
+ ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) +
+ "/DirNameWith19Charss"));
+
// Similarly for a relative pathname. Need to set the current directory to
// TestDirectory so that the one we create ends up in the right place.
char PreviousDir[260];
OpenPOWER on IntegriCloud