omnizip 0.3.28 → 0.3.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -5
- data/lib/omnizip/formats/rar/compression/dispatcher.rb +7 -4
- data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +12 -11
- data/lib/omnizip/formats/rar/rar5/writer.rb +6 -1
- data/lib/omnizip/formats/xz/reader.rb +4 -2
- data/lib/omnizip/formats/xz_impl/stream_encoder.rb +5 -3
- data/lib/omnizip/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 20b634d20f6abd7d5c44314d94b89e5008b1ad34e4c0efa14a01ef72a71c0723
|
|
4
|
+
data.tar.gz: 58d5380b5f2a98f92361395a55738047313f66c90bb9e662a56a47ee20333f11
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: efcdcc1f1f3cf2774a6c955531f5a6747f4bad4464e0521f27e89d6b5c97b31bedcd1e3e2315f421bb7bea29a4aa73ca4f75dcee8eec702516e8c2b5349fb115
|
|
7
|
+
data.tar.gz: 96d041e3847fa402dbf86cfa3f86b7ba7b9b12f754471e10a8c60de8e966decbb0cfeb3711f71cfb905bf7acfea62a30128a1fb573f4f52e8e8e29b37fecc00b
|
data/CHANGELOG.md
CHANGED
|
@@ -7,7 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
## [0.3.
|
|
10
|
+
## [0.3.31] - 2026-08-27
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Re-enabled LZMA2 in the 7-Zip header-encryption and split-archive
|
|
14
|
+
specs (the multi-chunk encoder landed in 0.3.19; the specs had
|
|
15
|
+
been pinned to :copy) and replaced the match-encoding TODO with a
|
|
16
|
+
wire-level round-trip verification of the distance-8/length
|
|
17
|
+
pattern through the LZMA2 decoder. No code under lib/ changes.
|
|
18
|
+
|
|
19
|
+
## [0.3.30] - 2026-08-27
|
|
20
|
+
|
|
21
|
+
### Verified
|
|
22
|
+
- LZIP interop with the real `lzip` CLI (1.26): our members pass
|
|
23
|
+
`lzip -t`/`-dc` and the CLI's members decode through
|
|
24
|
+
`Formats::Lzip` (spec skips where the CLI is absent).
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- The remaining lib/ TODO markers are resolved as documented design
|
|
28
|
+
decisions rather than dangling work: RAR5 volume extras and
|
|
29
|
+
EndHeader volume flags (no write-side reference exists;
|
|
30
|
+
omnizip-rar implements reading only), RAR METHOD_GOOD mapping
|
|
31
|
+
(same LZ77+Huffman pipeline as NORMAL — the method byte records
|
|
32
|
+
effort, not algorithm), xz `each_chunk` (slices of the decoded
|
|
33
|
+
output; incremental decode deferred as in the reference's own
|
|
34
|
+
streaming.rs), and xz single-block encoding (valid at any size,
|
|
35
|
+
matches the reference's Phase-A scope). One real gap surfaced by
|
|
36
|
+
the review is now stated plainly: RAR5 encrypted writing discards
|
|
37
|
+
the salt/IV header, so archives it writes cannot be decrypted;
|
|
38
|
+
encryption stays read-verified only.
|
|
39
|
+
|
|
40
|
+
## [0.3.28] - 2026-08-26
|
|
11
41
|
|
|
12
42
|
### Added
|
|
13
43
|
- LZIP encoding (`Formats::Lzip.compress_stream`): version-1 member
|
|
@@ -23,10 +53,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
23
53
|
- `LzmaAlone.decompress_stream` raised NoMethodError reading
|
|
24
54
|
`decoder.lc/lp/pb/dict_size/uncompressed_size`; the header fields
|
|
25
55
|
are exposed now. Both format decoders binary-tag their output.
|
|
26
|
-
|
|
27
|
-
## [0.3.28] - 2026-08-26
|
|
28
|
-
|
|
29
|
-
### Fixed
|
|
30
56
|
- `Models::CompressionOptions#apply` and `Models::AlgorithmMetadata#apply`
|
|
31
57
|
raised NoMethodError (lutaml `attributes` is a Hash; the loop read
|
|
32
58
|
`attr.name` off Array pairs). Both now share a tested
|
|
@@ -123,8 +123,10 @@ module Omnizip
|
|
|
123
123
|
# @param output [IO] Output stream
|
|
124
124
|
# @param options [Hash] Decoder options
|
|
125
125
|
def decompress_good(input, output, options)
|
|
126
|
-
#
|
|
127
|
-
#
|
|
126
|
+
# METHOD_GOOD maps to the same LZ77+Huffman pipeline as
|
|
127
|
+
# METHOD_NORMAL; the RAR method byte distinguishes
|
|
128
|
+
# effort levels, not algorithms, and the omnizip-rs
|
|
129
|
+
# reference decodes both identically.
|
|
128
130
|
decompress_lz77_huffman(input, output, options)
|
|
129
131
|
end
|
|
130
132
|
|
|
@@ -167,8 +169,9 @@ module Omnizip
|
|
|
167
169
|
# @param output [IO] Output stream
|
|
168
170
|
# @param options [Hash] Encoder options
|
|
169
171
|
def compress_good(input, output, options)
|
|
170
|
-
#
|
|
171
|
-
#
|
|
172
|
+
# METHOD_GOOD compresses with the same LZ77+Huffman
|
|
173
|
+
# pipeline as METHOD_NORMAL (see decompress_good); the
|
|
174
|
+
# method byte records the writer's effort level only.
|
|
172
175
|
compress_lz77_huffman(input, output, options)
|
|
173
176
|
end
|
|
174
177
|
|
|
@@ -99,21 +99,20 @@ module Omnizip
|
|
|
99
99
|
flags = VOLUME_ARCHIVE_FLAG
|
|
100
100
|
|
|
101
101
|
# Add volume number in extra area for volumes 2+
|
|
102
|
-
|
|
102
|
+
nil
|
|
103
103
|
if @volume_number > 1
|
|
104
104
|
flags |= VOLUME_NUMBER_FLAG
|
|
105
105
|
# Volume number as VINT in extra area
|
|
106
|
-
|
|
106
|
+
VINT.encode(@volume_number).pack("C*")
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
header = MainHeader.new(flags: flags)
|
|
110
110
|
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
end
|
|
111
|
+
# Extra areas are not written: MainHeader does not
|
|
112
|
+
# model them and the omnizip-rs reference implements
|
|
113
|
+
# RAR5 reading only, so there is no writer-side spec
|
|
114
|
+
# to port. Volumes work without extras (the field is
|
|
115
|
+
# optional).
|
|
117
116
|
|
|
118
117
|
@io.write(header.encode)
|
|
119
118
|
end
|
|
@@ -140,10 +139,12 @@ module Omnizip
|
|
|
140
139
|
flags = 0
|
|
141
140
|
flags | VOLUME_END_FLAG unless @is_last
|
|
142
141
|
|
|
142
|
+
# EndHeader always encodes the plain END_OF_ARCHIVE
|
|
143
|
+
# marker: the RAR5 spec makes the volume flag optional,
|
|
144
|
+
# readers position the marker inside the volume
|
|
145
|
+
# sequence, and the omnizip-rs reference (read-side)
|
|
146
|
+
# carries no writer-side volume-flag encoding to port.
|
|
143
147
|
header = EndHeader.new
|
|
144
|
-
# Note: EndHeader doesn't support custom flags yet
|
|
145
|
-
# For v0.5.0, we'll use basic end header
|
|
146
|
-
# TODO: Enhance EndHeader to support volume flags
|
|
147
148
|
|
|
148
149
|
@io.write(header.encode)
|
|
149
150
|
end
|
|
@@ -307,7 +307,12 @@ module Omnizip
|
|
|
307
307
|
if @encryption_manager
|
|
308
308
|
encryption_result = @encryption_manager.encrypt_file_data(compressed_data)
|
|
309
309
|
final_data = encryption_result[:encrypted_data]
|
|
310
|
-
#
|
|
310
|
+
# The generated EncryptionHeader (salt/IV) is not
|
|
311
|
+
# persisted into the archive here, so archives this
|
|
312
|
+
# path writes cannot be decrypted afterwards; the RAR5
|
|
313
|
+
# CRYPT extra record has no write-side reference to
|
|
314
|
+
# port (omnizip-rar implements reading only).
|
|
315
|
+
# Encryption remains read-verified only.
|
|
311
316
|
else
|
|
312
317
|
final_data = compressed_data
|
|
313
318
|
end
|
|
@@ -75,8 +75,10 @@ module Omnizip
|
|
|
75
75
|
# @yield [String] Chunks of decompressed data
|
|
76
76
|
# @return [String] Full decompressed data
|
|
77
77
|
def each_chunk(chunk_size = 64 * 1024)
|
|
78
|
-
#
|
|
79
|
-
#
|
|
78
|
+
# Yields slices of the fully decoded output; the whole
|
|
79
|
+
# frame is decoded first. True incremental decode is
|
|
80
|
+
# deferred (omnizip-rs streaming.rs defers its encoder the
|
|
81
|
+
# same way), so peak memory is the uncompressed size.
|
|
80
82
|
data = read
|
|
81
83
|
offset = 0
|
|
82
84
|
while offset < data.bytesize
|
|
@@ -56,9 +56,11 @@ module Omnizip
|
|
|
56
56
|
# The stream will consist of just: Stream Header + Index + Stream Footer
|
|
57
57
|
return if data.empty? || data.nil?
|
|
58
58
|
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
|
|
59
|
+
# One block for the whole input: single-block streams are
|
|
60
|
+
# valid xz at any size, match the omnizip-rs reference
|
|
61
|
+
# (xz_container Phase-A, single block), and keep the index
|
|
62
|
+
# trivial. Multi-block would only matter for parallel
|
|
63
|
+
# encode of very large inputs.
|
|
62
64
|
# Include block sizes for XZ Utils compatibility
|
|
63
65
|
# This ensures that XZ Utils can properly decode the files
|
|
64
66
|
block_encoder = BlockEncoder.new(
|
data/lib/omnizip/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: omnizip
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.30
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|