Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Unified Diff: import/cross/tar_processor.cc

Issue 159129: Refactor tar code to support long names.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/o3d/
Patch Set: Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: import/cross/tar_processor.cc
===================================================================
--- import/cross/tar_processor.cc (revision 21085)
+++ import/cross/tar_processor.cc (working copy)
@@ -37,6 +37,9 @@
namespace o3d {
+static const int kFileSizeOffset = 124;
+static const int kLinkFlagOffset = 156;
+
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int TarProcessor::ProcessBytes(MemoryReadStream *stream, size_t n) {
// Keep processing the byte-stream until we've consumed all we're given
@@ -60,26 +63,41 @@
bytes_to_consume -= bytes_to_read;
if (header_bytes_read_ == TAR_HEADER_SIZE) {
- const char *filename = (const char *)header_;
-
// The tar format stupidly represents size_teger values as
Chris Rogers 2009/07/21 19:14:28 might as well fix this comment now "size_teger"
// octal strings!!
size_t file_size = 0;
- sscanf(header_ + 124, "%o", &file_size);
+ sscanf(header_ + kFileSizeOffset, "%o", &file_size);
- // Only callback client if this is a "real" header
- // (filename is not NULL)
- // Extra zero-padding can be added by the gzip compression
- // (at end of archive), so ignore these ones.
- //
- // Also, ignore entries for directories (which have zero size)
- if (header_[0] != 0 && file_size > 0) {
- ArchiveFileInfo info(filename, file_size);
- callback_client_->ReceiveFileHeader(info);
- } else if (header_[0] == 0) {
- // If filename is NULL due to zero-padding then file size
- // should also be NULL
- assert(file_size == 0);
+ // Check if it's a long filename
+ char type = header_[kLinkFlagOffset];
+ if (type == 'L') {
+ getting_filename_ = true;
+ // We should pick some size that's too large.
+ if (file_size > 1024) {
+ return -1;
+ }
+ } else {
+ getting_filename_ = false;
+ const char *filename = (const char *)header_;
+ if (!file_name_.empty()) {
+ filename = file_name_.c_str();
+ }
+
+ // Only callback client if this is a "real" header
+ // (filename is not NULL)
+ // Extra zero-padding can be added by the gzip compression
+ // (at end of archive), so ignore these ones.
+ //
+ // Also, ignore entries for directories (which have zero size)
+ if (header_[0] != 0 && file_size > 0) {
+ ArchiveFileInfo info(filename, file_size);
+ callback_client_->ReceiveFileHeader(info);
+ } else if (header_[0] == 0) {
+ // If filename is NULL due to zero-padding then file size
+ // should also be NULL
+ // TODO(gman): Won't this crash the plugin if I make a bad tar?
+ assert(file_size == 0);
+ }
}
// Round filesize up to nearest block size
@@ -89,6 +107,9 @@
// Our client doesn't want to be bothered with the block padding,
// so only send him the actual file bytes
client_file_bytes_to_read_ = file_size;
+
+ // Clear the file_name_ so we don't use it next time.
+ file_name_.clear();
}
}
@@ -105,9 +126,17 @@
size_t client_bytes_this_time =
std::min(bytes_to_consume, client_file_bytes_to_read_);
- if (!callback_client_->ReceiveFileData(&client_read_stream,
- client_bytes_this_time)) {
- return -1;
+ if (getting_filename_) {
+ String name_piece(
+ client_read_stream.GetDirectMemoryPointerAs<const char>(),
+ client_bytes_this_time);
+ client_read_stream.Skip(client_bytes_this_time);
+ file_name_ += name_piece;
+ } else {
+ if (!callback_client_->ReceiveFileData(&client_read_stream,
+ client_bytes_this_time)) {
+ return -1;
+ }
}
client_file_bytes_to_read_ -= client_bytes_this_time;

Powered by Google App Engine
This is Rietveld 408576698