From f17b402f0832f5f1d428d1eef3999016943c3f49 Mon Sep 17 00:00:00 2001 From: "Caleb J. Gardner" Date: Tue, 2 Jun 2026 22:33:28 -0500 Subject: [PATCH] Fixed some issues --- build.zig | 1 + src/archive.zig | 42 ++++++++++++++++++++++++++++++++++++++++++ src/decomp_cache.zig | 7 +++++-- src/meta_rdr.zig | 10 ++++++++-- 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/build.zig b/build.zig index 67ec998..3f47ee2 100644 --- a/build.zig +++ b/build.zig @@ -74,6 +74,7 @@ pub fn build(b: *std.Build) !void { b.installArtifact(exe); + // Tests const lib_test = b.addTest(.{ .name = "squashfs-test", .root_module = lib.root_module, diff --git a/src/archive.zig b/src/archive.zig index a052c78..4c6f9a9 100644 --- a/src/archive.zig +++ b/src/archive.zig @@ -148,6 +148,8 @@ test "Basics" { var arc: Archive = try .init(alloc, io, archive_file); defer arc.deinit(io); + try std.testing.expectEqualDeep(arc.super, LinuxPATestCorrectSuperblock); + var root_file = try arc.root(alloc, io); defer root_file.deinit(); } @@ -183,3 +185,43 @@ test "FullExtraction" { try arc.extract(alloc, io, TestFullExtractLocation, .default); } + +const LinuxPATestCorrectSuperblock: Superblock = .{ + .magic = std.mem.readInt(u32, "hsqs", .little), + .inode_count = 2974, + .mod_time = 1632696724, + .block_size = 131072, + .frag_count = 264, + .compression = .zstd, + .block_log = 17, + .flags = .{ + .inode_uncompressed = false, + .data_uncompressed = false, + .check = false, + .frag_uncompressed = false, + .frag_never = false, + .frag_always = false, + .de_dupe = true, + .exportable = true, + .xattr_uncompressed = false, + .xattr_never = false, + .compression_options = false, + .id_uncompressed = false, + ._ = 0, + }, + .id_count = 1, + .ver_maj = 4, + .ver_min = 0, + .root_ref = .{ + .block_offset = 1363, + .block_start = 29237, + ._ = 0, + }, + .size = 106841744, + .id_start = 106841632, + .xattr_start = 106841720, + .inode_start = 106778274, + .dir_start = 106807998, + .frag_start = 106837747, + .export_start = 106841602, +}; diff --git a/src/decomp_cache.zig b/src/decomp_cache.zig index 52d913b..69514d8 100644 --- a/src/decomp_cache.zig +++ b/src/decomp_cache.zig @@ -70,6 +70,7 @@ pub fn get(self: *DecompCache, io: Io, offset: u64, compressed_size: u32, max_si if (!self.alloc.resize(out, decomp_size)) { const new_out = try self.alloc.alloc(u8, decomp_size); @memcpy(new_out, out[0..decomp_size]); + self.alloc.free(out); out = new_out; } else { out.len = decomp_size; @@ -77,8 +78,10 @@ pub fn get(self: *DecompCache, io: Io, offset: u64, compressed_size: u32, max_si } self.cur_mem += decomp_size; - cache.value_ptr.data = out; - _ = cache.value_ptr.usage.fetchAdd(1, .acquire); + cache.value_ptr.* = .{ + .data = out, + .usage = .init(1), + }; return out; } pub fn finished(self: *DecompCache, io: Io, offset: u64) void { diff --git a/src/meta_rdr.zig b/src/meta_rdr.zig index 2bd3273..d32ca11 100644 --- a/src/meta_rdr.zig +++ b/src/meta_rdr.zig @@ -34,16 +34,22 @@ pub fn init(io: Io, cache: *DecompCache, start: u64) MetadataReader { }; } pub fn deinit(self: *MetadataReader, io: Io) void { - self.cache.finished(io, self.cur_offset); + if (self.cur_offset != 0) + self.cache.finished(io, self.cur_offset); } fn advance(self: *MetadataReader) !void { - self.cache.finished(self.io, self.cur_offset); + if (self.cur_offset != 0) + self.cache.finished(self.io, self.cur_offset); self.interface.seek = 0; errdefer self.interface.end = 0; const hdr: Header = @bitCast(std.mem.readInt(u16, self.cache.map.memory[self.next_offset..][0..2], .little)); + if (hdr.size > 8192) { + std.debug.print("Bad metadata header at {}: {}\n", .{ self.next_offset, hdr }); + return error.ReadFailed; + } self.cur_offset = self.next_offset + 2; self.next_offset = self.cur_offset + hdr.size;