Skip to content

Commit 4687b45

Browse files
committed
Reland D78945 TarWriter: Only use 137 of the 155 prefix bytes.
With a fix to unittests/Support/TarWriterTest.cpp This makes lld's --reproduce output more compatible with tar 1.13 and before. This is a very old version of tar, but it's the version in both gnuwin and unxutils, and the cost for supporting them are very low, so we might as well just do that. https://bugs.chromium.org/p/chromium/issues/detail?id=1073524#c21 and onward has more details. Differential Revision: https://reviews.llvm.org/D78945
1 parent 5eff75d commit 4687b45

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

llvm/lib/Support/TarWriter.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,17 @@ static bool splitUstar(StringRef Path, StringRef &Prefix, StringRef &Name) {
131131
return true;
132132
}
133133

134-
size_t Sep = Path.rfind('/', sizeof(UstarHeader::Prefix) + 1);
134+
// tar 1.13 and earlier unconditionally look at the tar header interpreted
135+
// as an 'oldgnu_header', which has an 'isextended' byte at offset 482 in the
136+
// header, corresponding to offset 137 in the prefix. That's the version of
137+
// tar in gnuwin, so only use 137 of the 155 bytes in the prefix. This means
138+
// we'll need a pax header after 237 bytes of path instead of after 255,
139+
// but in return paths up to 237 bytes work with gnuwin, instead of just
140+
// 137 bytes of directory + 100 bytes of basename previously.
141+
// (tar-1.13 also doesn't support pax headers, but in practice all paths in
142+
// llvm's test suite are short enough for that to not matter.)
143+
const int MaxPrefix = 137;
144+
size_t Sep = Path.rfind('/', MaxPrefix + 1);
135145
if (Sep == StringRef::npos)
136146
return false;
137147
if (Path.size() - Sep - 1 >= sizeof(UstarHeader::Name))

llvm/unittests/Support/TarWriterTest.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,30 +81,30 @@ TEST_F(TarWriterTest, Basics) {
8181
}
8282

8383
TEST_F(TarWriterTest, LongFilename) {
84-
std::string x154(154, 'x');
85-
std::string x155(155, 'x');
84+
std::string x136(136, 'x');
85+
std::string x137(137, 'x');
8686
std::string y99(99, 'y');
8787
std::string y100(100, 'y');
8888

89-
UstarHeader Hdr1 = createUstar("", x154 + "/" + y99);
90-
EXPECT_EQ("/" + x154, StringRef(Hdr1.Prefix));
89+
UstarHeader Hdr1 = createUstar("", x136 + "/" + y99);
90+
EXPECT_EQ("/" + x136, StringRef(Hdr1.Prefix));
9191
EXPECT_EQ(y99, StringRef(Hdr1.Name));
9292

93-
UstarHeader Hdr2 = createUstar("", x155 + "/" + y99);
93+
UstarHeader Hdr2 = createUstar("", x137 + "/" + y99);
9494
EXPECT_EQ("", StringRef(Hdr2.Prefix));
9595
EXPECT_EQ("", StringRef(Hdr2.Name));
9696

97-
UstarHeader Hdr3 = createUstar("", x154 + "/" + y100);
97+
UstarHeader Hdr3 = createUstar("", x136 + "/" + y100);
9898
EXPECT_EQ("", StringRef(Hdr3.Prefix));
9999
EXPECT_EQ("", StringRef(Hdr3.Name));
100100

101-
UstarHeader Hdr4 = createUstar("", x155 + "/" + y100);
101+
UstarHeader Hdr4 = createUstar("", x137 + "/" + y100);
102102
EXPECT_EQ("", StringRef(Hdr4.Prefix));
103103
EXPECT_EQ("", StringRef(Hdr4.Name));
104104

105105
std::string yz = "yyyyyyyyyyyyyyyyyyyy/zzzzzzzzzzzzzzzzzzzz";
106-
UstarHeader Hdr5 = createUstar("", x154 + "/" + yz);
107-
EXPECT_EQ("/" + x154, StringRef(Hdr5.Prefix));
106+
UstarHeader Hdr5 = createUstar("", x136 + "/" + yz);
107+
EXPECT_EQ("/" + x136, StringRef(Hdr5.Prefix));
108108
EXPECT_EQ(yz, StringRef(Hdr5.Name));
109109
}
110110

0 commit comments

Comments
 (0)