feat: add bounded Quantum cabinet extraction

This commit is contained in:
2026-07-22 19:23:00 +02:00
parent 531612829d
commit a7b1cd7d16
20 changed files with 1099 additions and 66 deletions

View File

@@ -11,7 +11,7 @@
| CAB LZX `0x1303` | Supported extraction | Byte-for-byte rust-cab MIT unit fixture, two text entries |
| CAB without compression | Supported extraction | Byte-for-byte rust-cab MIT unit fixture |
| CAB MSZIP | Supported extraction | rust-cab single-block fixture plus a generated two-block dictionary-chain fixture |
| CAB Quantum | Unsupported | Metadata is recognized; extraction fails with `cab-compression-unsupported` |
| CAB Quantum | Supported extraction | Pinned compcol qtm.txt payload, generated one-folder CAB, and two-frame state/sentinel tests |
| Multi-cabinet CAB / spanning files | Unsupported | Header flags and spanning folder indexes are rejected |
| `.onetoc2` package entries | Listed only | Files are identified, but notebook hierarchy and section order are not interpreted |
| Standalone `.onetoc2` | Unsupported in the app | The picker accepts only `.one` and `.onepkg` |
@@ -30,6 +30,14 @@ and carries at most 32 KiB of history between blocks in one folder. The MSZIP
tests establish CAB extraction behavior; no redistributable MSZIP-compressed
OneNote export is currently present, so they do not establish producer-specific
`.onepkg` compatibility.
Quantum validates level/window metadata, bounds its window to 2 MiB by default,
requires full 32 KiB intermediate frames, preserves its arithmetic models and
LZ window across frames, and injects exactly one `0xFF` CAB block sentinel.
Trailer padding is limited to the documented 0..4 zero bytes; match, frame,
output, operation, and cancellation bounds are enforced. Its tests likewise
establish CAB extraction behavior only: no redistributable Quantum-compressed
OneNote export is currently present.
Trailing CAB data is ignored with a warning. Reserved CAB areas are bounded and
skipped. CAB names are decoded as strict UTF-8; unmarked valid UTF-8 receives a
warning, while invalid non-ASCII legacy-code-page names are rejected rather

View File

@@ -12,11 +12,12 @@ The desktop `.one` reader adapts selected structures from the pinned
The browser-native package path has separate MIT provenance:
| TypeScript module | Upstream path(s) | Revision and selected licence | Port scope and deviations |
| -------------------------------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `src/onenote/onepkg/{cabinet,checksum}.ts` | rust-cab `src/{cabinet,folder,file,ctype,checksum}.rs` | `c5839f5fdfa4c4e7cc9b22f570c79c96af0560e2`, MIT | CAB reading/checksum adapted for immutable browser bytes, strict normalized paths, checked ranges/checksums, whole-folder extraction, explicit limits, and cancellation/yield hooks; writers are not ported |
| `src/onenote/onepkg/mszip/decoder.ts` | rust-cab `src/mszip.rs`; fflate raw DEFLATE | rust-cab revision above; fflate 0.8.3, MIT | `CK` framing and persistent 32 KiB folder history follow rust-cab; raw DEFLATE uses fflate with a caller-owned bounded buffer and strict declared-size checks |
| `src/onenote/onepkg/lzx/{bit-reader,huffman,decoder}.ts` | lzxd 0.2.5 `src/{bitstream,tree,block,window,lib}.rs` | `4748e43594e3e30cff2ace3a6ad7a376c9816fdd`, MIT option of MIT OR Apache-2.0 | Directly translated core with typed arrays, CAB CFDATA boundaries, persistent folder state, strict malformed-stream errors, and operation/window/cancellation limits; delta reference data is omitted |
| TypeScript module | Upstream path(s) | Revision and selected licence | Port scope and deviations |
| ------------------------------------------------------------------------ | ------------------------------------------------------ | --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `src/onenote/onepkg/{cabinet,checksum}.ts` | rust-cab `src/{cabinet,folder,file,ctype,checksum}.rs` | `c5839f5fdfa4c4e7cc9b22f570c79c96af0560e2`, MIT | CAB reading/checksum adapted for immutable browser bytes, strict normalized paths, checked ranges/checksums, whole-folder extraction, explicit limits, and cancellation/yield hooks; writers are not ported |
| `src/onenote/onepkg/mszip/decoder.ts` | rust-cab `src/mszip.rs`; fflate raw DEFLATE | rust-cab revision above; fflate 0.8.3, MIT | `CK` framing and persistent 32 KiB folder history follow rust-cab; raw DEFLATE uses fflate with a caller-owned bounded buffer and strict declared-size checks |
| `src/onenote/onepkg/quantum/{bit-reader,budget,decoder,model,tables}.ts` | compcol `src/quantum/{bits,decoder,model,tables}.rs` | `04a6db2aa7bd487a89c559631d79d1b384139f50`, MIT | Native TypeScript arithmetic/model/LZ decoder; fixed CAB output, 2 MiB maximum window, strict match/frame/trailer checks, two-block lookahead, operation budget, and cancellation checkpoints |
| `src/onenote/onepkg/lzx/{bit-reader,huffman,decoder}.ts` | lzxd 0.2.5 `src/{bitstream,tree,block,window,lib}.rs` | `4748e43594e3e30cff2ace3a6ad7a376c9816fdd`, MIT option of MIT OR Apache-2.0 | Directly translated core with typed arrays, CAB CFDATA boundaries, persistent folder state, strict malformed-stream errors, and operation/window/cancellation limits; delta reference data is omitted |
The bounded binary readers, format detection, parser limits/error model, path
policy, worker protocol/DTOs, package-to-section boundary, and application UI
@@ -24,8 +25,8 @@ are original TypeScript implementations guided by the normative specifications
and project requirements.
Files adapted from `onenote.rs` carry an MPL-2.0 notice, SPDX identifier,
upstream path/revision, and deviations. Files adapted from rust-cab or lzxd
carry their MIT provenance, copyright notice, exact revision, and deviations.
upstream path/revision, and deviations. Files adapted from rust-cab, compcol,
or lzxd carry their MIT provenance, copyright notice, exact revision, and deviations.
Licence texts are reproduced in `LICENSES/` and included in the release ZIP.
Focused tests cover successful pinned fixtures plus malformed bounds,

