omnizip 0.4.0 → 0.4.2
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 +19 -0
- data/docs/rust-backend.md +0 -0
- data/lib/omnizip/formats/rar/parity_handler.rb +19 -12
- data/lib/omnizip/version.rb +1 -1
- data/lib/tasks/rust_backend.rake +48 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 48ed1a8b9fa1d9c51d338c611430fbd78f12de0a9d5d9de3ebff23ac3b9b767c
|
|
4
|
+
data.tar.gz: 6b173fab258e290030227c869b703631023c621699e810753259b14ef613ef34
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 07fba2b58cca8f0c0429042e4a2813d5618158cb8231625ad1e6f5c32d1bc532d45a8bb952a3087d6274862647dbab0480aca8c96561f24c5a3debf2a1f7dd63
|
|
7
|
+
data.tar.gz: 8422215bde30fa926b235b20dddbeba195573a82d1678ea98d541be6e37e6e14c7a6ae444e53b1a4505733a6420a4d9d3a53cec3605c751c5bf6eac49678ef86
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Fixed
|
|
11
|
+
- RAR recovery-record repair fails loudly instead of pretending:
|
|
12
|
+
`recover_with_reed_solomon` returned nil and `recover_with_xor`
|
|
13
|
+
applied a transform the record does not use. Neither unrar (its
|
|
14
|
+
recvol5/rs16 cover only the separate .rev volumes) nor any public
|
|
15
|
+
spec carries the in-archive RAR5 RS parameters, so both paths now
|
|
16
|
+
raise `NotImplementedError` with par2 guidance, surfaced through
|
|
17
|
+
`ArchiveRepairer` results. The `ozip repair` counterpart (Rust)
|
|
18
|
+
ships in omnizip-rs with the same honest contract.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- `rake rust:build` — one command to build and vendor the Rust
|
|
22
|
+
backend's cdylib (clones omnizip-rs or reuses a checkout via
|
|
23
|
+
REPO=); the loader gains the `vendor/` resolution tier behind
|
|
24
|
+
`OMNIZIP_FFI_DYLIB`. No toolchain, no failure: the gem stays
|
|
25
|
+
pure Ruby. docs/rust-backend.md documents the tier policy,
|
|
26
|
+
resolution order, and CI pinning.
|
|
27
|
+
|
|
28
|
+
|
|
10
29
|
### Added
|
|
11
30
|
- Rust-accelerated backend tier: `Omnizip::Backends` is the single
|
|
12
31
|
tier switch between the pure-Ruby cores and the `omnizip-ffi`
|
|
File without changes
|
|
@@ -266,10 +266,16 @@ module Omnizip
|
|
|
266
266
|
# @param parity_data [String] Parity information
|
|
267
267
|
# @return [String, nil] Recovered data
|
|
268
268
|
def recover_with_reed_solomon(_corrupted_data, _parity_data)
|
|
269
|
-
#
|
|
270
|
-
#
|
|
271
|
-
#
|
|
272
|
-
|
|
269
|
+
# The in-archive RAR5 recovery record's RS parameters exist
|
|
270
|
+
# only in the proprietary rar binary — unrar carries no
|
|
271
|
+
# implementation (its recvol5/rs16 cover only the separate
|
|
272
|
+
# .rev volume feature), and no independent spec is public.
|
|
273
|
+
# Fail loudly with actionable guidance instead of pretending
|
|
274
|
+
# recovery happened.
|
|
275
|
+
raise NotImplementedError,
|
|
276
|
+
"in-archive RAR5 Reed-Solomon recovery is not implemented " \
|
|
277
|
+
"(rar-proprietary format); protect archives with external " \
|
|
278
|
+
"parity (par2) instead"
|
|
273
279
|
end
|
|
274
280
|
|
|
275
281
|
# Recover data using XOR (RAR4)
|
|
@@ -277,14 +283,15 @@ module Omnizip
|
|
|
277
283
|
# @param corrupted_data [String] Corrupted block
|
|
278
284
|
# @param parity_data [String] Parity information
|
|
279
285
|
# @return [String] Recovered data
|
|
280
|
-
def recover_with_xor(
|
|
281
|
-
#
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
286
|
+
def recover_with_xor(_corrupted_data, _parity_data)
|
|
287
|
+
# RAR4's integrated recovery record is likewise rar-proprietary
|
|
288
|
+
# (unrar has no repair path for it either); a cyclic XOR with
|
|
289
|
+
# arbitrary parity bytes is not the record's actual transform
|
|
290
|
+
# and would silently fabricate corrupt bytes. Refuse honestly.
|
|
291
|
+
raise NotImplementedError,
|
|
292
|
+
"in-archive RAR4 recovery-record repair is not implemented " \
|
|
293
|
+
"(rar-proprietary format); protect archives with external " \
|
|
294
|
+
"parity (par2) instead"
|
|
288
295
|
end
|
|
289
296
|
end
|
|
290
297
|
end
|
data/lib/omnizip/version.rb
CHANGED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# One command to build the Rust-accelerated backend's cdylib into
|
|
4
|
+
# the gem's vendor dir (TODO.ref-parity/62 — the distribution
|
|
5
|
+
# story). Requires git + a Rust toolchain; the gem stays fully
|
|
6
|
+
# functional (pure Ruby) without ever running this.
|
|
7
|
+
#
|
|
8
|
+
# bundle exec rake rust:build
|
|
9
|
+
# bundle exec rake rust:build REPO=/path/to/omnizip-rs
|
|
10
|
+
desc "Build the omnizip-ffi cdylib into vendor/ for the Rust tier"
|
|
11
|
+
task "rust:build" do
|
|
12
|
+
repo = ENV.fetch("REPO", nil)
|
|
13
|
+
gem_root = File.expand_path("../..", __dir__)
|
|
14
|
+
build = File.join(gem_root, "build", "rust")
|
|
15
|
+
|
|
16
|
+
require "fileutils"
|
|
17
|
+
FileUtils.mkdir_p(build)
|
|
18
|
+
src = if repo
|
|
19
|
+
File.expand_path(repo)
|
|
20
|
+
else
|
|
21
|
+
target = File.join(build, "omnizip-rs")
|
|
22
|
+
if File.directory?(File.join(target, ".git"))
|
|
23
|
+
system("git", "-C", target, "fetch", "--quiet", "origin") or abort "git fetch failed in #{target}"
|
|
24
|
+
system("git", "-C", target, "reset", "--quiet", "--hard", "origin/main") or abort "git reset failed"
|
|
25
|
+
else
|
|
26
|
+
system("git", "clone", "--quiet", "--depth", "1",
|
|
27
|
+
"https://github.com/omnizip/omnizip-rs.git", target) or abort "clone failed"
|
|
28
|
+
end
|
|
29
|
+
target
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
abort "#{src} has no omnizip-ffi crate" unless File.directory?(File.join(src, "omnizip-ffi"))
|
|
33
|
+
|
|
34
|
+
system("cargo", "build", "--release", "-p", "omnizip-ffi", chdir: src) or abort "cargo build failed"
|
|
35
|
+
|
|
36
|
+
vendor = File.join(gem_root, "vendor")
|
|
37
|
+
FileUtils.mkdir_p(vendor)
|
|
38
|
+
%w[dylib so dll].each do |ext|
|
|
39
|
+
candidate = File.join(src, "target", "release", "libomnizip_ffi.#{ext}")
|
|
40
|
+
next unless File.file?(candidate)
|
|
41
|
+
|
|
42
|
+
FileUtils.cp(candidate, vendor)
|
|
43
|
+
puts "vendored: #{File.join(vendor, "libomnizip_ffi.#{ext}")}"
|
|
44
|
+
puts "tier: OMNIZIP_BACKEND=auto now uses the Rust decoders"
|
|
45
|
+
exit 0
|
|
46
|
+
end
|
|
47
|
+
abort "cdylib not found under #{src}/target/release"
|
|
48
|
+
end
|
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.4.
|
|
4
|
+
version: 0.4.2
|
|
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-09-
|
|
11
|
+
date: 2026-09-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|
|
@@ -211,6 +211,7 @@ files:
|
|
|
211
211
|
- docs/reference/index.adoc
|
|
212
212
|
- docs/resources/faq.adoc
|
|
213
213
|
- docs/resources/quick-reference.adoc
|
|
214
|
+
- docs/rust-backend.md
|
|
214
215
|
- docs/troubleshooting/index.adoc
|
|
215
216
|
- docs/xar_format.md
|
|
216
217
|
- examples/api_comparison.rb
|
|
@@ -722,6 +723,7 @@ files:
|
|
|
722
723
|
- lib/omnizip/zip/input_stream.rb
|
|
723
724
|
- lib/omnizip/zip/output_stream.rb
|
|
724
725
|
- lib/tasks/msi_test_files.rake
|
|
726
|
+
- lib/tasks/rust_backend.rake
|
|
725
727
|
- readme-docs/advanced-features.adoc
|
|
726
728
|
- readme-docs/api-usage.adoc
|
|
727
729
|
- readme-docs/architecture.adoc
|