]> granicus.if.org Git - clang/commitdiff
[VFS] Just normalize away .. and . in paths for in-memory file systems.
authorBenjamin Kramer <benny.kra@googlemail.com>
Fri, 9 Oct 2015 13:03:22 +0000 (13:03 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Fri, 9 Oct 2015 13:03:22 +0000 (13:03 +0000)
This simplifies the code and gets us support for .. for free.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@249830 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/VirtualFileSystem.h
lib/Basic/VirtualFileSystem.cpp
unittests/Basic/VirtualFileSystemTest.cpp

index 3f2d3b800afb07b7edacae4b7dd64c8086d2a43e..f93d69f604ec8d5fdb7c43e223bf5caf35feb2f9 100644 (file)
@@ -283,7 +283,7 @@ public:
   /// Add a buffer to the VFS with a path. The VFS does not own the buffer.
   void addFileNoOwn(const Twine &Path, time_t ModificationTime,
                     llvm::MemoryBuffer *Buffer);
-  StringRef toString() const;
+  std::string toString() const;
 
   llvm::ErrorOr<Status> status(const Twine &Path) override;
   llvm::ErrorOr<std::unique_ptr<File>>
index 04383dbb878cda32e8603ecf44e5f18c0545b59a..6e55d2e7d7860c589c1b3310e1e67481b6193f71 100644 (file)
@@ -10,6 +10,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Basic/VirtualFileSystem.h"
+#include "clang/Basic/FileManager.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
@@ -482,7 +483,7 @@ InMemoryFileSystem::InMemoryFileSystem()
 
 InMemoryFileSystem::~InMemoryFileSystem() {}
 
-StringRef InMemoryFileSystem::toString() const {
+std::string InMemoryFileSystem::toString() const {
   return Root->toString(/*Indent=*/0);
 }
 
@@ -496,17 +497,14 @@ void InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime,
   assert(!EC);
   (void)EC;
 
+  FileManager::removeDotPaths(Path, /*RemoveDotDot=*/true);
+  if (Path.empty())
+    return;
+
   detail::InMemoryDirectory *Dir = Root.get();
   auto I = llvm::sys::path::begin(Path), E = llvm::sys::path::end(Path);
   while (true) {
     StringRef Name = *I;
-    // Skip over ".".
-    // FIXME: Also handle "..".
-    if (Name == ".") {
-      ++I;
-      continue;
-    }
-
     detail::InMemoryNode *Node = Dir->getChild(Name);
     ++I;
     if (!Node) {
@@ -558,17 +556,12 @@ lookupInMemoryNode(const InMemoryFileSystem &FS, detail::InMemoryDirectory *Dir,
   assert(!EC);
   (void)EC;
 
+  FileManager::removeDotPaths(Path, /*RemoveDotDot=*/true);
+  if (Path.empty())
+    return Dir;
+
   auto I = llvm::sys::path::begin(Path), E = llvm::sys::path::end(Path);
   while (true) {
-    // Skip over ".".
-    // FIXME: Also handle "..".
-    if (*I == ".") {
-      ++I;
-      if (I == E)
-        return Dir;
-      continue;
-    }
-
     detail::InMemoryNode *Node = Dir->getChild(*I);
     ++I;
     if (!Node)
index 6ed811f22f3f9725b95d101534623841935b0a01..b98e999cd6018c26791eee11fe70a08e3c29283d 100644 (file)
@@ -569,6 +569,7 @@ TEST_F(InMemoryFileSystemTest, OverlayFileNoOwn) {
 TEST_F(InMemoryFileSystemTest, OpenFileForRead) {
   FS.addFile("/a", 0, MemoryBuffer::getMemBuffer("a"));
   FS.addFile("././c", 0, MemoryBuffer::getMemBuffer("c"));
+  FS.addFile("./d/../d", 0, MemoryBuffer::getMemBuffer("d"));
   auto File = FS.openFileForRead("/a");
   ASSERT_EQ("a", (*(*File)->getBuffer("ignored"))->getBuffer());
   File = FS.openFileForRead("/a"); // Open again.
@@ -581,6 +582,8 @@ TEST_F(InMemoryFileSystemTest, OpenFileForRead) {
   ASSERT_EQ(File.getError(), errc::no_such_file_or_directory) << FS.toString();
   File = FS.openFileForRead("./c");
   ASSERT_EQ("c", (*(*File)->getBuffer("ignored"))->getBuffer());
+  File = FS.openFileForRead("e/../d");
+  ASSERT_EQ("d", (*(*File)->getBuffer("ignored"))->getBuffer());
 }
 
 TEST_F(InMemoryFileSystemTest, DirectoryIteration) {