[llvm] r319750 - [Support/TarWriter] - Don't allow TarWriter to add the same file more than once.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 5 02:09:59 PST 2017


Author: grimar
Date: Tue Dec  5 02:09:59 2017
New Revision: 319750

URL: http://llvm.org/viewvc/llvm-project?rev=319750&view=rev
Log:
[Support/TarWriter] - Don't allow TarWriter to add the same file more than once.

This is for PR35460.

Currently when LLD adds files to TarWriter it may pass the same file
multiple times. For example it happens for clang reproduce file which specifies
archive (.a) files more than once in command line. 
Patch makes TarWriter to ignore files with the same path, so it will
add only the first one to archive.

Differential revision: https://reviews.llvm.org/D40606

Modified:
    llvm/trunk/include/llvm/Support/TarWriter.h
    llvm/trunk/lib/Support/TarWriter.cpp
    llvm/trunk/unittests/Support/TarWriterTest.cpp

Modified: llvm/trunk/include/llvm/Support/TarWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/TarWriter.h?rev=319750&r1=319749&r2=319750&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/TarWriter.h (original)
+++ llvm/trunk/include/llvm/Support/TarWriter.h Tue Dec  5 02:09:59 2017
@@ -11,6 +11,7 @@
 #define LLVM_SUPPORT_TAR_WRITER_H
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -26,6 +27,7 @@ private:
   TarWriter(int FD, StringRef BaseDir);
   raw_fd_ostream OS;
   std::string BaseDir;
+  StringSet<> Files;
 };
 }
 

Modified: llvm/trunk/lib/Support/TarWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/TarWriter.cpp?rev=319750&r1=319749&r2=319750&view=diff
==============================================================================
--- llvm/trunk/lib/Support/TarWriter.cpp (original)
+++ llvm/trunk/lib/Support/TarWriter.cpp Tue Dec  5 02:09:59 2017
@@ -173,6 +173,10 @@ void TarWriter::append(StringRef Path, S
   // Write Path and Data.
   std::string Fullpath = BaseDir + "/" + sys::path::convert_to_slash(Path);
 
+  // We do not want to include the same file more than once.
+  if (!Files.insert(Fullpath).second)
+    return;
+
   StringRef Prefix;
   StringRef Name;
   if (splitUstar(Fullpath, Prefix, Name)) {

Modified: llvm/trunk/unittests/Support/TarWriterTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/TarWriterTest.cpp?rev=319750&r1=319749&r2=319750&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/TarWriterTest.cpp (original)
+++ llvm/trunk/unittests/Support/TarWriterTest.cpp Tue Dec  5 02:09:59 2017
@@ -120,4 +120,60 @@ TEST_F(TarWriterTest, Pax) {
   StringRef Pax = StringRef((char *)(Buf.data() + 512), 512);
   EXPECT_TRUE(Pax.startswith("211 path=/" + std::string(200, 'x')));
 }
+
+TEST_F(TarWriterTest, SingleFile) {
+  SmallString<128> Path;
+  std::error_code EC =
+      sys::fs::createTemporaryFile("TarWriterTest", "tar", Path);
+  EXPECT_FALSE((bool)EC);
+
+  Expected<std::unique_ptr<TarWriter>> TarOrErr = TarWriter::create(Path, "");
+  EXPECT_TRUE((bool)TarOrErr);
+  std::unique_ptr<TarWriter> Tar = std::move(*TarOrErr);
+  Tar->append("FooPath", "foo");
+  Tar.reset();
+
+  uint64_t TarSize;
+  EC = sys::fs::file_size(Path, TarSize);
+  EXPECT_FALSE((bool)EC);
+  EXPECT_EQ(TarSize, 2048);
 }
+
+TEST_F(TarWriterTest, NoDuplicate) {
+  SmallString<128> Path;
+  std::error_code EC =
+      sys::fs::createTemporaryFile("TarWriterTest", "tar", Path);
+  EXPECT_FALSE((bool)EC);
+
+  Expected<std::unique_ptr<TarWriter>> TarOrErr = TarWriter::create(Path, "");
+  EXPECT_TRUE((bool)TarOrErr);
+  std::unique_ptr<TarWriter> Tar = std::move(*TarOrErr);
+  Tar->append("FooPath", "foo");
+  Tar->append("BarPath", "bar");
+  Tar.reset();
+
+  uint64_t TarSize;
+  EC = sys::fs::file_size(Path, TarSize);
+  EXPECT_FALSE((bool)EC);
+  EXPECT_EQ(TarSize, 3072);
+}
+
+TEST_F(TarWriterTest, Duplicate) {
+  SmallString<128> Path;
+  std::error_code EC =
+      sys::fs::createTemporaryFile("TarWriterTest", "tar", Path);
+  EXPECT_FALSE((bool)EC);
+
+  Expected<std::unique_ptr<TarWriter>> TarOrErr = TarWriter::create(Path, "");
+  EXPECT_TRUE((bool)TarOrErr);
+  std::unique_ptr<TarWriter> Tar = std::move(*TarOrErr);
+  Tar->append("FooPath", "foo");
+  Tar->append("FooPath", "bar");
+  Tar.reset();
+
+  uint64_t TarSize;
+  EC = sys::fs::file_size(Path, TarSize);
+  EXPECT_FALSE((bool)EC);
+  EXPECT_EQ(TarSize, 2048);
+}
+} // namespace




More information about the llvm-commits mailing list