authorgravatar for igor.anic@gmail.comIgor Anić <igor.anic@gmail.com> 2023-11-27 22:23:16+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-13 19:37:33-07:00
logbe5d04ab7922d84b59dad06de3df378b94827d4a
tree814b071b6cc5cdd30d4398f557039e4a1b06606b
parent18170633754afb68c5831bfe4534c64af93ba55b

tar: add pax linkpath attribute parsing

Name of symbolic link can be also found in pax attribute.

1 files changed, 25 insertions(+), 16 deletions(-)

lib/std/tar.zig+25-16
......@@ -226,6 +226,9 @@ fn Iterator(comptime ReaderType: type) type {
226226 return struct {
227227 file_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined,
228228 file_name_len: usize = 0,
229 link_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined,
230 link_name_len: usize = 0,
231
229232 reader: BufferedReader(ReaderType),
230233 diagnostics: ?*Options.Diagnostics,
231234
......@@ -275,6 +278,8 @@ fn Iterator(comptime ReaderType: type) type {
275278
276279 pub fn next(self: *Self) !?File {
277280 self.file_name_len = 0;
281 self.link_name_len = 0;
282
278283 while (true) {
279284 const chunk = try self.reader.readChunk(1024);
280285 switch (chunk.len) {
......@@ -287,10 +292,12 @@ fn Iterator(comptime ReaderType: type) type {
287292 const header: Header = .{ .bytes = chunk[0..512] };
288293 if (header.isZeroBlock()) return null;
289294 const file_size = try header.fileSize();
290 const file_type = header.fileType();
291 const link_name = header.linkName();
292295 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];
294301 const file_name = if (self.file_name_len == 0)
295302 try header.fullFileName(&self.file_name_buffer)
296303 else
......@@ -314,7 +321,7 @@ fn Iterator(comptime ReaderType: type) type {
314321
315322 const chunk_size: usize = rounded_file_size + 512;
316323 var data_off: usize = 0;
317 const file_name_override_len = while (data_off < file_size) {
324 while (data_off < file_size) {
318325 const slice = try self.reader.readChunk(chunk_size - data_off);
319326 if (slice.len == 0) return error.UnexpectedEndOfStream;
320327 const remaining_size: usize = file_size - data_off;
......@@ -323,18 +330,22 @@ fn Iterator(comptime ReaderType: type) type {
323330 if (std.mem.eql(u8, attr_info.key, "path")) {
324331 if (attr_info.value_len > self.file_name_buffer.len) return error.NameTooLong;
325332 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);
328344 }
329
330 try self.reader.skip(attr_info.size);
331345 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);
335348
336 try self.reader.skip(rounded_file_size - data_off - file_name_override_len);
337 self.file_name_len = file_name_override_len;
338349 continue;
339350 },
340351 .hard_link => return error.TarUnsupportedFileType,
......@@ -599,9 +610,7 @@ test "Go test cases" {
599610 .name = "a/b",
600611 .size = 0,
601612 .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",
605614 },
606615 },
607616 .chksums = &[_][]const u8{