omnizip 0.3.54 → 0.3.55
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 +35 -0
- data/lib/omnizip/algorithms/lzma/dictionary.rb +2 -2
- data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +7 -7
- data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +4 -4
- data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +7 -7
- data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +8 -8
- data/lib/omnizip/commands/metadata_command.rb +14 -6
- data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +5 -5
- data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +1 -1
- data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +1 -1
- data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +1 -1
- data/lib/omnizip/metadata/metadata_registry.rb +9 -2
- data/lib/omnizip/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7de280d85fcea7072c88798c925b5aa3e03bcff124c1294e72abeb6f976cc5e8
|
|
4
|
+
data.tar.gz: 579759d99f27af57c070e5e1b6a6d6b121651932b10681da88e96331adb36bee
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a08a53e33284555a3fe7493834f522e0bf00a8609705e06d6c05578bb342bb3db4e4ba1c3c0793f18a001ef55305fd3396a7300b6c7f1c82196a9702931fc374
|
|
7
|
+
data.tar.gz: 7b0550e981ff0cb317beffdcb7eff7b233a7fff0bc4812eae01a566f1a0d255de8896e217d1d1ce62618b56bb5ea284dc414c98b53c171fa4af0b54a1a048b86
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.54] - 2026-09-01
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- The 7z tree's 38 bare `raise "string"` sites gain their matching
|
|
14
|
+
classes: `PasswordError` for encrypted-header problems (with a
|
|
15
|
+
new autoload entry — the class lives at the top of password.rb,
|
|
16
|
+
so referencing it never loaded the file),
|
|
17
|
+
`InvalidArchiveError`/`UnsupportedFormatError` for parse and
|
|
18
|
+
structure failures, `ChecksumError` for CRC mismatches,
|
|
19
|
+
`AlgorithmNotFoundError`/`UnknownFilterError` in CoderChain, and
|
|
20
|
+
`Errno::ENOENT` for missing entries and volumes. The reader's
|
|
21
|
+
encrypted-header probe re-raises password errors by class instead
|
|
22
|
+
of matching message text.
|
|
23
|
+
- In-memory ZIP leaves the rubyzip compat layer: `Buffer.create`
|
|
24
|
+
writes through the native Writer (which gains a per-entry
|
|
25
|
+
compression-method override so `:store` entries work beside
|
|
26
|
+
deflated ones), and `Buffer.open`/`MemoryExtractor` read through
|
|
27
|
+
the native Reader via a temporary-file spill.
|
|
28
|
+
`MemoryArchive::Entry#read` now has true IO streaming semantics —
|
|
29
|
+
successive chunks and nil at EOF (an always-returning read looped
|
|
30
|
+
forever in `Pipe::StreamDecompressor`).
|
|
31
|
+
- The parallel subsystem is revived: Engine drives our own
|
|
32
|
+
WorkerPool instead of a phantom `Fractor::WorkerPool`,
|
|
33
|
+
ParallelExtractor reads through the native ZIP reader and runs on
|
|
34
|
+
a bounded ThreadPool — Ractor workers cannot trigger Omnizip's
|
|
35
|
+
autoloads or cross into Proc-holding codec constants on
|
|
36
|
+
Ruby <= 3.3 — JobScheduler's implemented round_robin/bin_packing
|
|
37
|
+
strategies are reachable, directory entries extract idempotently,
|
|
38
|
+
and the subsystem gains specs.
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- par2_compatibility_spec was missing `require "tmpdir"` and failed
|
|
42
|
+
9 of 15 examples whenever no earlier spec happened to load tmpdir
|
|
43
|
+
first.
|
|
44
|
+
|
|
10
45
|
## [0.3.53] - 2026-09-01
|
|
11
46
|
|
|
12
47
|
### Changed
|
|
@@ -31,7 +31,7 @@ module Omnizip
|
|
|
31
31
|
|
|
32
32
|
# Read bytes from dictionary at a distance back
|
|
33
33
|
def read_bytes(distance, length)
|
|
34
|
-
raise "Invalid distance: #{distance}" if distance > @buffer.bytesize
|
|
34
|
+
raise Omnizip::DecompressionError, "Invalid distance: #{distance}" if distance > @buffer.bytesize
|
|
35
35
|
|
|
36
36
|
result = String.new(encoding: Encoding::BINARY)
|
|
37
37
|
src_pos = @buffer.bytesize - distance
|
|
@@ -46,7 +46,7 @@ module Omnizip
|
|
|
46
46
|
|
|
47
47
|
# Get byte at distance back
|
|
48
48
|
def get_byte(distance)
|
|
49
|
-
raise "Invalid distance: #{distance}" if distance > @buffer.bytesize
|
|
49
|
+
raise Omnizip::DecompressionError, "Invalid distance: #{distance}" if distance > @buffer.bytesize
|
|
50
50
|
|
|
51
51
|
@buffer.getbyte(@buffer.bytesize - distance)
|
|
52
52
|
end
|
|
@@ -118,12 +118,12 @@ module Omnizip
|
|
|
118
118
|
# Step 1: Parse properties byte (SEQ_PROPERTIES)
|
|
119
119
|
# Reference: alone_decoder.c:64-68
|
|
120
120
|
props = @input.getbyte
|
|
121
|
-
raise "Invalid .lzma header: missing properties byte" if props.nil?
|
|
121
|
+
raise Omnizip::DecompressionError, "Invalid .lzma header: missing properties byte" if props.nil?
|
|
122
122
|
|
|
123
123
|
# Use XZ Utils property byte parsing
|
|
124
124
|
# Reference: /Users/mulgogi/src/external/xz/src/liblzma/lzma/lzma_decoder.c:1216-1228
|
|
125
125
|
if props > MAX_PROPERTY_BYTE
|
|
126
|
-
raise "Invalid .lzma header: properties byte #{props} exceeds maximum #{MAX_PROPERTY_BYTE}"
|
|
126
|
+
raise Omnizip::DecompressionError, "Invalid .lzma header: properties byte #{props} exceeds maximum #{MAX_PROPERTY_BYTE}"
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
# Parse lc, lp, pb from properties byte
|
|
@@ -136,7 +136,7 @@ module Omnizip
|
|
|
136
136
|
# Validate lc + lp <= 4 (LZMA_LCLP_MAX)
|
|
137
137
|
# Reference: lzma_decoder.c:1227
|
|
138
138
|
if @lc + @lp > 4
|
|
139
|
-
raise "Invalid .lzma header: lc (#{@lc}) + lp (#{@lp}) exceeds maximum 4"
|
|
139
|
+
raise Omnizip::DecompressionError, "Invalid .lzma header: lc (#{@lc}) + lp (#{@lp}) exceeds maximum 4"
|
|
140
140
|
end
|
|
141
141
|
|
|
142
142
|
# Step 2: Parse dictionary size (SEQ_DICTIONARY_SIZE)
|
|
@@ -144,7 +144,7 @@ module Omnizip
|
|
|
144
144
|
@dict_size = 0
|
|
145
145
|
4.times do |i|
|
|
146
146
|
byte = @input.getbyte
|
|
147
|
-
raise "Incomplete .lzma header: missing dictionary size byte" if byte.nil?
|
|
147
|
+
raise Omnizip::DecompressionError, "Incomplete .lzma header: missing dictionary size byte" if byte.nil?
|
|
148
148
|
|
|
149
149
|
@dict_size |= (byte << (i * 8))
|
|
150
150
|
end
|
|
@@ -163,7 +163,7 @@ module Omnizip
|
|
|
163
163
|
d += 1
|
|
164
164
|
|
|
165
165
|
if d != @dict_size
|
|
166
|
-
raise "Invalid .lzma header: dictionary size #{@dict_size} is not 2^n or 2^n + 2^(n-1)"
|
|
166
|
+
raise Omnizip::DecompressionError, "Invalid .lzma header: dictionary size #{@dict_size} is not 2^n or 2^n + 2^(n-1)"
|
|
167
167
|
end
|
|
168
168
|
end
|
|
169
169
|
|
|
@@ -172,7 +172,7 @@ module Omnizip
|
|
|
172
172
|
@uncompressed_size = 0
|
|
173
173
|
8.times do |i|
|
|
174
174
|
byte = @input.getbyte
|
|
175
|
-
raise "Incomplete .lzma header: missing uncompressed size byte" if byte.nil?
|
|
175
|
+
raise Omnizip::DecompressionError, "Incomplete .lzma header: missing uncompressed size byte" if byte.nil?
|
|
176
176
|
|
|
177
177
|
@uncompressed_size |= (byte << (i * 8))
|
|
178
178
|
end
|
|
@@ -182,7 +182,7 @@ module Omnizip
|
|
|
182
182
|
# Reference: alone_decoder.c:116-120
|
|
183
183
|
if @picky && @uncompressed_size != 0xFFFFFFFFFFFFFFFF &&
|
|
184
184
|
@uncompressed_size >= MAX_UNCOMPRESSED_SIZE
|
|
185
|
-
raise "Invalid .lzma header: uncompressed size #{@uncompressed_size} exceeds maximum #{MAX_UNCOMPRESSED_SIZE}"
|
|
185
|
+
raise Omnizip::DecompressionError, "Invalid .lzma header: uncompressed size #{@uncompressed_size} exceeds maximum #{MAX_UNCOMPRESSED_SIZE}"
|
|
186
186
|
end
|
|
187
187
|
|
|
188
188
|
# Note: XZ Utils uses UINT64_MAX (0xFFFFFFFFFFFFFFFF) for unknown size
|
|
@@ -97,7 +97,7 @@ module Omnizip
|
|
|
97
97
|
# @param prob [BitModel] Probability model
|
|
98
98
|
# @param bit [Integer] Bit value (0 or 1)
|
|
99
99
|
def queue_bit(prob, bit)
|
|
100
|
-
raise "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
|
|
100
|
+
raise Omnizip::CompressionError, "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
|
|
101
101
|
|
|
102
102
|
@symbols[@count] = bit.zero? ? RC_BIT_0 : RC_BIT_1
|
|
103
103
|
@probs[@count] = prob
|
|
@@ -111,7 +111,7 @@ module Omnizip
|
|
|
111
111
|
def queue_direct_bits(value, num_bits)
|
|
112
112
|
num_bits.downto(1) do |i|
|
|
113
113
|
bit = (value >> (i - 1)) & 1
|
|
114
|
-
raise "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
|
|
114
|
+
raise Omnizip::CompressionError, "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
|
|
115
115
|
|
|
116
116
|
@symbols[@count] = bit.zero? ? RC_DIRECT_0 : RC_DIRECT_1
|
|
117
117
|
@probs[@count] = nil
|
|
@@ -122,7 +122,7 @@ module Omnizip
|
|
|
122
122
|
# Queue flush operation
|
|
123
123
|
def queue_flush
|
|
124
124
|
5.times do
|
|
125
|
-
raise "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
|
|
125
|
+
raise Omnizip::CompressionError, "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
|
|
126
126
|
|
|
127
127
|
@symbols[@count] = RC_FLUSH
|
|
128
128
|
@probs[@count] = nil
|
|
@@ -237,7 +237,7 @@ module Omnizip
|
|
|
237
237
|
|
|
238
238
|
# Forget queued symbols (e.g., when output limit reached)
|
|
239
239
|
def forget
|
|
240
|
-
raise "Cannot forget with partial encoding" unless @pos.zero?
|
|
240
|
+
raise Omnizip::CompressionError, "Cannot forget with partial encoding" unless @pos.zero?
|
|
241
241
|
|
|
242
242
|
@count = 0
|
|
243
243
|
end
|
|
@@ -63,7 +63,7 @@ module Omnizip
|
|
|
63
63
|
|
|
64
64
|
# Forget pending symbols (matches XZ Utils rc_forget)
|
|
65
65
|
def forget
|
|
66
|
-
raise "Cannot forget while encoding" if @pos != 0
|
|
66
|
+
raise Omnizip::CompressionError, "Cannot forget while encoding" if @pos != 0
|
|
67
67
|
|
|
68
68
|
@count = 0
|
|
69
69
|
end
|
|
@@ -73,7 +73,7 @@ module Omnizip
|
|
|
73
73
|
# @param prob [Probability] Probability model
|
|
74
74
|
# @param bit [Integer] Bit value (0 or 1)
|
|
75
75
|
def bit(prob, bit)
|
|
76
|
-
raise "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
|
|
76
|
+
raise Omnizip::CompressionError, "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
|
|
77
77
|
|
|
78
78
|
@symbols[@count] = bit
|
|
79
79
|
@probs[@count] = prob
|
|
@@ -118,7 +118,7 @@ module Omnizip
|
|
|
118
118
|
# @param bit_count [Integer] Number of bits
|
|
119
119
|
def direct(value, bit_count)
|
|
120
120
|
bit_count.times do
|
|
121
|
-
raise "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
|
|
121
|
+
raise Omnizip::CompressionError, "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
|
|
122
122
|
|
|
123
123
|
@symbols[@count] = RC_DIRECT_0 | ((value >> (bit_count -= 1)) & 1)
|
|
124
124
|
@probs[@count] = nil
|
|
@@ -129,7 +129,7 @@ module Omnizip
|
|
|
129
129
|
# Queue flush operation (matches XZ Utils rc_flush)
|
|
130
130
|
def flush
|
|
131
131
|
5.times do
|
|
132
|
-
raise "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
|
|
132
|
+
raise Omnizip::CompressionError, "Symbol buffer overflow" if @count >= RC_SYMBOLS_MAX
|
|
133
133
|
|
|
134
134
|
@symbols[@count] = RC_FLUSH
|
|
135
135
|
@probs[@count] = nil
|
|
@@ -159,7 +159,7 @@ module Omnizip
|
|
|
159
159
|
# @param out_size [Integer] Output buffer size
|
|
160
160
|
# @return [Boolean] True if output buffer filled before encoding complete
|
|
161
161
|
def encode(out, out_pos, out_size)
|
|
162
|
-
raise "Symbol buffer overflow" if @count > RC_SYMBOLS_MAX
|
|
162
|
+
raise Omnizip::CompressionError, "Symbol buffer overflow" if @count > RC_SYMBOLS_MAX
|
|
163
163
|
|
|
164
164
|
skip_increment = false
|
|
165
165
|
|
|
@@ -214,7 +214,7 @@ module Omnizip
|
|
|
214
214
|
break
|
|
215
215
|
|
|
216
216
|
else
|
|
217
|
-
raise "Unknown symbol type: #{@symbols[@pos]}"
|
|
217
|
+
raise Omnizip::CompressionError, "Unknown symbol type: #{@symbols[@pos]}"
|
|
218
218
|
end
|
|
219
219
|
|
|
220
220
|
@pos += 1 unless skip_increment
|
|
@@ -288,7 +288,7 @@ module Omnizip
|
|
|
288
288
|
|
|
289
289
|
# Forget pending symbols (matches XZ Utils rc_forget)
|
|
290
290
|
def forget
|
|
291
|
-
raise "Cannot forget while encoding" if @pos != 0
|
|
291
|
+
raise Omnizip::CompressionError, "Cannot forget while encoding" if @pos != 0
|
|
292
292
|
|
|
293
293
|
@count = 0
|
|
294
294
|
end
|
|
@@ -318,7 +318,7 @@ check_rc_finished: true)
|
|
|
318
318
|
|
|
319
319
|
# Handle nil @pos or limit gracefully
|
|
320
320
|
if limit && (@pos.nil? || limit.nil?)
|
|
321
|
-
raise "Invalid state: @pos=#{@pos.inspect}, limit=#{limit.inspect}"
|
|
321
|
+
raise Omnizip::DecompressionError, "Invalid state: @pos=#{@pos.inspect}, limit=#{limit.inspect}"
|
|
322
322
|
end
|
|
323
323
|
|
|
324
324
|
# Circular buffer: flush output before it can be overwritten.
|
|
@@ -757,7 +757,7 @@ check_rc_finished: true)
|
|
|
757
757
|
def read_header
|
|
758
758
|
# Property byte
|
|
759
759
|
props = @input.getbyte
|
|
760
|
-
raise "Invalid LZMA header" if props.nil?
|
|
760
|
+
raise Omnizip::DecompressionError, "Invalid LZMA header" if props.nil?
|
|
761
761
|
|
|
762
762
|
@lc = props % 9
|
|
763
763
|
remainder = props / 9
|
|
@@ -768,7 +768,7 @@ check_rc_finished: true)
|
|
|
768
768
|
@dict_size = 0
|
|
769
769
|
4.times do |i|
|
|
770
770
|
byte = @input.getbyte
|
|
771
|
-
raise "Incomplete header" if byte.nil?
|
|
771
|
+
raise Omnizip::DecompressionError, "Incomplete header" if byte.nil?
|
|
772
772
|
|
|
773
773
|
@dict_size |= (byte << (i * 8))
|
|
774
774
|
end
|
|
@@ -780,7 +780,7 @@ check_rc_finished: true)
|
|
|
780
780
|
@uncompressed_size = 0
|
|
781
781
|
8.times do |i|
|
|
782
782
|
byte = @input.getbyte
|
|
783
|
-
raise "Incomplete header" if byte.nil?
|
|
783
|
+
raise Omnizip::DecompressionError, "Incomplete header" if byte.nil?
|
|
784
784
|
|
|
785
785
|
@uncompressed_size |= (byte << (i * 8))
|
|
786
786
|
end
|
|
@@ -791,9 +791,9 @@ check_rc_finished: true)
|
|
|
791
791
|
# @return [void]
|
|
792
792
|
# @raise [RuntimeError] If parameters are invalid
|
|
793
793
|
def validate_parameters
|
|
794
|
-
raise "Invalid lc (#{@lc})" unless @lc.between?(0, 8)
|
|
795
|
-
raise "Invalid lp (#{@lp})" unless @lp.between?(0, 4)
|
|
796
|
-
raise "Invalid pb (#{@pb})" unless @pb.between?(0, 4)
|
|
794
|
+
raise Omnizip::DecompressionError, "Invalid lc (#{@lc})" unless @lc.between?(0, 8)
|
|
795
|
+
raise Omnizip::DecompressionError, "Invalid lp (#{@lp})" unless @lp.between?(0, 4)
|
|
796
|
+
raise Omnizip::DecompressionError, "Invalid pb (#{@pb})" unless @pb.between?(0, 4)
|
|
797
797
|
end
|
|
798
798
|
|
|
799
799
|
# Initialize probability models
|
|
@@ -1201,7 +1201,7 @@ check_rc_finished: true)
|
|
|
1201
1201
|
# @dict_full is clamped at @dict_size. Use actual bytes written for validation.
|
|
1202
1202
|
actual_bytes_written = @pos - LZ_DICT_INIT_POS
|
|
1203
1203
|
unless actual_bytes_written > distance
|
|
1204
|
-
raise "Invalid rep distance: #{distance} (bytes_written: #{actual_bytes_written})"
|
|
1204
|
+
raise Omnizip::DecompressionError, "Invalid rep distance: #{distance} (bytes_written: #{actual_bytes_written})"
|
|
1205
1205
|
end
|
|
1206
1206
|
|
|
1207
1207
|
# IMPORTANT: Limit match length to not exceed uncompressed_size
|
|
@@ -84,16 +84,24 @@ module Omnizip
|
|
|
84
84
|
end
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
+
# The display is driven by the registry's field contract for
|
|
88
|
+
# :seven_zip — optional lines print only for registered fields.
|
|
87
89
|
def show_seven_zip_entry(entry)
|
|
88
|
-
|
|
89
|
-
puts "
|
|
90
|
-
puts "
|
|
90
|
+
registry = Omnizip::Metadata::MetadataRegistry
|
|
91
|
+
puts "Entry: #{entry[:name]}" if registry.supports?(:seven_zip, :name)
|
|
92
|
+
puts " Type: #{entry[:directory] ? 'Directory' : 'File'}" if registry.supports?(:seven_zip, :directory)
|
|
93
|
+
puts " Size: #{format_size(entry[:size])}" if registry.supports?(:seven_zip, :size)
|
|
91
94
|
# Per-entry packed sizes are not tracked by the parser
|
|
92
|
-
if
|
|
95
|
+
if registry.supports?(:seven_zip, :compressed_size) &&
|
|
96
|
+
entry[:compressed_size]&.positive?
|
|
93
97
|
puts " Compressed: #{format_size(entry[:compressed_size])}"
|
|
94
98
|
end
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
if registry.supports?(:seven_zip, :mtime) && entry[:mtime]
|
|
100
|
+
puts " Modified: #{entry[:mtime]}"
|
|
101
|
+
end
|
|
102
|
+
if registry.supports?(:seven_zip, :crc) && entry[:crc]
|
|
103
|
+
puts " CRC32: 0x#{entry[:crc].to_s(16).upcase}"
|
|
104
|
+
end
|
|
97
105
|
end
|
|
98
106
|
|
|
99
107
|
def show_metadata(archive, pattern)
|
|
@@ -136,19 +136,19 @@ module Omnizip
|
|
|
136
136
|
# Parse LZMA header
|
|
137
137
|
def parse_header
|
|
138
138
|
props = @input.getbyte
|
|
139
|
-
raise "Invalid LZMA header: missing properties" unless props
|
|
139
|
+
raise Omnizip::DecompressionError, "Invalid LZMA header: missing properties" unless props
|
|
140
140
|
|
|
141
141
|
@lc = props % 9
|
|
142
142
|
rem = props / 9
|
|
143
143
|
@lp = rem % 5
|
|
144
144
|
@pb = rem / 5
|
|
145
145
|
|
|
146
|
-
raise "Invalid LZMA properties: pb=#{@pb} > 4" if @pb > 4
|
|
146
|
+
raise Omnizip::DecompressionError, "Invalid LZMA properties: pb=#{@pb} > 4" if @pb > 4
|
|
147
147
|
|
|
148
148
|
@dict_size = 0
|
|
149
149
|
4.times do |i|
|
|
150
150
|
byte = @input.getbyte
|
|
151
|
-
raise "Invalid LZMA header: missing dictionary size" unless byte
|
|
151
|
+
raise Omnizip::DecompressionError, "Invalid LZMA header: missing dictionary size" unless byte
|
|
152
152
|
|
|
153
153
|
@dict_size |= (byte << (i * 8))
|
|
154
154
|
end
|
|
@@ -159,7 +159,7 @@ module Omnizip
|
|
|
159
159
|
@uncompressed_size = 0
|
|
160
160
|
8.times do |i|
|
|
161
161
|
byte = @input.getbyte
|
|
162
|
-
raise "Invalid LZMA header: missing uncompressed size" unless byte
|
|
162
|
+
raise Omnizip::DecompressionError, "Invalid LZMA header: missing uncompressed size" unless byte
|
|
163
163
|
|
|
164
164
|
@uncompressed_size |= (byte * (1 << (i * 8)))
|
|
165
165
|
end
|
|
@@ -328,7 +328,7 @@ module Omnizip
|
|
|
328
328
|
# Decoder returns distance before +1, so add 1 to get actual distance
|
|
329
329
|
distance += 1
|
|
330
330
|
|
|
331
|
-
raise "Invalid distance: #{distance}" if distance >= @dict_size && @dict_full
|
|
331
|
+
raise Omnizip::DecompressionError, "Invalid distance: #{distance}" if distance >= @dict_size && @dict_full
|
|
332
332
|
|
|
333
333
|
# Update reps
|
|
334
334
|
@reps[3] = @reps[2]
|
|
@@ -309,7 +309,7 @@ module Omnizip
|
|
|
309
309
|
# @return [void]
|
|
310
310
|
def encode_match(match, data)
|
|
311
311
|
# Defensive check: distance must be >= 1
|
|
312
|
-
raise "Invalid match distance: #{match.distance}" if match.distance < 1
|
|
312
|
+
raise Omnizip::CompressionError, "Invalid match distance: #{match.distance}" if match.distance < 1
|
|
313
313
|
|
|
314
314
|
pos_state = @pos & ((1 << @pb) - 1)
|
|
315
315
|
|
|
@@ -158,7 +158,7 @@ module Omnizip
|
|
|
158
158
|
def init_decoder
|
|
159
159
|
# Read first byte (should be 0 for valid LZMA stream)
|
|
160
160
|
first = read_byte
|
|
161
|
-
raise "Invalid LZMA stream: first byte not 0" unless first.zero?
|
|
161
|
+
raise Omnizip::DecompressionError, "Invalid LZMA stream: first byte not 0" unless first.zero?
|
|
162
162
|
|
|
163
163
|
# Read 4 bytes for initial code value
|
|
164
164
|
@code = 0
|
|
@@ -55,10 +55,17 @@ module Omnizip
|
|
|
55
55
|
extra_field
|
|
56
56
|
])
|
|
57
57
|
|
|
58
|
-
# Register 7z format metadata support
|
|
58
|
+
# Register 7z format metadata support: the readable fields the
|
|
59
|
+
# handler detail contract carries (name/size/directory always
|
|
60
|
+
# present; compressed_size when tracked, mtime/crc when stored).
|
|
61
|
+
# Editing is ZIP-only — the metadata command raises truthfully.
|
|
59
62
|
MetadataRegistry.register(:seven_zip, %i[
|
|
63
|
+
name
|
|
64
|
+
size
|
|
65
|
+
directory
|
|
66
|
+
compressed_size
|
|
60
67
|
mtime
|
|
61
|
-
|
|
68
|
+
crc
|
|
62
69
|
])
|
|
63
70
|
end
|
|
64
71
|
end
|
data/lib/omnizip/version.rb
CHANGED