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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2009, Google Inc. 2 * Copyright 2009, Google Inc.
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 19 matching lines...) Expand all
30 */ 30 */
31 31
32 // 32 //
33 // TarProcessor processes a tar byte stream (uncompressed). 33 // TarProcessor processes a tar byte stream (uncompressed).
34 34
35 #include "base/logging.h" 35 #include "base/logging.h"
36 #include "import/cross/tar_processor.h" 36 #include "import/cross/tar_processor.h"
37 37
38 namespace o3d { 38 namespace o3d {
39 39
40 static const int kFileSizeOffset = 124;
41 static const int kLinkFlagOffset = 156;
42
40 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 43 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41 int TarProcessor::ProcessBytes(MemoryReadStream *stream, size_t n) { 44 int TarProcessor::ProcessBytes(MemoryReadStream *stream, size_t n) {
42 // Keep processing the byte-stream until we've consumed all we're given 45 // Keep processing the byte-stream until we've consumed all we're given
43 // 46 //
44 size_t bytes_to_consume = n; 47 size_t bytes_to_consume = n;
45 48
46 while (bytes_to_consume > 0) { 49 while (bytes_to_consume > 0) {
47 // First see if we have any more header bytes to read 50 // First see if we have any more header bytes to read
48 if (header_bytes_read_ < TAR_HEADER_SIZE) { 51 if (header_bytes_read_ < TAR_HEADER_SIZE) {
49 // Read header bytes 52 // Read header bytes
50 size_t header_bytes_remaining = TAR_HEADER_SIZE - header_bytes_read_; 53 size_t header_bytes_remaining = TAR_HEADER_SIZE - header_bytes_read_;
51 size_t bytes_to_read = std::min(bytes_to_consume, header_bytes_remaining); 54 size_t bytes_to_read = std::min(bytes_to_consume, header_bytes_remaining);
52 size_t bytes_read = 55 size_t bytes_read =
53 stream->Read(reinterpret_cast<uint8*>(header_ + header_bytes_read_), 56 stream->Read(reinterpret_cast<uint8*>(header_ + header_bytes_read_),
54 bytes_to_read); 57 bytes_to_read);
55 if (bytes_read != bytes_to_read) { 58 if (bytes_read != bytes_to_read) {
56 return -1; 59 return -1;
57 } 60 }
58 61
59 header_bytes_read_ += bytes_to_read; 62 header_bytes_read_ += bytes_to_read;
60 bytes_to_consume -= bytes_to_read; 63 bytes_to_consume -= bytes_to_read;
61 64
62 if (header_bytes_read_ == TAR_HEADER_SIZE) { 65 if (header_bytes_read_ == TAR_HEADER_SIZE) {
63 const char *filename = (const char *)header_;
64
65 // The tar format stupidly represents size_teger values as 66 // 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"
66 // octal strings!! 67 // octal strings!!
67 size_t file_size = 0; 68 size_t file_size = 0;
68 sscanf(header_ + 124, "%o", &file_size); 69 sscanf(header_ + kFileSizeOffset, "%o", &file_size);
69 70
70 // Only callback client if this is a "real" header 71 // Check if it's a long filename
71 // (filename is not NULL) 72 char type = header_[kLinkFlagOffset];
72 // Extra zero-padding can be added by the gzip compression 73 if (type == 'L') {
73 // (at end of archive), so ignore these ones. 74 getting_filename_ = true;
74 // 75 // We should pick some size that's too large.
75 // Also, ignore entries for directories (which have zero size) 76 if (file_size > 1024) {
76 if (header_[0] != 0 && file_size > 0) { 77 return -1;
77 ArchiveFileInfo info(filename, file_size); 78 }
78 callback_client_->ReceiveFileHeader(info); 79 } else {
79 } else if (header_[0] == 0) { 80 getting_filename_ = false;
80 // If filename is NULL due to zero-padding then file size 81 const char *filename = (const char *)header_;
81 // should also be NULL 82 if (!file_name_.empty()) {
82 assert(file_size == 0); 83 filename = file_name_.c_str();
84 }
85
86 // Only callback client if this is a "real" header
87 // (filename is not NULL)
88 // Extra zero-padding can be added by the gzip compression
89 // (at end of archive), so ignore these ones.
90 //
91 // Also, ignore entries for directories (which have zero size)
92 if (header_[0] != 0 && file_size > 0) {
93 ArchiveFileInfo info(filename, file_size);
94 callback_client_->ReceiveFileHeader(info);
95 } else if (header_[0] == 0) {
96 // If filename is NULL due to zero-padding then file size
97 // should also be NULL
98 // TODO(gman): Won't this crash the plugin if I make a bad tar?
99 assert(file_size == 0);
100 }
83 } 101 }
84 102
85 // Round filesize up to nearest block size 103 // Round filesize up to nearest block size
86 file_bytes_to_read_ = 104 file_bytes_to_read_ =
87 (file_size + TAR_BLOCK_SIZE - 1) & ~(TAR_BLOCK_SIZE - 1); 105 (file_size + TAR_BLOCK_SIZE - 1) & ~(TAR_BLOCK_SIZE - 1);
88 106
89 // Our client doesn't want to be bothered with the block padding, 107 // Our client doesn't want to be bothered with the block padding,
90 // so only send him the actual file bytes 108 // so only send him the actual file bytes
91 client_file_bytes_to_read_ = file_size; 109 client_file_bytes_to_read_ = file_size;
110
111 // Clear the file_name_ so we don't use it next time.
112 file_name_.clear();
92 } 113 }
93 } 114 }
94 115
95 if (bytes_to_consume > 0) { 116 if (bytes_to_consume > 0) {
96 // Looks like we have some left-over bytes past the header 117 // Looks like we have some left-over bytes past the header
97 // -- size_terpret as file bytes 118 // -- size_terpret as file bytes
98 if (client_file_bytes_to_read_ > 0) { 119 if (client_file_bytes_to_read_ > 0) {
99 // Callback to client with some file data 120 // Callback to client with some file data
100 121
101 // Use a copy of the stream in case the client doesn't read 122 // Use a copy of the stream in case the client doesn't read
102 // the amount they're supposed to 123 // the amount they're supposed to
103 MemoryReadStream client_read_stream(*stream); 124 MemoryReadStream client_read_stream(*stream);
104 125
105 size_t client_bytes_this_time = 126 size_t client_bytes_this_time =
106 std::min(bytes_to_consume, client_file_bytes_to_read_); 127 std::min(bytes_to_consume, client_file_bytes_to_read_);
107 128
108 if (!callback_client_->ReceiveFileData(&client_read_stream, 129 if (getting_filename_) {
109 client_bytes_this_time)) { 130 String name_piece(
110 return -1; 131 client_read_stream.GetDirectMemoryPointerAs<const char>(),
132 client_bytes_this_time);
133 client_read_stream.Skip(client_bytes_this_time);
134 file_name_ += name_piece;
135 } else {
136 if (!callback_client_->ReceiveFileData(&client_read_stream,
137 client_bytes_this_time)) {
138 return -1;
139 }
111 } 140 }
112 141
113 client_file_bytes_to_read_ -= client_bytes_this_time; 142 client_file_bytes_to_read_ -= client_bytes_this_time;
114 file_bytes_to_read_ -= client_bytes_this_time; 143 file_bytes_to_read_ -= client_bytes_this_time;
115 144
116 // Advance stream the amount the client should have consumed 145 // Advance stream the amount the client should have consumed
117 stream->Skip(client_bytes_this_time); 146 stream->Skip(client_bytes_this_time);
118 147
119 bytes_to_consume -= client_bytes_this_time; 148 bytes_to_consume -= client_bytes_this_time;
120 } 149 }
(...skipping 14 matching lines...) Expand all
135 // setting to 0 makes us want more header bytes 164 // setting to 0 makes us want more header bytes
136 header_bytes_read_ = 0; 165 header_bytes_read_ = 0;
137 } 166 }
138 } 167 }
139 } 168 }
140 169
141 return 0; 170 return 0;
142 } 171 }
143 172
144 } // namespace o3d 173 } // namespace o3d
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698