From 4554619e7e8fc1c82b3496efed1ba75e311060df Mon Sep 17 00:00:00 2001 From: Hawkynt Date: Mon, 19 Oct 2026 13:23:31 +0200 Subject: [PATCH 1/3] + SeqBox (.sbx) container: read and create SeqBox had no descriptor. It is Marco Pontello's recoverable single-file container: the file is cut into 512/128/4096/488-byte blocks (versions 1-4), each carrying "SBx", version, CRC-16, a 6-byte file UID and a sequence number, so it survives on a damaged or unindexed disk; block 0 holds optional TLV metadata (name, size, times, SHA-256 multihash). The reader verifies every block (signature, version, UID, CRC-16/CCITT seeded with the version, contiguous sequence), trims to FSZ and checks the SHA-256; without metadata it keeps the 0x1A padding as sbxdec does. The writer emits the sbxenc layout with full metadata. Lists as one entry named by FNM; creating from more than one file or with a password is refused. Oracle: containers written by the reference sbxenc 1.0.2 at every version (with and without metadata, empty file) are committed and decoded byte for byte; the reference sbxdec decodes what we write at every version and reports "hash match!" (tool-gated, SEQBOX_HOME or /opt/seqbox). Sourcing: rung 3 - layout from the format author's README; the reference scripts (whose headers say AGPL-3.0 while the repository says MIT) were used only as a black-box oracle, no code taken. --- Compression.Tests/Compression.Tests.csproj | 4 + .../ConversionMatrix/ConversionMatrixTests.cs | 1 + .../SeqBox/ReferenceVectors/README.md | 20 ++ .../SeqBox/ReferenceVectors/empty-v1.sbx | Bin 0 -> 512 bytes .../SeqBox/ReferenceVectors/fox-nometa-v1.sbx | Bin 0 -> 2560 bytes .../SeqBox/ReferenceVectors/fox-v1.sbx | Bin 0 -> 3072 bytes .../SeqBox/ReferenceVectors/fox-v3.sbx | Bin 0 -> 8192 bytes .../SeqBox/ReferenceVectors/noise-v2.sbx | Bin 0 -> 1280 bytes .../SeqBox/ReferenceVectors/noise-v4.sbx | Bin 0 -> 1952 bytes Compression.Tests/SeqBox/SeqBoxTests.cs | 203 +++++++++++++++ .../FileFormat.SeqBox/SeqBoxContainer.cs | 239 ++++++++++++++++++ .../SeqBoxFormatDescriptor.cs | 91 +++++++ Hawkynt.FileFormats.Archives/README.md | 3 +- Hawkynt.FileFormats.Archives/REFERENCE.md | 76 ++++++ docs/catalogue/our-registry.csv | 1 + docs/catalogue/reference-formats.csv | 2 +- 16 files changed, 638 insertions(+), 2 deletions(-) create mode 100644 Compression.Tests/SeqBox/ReferenceVectors/README.md create mode 100644 Compression.Tests/SeqBox/ReferenceVectors/empty-v1.sbx create mode 100644 Compression.Tests/SeqBox/ReferenceVectors/fox-nometa-v1.sbx create mode 100644 Compression.Tests/SeqBox/ReferenceVectors/fox-v1.sbx create mode 100644 Compression.Tests/SeqBox/ReferenceVectors/fox-v3.sbx create mode 100644 Compression.Tests/SeqBox/ReferenceVectors/noise-v2.sbx create mode 100644 Compression.Tests/SeqBox/ReferenceVectors/noise-v4.sbx create mode 100644 Compression.Tests/SeqBox/SeqBoxTests.cs create mode 100644 Hawkynt.FileFormats.Archives/FileFormats/FileFormat.SeqBox/SeqBoxContainer.cs create mode 100644 Hawkynt.FileFormats.Archives/FileFormats/FileFormat.SeqBox/SeqBoxFormatDescriptor.cs diff --git a/Compression.Tests/Compression.Tests.csproj b/Compression.Tests/Compression.Tests.csproj index 7bba71ab0..c5adf5f57 100644 --- a/Compression.Tests/Compression.Tests.csproj +++ b/Compression.Tests/Compression.Tests.csproj @@ -118,6 +118,10 @@ ZfsVectors.%(Filename)%(Extension) + + + SeqBoxVectors.%(Filename)%(Extension) + DarVectors.%(Filename)%(Extension) diff --git a/Compression.Tests/ConversionMatrix/ConversionMatrixTests.cs b/Compression.Tests/ConversionMatrix/ConversionMatrixTests.cs index 5978a0c11..cbe94366e 100644 --- a/Compression.Tests/ConversionMatrix/ConversionMatrixTests.cs +++ b/Compression.Tests/ConversionMatrix/ConversionMatrixTests.cs @@ -126,6 +126,7 @@ public static IEnumerable Grid() { { "StuffItX", "[single-payload/whole-image target] writer emits an image that re-lists as 0 files" }, { "Umx", "[single-payload/whole-image target] Unreal package; writer emits a blob that re-lists as 0 files" }, { "Wbn", "[single-payload/whole-image target] WebBundle writer collapses tree to a single FULL.wbn" }, + { "SeqBox", "[single-payload/whole-image target] a SeqBox container holds exactly one file; a tree of several is refused" }, { "Wrapster", "[single-payload/whole-image target] Wrapster MP3 wrapper; one FULL.mp3 + 0/1 frame, not a tree" }, { "xDisk", "[single-payload/whole-image target] Amiga xDisk image; writer emits one .xdsk blob" }, { "xMash", "[single-payload/whole-image target] Amiga xMash image; writer emits one .xmsh blob" }, diff --git a/Compression.Tests/SeqBox/ReferenceVectors/README.md b/Compression.Tests/SeqBox/ReferenceVectors/README.md new file mode 100644 index 000000000..62894d80a --- /dev/null +++ b/Compression.Tests/SeqBox/ReferenceVectors/README.md @@ -0,0 +1,20 @@ +# SeqBox reference containers + +Every file here was written by the reference encoder `sbxenc.py` 1.0.2 from +[MarcoPon/SeqBox](https://github.com/MarcoPon/SeqBox) at revision +`dee472acfe89f08b7112ce854ca98f2094fbae3b`, run with Python 3.12 on Ubuntu 24.04 (WSL), never by +CompressionWorkbench. + +Sources: `fox.txt` = `The quick brown fox jumps over the lazy dog. ` × 50 (2250 bytes), `noise.bin` = +the 1000 bytes `(i * 31 + 7) mod 256`, `empty.bin` = 0 bytes; all with mtime 2001-02-03 04:05:06 UTC. + +| File | Command | What it pins | +| --- | --- | --- | +| `fox-v1.sbx` | `sbxenc.py -uid 0000c0ffee01 fox.txt fox-v1.sbx` | version 1 (512-byte blocks), full metadata block | +| `noise-v2.sbx` | `sbxenc.py -uid 0000c0ffee02 -sv 2 noise.bin noise-v2.sbx` | version 2 (128-byte blocks) | +| `fox-v3.sbx` | `sbxenc.py -uid 0000c0ffee03 -sv 3 fox.txt fox-v3.sbx` | version 3 (4096-byte blocks) | +| `noise-v4.sbx` | `sbxenc.py -uid 0000c0ffee04 -sv 4 noise.bin noise-v4.sbx` | version 4 (488-byte blocks) | +| `fox-nometa-v1.sbx` | `sbxenc.py -uid 0000c0ffee05 -nm fox.txt fox-nometa-v1.sbx` | no metadata block: payload keeps the 0x1A padding | +| `empty-v1.sbx` | `sbxenc.py -uid 0000c0ffee06 empty.bin empty-v1.sbx` | metadata block only | + +`sbxdec.py -i fox-v1.sbx` reports the expected name, size (2250) and SHA-256. diff --git a/Compression.Tests/SeqBox/ReferenceVectors/empty-v1.sbx b/Compression.Tests/SeqBox/ReferenceVectors/empty-v1.sbx new file mode 100644 index 0000000000000000000000000000000000000000..252ee4d751549a03da9762e71b896ba416b9c85d GIT binary patch literal 512 zcmWG`s$jgr$G~vl|2sAYAaL{ZR_e003LNPvZap literal 0 HcmV?d00001 diff --git a/Compression.Tests/SeqBox/ReferenceVectors/fox-nometa-v1.sbx b/Compression.Tests/SeqBox/ReferenceVectors/fox-nometa-v1.sbx new file mode 100644 index 0000000000000000000000000000000000000000..cf41fd4727de59a632d416e02b46a3c524301976 GIT binary patch literal 2560 zcmWG`s$jI2VPH7${~ap>0|R47Myf(#X=ZY^LQ+wFd7eUAeuY9-X>LKWLVj6lkwOVj zIw!HJQXwTjT~A?D@sJOVU|{?|$cM*2(`fXMtn>|v|6mq){4nt*V=gf}!lJtM6Srf<2Uk6lTO&Zr!tu?Z-C$prjWjHdku?ZmGE{d3pNed1>2a zT%1=*je@}w0>Qxe@BIajf5woERE5IQ%;ao^q@w)tJOy9^P{=CHEhtvVFH0>_C;>|6 zBvw@_q~xdTDU2!}@}U8W|DaBI{4p&UU$g-p|16`0 c|H!J{K=FTC2p<2eqjf*5aWi<@XtZ<*0IY?lk^lez literal 0 HcmV?d00001 diff --git a/Compression.Tests/SeqBox/ReferenceVectors/fox-v3.sbx b/Compression.Tests/SeqBox/ReferenceVectors/fox-v3.sbx new file mode 100644 index 0000000000000000000000000000000000000000..dd7a1a94e6b6dd7463e594c14299c08a6d556eb3 GIT binary patch literal 8192 zcmWG`s$jn4z`$_e|2t*|AaL{ZWlzhm&?~7Z3HI~l0y1^WjP;6>D%^sjI6w**7&uP3 zxrBh(R@Kc#!BBSA)%Wfm!5&IN3NvCXx9-`-_G24=P|^z%n=3Vcx71vfygYsKytM5y zF3u~ZM!{$ZjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk0DVIs7})=}NrCtO z8ACEs6$(o;ld~0)it@|z6o3N&3R$JO1;q;aWvN99B|zz%#Hvb#l>Br(g;B+$p)r~^ rMsvz&Q7~FCj#d++mFA#o70|aGHEP>v2#kinXb6mkz-R~zr4RrBCFY?r literal 0 HcmV?d00001 diff --git a/Compression.Tests/SeqBox/ReferenceVectors/noise-v2.sbx b/Compression.Tests/SeqBox/ReferenceVectors/noise-v2.sbx new file mode 100644 index 0000000000000000000000000000000000000000..f8a6f23594ab6c12f16e3c74722bb83a8b18c840 GIT binary patch literal 1280 zcmWG`s$lxk&A@Qr|2rlIAaL{Z<;=^^EKb!+%FGM)^W_0^bjytNijykbf}=P?xR>Dh8| zVaM8ql~OPe476X-0d7AdyP9iC^P+$0MRL|OZ z;bl{|T>d0z;GfsK=JYF04fnLxC5Im|D%i)>&e?tIr-XS}>6FcvJ__jj<@T&T^^yZ* z{{$hp{mklasV$2SJ!Fu#i>;Zx>*fz}v(S>sn=XFf*YnNkUUl*XwZjKw{}c(h{VasS zi`wA>vj2n++e<|F4c1qI|so?{%|D6=vehyma WH}voU+3$tO|D3eWZ?N!zl|KNGLq^g7 literal 0 HcmV?d00001 diff --git a/Compression.Tests/SeqBox/ReferenceVectors/noise-v4.sbx b/Compression.Tests/SeqBox/ReferenceVectors/noise-v4.sbx new file mode 100644 index 0000000000000000000000000000000000000000..340b730637ee6d5b4493a6f3a548828e88e39220 GIT binary patch literal 1952 zcmWG`s$j8w%D`~o|2q~2AaL{Z<;=^^EKb!+%FGM)^W_0^bjwWiijykbf}=P?xR>Dh8| zVaM8ql~SXCz9A3{jOU%l;PK4JuI8H3yy)PA|8ll5)w6cq_%3D|Qaownh4*~AKG|I> zPdsN+bxCeoc;Nm&S)1spnLDn36Ez7gnz-ToJ6;{{tj-n3pRuYqCp9kEfA6o1byVey z?bp7F7zY(jSby#c}pSJbNXCcFY{JynkUUO-Bq_-_S@|a1{A--hcg^WnoEq+FtxFC+VpOn?tDUp^)=vrZu+k};FMSly_si{Bed;BLx?5_? z;zJJ^X79TBL)TG<=MXh` SJTsGQujoL +/// SeqBox (.sbx): containers written by the reference sbxenc (SeqBox/ReferenceVectors), our +/// writer, and the reference sbxdec as a live oracle for what we write. +/// +[TestFixture] +public class SeqBoxTests { + + private static readonly byte[] FoxText = + System.Text.Encoding.ASCII.GetBytes(string.Concat(Enumerable.Repeat("The quick brown fox jumps over the lazy dog. ", 50))); + + private static readonly byte[] Noise = Enumerable.Range(0, 1000).Select(i => (byte)((i * 31 + 7) % 256)).ToArray(); + + private static readonly long FoxTime = new DateTimeOffset(2001, 2, 3, 4, 5, 6, TimeSpan.Zero).ToUnixTimeSeconds(); + + private string _tmpDir = null!; + + [SetUp] + public void Setup() { + this._tmpDir = Path.Combine(Path.GetTempPath(), $"cwb_sbx_{Guid.NewGuid():N}"); + Directory.CreateDirectory(this._tmpDir); + } + + [TearDown] + public void Teardown() { + try { Directory.Delete(this._tmpDir, true); } catch { /* best effort */ } + } + + // ── reference containers (sbxenc 1.0.2) ───────────────────────────── + + [TestCase("fox-v1.sbx", 1, "fox.txt")] + [TestCase("fox-v3.sbx", 3, "fox.txt")] + [TestCase("noise-v2.sbx", 2, "noise.bin")] + [TestCase("noise-v4.sbx", 4, "noise.bin")] + [Category("ThemVsUs")] + public void GivenSbxencContainer_WhenRead_ThenMetadataAndPayloadMatchTheSource(string vector, int version, string name) { + var p = SeqBoxContainer.Read(new MemoryStream(LoadVector(vector))); + + Assert.That(p.Version, Is.EqualTo(version)); + Assert.That(p.Metadata, Is.Not.Null); + Assert.That(p.Metadata!.FileName, Is.EqualTo(name)); + Assert.That(p.Metadata.SbxName, Is.EqualTo(vector)); + Assert.That(p.Metadata.FileTime, Is.EqualTo(FoxTime)); + Assert.That(p.Data, Is.EqualTo(name == "fox.txt" ? FoxText : Noise)); + } + + [Test, Category("ThemVsUs")] + public void GivenSbxencContainerWithoutMetadata_WhenRead_ThenPayloadKeepsTheLastBlocksPadding() { + var p = SeqBoxContainer.Read(new MemoryStream(LoadVector("fox-nometa-v1.sbx"))); + + Assert.That(p.Metadata, Is.Null); + Assert.That(p.DataBlocks, Is.EqualTo(5)); + Assert.That(p.Data.AsSpan(0, FoxText.Length).ToArray(), Is.EqualTo(FoxText)); + Assert.That(p.Data.Skip(FoxText.Length), Has.All.EqualTo((byte)0x1A)); + } + + [Test, Category("Boundary")] + public void GivenSbxencContainerOfAnEmptyFile_WhenRead_ThenOnlyTheMetadataBlockAndAnEmptyPayload() { + var p = SeqBoxContainer.Read(new MemoryStream(LoadVector("empty-v1.sbx"))); + + Assert.That(p.DataBlocks, Is.Zero); + Assert.That(p.Metadata!.FileSize, Is.Zero); + Assert.That(p.Data, Is.Empty); + } + + [Test, Category("ThemVsUs")] + public void GivenSbxencContainer_WhenListedAndExtractedThroughTheDescriptor_ThenOneNamedEntry() { + var d = new SeqBoxFormatDescriptor(); + var bytes = LoadVector("fox-v1.sbx"); + + var list = d.List(new MemoryStream(bytes), null); + Assert.That(list.Single().Name, Is.EqualTo("fox.txt")); + Assert.That(list.Single().OriginalSize, Is.EqualTo(FoxText.Length)); + + d.Extract(new MemoryStream(bytes), this._tmpDir, null, null); + Assert.That(File.ReadAllBytes(Path.Combine(this._tmpDir, "fox.txt")), Is.EqualTo(FoxText)); + } + + // ── our writer ────────────────────────────────────────────────────── + + [TestCase(1, 512)] + [TestCase(2, 128)] + [TestCase(3, 4096)] + [TestCase(4, 488)] + [Category("RoundTrip")] + public void GivenData_WhenWrittenAtEachVersion_ThenBlockAlignedAndRoundTrips(int version, int blockSize) { + var ms = new MemoryStream(); + SeqBoxContainer.Write(ms, Noise, "noise.bin", version, uid: [0, 0, 0xC0, 0xFF, 0xEE, 0x09]); + + Assert.That(ms.Length % blockSize, Is.Zero); + var p = SeqBoxContainer.Read(new MemoryStream(ms.ToArray())); + Assert.That(p.Version, Is.EqualTo(version)); + Assert.That(p.Uid, Is.EqualTo(new byte[] { 0, 0, 0xC0, 0xFF, 0xEE, 0x09 })); + Assert.That(p.Data, Is.EqualTo(Noise)); + } + + [Test, Category("Boundary")] + public void GivenPayloadOfExactlyOneBlock_WhenWritten_ThenNoPaddingBlockFollows() { + var data = Enumerable.Range(0, 496).Select(i => (byte)i).ToArray(); + var ms = new MemoryStream(); + SeqBoxContainer.Write(ms, data, "x.bin"); + + Assert.That(ms.Length, Is.EqualTo(2 * 512)); + Assert.That(SeqBoxContainer.Read(new MemoryStream(ms.ToArray())).Data, Is.EqualTo(data)); + } + + [Test, Category("Boundary")] + public void GivenEmptyFile_WhenWritten_ThenOnlyTheMetadataBlock() { + var ms = new MemoryStream(); + SeqBoxContainer.Write(ms, [], "empty.bin"); + + Assert.That(ms.Length, Is.EqualTo(512)); + Assert.That(SeqBoxContainer.Read(new MemoryStream(ms.ToArray())).Data, Is.Empty); + } + + [Test, Category("Exception")] + public void GivenTwoFiles_WhenCreated_ThenRefusesBecauseSeqBoxHoldsOneFile() { + var d = new SeqBoxFormatDescriptor(); + Assert.That(() => d.Create(new MemoryStream(), + [ArchiveInputInfo.InMemory("a", [1]), ArchiveInputInfo.InMemory("b", [2])], new FormatCreateOptions()), + Throws.InstanceOf()); + } + + [Test, Category("Exception")] + public void GivenFlippedDataByte_WhenRead_ThenTheBlockCrcRejectsIt() { + var bytes = LoadVector("fox-v1.sbx"); + bytes[512 * 2 + 100] ^= 0x01; + + Assert.That(() => SeqBoxContainer.Read(new MemoryStream(bytes)), Throws.InstanceOf().With.Message.Contains("CRC")); + } + + [Test, Category("Exception")] + public void GivenSwappedBlocks_WhenRead_ThenTheSequenceCheckRejectsIt() { + var bytes = LoadVector("fox-v1.sbx"); + var swapped = bytes.ToArray(); + bytes.AsSpan(512, 512).CopyTo(swapped.AsSpan(1024)); + bytes.AsSpan(1024, 512).CopyTo(swapped.AsSpan(512)); + + Assert.That(() => SeqBoxContainer.Read(new MemoryStream(swapped)), Throws.InstanceOf().With.Message.Contains("order")); + } + + [Test, Category("Exception")] + public void GivenMissingLastBlock_WhenRead_ThenTheFileSizeCheckRejectsIt() { + var bytes = LoadVector("fox-v1.sbx"); + + Assert.That(() => SeqBoxContainer.Read(new MemoryStream(bytes[..^512])), Throws.InstanceOf()); + } + + [Test, Category("Exception")] + public void GivenUnknownVersion_WhenRead_ThenRefused() { + var bytes = LoadVector("fox-v1.sbx"); + bytes[3] = 9; + + Assert.That(() => SeqBoxContainer.Read(new MemoryStream(bytes)), Throws.InstanceOf()); + Assert.That(SeqBoxContainer.IsSeqBox(bytes), Is.False); + } + + // ── oracle: the reference decoder reads what we write ─────────────── + + [TestCase(1)] + [TestCase(2)] + [TestCase(3)] + [TestCase(4)] + [Category("ExternalInterop")] + public void GivenOurContainer_WhenSbxdecDecodesIt_ThenHashMatchesAndBytesAreIdentical(int version) { + var sbxdec = RequireSbxdec(); + var big = Enumerable.Range(0, 20_000).Select(i => (byte)(i * 7 + (i >> 8))).ToArray(); + var path = Path.Combine(this._tmpDir, "ours.sbx"); + using (var f = File.Create(path)) + SeqBoxContainer.Write(f, big, "big.bin", version); + var outPath = Path.Combine(this._tmpDir, "decoded.bin"); + + var r = FsInteropToolbox.RunWsl( + $"python3 {sbxdec} -o '{FsInteropToolbox.WinToWsl(path)}' '{FsInteropToolbox.WinToWsl(outPath)}'"); + + Assert.That(r.ExitCode, Is.EqualTo(0), $"sbxdec rejected our container:\n{r.StdOut}\n{r.StdErr}"); + Assert.That(r.StdOut, Does.Contain("hash match!")); + Assert.That(File.ReadAllBytes(outPath), Is.EqualTo(big)); + } + + private static string RequireSbxdec() { + if (OperatingSystem.IsWindows() && !FsInteropToolbox.WslAvailable) + Assert.Ignore("WSL is not available."); + var dir = Environment.GetEnvironmentVariable("SEQBOX_HOME") ?? "/opt/seqbox"; + var probe = FsInteropToolbox.RunWsl($"test -f '{dir}/sbxdec.py' && command -v python3"); + if (probe.ExitCode != 0) + Assert.Ignore($"SeqBox reference tools not found at {dir} (set SEQBOX_HOME to a checkout of github.com/MarcoPon/SeqBox)."); + return $"'{dir}/sbxdec.py'"; + } + + private static byte[] LoadVector(string name) { + using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream($"SeqBoxVectors.{name}") + ?? throw new InvalidOperationException($"missing embedded vector {name}"); + using var ms = new MemoryStream(); + stream.CopyTo(ms); + return ms.ToArray(); + } +} diff --git a/Hawkynt.FileFormats.Archives/FileFormats/FileFormat.SeqBox/SeqBoxContainer.cs b/Hawkynt.FileFormats.Archives/FileFormats/FileFormat.SeqBox/SeqBoxContainer.cs new file mode 100644 index 000000000..0d14ac933 --- /dev/null +++ b/Hawkynt.FileFormats.Archives/FileFormats/FileFormat.SeqBox/SeqBoxContainer.cs @@ -0,0 +1,239 @@ +using System.Buffers.Binary; +using System.Security.Cryptography; +using System.Text; +using Compression.Core.Checksums; + +namespace FileFormat.SeqBox; + +/// Metadata carried by a SeqBox block 0 (all fields optional). +/// FNM: the encoded file's name (UTF-8). +/// SNM: the container's own file name (UTF-8). +/// FSZ: the encoded file's size; trims the last block's 0x1A padding. +/// FDT: the encoded file's modification time, seconds since the Unix epoch. +/// SDT: when the container was made, seconds since the Unix epoch. +/// HSH: a multihash; 0x12 0x20 + 32 bytes is SHA-256. +public sealed record SeqBoxMetadata( + string? FileName = null, + string? SbxName = null, + long? FileSize = null, + long? FileTime = null, + long? SbxTime = null, + byte[]? Hash = null); + +/// +/// SeqBox (SBX) single-file container: the file is cut into fixed-size blocks, each with a +/// 16-byte header ("SBx", version, CRC-16, 6-byte file UID, 32-bit sequence number, all +/// big-endian) so the file can be recovered from a damaged or unindexed disk by scanning for +/// blocks. Block 0 optionally carries TLV metadata; data blocks start at sequence 1, and the last +/// one is padded with 0x1A. The CRC is CRC-16/CCITT (polynomial 0x1021, MSB first) seeded with +/// the version number and taken over everything after the CRC field. +/// +/// +/// Layout from the format author's description (github.com/MarcoPon/SeqBox, README); the +/// reference sbxenc/sbxdec were used only as a black-box oracle. +/// +public static class SeqBoxContainer { + /// Size of every block header. + public const int HeaderSize = 16; + + /// The three signature bytes every block starts with. + public static ReadOnlySpan Signature => "SBx"u8; + + /// Multihash prefix for SHA-256 (code 0x12, length 32). + private static ReadOnlySpan Sha256Multihash => [0x12, 0x20]; + + /// Block size of a SeqBox version, or 0 for an unknown version. + public static int BlockSize(int version) => version switch { + 1 => 512, + 2 => 128, + 3 => 4096, + 4 => 488, // Amiga OFS data-block payload + _ => 0, + }; + + /// Whether the stream starts with a valid SeqBox block (signature, known version, CRC). + public static bool IsSeqBox(ReadOnlySpan head) { + if (head.Length < HeaderSize || !head[..3].SequenceEqual(Signature)) + return false; + var size = BlockSize(head[3]); + return size > 0 && head.Length >= size && CrcOk(head[..size]); + } + + private static ushort Crc(ReadOnlySpan blockAfterCrc, int version) { + var crc = new Crc16Ccitt((ushort)version); + crc.Update(blockAfterCrc); + return (ushort)crc.Value; + } + + private static bool CrcOk(ReadOnlySpan block) + => BinaryPrimitives.ReadUInt16BigEndian(block[4..]) == Crc(block[6..], block[3]); + + /// A parsed container: version, UID, metadata (if block 0 is present) and the payload. + public sealed record Parsed(int Version, byte[] Uid, SeqBoxMetadata? Metadata, int DataBlocks, long PayloadLength, byte[] Data); + + /// + /// Parses and verifies a whole container. Every block must carry the signature, the first + /// block's version and UID and a valid CRC; data blocks must be numbered 1, 2, 3, … in file + /// order. With FSZ the payload is trimmed to it; with an HSH SHA-256 the payload is verified. + /// Without FSZ the trailing 0x1A padding cannot be told from data and is kept, as sbxdec does. + /// + /// Any block is damaged, missing or out of order, or the hash does not match. + public static Parsed Read(Stream stream) { + ArgumentNullException.ThrowIfNull(stream); + if (stream.CanSeek) stream.Position = 0; + Span head = stackalloc byte[4]; + if (stream.ReadAtLeast(head, 4, throwOnEndOfStream: false) < 4 || !head[..3].SequenceEqual(Signature)) + throw new InvalidDataException("Not a SeqBox container (missing 'SBx' signature)."); + int version = head[3], blockSize = BlockSize(version); + if (blockSize == 0) + throw new InvalidDataException($"SeqBox block version {version} is not supported."); + + var block = new byte[blockSize]; + head.CopyTo(block); + var filled = 4; + byte[]? uid = null; + SeqBoxMetadata? metadata = null; + using var payload = new MemoryStream(); + long expectedSeq = 1; + var blockIndex = 0; + var dataBlocks = 0; + while (true) { + var got = stream.ReadAtLeast(block.AsSpan(filled), blockSize - filled, throwOnEndOfStream: false); + if (got + filled == 0) break; + if (got + filled < blockSize) { + if (blockIndex == 0) + throw new InvalidDataException("SeqBox container is shorter than one block."); + break; // sbxdec ignores a trailing partial block + } + filled = 0; + + if (!block.AsSpan(0, 3).SequenceEqual(Signature) || block[3] != version) + throw new InvalidDataException($"SeqBox block {blockIndex} has no valid signature."); + if (!CrcOk(block)) + throw new InvalidDataException($"SeqBox block {blockIndex} fails its CRC."); + var blockUid = block.AsSpan(6, 6).ToArray(); + if (uid is null) uid = blockUid; + else if (!blockUid.AsSpan().SequenceEqual(uid)) + throw new InvalidDataException($"SeqBox block {blockIndex} belongs to another file (UID mismatch)."); + + var seq = BinaryPrimitives.ReadUInt32BigEndian(block.AsSpan(12)); + if (seq == 0) { + if (blockIndex != 0) + throw new InvalidDataException($"SeqBox metadata block found at position {blockIndex}."); + metadata = ParseMetadata(block.AsSpan(HeaderSize)); + } else { + if (seq != expectedSeq) + throw new InvalidDataException($"SeqBox block {expectedSeq} is missing or out of order (found {seq})."); + ++expectedSeq; + ++dataBlocks; + payload.Write(block, HeaderSize, blockSize - HeaderSize); + } + ++blockIndex; + } + + var data = payload.ToArray(); + if (metadata?.FileSize is { } size) { + // The size has to land in the last data block: anything else means blocks are missing + // from the end or the metadata belongs to a different file. + var dataSize = blockSize - HeaderSize; + var fits = dataBlocks == 0 ? size == 0 : size > (long)(dataBlocks - 1) * dataSize && size <= data.Length; + if (!fits) + throw new InvalidDataException($"SeqBox file size {size} does not fit the {dataBlocks} data blocks present."); + data = data[..(int)size]; + } + if (metadata?.Hash is { Length: 34 } hash && hash.AsSpan(0, 2).SequenceEqual(Sha256Multihash) + && !SHA256.HashData(data).AsSpan().SequenceEqual(hash.AsSpan(2))) + throw new InvalidDataException("SeqBox SHA-256 does not match the decoded data."); + + return new(version, uid!, metadata, dataBlocks, data.Length, data); + } + + private static SeqBoxMetadata ParseMetadata(ReadOnlySpan area) { + string? fnm = null, snm = null; + long? fsz = null, fdt = null, sdt = null; + byte[]? hsh = null; + var p = 0; + while (p + 4 <= area.Length) { + var id = area.Slice(p, 3); + if (id[0] == 0x1A && id[1] == 0x1A && id[2] == 0x1A) break; + int len = area[p + 3]; + if (p + 4 + len > area.Length) + throw new InvalidDataException("SeqBox metadata entry runs past the block."); + var value = area.Slice(p + 4, len); + switch (Encoding.ASCII.GetString(id)) { + case "FNM": fnm = Encoding.UTF8.GetString(value); break; + case "SNM": snm = Encoding.UTF8.GetString(value); break; + case "FSZ": fsz = ReadBigEndian(value); break; + case "FDT": fdt = ReadBigEndian(value); break; + case "SDT": sdt = ReadBigEndian(value); break; + case "HSH": hsh = value.ToArray(); break; + // PID and unknown ids are skipped: the TLV length makes that safe. + } + p += 4 + len; + } + return new(fnm, snm, fsz, fdt, sdt, hsh); + } + + private static long ReadBigEndian(ReadOnlySpan value) { + if (value.Length is 0 or > 8) + throw new InvalidDataException("SeqBox numeric metadata must be 1-8 bytes."); + long v = 0; + foreach (var b in value) v = (v << 8) | b; + return v; + } + + /// + /// Writes a container the way sbxenc does: block 0 with FNM, SNM, FSZ, FDT, SDT and a SHA-256 + /// HSH (unless is false), then the data in sequence-numbered + /// blocks, the last padded with 0x1A. An empty file is the metadata block alone. + /// + public static void Write(Stream output, ReadOnlySpan data, string fileName, int version = 1, + byte[]? uid = null, DateTimeOffset? fileTime = null, string? sbxName = null, + DateTimeOffset? sbxTime = null, bool withMetadata = true) { + ArgumentNullException.ThrowIfNull(output); + var blockSize = BlockSize(version); + if (blockSize == 0) + throw new ArgumentOutOfRangeException(nameof(version), version, "SeqBox versions are 1 (512), 2 (128), 3 (4096) and 4 (488)."); + if (uid is { Length: not 6 }) + throw new ArgumentException("A SeqBox UID is 6 bytes.", nameof(uid)); + uid ??= RandomNumberGenerator.GetBytes(6); + var dataSize = blockSize - HeaderSize; + var block = new byte[blockSize]; + + if (withMetadata) { + var meta = new MemoryStream(); + void Tlv(string id, ReadOnlySpan value) { + if (value.Length > 255) + throw new NotSupportedException($"SeqBox metadata '{id}' is longer than 255 bytes."); + meta.Write(Encoding.ASCII.GetBytes(id)); + meta.WriteByte((byte)value.Length); + meta.Write(value); + } + static byte[] Be(long v) { var b = new byte[8]; BinaryPrimitives.WriteInt64BigEndian(b, v); return b; } + Tlv("FNM", Encoding.UTF8.GetBytes(fileName)); + if (sbxName is not null) Tlv("SNM", Encoding.UTF8.GetBytes(sbxName)); + Tlv("FSZ", Be(data.Length)); + Tlv("FDT", Be((fileTime ?? DateTimeOffset.UnixEpoch).ToUnixTimeSeconds())); + Tlv("SDT", Be((sbxTime ?? DateTimeOffset.UtcNow).ToUnixTimeSeconds())); + Tlv("HSH", [.. Sha256Multihash, .. SHA256.HashData(data)]); + if (meta.Length > dataSize) + throw new NotSupportedException($"SeqBox metadata ({meta.Length} bytes) does not fit a version-{version} block."); + EmitBlock(output, block, version, uid, 0, meta.ToArray()); + } + + uint seq = 0; + for (var offset = 0; offset < data.Length; offset += dataSize) + EmitBlock(output, block, version, uid, ++seq, data.Slice(offset, Math.Min(dataSize, data.Length - offset))); + } + + private static void EmitBlock(Stream output, byte[] block, int version, byte[] uid, uint seq, ReadOnlySpan content) { + block.AsSpan().Fill(0x1A); + Signature.CopyTo(block); + block[3] = (byte)version; + uid.CopyTo(block, 6); + BinaryPrimitives.WriteUInt32BigEndian(block.AsSpan(12), seq); + content.CopyTo(block.AsSpan(HeaderSize)); + BinaryPrimitives.WriteUInt16BigEndian(block.AsSpan(4), Crc(block.AsSpan(6), version)); + output.Write(block); + } +} diff --git a/Hawkynt.FileFormats.Archives/FileFormats/FileFormat.SeqBox/SeqBoxFormatDescriptor.cs b/Hawkynt.FileFormats.Archives/FileFormats/FileFormat.SeqBox/SeqBoxFormatDescriptor.cs new file mode 100644 index 000000000..c9b749434 --- /dev/null +++ b/Hawkynt.FileFormats.Archives/FileFormats/FileFormat.SeqBox/SeqBoxFormatDescriptor.cs @@ -0,0 +1,91 @@ +using Compression.Registry; +using static Compression.Registry.FormatHelpers; + +namespace FileFormat.SeqBox; + +/// +/// SeqBox (.sbx), Marco Pontello's recoverable single-file container. Lists as one entry named by +/// the FNM metadata; creates the sbxenc layout (version 1, 512-byte blocks, full metadata). +/// +public sealed class SeqBoxFormatDescriptor : IFormatDescriptor, IArchiveFormatOperations, IArchiveCreatable { + /// Entry name used when the container has no metadata block (sbxdec appends ".out"). + public const string UnnamedEntry = "sbx.out"; + + /// + public string Id => "SeqBox"; + /// + public string DisplayName => "SeqBox"; + /// + public FormatCategory Category => FormatCategory.Archive; + /// + public FormatCapabilities Capabilities => + FormatCapabilities.CanList | FormatCapabilities.CanExtract | FormatCapabilities.CanCreate | FormatCapabilities.CanTest; + /// + public string DefaultExtension => ".sbx"; + /// + public IReadOnlyList Extensions => [".sbx"]; + /// + public IReadOnlyList CompoundExtensions => []; + /// + public IReadOnlyList MagicSignatures => [ + new("SBx\x01"u8.ToArray(), Confidence: 0.85), + new("SBx\x02"u8.ToArray(), Confidence: 0.85), + new("SBx\x03"u8.ToArray(), Confidence: 0.85), + new("SBx\x04"u8.ToArray(), Confidence: 0.85), + ]; + /// + public IReadOnlyList Methods => [new("sbx1", "512-byte blocks"), new("sbx2", "128-byte blocks"), new("sbx3", "4096-byte blocks"), new("sbx4", "488-byte blocks")]; + /// + public string? TarCompressionFormatId => null; + /// + public AlgorithmFamily Family => AlgorithmFamily.Archive; + /// + public string Description => "SeqBox recoverable container: file split into self-identifying, CRC-checked, sequence-numbered blocks"; + + private static string EntryName(SeqBoxContainer.Parsed p) + => string.IsNullOrEmpty(p.Metadata?.FileName) ? UnnamedEntry : Path.GetFileName(p.Metadata!.FileName.Replace('\\', '/')); + + /// + public List List(Stream stream, string? password) { + var p = SeqBoxContainer.Read(stream); + DateTime? modified = p.Metadata?.FileTime is { } t ? DateTimeOffset.FromUnixTimeSeconds(t).UtcDateTime : null; + return [new ArchiveEntryInfo(0, EntryName(p), p.PayloadLength, stream.Length, $"sbx{p.Version}", false, false, modified)]; + } + + /// + public void Extract(Stream stream, string outputDir, string? password, string[]? files) { + var p = SeqBoxContainer.Read(stream); + var name = EntryName(p); + if (files is { Length: > 0 } && !MatchesFilter(name, files)) + return; + WriteFile(outputDir, name, p.Data); + } + + /// + public byte[] ExtractEntryToMemory(Stream archive, string entryName, string? password) { + var p = SeqBoxContainer.Read(archive); + return string.Equals(EntryName(p), entryName, StringComparison.OrdinalIgnoreCase) ? p.Data : []; + } + + /// + public void Create(Stream output, IReadOnlyList inputs, FormatCreateOptions options) { + ArgumentNullException.ThrowIfNull(output); + ArgumentNullException.ThrowIfNull(inputs); + var files = inputs.Where(i => !i.IsDirectory).ToList(); + if (files.Count != 1) + throw new NotSupportedException($"A SeqBox container holds exactly one file ({files.Count} given)."); + if (!string.IsNullOrEmpty(options.Password)) + throw new NotSupportedException("SeqBox password scrambling is not an encryption method and is not written."); + var version = (options.MethodName ?? "sbx1").Trim().ToLowerInvariant() switch { + "" or "sbx1" or "1" => 1, + "sbx2" or "2" => 2, + "sbx3" or "3" => 3, + "sbx4" or "4" => 4, + var m => throw new NotSupportedException($"SeqBox method '{m}' is not supported (sbx1-sbx4)."), + }; + var input = files[0]; + var name = Path.GetFileName(input.ArchiveName.Replace('\\', '/')); + var mtime = input.Metadata?.LastWriteTimeUtc; + SeqBoxContainer.Write(output, input.ReadContent(), name, version, fileTime: mtime); + } +} diff --git a/Hawkynt.FileFormats.Archives/README.md b/Hawkynt.FileFormats.Archives/README.md index d3f8c6198..f59646bb9 100644 --- a/Hawkynt.FileFormats.Archives/README.md +++ b/Hawkynt.FileFormats.Archives/README.md @@ -136,6 +136,7 @@ Every State, Test, Maintenance, Compress/Decompress and Demux/Mux/Remux cell is | PackDisk (Amiga) | `PackDisk` | `.pdsk` | WORM | ✅ | defrag | Whole-disk archiver: entries are track_NNN.raw | [Aminet](https://aminet.net) | | PackIt | `PackIt` | `.pit` | R/W | ✅ | defrag · wipe | | [GitHub](https://github.com/MacPaw/XADMaster) | | [RAR](https://en.wikipedia.org/wiki/RAR_(file_format)) | `Rar` | `.rar` | R/W | ✅ | wipe | v1–v5 readers; creation and edits emit RAR4/RAR5 without claiming WinRAR encoder parity | [rarlab.com](https://www.rarlab.com/technote.htm) | +| [SeqBox](https://github.com/MarcoPon/SeqBox) | `SeqBox` | `.sbx` | WORM | ✅ | — | Single-file recoverable container; versions 1-4, metadata block optional | [GitHub](https://github.com/MarcoPon/SeqBox) | | [7z](https://en.wikipedia.org/wiki/7z) | `SevenZip` | `.7z` | R/W | ✅ | compress · wipe | | [7-zip.org](https://www.7-zip.org/7z.html) | | [SHAR](https://en.wikipedia.org/wiki/Shar) | `Shar` | `.shar` `.sh` | R/W | ✅ | defrag | Add appends in place; Remove re-emits the script from the survivors | [gnu.org](https://www.gnu.org/software/sharutils/) | | [Spark (RISC OS)](https://en.wikipedia.org/wiki/ARC_(file_format)) | `Spark` | `.spk` `.spark` | R/W | ✅ | defrag · wipe | | [Archive Team](http://fileformats.archiveteam.org/wiki/Spark) | @@ -548,7 +549,7 @@ Use it when a .NET process needs to enumerate, extract, test, create, edit or in -Every public and protected member of all 2578 types, generated from the built assembly and its XML documentation, is in [REFERENCE.md](https://github.com/Hawkynt/CompressionWorkbench/blob/main/Hawkynt.FileFormats.Archives/REFERENCE.md). +Every public and protected member of all 2582 types, generated from the built assembly and its XML documentation, is in [REFERENCE.md](https://github.com/Hawkynt/CompressionWorkbench/blob/main/Hawkynt.FileFormats.Archives/REFERENCE.md). diff --git a/Hawkynt.FileFormats.Archives/REFERENCE.md b/Hawkynt.FileFormats.Archives/REFERENCE.md index 4f6a3d7bd..36c44b4bc 100644 --- a/Hawkynt.FileFormats.Archives/REFERENCE.md +++ b/Hawkynt.FileFormats.Archives/REFERENCE.md @@ -27078,6 +27078,82 @@ Implements `IArchiveFormatOperations`, `IArchiveInMemoryExtract`, `IFormatDescri | `Extract` | `void Extract(Stream stream, string outputDir, string password, string[] files)` | Decodes the supplied input. | | `List` | `List List(Stream stream, string password)` | Lists the entries in the supplied container. | +### Namespace `FileFormat.SeqBox` + +[`SeqBoxContainer`](#seqboxcontainer) · [`SeqBoxContainer.Parsed`](#seqboxcontainerparsed) · [`SeqBoxFormatDescriptor`](#seqboxformatdescriptor) · [`SeqBoxMetadata`](#seqboxmetadata) + +#### `SeqBoxContainer` + +SeqBox (SBX) single-file container: the file is cut into fixed-size blocks, each with a 16-byte header (`"SBx"`, version, CRC-16, 6-byte file UID, 32-bit sequence number, all big-endian) so the file can be recovered from a damaged or unindexed disk by scanning for blocks. Block 0 optionally carries TLV metadata; data blocks start at sequence 1, and the last one is padded with 0x1A. The CRC is CRC-16/CCITT (polynomial 0x1021, MSB first) seeded with the version number and taken over everything after the CRC field. + +| Member | Signature | Summary | +| --- | --- | --- | +| `HeaderSize` | `const int HeaderSize` | Size of every block header. | +| `Signature` | `static ReadOnlySpan Signature { get; }` | The three signature bytes every block starts with. | +| `BlockSize` | `static int BlockSize(int version)` | Block size of a SeqBox version, or 0 for an unknown version. | +| `IsSeqBox` | `static bool IsSeqBox(ReadOnlySpan head)` | Whether the stream starts with a valid SeqBox block (signature, known version, CRC). | +| `Read` | `static Parsed Read(Stream stream)` | Parses and verifies a whole container. Every block must carry the signature, the first block's version and UID and a valid CRC; data blocks must be numbered 1, 2, 3, … in file order. With FSZ the payload is trimmed to it; with an HSH SHA-256 the payload is verified. Without FSZ the trailing 0x1A padding cannot be told from data and is kept, as sbxdec does. | +| `Write` | `static void Write(Stream output, ReadOnlySpan data, string fileName, int version = 1, byte[] uid = null, DateTimeOffset? fileTime = null, string sbxName = null, DateTimeOffset? sbxTime = null, bool withMetadata = true)` | Writes a container the way sbxenc does: block 0 with FNM, SNM, FSZ, FDT, SDT and a SHA-256 HSH (unless `withMetadata` is false), then the data in sequence-numbered blocks, the last padded with 0x1A. An empty file is the metadata block alone. | + +#### `SeqBoxContainer.Parsed` + +A parsed container: version, UID, metadata (if block 0 is present) and the payload. + +Implements `IEquatable`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `Parsed` | `Parsed(int Version, byte[] Uid, SeqBoxMetadata Metadata, int DataBlocks, long PayloadLength, byte[] Data)` | A parsed container: version, UID, metadata (if block 0 is present) and the payload. | +| `DataBlocks` | `int DataBlocks { get; init; }` | | +| `Data` | `byte[] Data { get; init; }` | | +| `Metadata` | `SeqBoxMetadata Metadata { get; init; }` | | +| `PayloadLength` | `long PayloadLength { get; init; }` | | +| `Uid` | `byte[] Uid { get; init; }` | | +| `Version` | `int Version { get; init; }` | | + +#### `SeqBoxFormatDescriptor` + +SeqBox (.sbx), Marco Pontello's recoverable single-file container. Lists as one entry named by the FNM metadata; creates the sbxenc layout (version 1, 512-byte blocks, full metadata). + +Implements `IArchiveCreatable`, `IArchiveFormatOperations`, `IFormatDescriptor`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SeqBoxFormatDescriptor` | `SeqBoxFormatDescriptor()` | | +| `UnnamedEntry` | `const string UnnamedEntry` | Entry name used when the container has no metadata block (sbxdec appends ".out"). | +| `Capabilities` | `FormatCapabilities Capabilities { get; }` | | +| `Category` | `FormatCategory Category { get; }` | | +| `CompoundExtensions` | `IReadOnlyList CompoundExtensions { get; }` | | +| `DefaultExtension` | `string DefaultExtension { get; }` | | +| `Description` | `string Description { get; }` | | +| `DisplayName` | `string DisplayName { get; }` | | +| `Extensions` | `IReadOnlyList Extensions { get; }` | | +| `Family` | `AlgorithmFamily Family { get; }` | | +| `Id` | `string Id { get; }` | | +| `MagicSignatures` | `IReadOnlyList MagicSignatures { get; }` | | +| `Methods` | `IReadOnlyList Methods { get; }` | | +| `TarCompressionFormatId` | `string TarCompressionFormatId { get; }` | | +| `Create` | `void Create(Stream output, IReadOnlyList inputs, FormatCreateOptions options)` | | +| `ExtractEntryToMemory` | `byte[] ExtractEntryToMemory(Stream archive, string entryName, string password)` | | +| `Extract` | `void Extract(Stream stream, string outputDir, string password, string[] files)` | | +| `List` | `List List(Stream stream, string password)` | | + +#### `SeqBoxMetadata` + +Metadata carried by a SeqBox block 0 (all fields optional). + +Implements `IEquatable`. + +| Member | Signature | Summary | +| --- | --- | --- | +| `SeqBoxMetadata` | `SeqBoxMetadata(string FileName = null, string SbxName = null, long? FileSize = null, long? FileTime = null, long? SbxTime = null, byte[] Hash = null)` | Metadata carried by a SeqBox block 0 (all fields optional). | +| `FileName` | `string FileName { get; init; }` | FNM: the encoded file's name (UTF-8). | +| `FileSize` | `long? FileSize { get; init; }` | FSZ: the encoded file's size; trims the last block's 0x1A padding. | +| `FileTime` | `long? FileTime { get; init; }` | FDT: the encoded file's modification time, seconds since the Unix epoch. | +| `Hash` | `byte[] Hash { get; init; }` | HSH: a multihash; `0x12 0x20` + 32 bytes is SHA-256. | +| `SbxName` | `string SbxName { get; init; }` | SNM: the container's own file name (UTF-8). | +| `SbxTime` | `long? SbxTime { get; init; }` | SDT: when the container was made, seconds since the Unix epoch. | + ### Namespace `FileFormat.SevenZip` [`SevenZipCodec`](#sevenzipcodec) · [`SevenZipEntry`](#sevenzipentry) · [`SevenZipFilter`](#sevenzipfilter) · [`SevenZipFormatDescriptor`](#sevenzipformatdescriptor) · [`SevenZipInPlaceAdder`](#sevenzipinplaceadder) · [`SevenZipInPlaceRemover`](#sevenzipinplaceremover) · [`SevenZipLayoutMap`](#sevenziplayoutmap) · [`SevenZipReader`](#sevenzipreader) · [`SevenZipWriter`](#sevenzipwriter) · [`SevenZipWriter.BlockDescriptor`](#sevenzipwriterblockdescriptor) · [`SolidBlockOptimizer`](#solidblockoptimizer) · [`SolidBlockOptimizer.DetailedProgress`](#solidblockoptimizerdetailedprogress) · [`SolidBlockOptimizer.OptimizeResult`](#solidblockoptimizeroptimizeresult) · [`SolidBlockOptimizer.ProgressCallback`](#solidblockoptimizerprogresscallback) · [`SolidBlockOptimizer.TrialResult`](#solidblockoptimizertrialresult) · [`SolidBlockPlanner`](#solidblockplanner) · [`SolidBlockPlanner.SolidBlock`](#solidblockplannersolidblock) diff --git a/docs/catalogue/our-registry.csv b/docs/catalogue/our-registry.csv index a8bf87611..831d72a51 100644 --- a/docs/catalogue/our-registry.csv +++ b/docs/catalogue/our-registry.csv @@ -459,6 +459,7 @@ format,Sarc,Nintendo SARC,Archive,,.sarc;.pack;.bars,Y,Y,Y,Y format,Sbc,Bluetooth SBC / mSBC,Audio,,.sbc;.msbc,Y,Y,, format,Sdat,SDAT (Nintendo DS sound archive),Audio,,.sdat,Y,Y,, format,Sds,SDS (MIDI Sample Dump),Audio,,.sds,Y,Y,, +format,SeqBox,SeqBox,Archive,,.sbx,Y,Y,Y, format,SevenZip,7z,Archive,,.7z,Y,Y,Y,Y format,Sf2,SoundFont 2,Audio,,.sf2,Y,Y,, format,Sfar,BioWare SFAR,Archive,,.sfar,Y,Y,Y, diff --git a/docs/catalogue/reference-formats.csv b/docs/catalogue/reference-formats.csv index ab231c065..6fe41c4d6 100644 --- a/docs/catalogue/reference-formats.csv +++ b/docs/catalogue/reference-formats.csv @@ -69,7 +69,7 @@ BCM,bcm,compression,,,,,R,,,1,https://github.com/encode84/bcm,Bcm,Y,Y,,OK,, Split file (.001),001;002,archive,R,,R,,R,,,3,,SplitFile,Y,Y,,OK,, Apple Archive (.aar),aar,archive,,,,,,,Y,1,,,,,,MISSING,,https://developer.apple.com/documentation/applearchive Mozilla ARchive (MAR),mar;mac,archive,,,,,,fmt/1483,Y,2,,,,,,MISSING,,https://wiki.mozilla.org/Software_Update:MAR -SeqBox,sbx,archive,,,,,,,Y,1,,,,,,MISSING,,https://github.com/MarcoPon/SeqBox +SeqBox,sbx,archive,,,,,,,Y,1,https://github.com/MarcoPon/SeqBox,SeqBox,Y,Y,,OK,, AFA,afa,archive,,,,,,,Y,1,,,,,,MISSING,, B1,b1,archive,,,,,,,Y,1,,,,,,MISSING,, B6Z,b6z,archive,,,,,,,Y,1,,,,,,MISSING,, From 7e85fd703166ab3771a4f68ec33be5cf1ce214d3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 23 Oct 2026 13:50:40 +0000 Subject: [PATCH 2/3] * refresh the application screenshot --- screenshots/main-window.png | Bin 66235 -> 65657 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/screenshots/main-window.png b/screenshots/main-window.png index a9ceb7f7ce233693ac240e941d4af64380209648..e3795c0d04a8041389e0aaa3edc8cc5c89e36820 100644 GIT binary patch literal 65657 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

J-t(C?D*vNbSd$Mpldw%6G^3`$t6)P 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 O*JNyHeySLKDeAvN*8HCU literal 66235 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 From 67c60ff225f5aed5a07414ee0d318d803a6c9716 Mon Sep 17 00:00:00 2001 From: Hawkynt Date: Wed, 28 Oct 2026 06:49:48 +0100 Subject: [PATCH 3/3] # reject ambiguous firmware payloads before writing an image Adding a second named payload to Intel HEX could silently discard a file because the shared image builder kept only the first payload in filesystem enumeration order. Reject multiple non-metadata payloads, including an empty first payload, before any output is written. Tests verify creation refusal and byte-preserving add refusal. Verified all three regressions fail before the fix and pass after it, 93 focused tests, 34280 required tests with 1582 skips and no failures, and three package documentation checks. --- .../FirmwareHex/FirmwareHexPayloadTests.cs | 37 +++++++++++++++++++ .../FirmwareHexWriter.cs | 5 ++- 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 Compression.Tests/FirmwareHex/FirmwareHexPayloadTests.cs diff --git a/Compression.Tests/FirmwareHex/FirmwareHexPayloadTests.cs b/Compression.Tests/FirmwareHex/FirmwareHexPayloadTests.cs new file mode 100644 index 000000000..bbbc898af --- /dev/null +++ b/Compression.Tests/FirmwareHex/FirmwareHexPayloadTests.cs @@ -0,0 +1,37 @@ +using Compression.Registry; +using FileFormat.FirmwareHex; + +namespace Compression.Tests.FirmwareHex; + +[TestFixture] +public sealed class FirmwareHexPayloadTests { + [TestCase(false)] + [TestCase(true)] + public void Create_RejectsMultiplePayloadsWithoutWritingOutput(bool emptyFirst) { + var descriptor = new IntelHexFormatDescriptor(); + using var output = new MemoryStream(); + var inputs = new[] { + ArchiveInputInfo.InMemory("first.bin", emptyFirst ? [] : [1, 2, 3]), + ArchiveInputInfo.InMemory("second.bin", [9, 8, 7]), + }; + + Assert.Throws(() => + ((IArchiveCreatable)descriptor).Create(output, inputs, new FormatCreateOptions())); + Assert.That(output.Length, Is.Zero); + } + + [Test] + public void Add_RejectsAnotherPayloadWithoutChangingTheArchive() { + var descriptor = new IntelHexFormatDescriptor(); + using var archive = new MemoryStream(); + ((IArchiveCreatable)descriptor).Create(archive, + [ArchiveInputInfo.InMemory("firmware.bin", [1, 2, 3])], new FormatCreateOptions()); + var original = archive.ToArray(); + archive.Position = 0; + + Assert.Throws(() => ((IArchiveModifiable)descriptor).Add(archive, + [ArchiveInputInfo.InMemory("ADD.BIN", [9, 8, 7])])); + Assert.That(archive.ToArray(), Is.EqualTo(original)); + } + +} diff --git a/Hawkynt.FileFormats.FileSystems/FileFormats/FileFormat.FirmwareHex/FirmwareHexWriter.cs b/Hawkynt.FileFormats.FileSystems/FileFormats/FileFormat.FirmwareHex/FirmwareHexWriter.cs index 6c7d4b452..1c9e17266 100644 --- a/Hawkynt.FileFormats.FileSystems/FileFormats/FileFormat.FirmwareHex/FirmwareHexWriter.cs +++ b/Hawkynt.FileFormats.FileSystems/FileFormats/FileFormat.FirmwareHex/FirmwareHexWriter.cs @@ -33,6 +33,7 @@ public static class FirmwareHexWriter { /// one the reader rendered. An input list with no payload describes an image /// with no data, which both formats can write. /// + /// More than one non-metadata payload is supplied. public static FirmwareImage ImageFrom(IReadOnlyList inputs, string sourceFormat) { ArgumentNullException.ThrowIfNull(inputs); @@ -53,7 +54,9 @@ public static FirmwareImage ImageFrom(IReadOnlyList inputs, st } // Any other single input is the payload, whatever it is called: a caller // converting a .bin into a .hex should not have to rename it first. - payload ??= input.ReadContent(); + if (payload is not null) + throw new InvalidDataException($"{sourceFormat} represents one logical firmware payload; multiple payload inputs are ambiguous."); + payload = input.ReadContent(); } List<(uint Address, byte[] Data)> segments;