View File

@@ -8,10 +8,11 @@ Version 0.1.0 records these immutable implementation revisions:
| [`toolbox-portal`](https://git.add-ideas.de/zemion/toolbox-portal/src/commit/5d2e466ad61e36a0e2be2a2d8459b1a127f53f11) | `5d2e466ad61e36a0e2be2a2d8459b1a127f53f11` | Reviewed ZIP shape, exact checksum lock, and independent-app assembly model |
| [`onenote.rs`](https://github.com/msiemens/onenote.rs/tree/5138a39a3f4e72b840932f9872fecde52fa9da60) | `5138a39a3f4e72b840932f9872fecde52fa9da60` | Selected desktop OneStore and MS-ONE structures adapted into TypeScript |
| [`rust-cab`](https://github.com/mdsteele/rust-cab/tree/c5839f5fdfa4c4e7cc9b22f570c79c96af0560e2) | `c5839f5fdfa4c4e7cc9b22f570c79c96af0560e2` | CAB structures, checksum, enumeration/extraction, MSZIP history, and unit fixtures |
| [`compcol`](https://github.com/KarpelesLab/compcol/tree/04a6db2aa7bd487a89c559631d79d1b384139f50) | `04a6db2aa7bd487a89c559631d79d1b384139f50` | Quantum bit reader, arithmetic models, LZ window, CAB sentinel behavior, and tests |
| [`lzxd` 0.2.5](https://github.com/Lonami/lzxd/tree/4748e43594e3e30cff2ace3a6ad7a376c9816fdd) | `4748e43594e3e30cff2ace3a6ad7a376c9816fdd` | LZX bitstream, Huffman, block/window, match, and E8 logic adapted into TypeScript |
The SDK and Portal revisions were inspected from the local repositories. The
three parser references were cloned and reviewed at the hashes above; a branch
four parser references were cloned and reviewed at the hashes above; a branch
name or package version alone is not used as provenance. Source-level mappings
and behavioural deviations are in [PORTING.md](PORTING.md).

View File

@@ -58,8 +58,9 @@ The CAB/package path applies these defaults:
| Total extracted entry bytes | 512 MiB |
| Folder compression ratio | 200:1 |
| One MSZIP compressed block | 32 KiB + 12 B |
| Quantum window | 2 MiB |
| LZX window | 8 MiB |
| LZX decode operations | 1,000,000,000 |
| LZX/Quantum decode operations | 1,000,000,000 |
A CFDATA block may declare at most 32 KiB of output. Counts and offsets use
checked arithmetic and bounded readers. The CAB parser verifies supplied block
@@ -71,8 +72,12 @@ MSZIP checks its `CK` framing and raw DEFLATE data, writes into a fixed caller
buffer with one overflow-detection byte, requires the exact declared output
size, and retains no more than 32 KiB of history. LZX checks its window, Huffman
trees, block sizes, match ranges, output size, and operation budget. CAB
extraction checks cancellation and yields between data blocks so the worker can
process termination. Desktop OneStore traversal checks fragment/reference
Quantum limits its window, model scans, arithmetic renormalisation, matches,
frame/output boundaries, operation count, and trailer padding. It queues at
most the current and next compressed block so a synthetic `0xFF` sentinel can
be consumed without buffering a complete folder. CAB extraction checks
cancellation during Quantum work and yields between data blocks so the worker
can process termination. Desktop OneStore traversal checks fragment/reference
cycles, nesting, object/property/reference counts, and byte ranges.
## Rendering and links