omnizip 0.3.20 → 0.3.22
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/TODO.refactor/00-overview.md +2 -2
- data/TODO.refactor/07-respond-to-replacement.md +225 -79
- data/lib/omnizip/algorithm.rb +2 -2
- data/lib/omnizip/algorithms/bzip2.rb +1 -0
- data/lib/omnizip/algorithms/deflate.rb +1 -0
- data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +3 -3
- data/lib/omnizip/algorithms/lzma.rb +11 -5
- data/lib/omnizip/algorithms/lzma2/encoder.rb +2 -0
- data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +2 -0
- data/lib/omnizip/algorithms/lzma2.rb +2 -0
- data/lib/omnizip/algorithms/ppmd7.rb +2 -0
- data/lib/omnizip/algorithms/ppmd_base.rb +2 -0
- data/lib/omnizip/algorithms/registration.rb +1 -1
- data/lib/omnizip/algorithms/zstandard/decoder.rb +62 -3
- data/lib/omnizip/algorithms/zstandard/dictionary.rb +73 -0
- data/lib/omnizip/algorithms/zstandard/encoder.rb +110 -30
- data/lib/omnizip/algorithms/zstandard/match_finder.rb +21 -5
- data/lib/omnizip/algorithms/zstandard.rb +52 -0
- data/lib/omnizip/chunked/writer.rb +3 -0
- data/lib/omnizip/commands/archive_extract_command.rb +3 -1
- data/lib/omnizip/commands/archive_list_command.rb +4 -3
- data/lib/omnizip/commands/profile_show_command.rb +2 -0
- data/lib/omnizip/convenience.rb +2 -0
- data/lib/omnizip/extraction/filter_chain.rb +4 -0
- data/lib/omnizip/extraction/selective_extractor.rb +7 -0
- data/lib/omnizip/file_type.rb +4 -0
- data/lib/omnizip/formats/ole.rb +2 -0
- data/lib/omnizip/formats/rar/decompressor.rb +1 -0
- data/lib/omnizip/formats/rar/license_validator.rb +2 -0
- data/lib/omnizip/formats/rar/reader.rb +1 -2
- data/lib/omnizip/formats/rpm.rb +1 -0
- data/lib/omnizip/formats/seven_zip/writer.rb +8 -0
- data/lib/omnizip/formats/tar/reader.rb +2 -0
- data/lib/omnizip/formats/xar/reader.rb +2 -0
- data/lib/omnizip/formats/xar/writer.rb +1 -0
- data/lib/omnizip/formats/xz.rb +2 -0
- data/lib/omnizip/formats/xz_impl/block_decoder.rb +3 -0
- data/lib/omnizip/formats/xz_impl/stream_decoder.rb +8 -0
- data/lib/omnizip/formats/zip/reader.rb +2 -0
- data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +1 -0
- data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +4 -9
- data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +1 -16
- data/lib/omnizip/io/buffered_input.rb +1 -0
- data/lib/omnizip/io/buffered_output.rb +1 -0
- data/lib/omnizip/io/source.rb +4 -0
- data/lib/omnizip/io/stream_manager.rb +3 -1
- data/lib/omnizip/link_handler.rb +2 -0
- data/lib/omnizip/metadata/metadata_validator.rb +2 -0
- data/lib/omnizip/models/filter_config.rb +2 -0
- data/lib/omnizip/version.rb +1 -1
- data/lib/omnizip/zip/file.rb +1 -1
- data/lib/omnizip/zip/input_stream.rb +2 -1
- metadata +2 -1
|
@@ -77,6 +77,7 @@ module Omnizip
|
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
def set_encoding(enc)
|
|
80
|
+
# allowed: caller-supplied IO; String streams lack set_encoding
|
|
80
81
|
@stream.set_encoding(enc) if @stream.respond_to?(:set_encoding)
|
|
81
82
|
end
|
|
82
83
|
end
|
|
@@ -110,7 +111,9 @@ module Omnizip
|
|
|
110
111
|
|
|
111
112
|
if ENV["XZ_BLOCK_DEBUG"]
|
|
112
113
|
warn "DEBUG: decode - compressed_size=#{compressed_size.inspect}, check_type=#{@check_type}"
|
|
114
|
+
# allowed: debug output under XZ_BLOCK_DEBUG
|
|
113
115
|
warn "DEBUG: @input.class=#{@input.class}, @input.respond_to?(:pos)=#{@input.respond_to?(:pos)}"
|
|
116
|
+
# allowed: debug output under XZ_BLOCK_DEBUG
|
|
114
117
|
pos = @input.respond_to?(:pos) ? @input.pos : "N/A"
|
|
115
118
|
warn "DEBUG: @input.pos=#{pos}"
|
|
116
119
|
end
|
|
@@ -46,6 +46,7 @@ module Omnizip
|
|
|
46
46
|
|
|
47
47
|
# Store original input and file size for backward_size validation (if available)
|
|
48
48
|
original_input = input
|
|
49
|
+
# allowed: caller-supplied IO; only sized streams get validated
|
|
49
50
|
original_file_size = input.size if input.respond_to?(:size)
|
|
50
51
|
|
|
51
52
|
output, block_count, final_input, block_sizes = decode_blocks(input,
|
|
@@ -57,6 +58,7 @@ module Omnizip
|
|
|
57
58
|
# multiples of four bytes...If the stored value does not match the real size of
|
|
58
59
|
# the Index field, the decoder MUST indicate an error."
|
|
59
60
|
# Reference: /Users/mulgogi/src/external/xz/src/liblzma/common/stream_decoder.c
|
|
61
|
+
# allowed: caller-supplied IO; footer check needs seeking
|
|
60
62
|
if original_input.respond_to?(:seek) && original_file_size&.positive?
|
|
61
63
|
# Use original input and file size for validation
|
|
62
64
|
validate_backward_size_from_footer(original_input,
|
|
@@ -138,6 +140,7 @@ module Omnizip
|
|
|
138
140
|
# @param byte [Integer] Byte to restore
|
|
139
141
|
# @raise [RuntimeError] If IO doesn't support ungetbyte
|
|
140
142
|
def self.restore_byte(input, byte)
|
|
143
|
+
# allowed: caller-supplied IO; FormatError follows when unsupported
|
|
141
144
|
return input.ungetbyte(byte) if input.respond_to?(:ungetbyte)
|
|
142
145
|
|
|
143
146
|
raise FormatError,
|
|
@@ -227,6 +230,7 @@ module Omnizip
|
|
|
227
230
|
# @param check_type [Symbol] Expected checksum type
|
|
228
231
|
# @param index_size [Integer, nil] Actual index size for backward_size validation
|
|
229
232
|
def self.verify_footer_if_seekable(input, check_type, index_size = nil)
|
|
233
|
+
# allowed: caller-supplied IO; skipped on non-seekable streams
|
|
230
234
|
return unless input.respond_to?(:seek) && input.respond_to?(:size) && input.size
|
|
231
235
|
|
|
232
236
|
original_pos = input.pos
|
|
@@ -290,6 +294,7 @@ module Omnizip
|
|
|
290
294
|
# @param input [IO] Input stream
|
|
291
295
|
# @raise [FormatError] If there's invalid trailing data
|
|
292
296
|
def self.verify_no_trailing_data(input)
|
|
297
|
+
# allowed: caller-supplied IO; needs byte-level positioning
|
|
293
298
|
return unless input.respond_to?(:pos) && input.respond_to?(:getbyte)
|
|
294
299
|
|
|
295
300
|
# Skip stream padding (null bytes)
|
|
@@ -304,6 +309,7 @@ module Omnizip
|
|
|
304
309
|
else
|
|
305
310
|
# Non-zero byte found - this should be a new stream or it's invalid
|
|
306
311
|
# Restore the byte and check if it's a valid stream header
|
|
312
|
+
# allowed: caller-supplied IO capability probe
|
|
307
313
|
input.ungetbyte(byte) if input.respond_to?(:ungetbyte)
|
|
308
314
|
|
|
309
315
|
# Stream padding must be a multiple of 4 bytes
|
|
@@ -345,6 +351,7 @@ module Omnizip
|
|
|
345
351
|
end
|
|
346
352
|
|
|
347
353
|
# Restore the bytes we read
|
|
354
|
+
# allowed: caller-supplied IO capability probe
|
|
348
355
|
if input.respond_to?(:ungetbyte)
|
|
349
356
|
potential_header.reverse_each do |b|
|
|
350
357
|
input.ungetbyte(b)
|
|
@@ -381,6 +388,7 @@ module Omnizip
|
|
|
381
388
|
# @raise [FormatError] If backward_size points to invalid position
|
|
382
389
|
def self.validate_backward_size_from_footer(input, file_size,
|
|
383
390
|
_index_size)
|
|
391
|
+
# allowed: caller-supplied IO; skipped on non-seekable streams
|
|
384
392
|
return unless input.respond_to?(:seek)
|
|
385
393
|
return if file_size.nil? || file_size.zero?
|
|
386
394
|
|
|
@@ -121,6 +121,7 @@ module Omnizip
|
|
|
121
121
|
# For raw mode, return actual decode bytes (excluding flush padding)
|
|
122
122
|
if @raw_mode
|
|
123
123
|
[@output.string, @range_encoder.bytes_for_decode]
|
|
124
|
+
# allowed: caller-supplied output; any #string sink buffers
|
|
124
125
|
elsif @output.respond_to?(:string)
|
|
125
126
|
# For File output, just return bytes written (don't try to read back)
|
|
126
127
|
# For StringIO, return the string and its size
|
|
@@ -416,16 +416,11 @@ module Omnizip
|
|
|
416
416
|
|
|
417
417
|
if @lzma2_debug
|
|
418
418
|
warn "DEBUG: decompress_lzma_chunk - After set_input, checking range_decoder..."
|
|
419
|
-
|
|
420
|
-
if
|
|
421
|
-
range_decoder =
|
|
422
|
-
if range_decoder
|
|
423
|
-
warn " range_decoder exists: code=0x#{range_decoder.code.to_s(16)}, range=0x#{range_decoder.range.to_s(16)}, init_bytes_remaining=#{range_decoder.init_bytes_remaining}"
|
|
424
|
-
else
|
|
425
|
-
warn " range_decoder is nil"
|
|
426
|
-
end
|
|
419
|
+
range_decoder = @lzma_decoder.range_decoder
|
|
420
|
+
if range_decoder
|
|
421
|
+
warn " range_decoder exists: code=0x#{range_decoder.code.to_s(16)}, range=0x#{range_decoder.range.to_s(16)}, init_bytes_remaining=#{range_decoder.init_bytes_remaining}"
|
|
427
422
|
else
|
|
428
|
-
warn "
|
|
423
|
+
warn " range_decoder is nil"
|
|
429
424
|
end
|
|
430
425
|
end
|
|
431
426
|
else
|
|
@@ -33,19 +33,6 @@ module Omnizip
|
|
|
33
33
|
#
|
|
34
34
|
# Ported from XZ Utils liblzma/lzma2_encoder.c
|
|
35
35
|
#
|
|
36
|
-
# Compatibility helper for Ruby 3.0-3.1 where String#byteslice doesn't exist
|
|
37
|
-
module StringCompat
|
|
38
|
-
if "".respond_to?(:byteslice)
|
|
39
|
-
def self.byteslice(string, start, length)
|
|
40
|
-
string.byteslice(start, length)
|
|
41
|
-
end
|
|
42
|
-
else
|
|
43
|
-
def self.byteslice(string, start, length)
|
|
44
|
-
string.bytes[start, length]&.pack("C*") || ""
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
36
|
# Constants
|
|
50
37
|
UINT32_MAX = 0xFFFFFFFF
|
|
51
38
|
REPS = 4
|
|
@@ -364,11 +351,9 @@ module Omnizip
|
|
|
364
351
|
|
|
365
352
|
# Write to output stream
|
|
366
353
|
if out_pos.value.positive?
|
|
367
|
-
# Use StringCompat.byteslice for Ruby 3.0-3.1 compatibility
|
|
368
354
|
# Ruby's [] operator has a bug with null bytes that can return extra bytes
|
|
369
355
|
# See: https://bugs.ruby-lang.org/issues/15985
|
|
370
|
-
output.write(
|
|
371
|
-
out_pos.value))
|
|
356
|
+
output.write(temp_buffer.byteslice(0, out_pos.value))
|
|
372
357
|
end
|
|
373
358
|
|
|
374
359
|
# Return the number of bytes written
|
data/lib/omnizip/io/source.rb
CHANGED
|
@@ -31,6 +31,7 @@ module Omnizip
|
|
|
31
31
|
when ::IO, ::StringIO, ::Tempfile then new(input)
|
|
32
32
|
when String then StringSource.new(input)
|
|
33
33
|
else
|
|
34
|
+
# allowed: boundary validation; duck-typing ends at this adapter
|
|
34
35
|
unless input.respond_to?(:read)
|
|
35
36
|
raise ArgumentError,
|
|
36
37
|
"Cannot adapt #{input.inspect} to Omnizip::IO::Source"
|
|
@@ -56,6 +57,7 @@ module Omnizip
|
|
|
56
57
|
end
|
|
57
58
|
|
|
58
59
|
def close
|
|
60
|
+
# allowed: wrapped object may be a read-only duck with no close
|
|
59
61
|
@io.close if @io.respond_to?(:close)
|
|
60
62
|
end
|
|
61
63
|
|
|
@@ -98,6 +100,7 @@ module Omnizip
|
|
|
98
100
|
when ::IO, ::StringIO, ::Tempfile then new(output)
|
|
99
101
|
when String then PathSink.new(output)
|
|
100
102
|
else
|
|
103
|
+
# allowed: boundary validation; duck-typing ends at this adapter
|
|
101
104
|
unless output.respond_to?(:write)
|
|
102
105
|
raise ArgumentError,
|
|
103
106
|
"Cannot adapt #{output.inspect} to Omnizip::IO::Sink"
|
|
@@ -116,6 +119,7 @@ module Omnizip
|
|
|
116
119
|
end
|
|
117
120
|
|
|
118
121
|
def close
|
|
122
|
+
# allowed: wrapped object may be a write-only duck with no close
|
|
119
123
|
@io.close if @io.respond_to?(:close)
|
|
120
124
|
end
|
|
121
125
|
|
|
@@ -71,13 +71,14 @@ module Omnizip
|
|
|
71
71
|
#
|
|
72
72
|
# @return [void]
|
|
73
73
|
def close
|
|
74
|
-
@source.close if @owned
|
|
74
|
+
@source.close if @owned
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
# Check if source is at end.
|
|
78
78
|
#
|
|
79
79
|
# @return [Boolean] True if at EOF
|
|
80
80
|
def eof?
|
|
81
|
+
# allowed: write-only sources have no eof?
|
|
81
82
|
@source.eof? if @source.respond_to?(:eof?)
|
|
82
83
|
end
|
|
83
84
|
|
|
@@ -103,6 +104,7 @@ module Omnizip
|
|
|
103
104
|
end
|
|
104
105
|
|
|
105
106
|
def validate_io_interface(source)
|
|
107
|
+
# allowed: boundary validation of a caller-supplied IO-like object
|
|
106
108
|
if source.respond_to?(:read) || source.respond_to?(:write)
|
|
107
109
|
source
|
|
108
110
|
else
|
data/lib/omnizip/link_handler.rb
CHANGED
|
@@ -9,6 +9,8 @@ module Omnizip
|
|
|
9
9
|
# @raise [ArgumentError] If metadata is invalid
|
|
10
10
|
def validate_entry(metadata)
|
|
11
11
|
validate_comment(metadata.comment) if metadata.comment
|
|
12
|
+
# validate_entry is public API.
|
|
13
|
+
# allowed: metadata need only expose what it validates
|
|
12
14
|
validate_time(metadata.mtime) if metadata.respond_to?(:mtime)
|
|
13
15
|
validate_permissions(metadata.unix_permissions) if metadata.unix_permissions
|
|
14
16
|
|
|
@@ -94,6 +94,8 @@ module Omnizip
|
|
|
94
94
|
# @raise [NotImplementedError] If filter doesn't support id_for_format
|
|
95
95
|
def id_for_format(format)
|
|
96
96
|
filter = filter_instance
|
|
97
|
+
# FilterRegistry accepts any class, with no inheritance check.
|
|
98
|
+
# allowed: keeps NotImplementedError for filters without the method
|
|
97
99
|
if filter.respond_to?(:id_for_format)
|
|
98
100
|
filter.id_for_format(format)
|
|
99
101
|
else
|
data/lib/omnizip/version.rb
CHANGED
data/lib/omnizip/zip/file.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "fileutils"
|
|
4
|
+
require "stringio"
|
|
4
5
|
|
|
5
6
|
module Omnizip
|
|
6
7
|
module Zip
|
|
@@ -102,7 +103,6 @@ module Omnizip
|
|
|
102
103
|
content = read_entry_data(entry)
|
|
103
104
|
|
|
104
105
|
if block
|
|
105
|
-
require "stringio"
|
|
106
106
|
StringIO.open(content, "rb", &block)
|
|
107
107
|
else
|
|
108
108
|
content
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "stringio"
|
|
4
|
+
|
|
3
5
|
module Omnizip
|
|
4
6
|
module Zip
|
|
5
7
|
# Rubyzip-compatible InputStream class
|
|
@@ -88,7 +90,6 @@ module Omnizip
|
|
|
88
90
|
@current_entry.compression_method,
|
|
89
91
|
@current_entry.size,
|
|
90
92
|
)
|
|
91
|
-
require "stringio"
|
|
92
93
|
@current_entry_io = StringIO.new(decompressed, "rb")
|
|
93
94
|
end
|
|
94
95
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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.22
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -301,6 +301,7 @@ files:
|
|
|
301
301
|
- lib/omnizip/algorithms/zstandard.rb
|
|
302
302
|
- lib/omnizip/algorithms/zstandard/constants.rb
|
|
303
303
|
- lib/omnizip/algorithms/zstandard/decoder.rb
|
|
304
|
+
- lib/omnizip/algorithms/zstandard/dictionary.rb
|
|
304
305
|
- lib/omnizip/algorithms/zstandard/encoder.rb
|
|
305
306
|
- lib/omnizip/algorithms/zstandard/frame.rb
|
|
306
307
|
- lib/omnizip/algorithms/zstandard/frame/block.rb
|