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