This is an archive of the discontinued LLVM Phabricator instance.

Fix off-by-one error in TarWriter.
ClosedPublic

Authored by ruiu on Sep 21 2017, 12:54 PM.

Details

Summary

The tar format originally supported up to 99 byte filename. The two
extensions are proposed later: Ustar or PAX.

In the UStar extension, a pathanme is split at a '/' and its "prefix"
and "suffix" are stored in different locations in the tar header. Since
"prefix" can be up to 155 byte, it can represent up to 254 byte
filename (but exact limit depends on the location of '/' character in
a pathname.)

Our TarWriter first attempt to use UStar extension and then fallback to
PAX extension.

But there's a bug in UStar header creation. "Suffix" part must be a NUL-
terminated string, but we didn't handle it correctly. As a result, if
your filename just 100 characters long, the last character was droppped.

This patch fixes the issue.

Event Timeline

ruiu created this revision.Sep 21 2017, 12:54 PM
zturner added inline comments.Sep 21 2017, 1:04 PM
llvm/lib/Support/TarWriter.cpp
128

I don't think we need std::string here. Can't we just use StringRef again? Also, how about just returning Optional<std::pair<StringRef, StringRef>>?

130–131

return std::make_pair(StringRef(), Path);

134

What about this Path?

<total of 95 a's>/aaaaa/bb

in this case we have 95 + 1 + 5 = 101 characters, followed by a /, followed by bb.

Does this path conform to Ustar header? You can split it as (<total of 95 a's>, "aaaaa/bb") but then you have a / in the name. Is this ok?

ruiu updated this revision to Diff 116255.Sep 21 2017, 1:11 PM
  • updated as per Zach's comments
ruiu added inline comments.Sep 21 2017, 1:11 PM
llvm/lib/Support/TarWriter.cpp
128

I actually tried to use Optional<std::pair<StringRef, StringRef>> but it looked like it is a bit too complicated type for this little helper function.

134

That's OK. Updated the comment a bit.

zturner edited edge metadata.Sep 21 2017, 4:05 PM

Can you add the following tests?

std::string(154, 'x') + "/" + std::string(100, 'y');
std::string(150, 'x') + "/" + std::string(20, 'y') + "/" + std::string(20, 'z');

Can you also add a test that if we can't use a Ustar header, that we can still produce a valid Tar file by using a Pax header?

llvm/lib/Support/TarWriter.cpp
128

Might as well make them StringRef& instead.

ruiu updated this revision to Diff 116636.Sep 25 2017, 8:04 PM
  • Address review comments.
This revision was automatically updated to reflect the committed changes.