Skip to content

Commit 62eec46

Browse files
committed
std.tar: support pax headers and gnulong_{name,link}
tar.zig: * add HeaderIterator() type and convert pipeToFileSystem() to use it. * add initial support for options.executable_bit_only. * initial windows support: * skip symlinks which require admin rights * workaround file.updateTimes() panic by truncating file times * add tests parseNumeric and parsePaxTime ported from https://go.dev/src/archive/tar/strconv_test.go. lib/std/compress/tar/testdata/ * copy a subset of tar files from https://go.dev/src/archive/tar/testdata reader_test.zig: * validate headers against files from testdata/. a port of https://go.dev/src/archive/tar/reader_test.go. test_decompress.zig: * runs tar.pipeToFileSystem() on valid testdata/ files.
1 parent a867599 commit 62eec46

24 files changed

+1900
-136
lines changed

lib/std/compress.zig

+1
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,5 @@ test {
4646
_ = xz;
4747
_ = zlib;
4848
_ = zstd;
49+
_ = @import("compress/tar.zig");
4950
}

lib/std/compress/tar.zig

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
test "std.tar" {
2+
_ = @import("tar/reader_test.zig");
3+
_ = @import("tar/test_decompress.zig");
4+
}

lib/std/compress/tar/reader_test.zig

+758
Large diffs are not rendered by default.
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const std = @import("std");
2+
const mem = std.mem;
3+
const tar = std.tar;
4+
const testing = std.testing;
5+
6+
test "tar decompress testdata" {
7+
const testdata_path = "lib/std/compress/tar/testdata";
8+
var testdata_dir = try std.fs.cwd().openIterableDir(testdata_path, .{});
9+
var iter = testdata_dir.iterate();
10+
var cache_dir = testing.tmpDir(.{});
11+
defer cache_dir.cleanup();
12+
const files_to_skip = [_][]const u8{
13+
"neg-size.tar",
14+
"pax-nul-xattrs.tar",
15+
"pax-nul-path.tar",
16+
"gnu-not-utf8.tar",
17+
};
18+
19+
entries: while (try iter.next()) |entry| {
20+
if (entry.kind == .File) {
21+
for (files_to_skip) |sf|
22+
if (mem.eql(u8, sf, entry.name)) continue :entries;
23+
} else continue;
24+
25+
const handle = try testdata_dir.dir.openFile(entry.name, .{});
26+
defer handle.close();
27+
const output_dir = try cache_dir.dir.makeOpenPath(entry.name, .{});
28+
// Untar the archive using the decompresser
29+
try tar.pipeToFileSystem(output_dir, handle.reader(), .{ .mode_mode = .ignore });
30+
try output_dir.deleteTree(entry.name);
31+
try tar.pipeToFileSystem(output_dir, handle.reader(), .{ .mode_mode = .executable_bit_only });
32+
}
33+
}
2.5 KB
Binary file not shown.
Binary file not shown.
1.5 KB
Binary file not shown.
2.5 KB
Binary file not shown.

lib/std/compress/tar/testdata/gnu.tar

3 KB
Binary file not shown.
2.5 KB
Binary file not shown.
512 Bytes
Binary file not shown.
1 KB
Binary file not shown.
Binary file not shown.
2.5 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.
2.5 KB
Binary file not shown.

lib/std/compress/tar/testdata/pax.tar

10 KB
Binary file not shown.
3 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.

lib/std/compress/tar/testdata/v7.tar

3.5 KB
Binary file not shown.
5 KB
Binary file not shown.

0 commit comments

Comments
 (0)