Skip to content

Commit cf081fa

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 * gzip them all with -9. results in around 95% file size reduction 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 cf081fa

32 files changed

+1944
-135
lines changed

lib/std/compress.zig

Lines changed: 1 addition & 0 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 762 additions & 0 deletions
Large diffs are not rendered by default.

lib/std/compress/tar/test_common.zig

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const std = @import("std");
2+
/// testing helper for decompressing a .gz file. returns an io.fixedBufferStream
3+
/// with the decompressed data. caller owns the returned FixedBufferStream.buffer
4+
pub fn decompressGz(
5+
comptime file_name: []const u8,
6+
alloc: std.mem.Allocator,
7+
) !std.io.FixedBufferStream([]u8) {
8+
var fbs = std.io.fixedBufferStream(@embedFile(file_name));
9+
var decompressor = try std.compress.gzip.decompress(alloc, fbs.reader());
10+
defer decompressor.deinit();
11+
const decompressed = try decompressor.reader().readAllAlloc(alloc, 1024 * 32);
12+
return std.io.fixedBufferStream(decompressed);
13+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
const std = @import("std");
2+
const mem = std.mem;
3+
const tar = std.tar;
4+
const testing = std.testing;
5+
const talloc = testing.allocator;
6+
const builtin = @import("builtin");
7+
const test_common = @import("test_common.zig");
8+
9+
test "tar decompress testdata" {
10+
// skip if wine and debug mode due to 'incorrect alignment'
11+
// TODO re-enable after https://github.com/ziglang/zig/issues/14036 is solved
12+
if (builtin.os.tag == .windows and builtin.mode == .Debug)
13+
return error.SkipZigTest;
14+
15+
const test_files = [_][]const u8{
16+
"xattrs.tar",
17+
"gnu-long-nul.tar",
18+
"v7.tar",
19+
"pax-bad-hdr-file.tar",
20+
"pax-global-records.tar",
21+
"star.tar",
22+
"pax-multi-hdrs.tar",
23+
"gnu.tar",
24+
"gnu-utf8.tar",
25+
"trailing-slash.tar",
26+
"pax.tar",
27+
"nil-uid.tar",
28+
"ustar-file-devs.tar",
29+
"pax-pos-size-file.tar",
30+
"hardlink.tar",
31+
"pax-records.tar",
32+
"gnu-multi-hdrs.tar",
33+
};
34+
35+
var cache_dir = testing.tmpDir(.{});
36+
defer cache_dir.cleanup();
37+
38+
inline for (test_files) |test_file| {
39+
var fbs = try test_common.decompressGz("testdata/" ++ test_file ++ ".gz", talloc);
40+
defer talloc.free(fbs.buffer);
41+
{
42+
var output_dir = try cache_dir.dir.makeOpenPath(test_file, .{});
43+
defer output_dir.close();
44+
try tar.pipeToFileSystem(output_dir, fbs.reader(), .{ .mode_mode = .ignore });
45+
}
46+
try cache_dir.dir.deleteTree(test_file);
47+
fbs.reset();
48+
{
49+
var output_dir = try cache_dir.dir.makeOpenPath(test_file, .{});
50+
defer output_dir.close();
51+
try tar.pipeToFileSystem(output_dir, fbs.reader(), .{ .mode_mode = .executable_bit_only });
52+
}
53+
}
54+
}
175 Bytes
Binary file not shown.
208 Bytes
Binary file not shown.
Binary file not shown.
109 Bytes
Binary file not shown.
148 Bytes
Binary file not shown.
163 Bytes
Binary file not shown.
164 Bytes
Binary file not shown.
220 Bytes
Binary file not shown.
119 Bytes
Binary file not shown.
61 Bytes
Binary file not shown.
219 Bytes
Binary file not shown.
134 Bytes
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
218 Bytes
Binary file not shown.
148 Bytes
Binary file not shown.
163 Bytes
Binary file not shown.
Binary file not shown.
186 Bytes
Binary file not shown.
412 Bytes
Binary file not shown.
179 Bytes
Binary file not shown.
134 Bytes
Binary file not shown.
Binary file not shown.
551 Bytes
Binary file not shown.
376 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)