| ... | @@ -226,6 +226,9 @@ fn Iterator(comptime ReaderType: type) type { | ... | @@ -226,6 +226,9 @@ fn Iterator(comptime ReaderType: type) type { |
| 226 | return struct { | 226 | return struct { |
| 227 | file_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined, | 227 | file_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined, |
| 228 | file_name_len: usize = 0, | 228 | file_name_len: usize = 0, |
| | 229 | link_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined, |
| | 230 | link_name_len: usize = 0, |
| | 231 | |
| 229 | reader: BufferedReader(ReaderType), | 232 | reader: BufferedReader(ReaderType), |
| 230 | diagnostics: ?*Options.Diagnostics, | 233 | diagnostics: ?*Options.Diagnostics, |
| 231 | | 234 | |
| ... | @@ -275,6 +278,8 @@ fn Iterator(comptime ReaderType: type) type { | ... | @@ -275,6 +278,8 @@ fn Iterator(comptime ReaderType: type) type { |
| 275 | | 278 | |
| 276 | pub fn next(self: *Self) !?File { | 279 | pub fn next(self: *Self) !?File { |
| 277 | self.file_name_len = 0; | 280 | self.file_name_len = 0; |
| | 281 | self.link_name_len = 0; |
| | 282 | |
| 278 | while (true) { | 283 | while (true) { |
| 279 | const chunk = try self.reader.readChunk(1024); | 284 | const chunk = try self.reader.readChunk(1024); |
| 280 | switch (chunk.len) { | 285 | switch (chunk.len) { |
| ... | @@ -287,10 +292,12 @@ fn Iterator(comptime ReaderType: type) type { | ... | @@ -287,10 +292,12 @@ fn Iterator(comptime ReaderType: type) type { |
| 287 | const header: Header = .{ .bytes = chunk[0..512] }; | 292 | const header: Header = .{ .bytes = chunk[0..512] }; |
| 288 | if (header.isZeroBlock()) return null; | 293 | if (header.isZeroBlock()) return null; |
| 289 | const file_size = try header.fileSize(); | 294 | const file_size = try header.fileSize(); |
| 290 | const file_type = header.fileType(); | | |
| 291 | const link_name = header.linkName(); | | |
| 292 | const rounded_file_size: usize = std.mem.alignForward(usize, file_size, 512); | 295 | const rounded_file_size: usize = std.mem.alignForward(usize, file_size, 512); |
| 293 | | 296 | const file_type = header.fileType(); |
| | 297 | const link_name = if (self.link_name_len == 0) |
| | 298 | header.linkName() |
| | 299 | else |
| | 300 | self.link_name_buffer[0..self.link_name_len]; |
| 294 | const file_name = if (self.file_name_len == 0) | 301 | const file_name = if (self.file_name_len == 0) |
| 295 | try header.fullFileName(&self.file_name_buffer) | 302 | try header.fullFileName(&self.file_name_buffer) |
| 296 | else | 303 | else |
| ... | @@ -314,7 +321,7 @@ fn Iterator(comptime ReaderType: type) type { | ... | @@ -314,7 +321,7 @@ fn Iterator(comptime ReaderType: type) type { |
| 314 | | 321 | |
| 315 | const chunk_size: usize = rounded_file_size + 512; | 322 | const chunk_size: usize = rounded_file_size + 512; |
| 316 | var data_off: usize = 0; | 323 | var data_off: usize = 0; |
| 317 | const file_name_override_len = while (data_off < file_size) { | 324 | while (data_off < file_size) { |
| 318 | const slice = try self.reader.readChunk(chunk_size - data_off); | 325 | const slice = try self.reader.readChunk(chunk_size - data_off); |
| 319 | if (slice.len == 0) return error.UnexpectedEndOfStream; | 326 | if (slice.len == 0) return error.UnexpectedEndOfStream; |
| 320 | const remaining_size: usize = file_size - data_off; | 327 | const remaining_size: usize = file_size - data_off; |
| ... | @@ -323,18 +330,22 @@ fn Iterator(comptime ReaderType: type) type { | ... | @@ -323,18 +330,22 @@ fn Iterator(comptime ReaderType: type) type { |
| 323 | if (std.mem.eql(u8, attr_info.key, "path")) { | 330 | if (std.mem.eql(u8, attr_info.key, "path")) { |
| 324 | if (attr_info.value_len > self.file_name_buffer.len) return error.NameTooLong; | 331 | if (attr_info.value_len > self.file_name_buffer.len) return error.NameTooLong; |
| 325 | self.reader.advance(attr_info.value_off); | 332 | self.reader.advance(attr_info.value_off); |
| 326 | data_off += attr_info.value_off; | 333 | try self.reader.copy(&self.file_name_buffer, attr_info.value_len); |
| 327 | break attr_info.value_len; | 334 | self.file_name_len = attr_info.value_len; |
| | 335 | self.reader.advance(1); |
| | 336 | } else if (std.mem.eql(u8, attr_info.key, "linkpath")) { |
| | 337 | if (attr_info.value_len > self.link_name_buffer.len) return error.NameTooLong; |
| | 338 | self.reader.advance(attr_info.value_off); |
| | 339 | try self.reader.copy(&self.link_name_buffer, attr_info.value_len); |
| | 340 | self.link_name_len = attr_info.value_len; |
| | 341 | self.reader.advance(1); |
| | 342 | } else { |
| | 343 | try self.reader.skip(attr_info.size); |
| 328 | } | 344 | } |
| 329 | | | |
| 330 | try self.reader.skip(attr_info.size); | | |
| 331 | data_off += attr_info.size; | 345 | data_off += attr_info.size; |
| 332 | } else 0; | 346 | } |
| 333 | | 347 | try self.reader.skip(rounded_file_size - data_off); |
| 334 | try self.reader.copy(&self.file_name_buffer, file_name_override_len); | | |
| 335 | | 348 | |
| 336 | try self.reader.skip(rounded_file_size - data_off - file_name_override_len); | | |
| 337 | self.file_name_len = file_name_override_len; | | |
| 338 | continue; | 349 | continue; |
| 339 | }, | 350 | }, |
| 340 | .hard_link => return error.TarUnsupportedFileType, | 351 | .hard_link => return error.TarUnsupportedFileType, |
| ... | @@ -599,9 +610,7 @@ test "Go test cases" { | ... | @@ -599,9 +610,7 @@ test "Go test cases" { |
| 599 | .name = "a/b", | 610 | .name = "a/b", |
| 600 | .size = 0, | 611 | .size = 0, |
| 601 | .file_type = .symbolic_link, | 612 | .file_type = .symbolic_link, |
| 602 | .link_name = "1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545", | 613 | .link_name = "123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100", |
| 603 | // TODO fix reading link name from pax header | | |
| 604 | // .link_name = "123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100", | | |
| 605 | }, | 614 | }, |
| 606 | }, | 615 | }, |
| 607 | .chksums = &[_][]const u8{ | 616 | .chksums = &[_][]const u8{ |