omnizip 0.3.48 → 0.3.49
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 +28 -0
- data/lib/omnizip/archive_handler.rb +3 -0
- data/lib/omnizip/archive_handlers/ole_handler.rb +37 -0
- data/lib/omnizip/archive_handlers/rpm_handler.rb +45 -0
- data/lib/omnizip/archive_handlers/xar_handler.rb +49 -0
- data/lib/omnizip/archive_handlers.rb +3 -0
- data/lib/omnizip/commands/decompress_command.rb +1 -1
- data/lib/omnizip/convenience.rb +4 -1
- data/lib/omnizip/formats/seven_zip/writer.rb +10 -0
- data/lib/omnizip/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f2d2eb9632ecf11d24224648408b2ca0bb56ed99b3a0ad6b077edbf84930ad52
|
|
4
|
+
data.tar.gz: 243668f7a95b77377911efcc686dec8f5d43a47b625aca6a30795b4d4d66a49a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fa7a60a3b4fba564f7b76786969699a446f46e72a7610065113c5fdcb02404b4d7ec3e9b6430d2ab48550ad19061341af5d29286786e1f833bb5b8a246735434
|
|
7
|
+
data.tar.gz: d2f4375f10f9922ca466d9c154d2bfbd42ccb3a376e58be025299af1d3dafdbcc6d43175dd3fe9d76c87057d7f067e1ff01900968982b8ed193833e9f7819405
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.48] - 2026-08-31
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- `omnizip archive create` routes through the Archive facade: the
|
|
14
|
+
command's two hand-munged format branches collapse into one
|
|
15
|
+
`Archive.create` call — the handler registry picks each format's
|
|
16
|
+
writer and applies its option semantics, and the command only
|
|
17
|
+
translates CLI vocabulary (414 -> 290 lines). Verified for 7z
|
|
18
|
+
(7zz byte-identical), RAR5, RAR4, volume splitting, and verbose
|
|
19
|
+
output.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
- The 7z handler proxy dropped the Builder's explicit directory
|
|
23
|
+
entries (derive-from-paths no-op), so CLI-created archives lost
|
|
24
|
+
the `dir/` entries the previous writer path emitted. The proxy
|
|
25
|
+
maps name-only adds to `add_directory_entry`, which preserves the
|
|
26
|
+
trailing slash; the Buffer read proxy no longer double-slashes
|
|
27
|
+
such names.
|
|
28
|
+
- The facade denied RAR passwords (`PASSWORD_FORMATS` listed 7z
|
|
29
|
+
only) while the RAR5 writer produces unrar-decryptable encrypted
|
|
30
|
+
archives — `:rar` added (verified with `unrar -p`).
|
|
31
|
+
- RAR4 recovery guard crashed on explicit boolean options:
|
|
32
|
+
`false&.to_i` still calls `to_i` (safe navigation guards nil
|
|
33
|
+
only) — Numeric check now.
|
|
34
|
+
- RAR interop specs gate on the unrar command (through its resolved
|
|
35
|
+
path), not the gem wrapper: CI runners can carry the gem without
|
|
36
|
+
the binary on PATH.
|
|
37
|
+
|
|
10
38
|
## [0.3.47] - 2026-08-31
|
|
11
39
|
|
|
12
40
|
### Fixed
|
|
@@ -68,6 +68,9 @@ module Omnizip
|
|
|
68
68
|
# file, which then self-registers at the bottom of the file.
|
|
69
69
|
LAZY_LOAD_TRIGGERS = {
|
|
70
70
|
zip: -> { Omnizip::ArchiveHandlers::ZipHandler },
|
|
71
|
+
rpm: -> { Omnizip::ArchiveHandlers::RpmHandler },
|
|
72
|
+
xar: -> { Omnizip::ArchiveHandlers::XarHandler },
|
|
73
|
+
ole: -> { Omnizip::ArchiveHandlers::OleHandler },
|
|
71
74
|
tar: -> { Omnizip::ArchiveHandlers::TarHandler },
|
|
72
75
|
seven_zip: -> { Omnizip::ArchiveHandlers::SevenZipHandler },
|
|
73
76
|
rar: -> { Omnizip::ArchiveHandlers::RarHandler },
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string: true
|
|
2
|
+
|
|
3
|
+
module Omnizip
|
|
4
|
+
module ArchiveHandlers
|
|
5
|
+
# Read-only adapter for OLE compound documents ( MSI installers,
|
|
6
|
+
# legacy Office binaries): stream listing, reading, and
|
|
7
|
+
# extraction. Stream names are listed exactly as stored — MSI
|
|
8
|
+
# installers mangle their table-stream names in a
|
|
9
|
+
# MSI-domain encoding this handler does not decode.
|
|
10
|
+
class OleHandler
|
|
11
|
+
def create(_path, **_options)
|
|
12
|
+
raise Omnizip::UnsupportedFormatError,
|
|
13
|
+
"compound documents cannot be created through the " \
|
|
14
|
+
"convenience API; use Omnizip::Formats::Ole directly"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def extract_to(path, output_dir, **_)
|
|
18
|
+
Omnizip::Formats::Ole.extract(path, output_dir)
|
|
19
|
+
Dir.glob(File.join(output_dir, "**", "*"))
|
|
20
|
+
.select { |f| File.file?(f) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def list(path, details: false, **_)
|
|
24
|
+
entries = Omnizip::Formats::Ole.list(path)
|
|
25
|
+
return entries unless details
|
|
26
|
+
|
|
27
|
+
entries.map { |name| { name: name, size: nil, directory: false } }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def read_entry(path, entry_name, **_)
|
|
31
|
+
Omnizip::Formats::Ole.read(path, entry_name)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
Omnizip::ArchiveHandler.register(:ole, Omnizip::ArchiveHandlers::OleHandler.new)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string: true
|
|
2
|
+
|
|
3
|
+
require "tmpdir"
|
|
4
|
+
|
|
5
|
+
module Omnizip
|
|
6
|
+
module ArchiveHandlers
|
|
7
|
+
# Read-only adapter for the RPM package format: extraction and
|
|
8
|
+
# listing over the CPIO payload; package metadata lives in
|
|
9
|
+
# Formats::Rpm.info. RPM writing exists at the format level but
|
|
10
|
+
# is not exposed through the convenience archive API.
|
|
11
|
+
class RpmHandler
|
|
12
|
+
def create(_path, **_options)
|
|
13
|
+
raise Omnizip::UnsupportedFormatError,
|
|
14
|
+
"rpm archives cannot be created through the convenience " \
|
|
15
|
+
"API; use Omnizip::Formats::Rpm::Writer directly"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def extract_to(path, output_dir, **_)
|
|
19
|
+
Omnizip::Formats::Rpm.extract(path, output_dir)
|
|
20
|
+
Dir.glob(File.join(output_dir, "**", "*"))
|
|
21
|
+
.select { |f| File.file?(f) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def list(path, details: false, **_)
|
|
25
|
+
entries = Omnizip::Formats::Rpm.list(path)
|
|
26
|
+
return entries unless details
|
|
27
|
+
|
|
28
|
+
entries.map { |name| { name: name, size: nil, directory: false } }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def read_entry(path, entry_name, **_)
|
|
32
|
+
Dir.mktmpdir("omnizip-rpm-entry") do |dir|
|
|
33
|
+
Omnizip::Formats::Rpm.extract(path, dir)
|
|
34
|
+
dest = File.join(dir, entry_name)
|
|
35
|
+
raise Errno::ENOENT, "Entry not found: #{entry_name}" unless
|
|
36
|
+
File.exist?(dest)
|
|
37
|
+
|
|
38
|
+
File.binread(dest)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
Omnizip::ArchiveHandler.register(:rpm, Omnizip::ArchiveHandlers::RpmHandler.new)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string: true
|
|
2
|
+
|
|
3
|
+
require "tmpdir"
|
|
4
|
+
|
|
5
|
+
module Omnizip
|
|
6
|
+
module ArchiveHandlers
|
|
7
|
+
# Read-only adapter for the XAR archive format: extraction and
|
|
8
|
+
# listing over the XML TOC. XAR writing exists at the format
|
|
9
|
+
# level but is not exposed through the convenience archive API.
|
|
10
|
+
class XarHandler
|
|
11
|
+
def create(_path, **_options)
|
|
12
|
+
raise Omnizip::UnsupportedFormatError,
|
|
13
|
+
"xar archives cannot be created through the convenience " \
|
|
14
|
+
"API; use Omnizip::Formats::Xar.create directly"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def extract_to(path, output_dir, **_)
|
|
18
|
+
Omnizip::Formats::Xar.extract(path, output_dir)
|
|
19
|
+
Dir.glob(File.join(output_dir, "**", "*"))
|
|
20
|
+
.select { |f| File.file?(f) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def list(path, details: false, **_)
|
|
24
|
+
entries = Omnizip::Formats::Xar.list(path)
|
|
25
|
+
if details
|
|
26
|
+
entries.map do |e|
|
|
27
|
+
{ name: e.name, size: e.size,
|
|
28
|
+
directory: false }
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
entries.map(&:name)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def read_entry(path, entry_name, **_)
|
|
36
|
+
Dir.mktmpdir("omnizip-xar-entry") do |dir|
|
|
37
|
+
Omnizip::Formats::Xar.extract(path, dir)
|
|
38
|
+
dest = File.join(dir, entry_name)
|
|
39
|
+
raise Errno::ENOENT, "Entry not found: #{entry_name}" unless
|
|
40
|
+
File.exist?(dest)
|
|
41
|
+
|
|
42
|
+
File.binread(dest)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
Omnizip::ArchiveHandler.register(:xar, Omnizip::ArchiveHandlers::XarHandler.new)
|
|
@@ -10,6 +10,9 @@ module Omnizip
|
|
|
10
10
|
autoload :SevenZipHandler, "omnizip/archive_handlers/seven_zip_handler"
|
|
11
11
|
autoload :RarHandler, "omnizip/archive_handlers/rar_handler"
|
|
12
12
|
autoload :CpioHandler, "omnizip/archive_handlers/cpio_handler"
|
|
13
|
+
autoload :RpmHandler, "omnizip/archive_handlers/rpm_handler"
|
|
14
|
+
autoload :XarHandler, "omnizip/archive_handlers/xar_handler"
|
|
15
|
+
autoload :OleHandler, "omnizip/archive_handlers/ole_handler"
|
|
13
16
|
autoload :IsoHandler, "omnizip/archive_handlers/iso_handler"
|
|
14
17
|
end
|
|
15
18
|
end
|
data/lib/omnizip/convenience.rb
CHANGED
|
@@ -236,7 +236,7 @@ module Omnizip
|
|
|
236
236
|
# creation raises truthfully instead (the format-level writers
|
|
237
237
|
# exist for CPIO/ISO but are not part of the archive API; RAR
|
|
238
238
|
# moved to the writable routes when its handler gained create).
|
|
239
|
-
READ_ONLY_FORMAT_EXTENSIONS = [
|
|
239
|
+
READ_ONLY_FORMAT_EXTENSIONS = %w[.iso .cpio .rpm .xar .msi].freeze
|
|
240
240
|
|
|
241
241
|
# Extensions whose format has a READ-ONLY handler: extraction and
|
|
242
242
|
# listing route to it, while creation keeps raising.
|
|
@@ -244,6 +244,9 @@ module Omnizip
|
|
|
244
244
|
".rar" => :rar,
|
|
245
245
|
".cpio" => :cpio,
|
|
246
246
|
".iso" => :iso,
|
|
247
|
+
".rpm" => :rpm,
|
|
248
|
+
".xar" => :xar,
|
|
249
|
+
".msi" => :ole,
|
|
247
250
|
}.freeze
|
|
248
251
|
|
|
249
252
|
# Extension -> single-file decompressor (stream interface).
|
|
@@ -37,6 +37,16 @@ module Omnizip
|
|
|
37
37
|
}.merge(options)
|
|
38
38
|
@collector = FileCollector.new
|
|
39
39
|
@entries = []
|
|
40
|
+
|
|
41
|
+
# Preprocessing filters are decode-side only: the write
|
|
42
|
+
# path does not apply them, so say so instead of silently
|
|
43
|
+
# ignoring the option
|
|
44
|
+
filters = @options[:filters]
|
|
45
|
+
return unless filters && !filters.empty?
|
|
46
|
+
|
|
47
|
+
warn "omnizip: the 7z writer does not apply filters " \
|
|
48
|
+
"(#{Array(filters).join(', ')}); writing unfiltered data. " \
|
|
49
|
+
"Filters apply when reading archives that contain them."
|
|
40
50
|
end
|
|
41
51
|
|
|
42
52
|
def add_file(file_path, archive_path = nil)
|
data/lib/omnizip/version.rb
CHANGED
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.49
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -327,9 +327,12 @@ files:
|
|
|
327
327
|
- lib/omnizip/archive_handlers.rb
|
|
328
328
|
- lib/omnizip/archive_handlers/cpio_handler.rb
|
|
329
329
|
- lib/omnizip/archive_handlers/iso_handler.rb
|
|
330
|
+
- lib/omnizip/archive_handlers/ole_handler.rb
|
|
330
331
|
- lib/omnizip/archive_handlers/rar_handler.rb
|
|
332
|
+
- lib/omnizip/archive_handlers/rpm_handler.rb
|
|
331
333
|
- lib/omnizip/archive_handlers/seven_zip_handler.rb
|
|
332
334
|
- lib/omnizip/archive_handlers/tar_handler.rb
|
|
335
|
+
- lib/omnizip/archive_handlers/xar_handler.rb
|
|
333
336
|
- lib/omnizip/archive_handlers/zip_handler.rb
|
|
334
337
|
- lib/omnizip/buffer.rb
|
|
335
338
|
- lib/omnizip/buffer/memory_archive.rb
|