From cbbb2ffd261ea30c4deb6230ff2fc168166fb1b1 Mon Sep 17 00:00:00 2001 From: Travis Staloch Date: Tue, 2 May 2023 03:47:51 -0700 Subject: [PATCH] std.tar: fix fuzzing crashes #1 this patch converts all the crashes submitted by @squeek502 (in https://github.com/ziglang/zig/pull/15382#issuecomment-1531070661) to errors. HeaderIterator: * add bounds checks to PaxIterator.next() * convert several unsafe int casts to safe ones misc: * added FileType.tagName() for debugging which returns null for unnamed enum values * make unixTime() fallible --- lib/std/compress/tar/reader_test.zig | 110 +++++++++++----------- lib/std/compress/tar/test_common.zig | 1 + lib/std/tar.zig | 136 +++++++++++++++------------ 3 files changed, 131 insertions(+), 116 deletions(-) diff --git a/lib/std/compress/tar/reader_test.zig b/lib/std/compress/tar/reader_test.zig index 27d14cef9505..8432f2ab26ff 100644 --- a/lib/std/compress/tar/reader_test.zig +++ b/lib/std/compress/tar/reader_test.zig @@ -40,7 +40,7 @@ test "std.tar validate testdata headers" { .uid = 73025, .gid = 5000, .size = 5, - .mtime = unixTime(1244428340, 0), + .mtime = try unixTime(1244428340, 0), .type = .normal, .uname = "dsymonds", .gname = "eng", @@ -51,7 +51,7 @@ test "std.tar validate testdata headers" { .uid = 73025, .gid = 5000, .size = 11, - .mtime = unixTime(1244436044, 0), + .mtime = try unixTime(1244436044, 0), .type = .normal, .uname = "dsymonds", .gname = "eng", @@ -71,7 +71,7 @@ test "std.tar validate testdata headers" { .uid = 1000, .gid = 1000, .size = 200, - .mtime = unixTime(1392395740, 0), + .mtime = try unixTime(1392395740, 0), .type = @intToEnum(FileType, 0x53), .linkname = "", .uname = "david", @@ -85,7 +85,7 @@ test "std.tar validate testdata headers" { .uid = 1000, .gid = 1000, .size = 200, - .mtime = unixTime(1392342187, 0), + .mtime = try unixTime(1392342187, 0), .type = @intToEnum(FileType, 0x30), .linkname = "", .uname = "david", @@ -104,7 +104,7 @@ test "std.tar validate testdata headers" { .uid = 1000, .gid = 1000, .size = 200, - .mtime = unixTime(1392340456, 0), + .mtime = try unixTime(1392340456, 0), .type = @intToEnum(FileType, 0x30), .linkname = "", .uname = "david", @@ -124,7 +124,7 @@ test "std.tar validate testdata headers" { .uid = 1000, .gid = 1000, .size = 200, - .mtime = unixTime(1392337404, 0), + .mtime = try unixTime(1392337404, 0), .type = @intToEnum(FileType, 0x30), .linkname = "", .uname = "david", @@ -144,7 +144,7 @@ test "std.tar validate testdata headers" { .uid = 1000, .gid = 1000, .size = 4, - .mtime = unixTime(1392398319, 0), + .mtime = try unixTime(1392398319, 0), .type = @intToEnum(FileType, 0x30), .linkname = "", .uname = "david", @@ -169,24 +169,24 @@ test "std.tar validate testdata headers" { .uid = 73025, .gid = 5000, .size = 5, - .mtime = unixTime(1244592783, 0), + .mtime = try unixTime(1244592783, 0), .type = .normal, .uname = "dsymonds", .gname = "eng", - .atime = unixTime(1244592783, 0), - .ctime = unixTime(1244592783, 0), + .atime = try unixTime(1244592783, 0), + .ctime = try unixTime(1244592783, 0), }, .{ .name = "small2.txt", .mode = 0o640, .uid = 73025, .gid = 5000, .size = 11, - .mtime = unixTime(1244592783, 0), + .mtime = try unixTime(1244592783, 0), .type = .normal, .uname = "dsymonds", .gname = "eng", - .atime = unixTime(1244592783, 0), - .ctime = unixTime(1244592783, 0), + .atime = try unixTime(1244592783, 0), + .ctime = try unixTime(1244592783, 0), } }, }, .{ @@ -197,7 +197,7 @@ test "std.tar validate testdata headers" { .uid = 73025, .gid = 5000, .size = 5, - .mtime = unixTime(1244593104, 0), + .mtime = try unixTime(1244593104, 0), .type = .normal, }, .{ .name = "small2.txt", @@ -205,7 +205,7 @@ test "std.tar validate testdata headers" { .uid = 73025, .gid = 5000, .size = 11, - .mtime = unixTime(1244593104, 0), + .mtime = try unixTime(1244593104, 0), .type = .normal, } }, }, @@ -219,9 +219,9 @@ test "std.tar validate testdata headers" { .uname = "shane", .gname = "shane", .size = 7, - .mtime = unixTime(1350244992, 23960108), - .ctime = unixTime(1350244992, 23960108), - .atime = unixTime(1350244992, 23960108), + .mtime = try unixTime(1350244992, 23960108), + .ctime = try unixTime(1350244992, 23960108), + .atime = try unixTime(1350244992, 23960108), .type = .normal, .pax_recs = &.{ "path", "a/123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100", @@ -238,9 +238,9 @@ test "std.tar validate testdata headers" { .uname = "shane", .gname = "shane", .size = 0, - .mtime = unixTime(1350266320, 910238425), - .ctime = unixTime(1350266320, 910238425), - .atime = unixTime(1350266320, 910238425), + .mtime = try unixTime(1350266320, 910238425), + .ctime = try unixTime(1350266320, 910238425), + .atime = try unixTime(1350266320, 910238425), .type = .symbolic_link, .linkname = "123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100", .pax_recs = &.{ @@ -268,7 +268,7 @@ test "std.tar validate testdata headers" { .uid = 319973, .gid = 5000, .size = 999, - .mtime = unixTime(1442282516, 0), + .mtime = try unixTime(1442282516, 0), .type = .normal, .uname = "joetsai", .gname = "eng", @@ -287,7 +287,7 @@ test "std.tar validate testdata headers" { .type = .normal, .name = "file", .uname = str_long_x10, - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .pax_recs = &.{ "GOLANG.pkg", "tar", "comment", "Hello, 世界", @@ -306,13 +306,13 @@ test "std.tar validate testdata headers" { }, .{ .type = .normal, .name = "file1", - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .fmt = FormatSet.initOne(.ustar), }, .{ .type = .normal, .name = "file2", .pax_recs = &.{ "path", "file2" }, - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .fmt = FormatSet.initOne(.pax), }, .{ .type = .global_extended_header, @@ -322,12 +322,12 @@ test "std.tar validate testdata headers" { }, .{ .type = .normal, .name = "file3", - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .fmt = FormatSet.initOne(.ustar), }, .{ .type = .normal, .name = "file4", - .mtime = unixTime(1400000000, 0), + .mtime = try unixTime(1400000000, 0), .pax_recs = &.{ "mtime", "1400000000" }, .fmt = FormatSet.initOne(.pax), } }, @@ -340,7 +340,7 @@ test "std.tar validate testdata headers" { .uid = 0, .gid = 0, .size = 14, - .mtime = unixTime(1365454838, 0), + .mtime = try unixTime(1365454838, 0), .type = .normal, .linkname = "", .uname = "eyefi", @@ -359,12 +359,12 @@ test "std.tar validate testdata headers" { .uid = 1000, .gid = 10, .size = 5, - .mtime = unixTime(1386065770, 448252320), + .mtime = try unixTime(1386065770, 448252320), .type = .normal, .uname = "alex", .gname = "wheel", - .atime = unixTime(1389782991, 419875220), - .ctime = unixTime(1389782956, 794414986), + .atime = try unixTime(1389782991, 419875220), + .ctime = try unixTime(1389782956, 794414986), .pax_recs = &.{ "user.key", "value", "user.key2", "value2", @@ -385,12 +385,12 @@ test "std.tar validate testdata headers" { .uid = 1000, .gid = 10, .size = 11, - .mtime = unixTime(1386065770, 449252304), + .mtime = try unixTime(1386065770, 449252304), .type = .normal, .uname = "alex", .gname = "wheel", - .atime = unixTime(1389782991, 419875220), - .ctime = unixTime(1386065770, 449252304), + .atime = try unixTime(1389782991, 419875220), + .ctime = try unixTime(1386065770, 449252304), .pax_recs = &.{ "security.selinux", ".unconfined_u=.object_r=.default_t=s0\x00", "mtime", "1386065770.449252304", @@ -408,7 +408,7 @@ test "std.tar validate testdata headers" { .headers = &.{.{ .name = "GNU2/GNU2/long-path-name", .linkname = "GNU4/GNU4/long-linkpath-name", - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .type = .symbolic_link, .fmt = FormatSet.initOne(.gnu), }}, @@ -425,12 +425,12 @@ test "std.tar validate testdata headers" { .uid = 1000, .gid = 1000, .size = 14, - .mtime = unixTime(1441973427, 0), + .mtime = try unixTime(1441973427, 0), .type = @intToEnum(FileType, 'D'), .uname = "rawr", .gname = "dsnet", - .atime = unixTime(1441974501, 0), - .ctime = unixTime(1441973436, 0), + .atime = try unixTime(1441974501, 0), + .ctime = try unixTime(1441973436, 0), .fmt = FormatSet.initOne(.gnu), }, .{ .name = "test2/foo", @@ -438,12 +438,12 @@ test "std.tar validate testdata headers" { .uid = 1000, .gid = 1000, .size = 64, - .mtime = unixTime(1441973363, 0), + .mtime = try unixTime(1441973363, 0), .type = .normal, .uname = "rawr", .gname = "dsnet", - .atime = unixTime(1441974501, 0), - .ctime = unixTime(1441973436, 0), + .atime = try unixTime(1441974501, 0), + .ctime = try unixTime(1441973436, 0), .fmt = FormatSet.initOne(.gnu), }, .{ .name = "test2/sparse", @@ -451,12 +451,12 @@ test "std.tar validate testdata headers" { .uid = 1000, .gid = 1000, .size = 536870912, - .mtime = unixTime(1441973427, 0), + .mtime = try unixTime(1441973427, 0), .type = @intToEnum(FileType, 'S'), .uname = "rawr", .gname = "dsnet", - .atime = unixTime(1441991948, 0), - .ctime = unixTime(1441973436, 0), + .atime = try unixTime(1441991948, 0), + .ctime = try unixTime(1441973436, 0), .fmt = FormatSet.initOne(.gnu), } }, }, @@ -466,7 +466,7 @@ test "std.tar validate testdata headers" { .headers = &.{.{ .name = "bar", .linkname = "PAX4/PAX4/long-linkpath-name", - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .type = @intToEnum(tar.FileType, '2'), .pax_recs = &.{ "linkpath", "PAX4/PAX4/long-linkpath-name", @@ -484,7 +484,7 @@ test "std.tar validate testdata headers" { .mode = 0o644, .uid = 1000, .gid = 1000, - .mtime = unixTime(1486082191, 0), + .mtime = try unixTime(1486082191, 0), .type = .normal, .uname = "rawr", .gname = "dsnet", @@ -503,7 +503,7 @@ test "std.tar validate testdata headers" { .mode = 0o644, .uid = 1000, .gid = 1000, - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .type = .normal, .uname = "☺", .gname = "⚹", @@ -522,7 +522,7 @@ test "std.tar validate testdata headers" { .mode = 0o644, .uid = 1000, .gid = 1000, - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .type = .normal, .uname = "rawr", .gname = "dsnet", @@ -568,7 +568,7 @@ test "std.tar validate testdata headers" { .headers = &.{.{ .name = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/foo", .uid = 0o10000000, - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .type = .normal, }}, }, @@ -579,7 +579,7 @@ test "std.tar validate testdata headers" { .name = "file", .mode = 0o644, .type = .normal, - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .dev_major = 1, .dev_minor = 1, .fmt = FormatSet.initOne(.ustar), @@ -592,7 +592,7 @@ test "std.tar validate testdata headers" { .name = "sparse.db", .type = .gnu_sparse, .size = 1000, - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .fmt = FormatSet.initOne(.gnu), }}, }, @@ -604,7 +604,7 @@ test "std.tar validate testdata headers" { .name = "sparse.db", .type = .gnu_sparse, .size = 1000, - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .fmt = FormatSet.initOne(.gnu), }}, }, @@ -616,7 +616,7 @@ test "std.tar validate testdata headers" { .name = "sparse.db", .type = .normal, .size = 1000, - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .pax_recs = &.{ "size", "1512", "GNU.sparse.major", "1", @@ -635,7 +635,7 @@ test "std.tar validate testdata headers" { .name = "sparse.db", .type = .normal, .size = 1000, - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .pax_recs = &.{ "size", "512", "GNU.sparse.major", "1", @@ -651,7 +651,7 @@ test "std.tar validate testdata headers" { .headers = &.{.{ .type = .directory, .name = one_to_nine_slash_x30, - .mtime = unixTime(0, 0), + .mtime = try unixTime(0, 0), .pax_recs = &.{ "path", one_to_nine_slash_x30 }, .fmt = FormatSet.initOne(.pax), }}, diff --git a/lib/std/compress/tar/test_common.zig b/lib/std/compress/tar/test_common.zig index 5a5abd412db4..3b3eabe6b6e6 100644 --- a/lib/std/compress/tar/test_common.zig +++ b/lib/std/compress/tar/test_common.zig @@ -1,4 +1,5 @@ const std = @import("std"); + /// testing helper for decompressing a .gz file. returns an io.fixedBufferStream /// with the decompressed data. caller owns the returned FixedBufferStream.buffer pub fn decompressGz( diff --git a/lib/std/tar.zig b/lib/std/tar.zig index 8a67b0cb89c1..2963b42e846c 100644 --- a/lib/std/tar.zig +++ b/lib/std/tar.zig @@ -36,6 +36,12 @@ pub const FileType = enum(u8) { result.set(@enumToInt(ft)); break :blk result; }; + + pub fn tagName(ft: FileType) ?[]const u8 { + return inline for (std.meta.fields(FileType)) |f| { + if (@enumToInt(ft) == f.value) break f.name; + } else null; + } }; fn parseOctal(raw: []const u8) !i64 { @@ -157,7 +163,7 @@ fn parsePaxTime(s: []const u8) !i128 { const secs = try fmt.parseInt(i64, ss, 10); const sn = parts[1]; - if (sn.len == 0) return unixTime(secs, 0); + if (sn.len == 0) return try unixTime(secs, 0); const all_digits = for (sn) |c| { if (!std.ascii.isDigit(c)) break false; @@ -173,9 +179,9 @@ fn parsePaxTime(s: []const u8) !i128 { log.debug("parsePaxTime secs={} nsecs={} sn.len={}", .{ secs, nsecs, sn.len }); return if (ss.len > 0 and ss[0] == '-') - unixTime(secs, -nsecs) + try unixTime(secs, -nsecs) else - unixTime(secs, nsecs); + try unixTime(secs, nsecs); } test parsePaxTime { @@ -185,53 +191,53 @@ test parsePaxTime { }; const cases = [_]TestCase{ - .{ "1350244992.023960108", unixTime(1350244992, 23960108) }, - .{ "1350244992.02396010", unixTime(1350244992, 23960100) }, - .{ "1350244992.0239601089", unixTime(1350244992, 23960108) }, - .{ "1350244992.3", unixTime(1350244992, 300000000) }, - .{ "1350244992", unixTime(1350244992, 0) }, - .{ "-1.000000001", unixTime(-1, -1e0 + 0e0) }, - .{ "-1.000001", unixTime(-1, -1e3 + 0e0) }, - .{ "-1.001000", unixTime(-1, -1e6 + 0e0) }, - .{ "-1", unixTime(-1, -0e0 + 0e0) }, - .{ "-1.999000", unixTime(-1, -1e9 + 1e6) }, - .{ "-1.999999", unixTime(-1, -1e9 + 1e3) }, - .{ "-1.999999999", unixTime(-1, -1e9 + 1e0) }, - .{ "0.000000001", unixTime(0, 1e0 + 0e0) }, - .{ "0.000001", unixTime(0, 1e3 + 0e0) }, - .{ "0.001000", unixTime(0, 1e6 + 0e0) }, - .{ "0", unixTime(0, 0e0) }, - .{ "0.999000", unixTime(0, 1e9 - 1e6) }, - .{ "0.999999", unixTime(0, 1e9 - 1e3) }, - .{ "0.999999999", unixTime(0, 1e9 - 1e0) }, - .{ "1.000000001", unixTime(1, 1e0 - 0e0) }, - .{ "1.000001", unixTime(1, 1e3 - 0e0) }, - .{ "1.001000", unixTime(1, 1e6 - 0e0) }, - .{ "1", unixTime(1, 0e0 - 0e0) }, - .{ "1.999000", unixTime(1, 1e9 - 1e6) }, - .{ "1.999999", unixTime(1, 1e9 - 1e3) }, - .{ "1.999999999", unixTime(1, 1e9 - 1e0) }, - .{ "-1350244992.023960108", unixTime(-1350244992, -23960108) }, - .{ "-1350244992.02396010", unixTime(-1350244992, -23960100) }, - .{ "-1350244992.0239601089", unixTime(-1350244992, -23960108) }, - .{ "-1350244992.3", unixTime(-1350244992, -300000000) }, - .{ "-1350244992", unixTime(-1350244992, 0) }, + .{ "1350244992.023960108", try unixTime(1350244992, 23960108) }, + .{ "1350244992.02396010", try unixTime(1350244992, 23960100) }, + .{ "1350244992.0239601089", try unixTime(1350244992, 23960108) }, + .{ "1350244992.3", try unixTime(1350244992, 300000000) }, + .{ "1350244992", try unixTime(1350244992, 0) }, + .{ "-1.000000001", try unixTime(-1, -1e0 + 0e0) }, + .{ "-1.000001", try unixTime(-1, -1e3 + 0e0) }, + .{ "-1.001000", try unixTime(-1, -1e6 + 0e0) }, + .{ "-1", try unixTime(-1, -0e0 + 0e0) }, + .{ "-1.999000", try unixTime(-1, -1e9 + 1e6) }, + .{ "-1.999999", try unixTime(-1, -1e9 + 1e3) }, + .{ "-1.999999999", try unixTime(-1, -1e9 + 1e0) }, + .{ "0.000000001", try unixTime(0, 1e0 + 0e0) }, + .{ "0.000001", try unixTime(0, 1e3 + 0e0) }, + .{ "0.001000", try unixTime(0, 1e6 + 0e0) }, + .{ "0", try unixTime(0, 0e0) }, + .{ "0.999000", try unixTime(0, 1e9 - 1e6) }, + .{ "0.999999", try unixTime(0, 1e9 - 1e3) }, + .{ "0.999999999", try unixTime(0, 1e9 - 1e0) }, + .{ "1.000000001", try unixTime(1, 1e0 - 0e0) }, + .{ "1.000001", try unixTime(1, 1e3 - 0e0) }, + .{ "1.001000", try unixTime(1, 1e6 - 0e0) }, + .{ "1", try unixTime(1, 0e0 - 0e0) }, + .{ "1.999000", try unixTime(1, 1e9 - 1e6) }, + .{ "1.999999", try unixTime(1, 1e9 - 1e3) }, + .{ "1.999999999", try unixTime(1, 1e9 - 1e0) }, + .{ "-1350244992.023960108", try unixTime(-1350244992, -23960108) }, + .{ "-1350244992.02396010", try unixTime(-1350244992, -23960100) }, + .{ "-1350244992.0239601089", try unixTime(-1350244992, -23960108) }, + .{ "-1350244992.3", try unixTime(-1350244992, -300000000) }, + .{ "-1350244992", try unixTime(-1350244992, 0) }, .{ "", error.InvalidCharacter }, - .{ "0", unixTime(0, 0) }, - .{ "1.", unixTime(1, 0) }, - .{ "0.0", unixTime(0, 0) }, + .{ "0", try unixTime(0, 0) }, + .{ "1.", try unixTime(1, 0) }, + .{ "0.0", try unixTime(0, 0) }, .{ ".5", error.InvalidCharacter }, - .{ "-1.3", unixTime(-1, -3e8) }, - .{ "-1.0", unixTime(-1, -0e0) }, - .{ "-0.0", unixTime(-0, -0e0) }, - .{ "-0.1", unixTime(-0, -1e8) }, - .{ "-0.01", unixTime(-0, -1e7) }, - .{ "-0.99", unixTime(-0, -99e7) }, - .{ "-0.98", unixTime(-0, -98e7) }, - .{ "-1.1", unixTime(-1, -1e8) }, - .{ "-1.01", unixTime(-1, -1e7) }, - .{ "-2.99", unixTime(-2, -99e7) }, - .{ "-5.98", unixTime(-5, -98e7) }, + .{ "-1.3", try unixTime(-1, -3e8) }, + .{ "-1.0", try unixTime(-1, -0e0) }, + .{ "-0.0", try unixTime(-0, -0e0) }, + .{ "-0.1", try unixTime(-0, -1e8) }, + .{ "-0.01", try unixTime(-0, -1e7) }, + .{ "-0.99", try unixTime(-0, -99e7) }, + .{ "-0.98", try unixTime(-0, -98e7) }, + .{ "-1.1", try unixTime(-1, -1e8) }, + .{ "-1.01", try unixTime(-1, -1e7) }, + .{ "-2.99", try unixTime(-2, -99e7) }, + .{ "-5.98", try unixTime(-5, -98e7) }, .{ "-", error.InvalidCharacter }, .{ "+", error.InvalidCharacter }, .{ "-1.-1", error.InvalidCharacter }, @@ -488,8 +494,11 @@ pub const Header = struct { } }; -pub fn unixTime(tv_sec: i64, tv_nsec: i64) i128 { - const result = @bitCast(i128, [_]i64{ tv_sec * time.ns_per_s, tv_nsec }); +pub fn unixTime(tv_sec: i64, tv_nsec: i64) !i128 { + const result = @bitCast(i128, [_]i64{ + try std.math.mul(i64, tv_sec, time.ns_per_s), + tv_nsec, + }); return result; } @@ -759,6 +768,7 @@ pub fn HeaderIterator(comptime Reader: type) type { } want -= block_len; } + if (want != 0) return error.UnexpectedEndOfStream; return outbuf.items[0..@intCast(usize, size)]; } @@ -779,7 +789,8 @@ pub fn HeaderIterator(comptime Reader: type) type { const v7 = self.v7Header(); switch (v7.type) { .global_extended_header, .extended_header => { - const size = @intCast(u64, try parseOctal(&v7.size)); + const size = std.math.cast(u64, try parseOctal(&v7.size)) orelse + return error.Header; self.pax_buf.items = try self.readBlocks(size, &self.pax_buf); }, else => {}, @@ -807,10 +818,11 @@ pub fn HeaderIterator(comptime Reader: type) type { return null; const pax_record = self.bytes[0..nl]; self.bytes = self.bytes[nl + 1 ..]; - assert(pax_record.len != 0); + if (pax_record.len == 0) return error.Header; const sp = mem.indexOfScalar(u8, pax_record, ' ') orelse return error.Header; const len = try fmt.parseUnsigned(u32, pax_record[0..sp], 10); + if (len > pax_record.len + 1 or sp + 2 > len) return error.Header; const rec = pax_record[sp + 1 .. len - 1]; const eqidx = mem.indexOfScalar(u8, rec, '=') orelse return error.Header; @@ -882,9 +894,11 @@ pub fn HeaderIterator(comptime Reader: type) type { .linkname = mem.sliceTo(&v7.linked_file_name, 0), .size = try parseNumeric(&v7.size), .mode = try parseNumeric(&v7.mode), - .uid = @intCast(i32, try parseNumeric(&v7.uid)), - .gid = @intCast(i32, try parseNumeric(&v7.gid)), - .mtime = unixTime(try parseNumeric(&v7.mod_time), 0), + .uid = std.math.cast(i32, try parseNumeric(&v7.uid)) orelse + return error.Header, + .gid = std.math.cast(i32, try parseNumeric(&v7.gid)) orelse + return error.Header, + .mtime = try unixTime(try parseNumeric(&v7.mod_time), 0), }; var prefix: []const u8 = ""; @@ -927,17 +941,17 @@ pub fn HeaderIterator(comptime Reader: type) type { } else if (format.contains(.star)) { const star = v7.star(); prefix = mem.sliceTo(&star.filename_prefix, 0); - hdr.atime = unixTime(try parseNumeric(&star.access_time), 0); - hdr.ctime = unixTime(try parseNumeric(&star.change_time), 0); + hdr.atime = try unixTime(try parseNumeric(&star.access_time), 0); + hdr.ctime = try unixTime(try parseNumeric(&star.change_time), 0); } else if (format.contains(.gnu)) { hdr.fmt = format; const gnu = v7.gnu(); if (gnu.access_time[0] != 0) - hdr.atime = unixTime(try parseNumeric(&gnu.access_time), 0); + hdr.atime = try unixTime(try parseNumeric(&gnu.access_time), 0); if (gnu.change_time[0] != 0) - hdr.ctime = unixTime(try parseNumeric(&gnu.change_time), 0); + hdr.ctime = try unixTime(try parseNumeric(&gnu.change_time), 0); } if (prefix.len > 0) { self.name_buf.items.len = 0; @@ -1095,7 +1109,7 @@ pub fn pipeToFileSystem( while (try iter.next()) |header| { const file_name = try stripComponents(header.name, options.strip_components); - log.info("pipeToFileSystem() header.type={s} stripped file_name={s}", .{ @tagName(header.type), file_name }); + log.info("pipeToFileSystem() header.type={?s} stripped file_name={s}", .{ header.type.tagName(), file_name }); if (file_name.len == 0 and FileType.named_types_bitset.isSet(@enumToInt(header.type))) continue; @@ -1162,7 +1176,7 @@ pub fn pipeToFileSystem( format.setIntersection(fmt_pax); }, else => { - log.err("unsupported type '{s}'", .{@tagName(header.type)}); + log.err("unsupported type '{?s}':{}", .{ header.type.tagName(), @enumToInt(header.type) }); return error.TarUnexpectedFileType; }, }