omnizip 0.4.7-arm-linux

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.
Files changed (632) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +32 -0
  4. data/.rubocop_todo.yml +293 -0
  5. data/CHANGELOG.md +1647 -0
  6. data/CONTEXT.md +68 -0
  7. data/COPYING +502 -0
  8. data/Gemfile +19 -0
  9. data/LICENSE +12 -0
  10. data/README.adoc +1327 -0
  11. data/Rakefile +15 -0
  12. data/TODO.refactor/00-overview.md +67 -0
  13. data/TODO.refactor/01-registry-base-class.md +81 -0
  14. data/TODO.refactor/02-error-hierarchy.md +57 -0
  15. data/TODO.refactor/03-autoload-entry-point.md +69 -0
  16. data/TODO.refactor/04-filter-base-consolidation.md +49 -0
  17. data/TODO.refactor/05-send-private-methods.md +64 -0
  18. data/TODO.refactor/06-instance-variable-access.md +69 -0
  19. data/TODO.refactor/07-respond-to-replacement.md +237 -0
  20. data/TODO.refactor/08-spec-doubles.md +27 -0
  21. data/TODO.refactor/09-cli-shared-module.md +35 -0
  22. data/TODO.refactor/10-format-detector-ocp.md +34 -0
  23. data/TODO.refactor/11-convenience-decoupling.md +38 -0
  24. data/TODO.refactor/12-thread-safety.md +8 -0
  25. data/TODO.refactor/13-lutaml-model-migration.md +158 -0
  26. data/TODO.refactor/14-add-missing-specs.md +25 -0
  27. data/benchmark/README.md +260 -0
  28. data/benchmark/benchmark_suite.rb +125 -0
  29. data/benchmark/compression_bench.rb +181 -0
  30. data/benchmark/filter_bench.rb +180 -0
  31. data/benchmark/models/benchmark_result.rb +59 -0
  32. data/benchmark/models/comparison_result.rb +69 -0
  33. data/benchmark/profile_suite.rb +167 -0
  34. data/benchmark/reporter.rb +150 -0
  35. data/benchmark/run_benchmarks.rb +66 -0
  36. data/benchmark/test_data.rb +137 -0
  37. data/config/formats/rar3_spec.yml +92 -0
  38. data/config/formats/rar5_spec.yml +102 -0
  39. data/docs/.github/workflows/docs.yml +142 -0
  40. data/docs/.gitignore +21 -0
  41. data/docs/.lychee.toml +67 -0
  42. data/docs/Gemfile +13 -0
  43. data/docs/RAR_WRITE_SUPPORT.md +26 -0
  44. data/docs/README.md +101 -0
  45. data/docs/_config.yml +112 -0
  46. data/docs/assets/logo.svg +1 -0
  47. data/docs/assets/omnizip-logo.pdf +1540 -11
  48. data/docs/comparison/feature-matrix.adoc +694 -0
  49. data/docs/comparison/index.adoc +113 -0
  50. data/docs/comparison/vs-7zip.adoc +309 -0
  51. data/docs/comparison/vs-peazip.adoc +77 -0
  52. data/docs/comparison/vs-rubyzip.adoc +342 -0
  53. data/docs/comparison/vs-winrar.adoc +100 -0
  54. data/docs/compatibility.adoc +579 -0
  55. data/docs/concepts/index.adoc +129 -0
  56. data/docs/developer/architecture.adoc +256 -0
  57. data/docs/developer/contributing.adoc +158 -0
  58. data/docs/developer/index.adoc +25 -0
  59. data/docs/developer/testing.adoc +212 -0
  60. data/docs/getting-started/basic-usage.adoc +263 -0
  61. data/docs/getting-started/index.adoc +42 -0
  62. data/docs/getting-started/installation.adoc +138 -0
  63. data/docs/getting-started/quick-start.adoc +183 -0
  64. data/docs/getting-started/your-first-archive.adoc +219 -0
  65. data/docs/guides/advanced-features/encryption.adoc +277 -0
  66. data/docs/guides/advanced-features/index.adoc +59 -0
  67. data/docs/guides/advanced-features/parallel-processing.adoc +144 -0
  68. data/docs/guides/advanced-features/progress-tracking.adoc +124 -0
  69. data/docs/guides/advanced-features/streaming.adoc +142 -0
  70. data/docs/guides/archive-formats/gzip-format.adoc +105 -0
  71. data/docs/guides/archive-formats/index.adoc +160 -0
  72. data/docs/guides/archive-formats/ole-format.adoc +151 -0
  73. data/docs/guides/archive-formats/rar-format.adoc +104 -0
  74. data/docs/guides/archive-formats/rar5.adoc +521 -0
  75. data/docs/guides/archive-formats/rpm-format.adoc +108 -0
  76. data/docs/guides/archive-formats/seven-zip-format.adoc +35 -0
  77. data/docs/guides/archive-formats/tar-format.adoc +106 -0
  78. data/docs/guides/archive-formats/xz-format.adoc +118 -0
  79. data/docs/guides/archive-formats/zip-format.adoc +35 -0
  80. data/docs/guides/compression-algorithms/bzip2.adoc +114 -0
  81. data/docs/guides/compression-algorithms/deflate.adoc +313 -0
  82. data/docs/guides/compression-algorithms/index.adoc +190 -0
  83. data/docs/guides/compression-algorithms/lzma.adoc +394 -0
  84. data/docs/guides/compression-algorithms/lzma2.adoc +244 -0
  85. data/docs/guides/compression-algorithms/ppmd.adoc +313 -0
  86. data/docs/guides/compression-algorithms/zstandard.adoc +296 -0
  87. data/docs/guides/creating-archives.adoc +348 -0
  88. data/docs/guides/extracting-archives.adoc +53 -0
  89. data/docs/guides/format-conversion.adoc +64 -0
  90. data/docs/guides/index.adoc +49 -0
  91. data/docs/guides/migration-rubyzip.adoc +217 -0
  92. data/docs/guides/parity-archives.adoc +605 -0
  93. data/docs/guides/performance-tuning.adoc +88 -0
  94. data/docs/index.adoc +228 -0
  95. data/docs/lychee.toml +67 -0
  96. data/docs/reference/api/overview.adoc +187 -0
  97. data/docs/reference/cli/compress-command.adoc +114 -0
  98. data/docs/reference/cli/overview.adoc +140 -0
  99. data/docs/reference/index.adoc +26 -0
  100. data/docs/resources/faq.adoc +185 -0
  101. data/docs/resources/quick-reference.adoc +222 -0
  102. data/docs/rust-backend.md +0 -0
  103. data/docs/troubleshooting/index.adoc +207 -0
  104. data/docs/xar_format.md +216 -0
  105. data/examples/api_comparison.rb +205 -0
  106. data/examples/deflate64_example.rb +96 -0
  107. data/examples/par2_demo.rb +121 -0
  108. data/examples/quick_start_native.rb +150 -0
  109. data/examples/quick_start_rubyzip.rb +115 -0
  110. data/examples/rubyzip_compatibility_demo.rb +194 -0
  111. data/exe/omnizip +27 -0
  112. data/lib/omnizip/algorithm.rb +176 -0
  113. data/lib/omnizip/algorithm_registry.rb +65 -0
  114. data/lib/omnizip/algorithms/.keep +0 -0
  115. data/lib/omnizip/algorithms/bzip2/bwt.rb +236 -0
  116. data/lib/omnizip/algorithms/bzip2/bz2.rb +687 -0
  117. data/lib/omnizip/algorithms/bzip2/rle.rb +146 -0
  118. data/lib/omnizip/algorithms/bzip2.rb +108 -0
  119. data/lib/omnizip/algorithms/deflate/constants.rb +28 -0
  120. data/lib/omnizip/algorithms/deflate/decoder.rb +37 -0
  121. data/lib/omnizip/algorithms/deflate/encoder.rb +45 -0
  122. data/lib/omnizip/algorithms/deflate.rb +135 -0
  123. data/lib/omnizip/algorithms/deflate64/constants.rb +45 -0
  124. data/lib/omnizip/algorithms/deflate64/decoder.rb +151 -0
  125. data/lib/omnizip/algorithms/deflate64/encoder.rb +95 -0
  126. data/lib/omnizip/algorithms/deflate64/huffman_coder.rb +352 -0
  127. data/lib/omnizip/algorithms/deflate64/lz77_encoder.rb +140 -0
  128. data/lib/omnizip/algorithms/deflate64.rb +118 -0
  129. data/lib/omnizip/algorithms/lzma/bit_model.rb +120 -0
  130. data/lib/omnizip/algorithms/lzma/constants.rb +112 -0
  131. data/lib/omnizip/algorithms/lzma/decoder.rb +146 -0
  132. data/lib/omnizip/algorithms/lzma/dictionary.rb +70 -0
  133. data/lib/omnizip/algorithms/lzma/distance_coder.rb +326 -0
  134. data/lib/omnizip/algorithms/lzma/encoder.rb +139 -0
  135. data/lib/omnizip/algorithms/lzma/length_coder.rb +172 -0
  136. data/lib/omnizip/algorithms/lzma/literal_decoder.rb +204 -0
  137. data/lib/omnizip/algorithms/lzma/literal_encoder.rb +208 -0
  138. data/lib/omnizip/algorithms/lzma/lzip_decoder.rb +368 -0
  139. data/lib/omnizip/algorithms/lzma/lzma1_encoder.rb +105 -0
  140. data/lib/omnizip/algorithms/lzma/lzma_alone_decoder.rb +194 -0
  141. data/lib/omnizip/algorithms/lzma/lzma_state.rb +128 -0
  142. data/lib/omnizip/algorithms/lzma/match.rb +32 -0
  143. data/lib/omnizip/algorithms/lzma/match_finder.rb +233 -0
  144. data/lib/omnizip/algorithms/lzma/match_finder_config.rb +142 -0
  145. data/lib/omnizip/algorithms/lzma/match_finder_factory.rb +84 -0
  146. data/lib/omnizip/algorithms/lzma/optimal_encoder.rb +159 -0
  147. data/lib/omnizip/algorithms/lzma/probability_models.rb +72 -0
  148. data/lib/omnizip/algorithms/lzma/range_coder.rb +82 -0
  149. data/lib/omnizip/algorithms/lzma/range_decoder.rb +274 -0
  150. data/lib/omnizip/algorithms/lzma/range_encoder.rb +202 -0
  151. data/lib/omnizip/algorithms/lzma/state.rb +127 -0
  152. data/lib/omnizip/algorithms/lzma/xz_buffered_range_encoder.rb +323 -0
  153. data/lib/omnizip/algorithms/lzma/xz_encoder.rb +420 -0
  154. data/lib/omnizip/algorithms/lzma/xz_encoder_fast.rb +640 -0
  155. data/lib/omnizip/algorithms/lzma/xz_match_finder_adapter.rb +224 -0
  156. data/lib/omnizip/algorithms/lzma/xz_price_calculator.rb +167 -0
  157. data/lib/omnizip/algorithms/lzma/xz_probability_models.rb +258 -0
  158. data/lib/omnizip/algorithms/lzma/xz_range_encoder.rb +223 -0
  159. data/lib/omnizip/algorithms/lzma/xz_range_encoder_exact.rb +314 -0
  160. data/lib/omnizip/algorithms/lzma/xz_state.rb +108 -0
  161. data/lib/omnizip/algorithms/lzma/xz_utils_decoder.rb +1311 -0
  162. data/lib/omnizip/algorithms/lzma.rb +266 -0
  163. data/lib/omnizip/algorithms/lzma2/chunk_manager.rb +180 -0
  164. data/lib/omnizip/algorithms/lzma2/constants.rb +38 -0
  165. data/lib/omnizip/algorithms/lzma2/encoder.rb +145 -0
  166. data/lib/omnizip/algorithms/lzma2/lzma2_chunk.rb +165 -0
  167. data/lib/omnizip/algorithms/lzma2/properties.rb +179 -0
  168. data/lib/omnizip/algorithms/lzma2/simple_lzma2_encoder.rb +122 -0
  169. data/lib/omnizip/algorithms/lzma2/xz_encoder_adapter.rb +85 -0
  170. data/lib/omnizip/algorithms/lzma2.rb +133 -0
  171. data/lib/omnizip/algorithms/ppmd7/constants.rb +74 -0
  172. data/lib/omnizip/algorithms/ppmd7/context.rb +151 -0
  173. data/lib/omnizip/algorithms/ppmd7/decoder.rb +127 -0
  174. data/lib/omnizip/algorithms/ppmd7/encoder.rb +153 -0
  175. data/lib/omnizip/algorithms/ppmd7/model.rb +245 -0
  176. data/lib/omnizip/algorithms/ppmd7/symbol_state.rb +57 -0
  177. data/lib/omnizip/algorithms/ppmd7.rb +146 -0
  178. data/lib/omnizip/algorithms/ppmd8/constants.rb +61 -0
  179. data/lib/omnizip/algorithms/ppmd8/context.rb +32 -0
  180. data/lib/omnizip/algorithms/ppmd8/decoder.rb +104 -0
  181. data/lib/omnizip/algorithms/ppmd8/encoder.rb +135 -0
  182. data/lib/omnizip/algorithms/ppmd8/model.rb +246 -0
  183. data/lib/omnizip/algorithms/ppmd8/restoration_method.rb +78 -0
  184. data/lib/omnizip/algorithms/ppmd8.rb +122 -0
  185. data/lib/omnizip/algorithms/ppmd_base.rb +142 -0
  186. data/lib/omnizip/algorithms/registration.rb +28 -0
  187. data/lib/omnizip/algorithms/zstandard/constants.rb +158 -0
  188. data/lib/omnizip/algorithms/zstandard/decoder.rb +249 -0
  189. data/lib/omnizip/algorithms/zstandard/dictionary.rb +73 -0
  190. data/lib/omnizip/algorithms/zstandard/encoder.rb +294 -0
  191. data/lib/omnizip/algorithms/zstandard/frame/block.rb +143 -0
  192. data/lib/omnizip/algorithms/zstandard/frame/header.rb +233 -0
  193. data/lib/omnizip/algorithms/zstandard/frame.rb +33 -0
  194. data/lib/omnizip/algorithms/zstandard/fse/bitstream.rb +183 -0
  195. data/lib/omnizip/algorithms/zstandard/fse/encoder.rb +534 -0
  196. data/lib/omnizip/algorithms/zstandard/fse/interleaved.rb +92 -0
  197. data/lib/omnizip/algorithms/zstandard/fse/table.rb +188 -0
  198. data/lib/omnizip/algorithms/zstandard/fse/table_description.rb +203 -0
  199. data/lib/omnizip/algorithms/zstandard/fse.rb +53 -0
  200. data/lib/omnizip/algorithms/zstandard/huffman.rb +276 -0
  201. data/lib/omnizip/algorithms/zstandard/huffman_encoder.rb +327 -0
  202. data/lib/omnizip/algorithms/zstandard/ldm.rb +121 -0
  203. data/lib/omnizip/algorithms/zstandard/literals.rb +241 -0
  204. data/lib/omnizip/algorithms/zstandard/literals_encoder.rb +96 -0
  205. data/lib/omnizip/algorithms/zstandard/match_finder.rb +483 -0
  206. data/lib/omnizip/algorithms/zstandard/sequences.rb +350 -0
  207. data/lib/omnizip/algorithms/zstandard/sequences_encoder.rb +333 -0
  208. data/lib/omnizip/algorithms/zstandard/xxhash.rb +159 -0
  209. data/lib/omnizip/algorithms/zstandard.rb +210 -0
  210. data/lib/omnizip/algorithms.rb +35 -0
  211. data/lib/omnizip/archive/builder.rb +48 -0
  212. data/lib/omnizip/archive/reader_session.rb +67 -0
  213. data/lib/omnizip/archive.rb +86 -0
  214. data/lib/omnizip/archive_handler.rb +82 -0
  215. data/lib/omnizip/archive_handlers/cpio_handler.rb +47 -0
  216. data/lib/omnizip/archive_handlers/iso_handler.rb +54 -0
  217. data/lib/omnizip/archive_handlers/ole_handler.rb +37 -0
  218. data/lib/omnizip/archive_handlers/rar_handler.rb +96 -0
  219. data/lib/omnizip/archive_handlers/rpm_handler.rb +45 -0
  220. data/lib/omnizip/archive_handlers/seven_zip_handler.rb +89 -0
  221. data/lib/omnizip/archive_handlers/tar_handler.rb +75 -0
  222. data/lib/omnizip/archive_handlers/xar_handler.rb +49 -0
  223. data/lib/omnizip/archive_handlers/zip_handler.rb +115 -0
  224. data/lib/omnizip/archive_handlers.rb +18 -0
  225. data/lib/omnizip/backends.rb +160 -0
  226. data/lib/omnizip/buffer/memory_archive.rb +246 -0
  227. data/lib/omnizip/buffer/memory_extractor.rb +234 -0
  228. data/lib/omnizip/buffer/seven_zip_bridge.rb +171 -0
  229. data/lib/omnizip/buffer.rb +187 -0
  230. data/lib/omnizip/checksum_registry.rb +41 -0
  231. data/lib/omnizip/checksums/crc32.rb +101 -0
  232. data/lib/omnizip/checksums/crc64.rb +102 -0
  233. data/lib/omnizip/checksums/crc_base.rb +158 -0
  234. data/lib/omnizip/checksums/registration.rb +16 -0
  235. data/lib/omnizip/checksums/verifier.rb +130 -0
  236. data/lib/omnizip/checksums.rb +11 -0
  237. data/lib/omnizip/chunked/memory_manager.rb +194 -0
  238. data/lib/omnizip/chunked/reader.rb +78 -0
  239. data/lib/omnizip/chunked/writer.rb +123 -0
  240. data/lib/omnizip/chunked.rb +123 -0
  241. data/lib/omnizip/cli/output_formatter.rb +112 -0
  242. data/lib/omnizip/cli.rb +604 -0
  243. data/lib/omnizip/commands/.keep +0 -0
  244. data/lib/omnizip/commands/archive_create_command.rb +245 -0
  245. data/lib/omnizip/commands/archive_extract_command.rb +231 -0
  246. data/lib/omnizip/commands/archive_list_command.rb +204 -0
  247. data/lib/omnizip/commands/archive_repair_command.rb +129 -0
  248. data/lib/omnizip/commands/archive_verify_command.rb +115 -0
  249. data/lib/omnizip/commands/compress_command.rb +115 -0
  250. data/lib/omnizip/commands/decompress_command.rb +149 -0
  251. data/lib/omnizip/commands/list_command.rb +51 -0
  252. data/lib/omnizip/commands/metadata_command.rb +215 -0
  253. data/lib/omnizip/commands/parity_create_command.rb +114 -0
  254. data/lib/omnizip/commands/parity_repair_command.rb +120 -0
  255. data/lib/omnizip/commands/parity_verify_command.rb +122 -0
  256. data/lib/omnizip/commands/profile_list_command.rb +54 -0
  257. data/lib/omnizip/commands/profile_show_command.rb +44 -0
  258. data/lib/omnizip/commands.rb +21 -0
  259. data/lib/omnizip/convenience.rb +389 -0
  260. data/lib/omnizip/converter/conversion_registry.rb +50 -0
  261. data/lib/omnizip/converter/conversion_strategy.rb +108 -0
  262. data/lib/omnizip/converter/extract_repack_strategy.rb +51 -0
  263. data/lib/omnizip/converter/seven_zip_to_zip_strategy.rb +43 -0
  264. data/lib/omnizip/converter/zip_to_seven_zip_strategy.rb +54 -0
  265. data/lib/omnizip/converter.rb +124 -0
  266. data/lib/omnizip/crypto/aes256/cipher.rb +104 -0
  267. data/lib/omnizip/crypto/aes256/constants.rb +28 -0
  268. data/lib/omnizip/crypto/aes256/key_derivation.rb +100 -0
  269. data/lib/omnizip/crypto/aes256.rb +102 -0
  270. data/lib/omnizip/crypto.rb +11 -0
  271. data/lib/omnizip/entry.rb +44 -0
  272. data/lib/omnizip/error.rb +110 -0
  273. data/lib/omnizip/eta/exponential_smoothing_estimator.rb +95 -0
  274. data/lib/omnizip/eta/moving_average_estimator.rb +96 -0
  275. data/lib/omnizip/eta/rate_calculator.rb +104 -0
  276. data/lib/omnizip/eta/sample_history.rb +143 -0
  277. data/lib/omnizip/eta/time_estimator.rb +106 -0
  278. data/lib/omnizip/eta.rb +68 -0
  279. data/lib/omnizip/extraction/filter_chain.rb +179 -0
  280. data/lib/omnizip/extraction/glob_pattern.rb +140 -0
  281. data/lib/omnizip/extraction/pattern_matcher.rb +66 -0
  282. data/lib/omnizip/extraction/predicate_pattern.rb +52 -0
  283. data/lib/omnizip/extraction/regex_pattern.rb +50 -0
  284. data/lib/omnizip/extraction/selective_extractor.rb +247 -0
  285. data/lib/omnizip/extraction.rb +115 -0
  286. data/lib/omnizip/file_type/mime_classifier.rb +144 -0
  287. data/lib/omnizip/file_type.rb +117 -0
  288. data/lib/omnizip/filter.rb +141 -0
  289. data/lib/omnizip/filter_pipeline.rb +108 -0
  290. data/lib/omnizip/filter_registry.rb +113 -0
  291. data/lib/omnizip/filters/bcj.rb +277 -0
  292. data/lib/omnizip/filters/bcj2/constants.rb +53 -0
  293. data/lib/omnizip/filters/bcj2/decoder.rb +263 -0
  294. data/lib/omnizip/filters/bcj2/encoder.rb +58 -0
  295. data/lib/omnizip/filters/bcj2/stream_data.rb +91 -0
  296. data/lib/omnizip/filters/bcj2.rb +93 -0
  297. data/lib/omnizip/filters/bcj_arm.rb +174 -0
  298. data/lib/omnizip/filters/bcj_arm64.rb +242 -0
  299. data/lib/omnizip/filters/bcj_ia64.rb +194 -0
  300. data/lib/omnizip/filters/bcj_ppc.rb +188 -0
  301. data/lib/omnizip/filters/bcj_sparc.rb +174 -0
  302. data/lib/omnizip/filters/bcj_x86.rb +191 -0
  303. data/lib/omnizip/filters/delta.rb +195 -0
  304. data/lib/omnizip/filters/xz_delta.rb +258 -0
  305. data/lib/omnizip/filters.rb +20 -0
  306. data/lib/omnizip/format_detector.rb +166 -0
  307. data/lib/omnizip/formats/.keep +0 -0
  308. data/lib/omnizip/formats/bzip2_file.rb +159 -0
  309. data/lib/omnizip/formats/cpio/bounded_io.rb +66 -0
  310. data/lib/omnizip/formats/cpio/constants.rb +55 -0
  311. data/lib/omnizip/formats/cpio/entry.rb +389 -0
  312. data/lib/omnizip/formats/cpio/reader.rb +194 -0
  313. data/lib/omnizip/formats/cpio/writer.rb +232 -0
  314. data/lib/omnizip/formats/cpio.rb +132 -0
  315. data/lib/omnizip/formats/format_spec_loader.rb +228 -0
  316. data/lib/omnizip/formats/gzip.rb +236 -0
  317. data/lib/omnizip/formats/iso/directory_builder.rb +321 -0
  318. data/lib/omnizip/formats/iso/directory_record.rb +162 -0
  319. data/lib/omnizip/formats/iso/joliet.rb +204 -0
  320. data/lib/omnizip/formats/iso/path_table.rb +125 -0
  321. data/lib/omnizip/formats/iso/reader.rb +194 -0
  322. data/lib/omnizip/formats/iso/rock_ridge.rb +349 -0
  323. data/lib/omnizip/formats/iso/volume_builder.rb +319 -0
  324. data/lib/omnizip/formats/iso/volume_descriptor.rb +168 -0
  325. data/lib/omnizip/formats/iso/writer.rb +543 -0
  326. data/lib/omnizip/formats/iso.rb +133 -0
  327. data/lib/omnizip/formats/lzip.rb +161 -0
  328. data/lib/omnizip/formats/lzma_alone.rb +149 -0
  329. data/lib/omnizip/formats/msi/cab_extractor.rb +181 -0
  330. data/lib/omnizip/formats/msi/constants.rb +157 -0
  331. data/lib/omnizip/formats/msi/directory_resolver.rb +188 -0
  332. data/lib/omnizip/formats/msi/entry.rb +134 -0
  333. data/lib/omnizip/formats/msi/reader.rb +301 -0
  334. data/lib/omnizip/formats/msi/string_pool.rb +246 -0
  335. data/lib/omnizip/formats/msi/table_parser.rb +244 -0
  336. data/lib/omnizip/formats/msi.rb +73 -0
  337. data/lib/omnizip/formats/ole/allocation_table.rb +263 -0
  338. data/lib/omnizip/formats/ole/constants.rb +61 -0
  339. data/lib/omnizip/formats/ole/dirent.rb +439 -0
  340. data/lib/omnizip/formats/ole/header.rb +199 -0
  341. data/lib/omnizip/formats/ole/ranges_io.rb +347 -0
  342. data/lib/omnizip/formats/ole/storage.rb +482 -0
  343. data/lib/omnizip/formats/ole/types/variant.rb +338 -0
  344. data/lib/omnizip/formats/ole.rb +143 -0
  345. data/lib/omnizip/formats/rar/archive_repairer.rb +240 -0
  346. data/lib/omnizip/formats/rar/archive_verifier.rb +192 -0
  347. data/lib/omnizip/formats/rar/block_parser.rb +282 -0
  348. data/lib/omnizip/formats/rar/compression/bit_stream.rb +180 -0
  349. data/lib/omnizip/formats/rar/compression/dispatcher.rb +210 -0
  350. data/lib/omnizip/formats/rar/compression/lz77_huffman/decoder.rb +212 -0
  351. data/lib/omnizip/formats/rar/compression/lz77_huffman/encoder.rb +154 -0
  352. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_builder.rb +217 -0
  353. data/lib/omnizip/formats/rar/compression/lz77_huffman/huffman_coder.rb +189 -0
  354. data/lib/omnizip/formats/rar/compression/lz77_huffman/match_finder.rb +135 -0
  355. data/lib/omnizip/formats/rar/compression/lz77_huffman/sliding_window.rb +165 -0
  356. data/lib/omnizip/formats/rar/compression/lz77_huffman.rb +25 -0
  357. data/lib/omnizip/formats/rar/compression/ppmd/context.rb +103 -0
  358. data/lib/omnizip/formats/rar/compression/ppmd/decoder.rb +238 -0
  359. data/lib/omnizip/formats/rar/compression/ppmd/encoder.rb +250 -0
  360. data/lib/omnizip/formats/rar/compression/ppmd.rb +16 -0
  361. data/lib/omnizip/formats/rar/compression.rb +17 -0
  362. data/lib/omnizip/formats/rar/compression_method_registry.rb +106 -0
  363. data/lib/omnizip/formats/rar/constants.rb +88 -0
  364. data/lib/omnizip/formats/rar/decompressor.rb +316 -0
  365. data/lib/omnizip/formats/rar/external_writer.rb +311 -0
  366. data/lib/omnizip/formats/rar/header.rb +209 -0
  367. data/lib/omnizip/formats/rar/license_validator.rb +111 -0
  368. data/lib/omnizip/formats/rar/models/rar_archive.rb +77 -0
  369. data/lib/omnizip/formats/rar/models/rar_entry.rb +65 -0
  370. data/lib/omnizip/formats/rar/models/rar_volume.rb +56 -0
  371. data/lib/omnizip/formats/rar/models.rb +14 -0
  372. data/lib/omnizip/formats/rar/parity_handler.rb +299 -0
  373. data/lib/omnizip/formats/rar/rar5/compression/lzma.rb +200 -0
  374. data/lib/omnizip/formats/rar/rar5/compression/lzss.rb +584 -0
  375. data/lib/omnizip/formats/rar/rar5/compression/store.rb +60 -0
  376. data/lib/omnizip/formats/rar/rar5/crc32.rb +39 -0
  377. data/lib/omnizip/formats/rar/rar5/encryption/aes256_cbc.rb +96 -0
  378. data/lib/omnizip/formats/rar/rar5/encryption/encryption_header.rb +114 -0
  379. data/lib/omnizip/formats/rar/rar5/encryption/encryption_manager.rb +162 -0
  380. data/lib/omnizip/formats/rar/rar5/encryption/key_derivation.rb +97 -0
  381. data/lib/omnizip/formats/rar/rar5/header.rb +208 -0
  382. data/lib/omnizip/formats/rar/rar5/models/encryption_options.rb +74 -0
  383. data/lib/omnizip/formats/rar/rar5/models/recovery_options.rb +63 -0
  384. data/lib/omnizip/formats/rar/rar5/models/solid_options.rb +63 -0
  385. data/lib/omnizip/formats/rar/rar5/models/volume_options.rb +74 -0
  386. data/lib/omnizip/formats/rar/rar5/multi_volume/ARCHITECTURE.md +290 -0
  387. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_manager.rb +260 -0
  388. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb +155 -0
  389. data/lib/omnizip/formats/rar/rar5/multi_volume/volume_writer.rb +176 -0
  390. data/lib/omnizip/formats/rar/rar5/solid/solid_encoder.rb +108 -0
  391. data/lib/omnizip/formats/rar/rar5/solid/solid_manager.rb +139 -0
  392. data/lib/omnizip/formats/rar/rar5/solid/solid_stream.rb +121 -0
  393. data/lib/omnizip/formats/rar/rar5/vint.rb +53 -0
  394. data/lib/omnizip/formats/rar/rar5/writer.rb +540 -0
  395. data/lib/omnizip/formats/rar/rar_format_base.rb +239 -0
  396. data/lib/omnizip/formats/rar/reader.rb +377 -0
  397. data/lib/omnizip/formats/rar/recovery_record.rb +245 -0
  398. data/lib/omnizip/formats/rar/volume_manager.rb +166 -0
  399. data/lib/omnizip/formats/rar/writer.rb +437 -0
  400. data/lib/omnizip/formats/rar.rb +193 -0
  401. data/lib/omnizip/formats/rar3/compressor.rb +71 -0
  402. data/lib/omnizip/formats/rar3/decompressor.rb +64 -0
  403. data/lib/omnizip/formats/rar3/reader.rb +107 -0
  404. data/lib/omnizip/formats/rar3/writer.rb +220 -0
  405. data/lib/omnizip/formats/rar3.rb +15 -0
  406. data/lib/omnizip/formats/rar5/compressor.rb +71 -0
  407. data/lib/omnizip/formats/rar5/decompressor.rb +64 -0
  408. data/lib/omnizip/formats/rar5/reader.rb +130 -0
  409. data/lib/omnizip/formats/rar5/writer.rb +65 -0
  410. data/lib/omnizip/formats/rar5.rb +15 -0
  411. data/lib/omnizip/formats/rpm/constants.rb +58 -0
  412. data/lib/omnizip/formats/rpm/entry.rb +106 -0
  413. data/lib/omnizip/formats/rpm/header.rb +106 -0
  414. data/lib/omnizip/formats/rpm/lead.rb +132 -0
  415. data/lib/omnizip/formats/rpm/tag.rb +228 -0
  416. data/lib/omnizip/formats/rpm/writer.rb +652 -0
  417. data/lib/omnizip/formats/rpm.rb +458 -0
  418. data/lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb +274 -0
  419. data/lib/omnizip/formats/seven_zip/coder_chain.rb +169 -0
  420. data/lib/omnizip/formats/seven_zip/constants.rb +126 -0
  421. data/lib/omnizip/formats/seven_zip/encoded_header.rb +110 -0
  422. data/lib/omnizip/formats/seven_zip/encrypted_header.rb +139 -0
  423. data/lib/omnizip/formats/seven_zip/file_collector.rb +143 -0
  424. data/lib/omnizip/formats/seven_zip/header.rb +102 -0
  425. data/lib/omnizip/formats/seven_zip/header_encryptor.rb +132 -0
  426. data/lib/omnizip/formats/seven_zip/header_writer.rb +425 -0
  427. data/lib/omnizip/formats/seven_zip/models/coder_info.rb +30 -0
  428. data/lib/omnizip/formats/seven_zip/models/file_entry.rb +65 -0
  429. data/lib/omnizip/formats/seven_zip/models/folder.rb +67 -0
  430. data/lib/omnizip/formats/seven_zip/models/stream_info.rb +42 -0
  431. data/lib/omnizip/formats/seven_zip/models.rb +20 -0
  432. data/lib/omnizip/formats/seven_zip/parser.rb +671 -0
  433. data/lib/omnizip/formats/seven_zip/reader.rb +626 -0
  434. data/lib/omnizip/formats/seven_zip/split_archive_reader.rb +611 -0
  435. data/lib/omnizip/formats/seven_zip/split_archive_writer.rb +308 -0
  436. data/lib/omnizip/formats/seven_zip/stream_compressor.rb +151 -0
  437. data/lib/omnizip/formats/seven_zip/stream_decompressor.rb +166 -0
  438. data/lib/omnizip/formats/seven_zip/writer.rb +801 -0
  439. data/lib/omnizip/formats/seven_zip.rb +179 -0
  440. data/lib/omnizip/formats/tar/constants.rb +73 -0
  441. data/lib/omnizip/formats/tar/entry.rb +98 -0
  442. data/lib/omnizip/formats/tar/header.rb +206 -0
  443. data/lib/omnizip/formats/tar/reader.rb +119 -0
  444. data/lib/omnizip/formats/tar/writer.rb +212 -0
  445. data/lib/omnizip/formats/tar.rb +74 -0
  446. data/lib/omnizip/formats/xar/constants.rb +119 -0
  447. data/lib/omnizip/formats/xar/entry.rb +268 -0
  448. data/lib/omnizip/formats/xar/header.rb +223 -0
  449. data/lib/omnizip/formats/xar/reader.rb +400 -0
  450. data/lib/omnizip/formats/xar/toc.rb +570 -0
  451. data/lib/omnizip/formats/xar/writer.rb +461 -0
  452. data/lib/omnizip/formats/xar.rb +145 -0
  453. data/lib/omnizip/formats/xz/reader.rb +121 -0
  454. data/lib/omnizip/formats/xz/writer.rb +416 -0
  455. data/lib/omnizip/formats/xz.rb +210 -0
  456. data/lib/omnizip/formats/xz_const.rb +49 -0
  457. data/lib/omnizip/formats/xz_impl/block_decoder.rb +761 -0
  458. data/lib/omnizip/formats/xz_impl/block_encoder.rb +304 -0
  459. data/lib/omnizip/formats/xz_impl/block_header.rb +210 -0
  460. data/lib/omnizip/formats/xz_impl/block_header_parser.rb +182 -0
  461. data/lib/omnizip/formats/xz_impl/index_decoder.rb +174 -0
  462. data/lib/omnizip/formats/xz_impl/index_encoder.rb +120 -0
  463. data/lib/omnizip/formats/xz_impl/stream_decoder.rb +470 -0
  464. data/lib/omnizip/formats/xz_impl/stream_encoder.rb +95 -0
  465. data/lib/omnizip/formats/xz_impl/stream_footer.rb +79 -0
  466. data/lib/omnizip/formats/xz_impl/stream_footer_parser.rb +115 -0
  467. data/lib/omnizip/formats/xz_impl/stream_header.rb +53 -0
  468. data/lib/omnizip/formats/xz_impl/stream_header_parser.rb +106 -0
  469. data/lib/omnizip/formats/xz_impl/vli.rb +128 -0
  470. data/lib/omnizip/formats/xz_impl.rb +52 -0
  471. data/lib/omnizip/formats/zip/central_directory_header.rb +223 -0
  472. data/lib/omnizip/formats/zip/constants.rb +69 -0
  473. data/lib/omnizip/formats/zip/end_of_central_directory.rb +132 -0
  474. data/lib/omnizip/formats/zip/local_file_header.rb +136 -0
  475. data/lib/omnizip/formats/zip/reader.rb +376 -0
  476. data/lib/omnizip/formats/zip/unix_extra_field.rb +153 -0
  477. data/lib/omnizip/formats/zip/writer.rb +489 -0
  478. data/lib/omnizip/formats/zip/zip64_end_of_central_directory.rb +102 -0
  479. data/lib/omnizip/formats/zip/zip64_end_of_central_directory_locator.rb +64 -0
  480. data/lib/omnizip/formats/zip/zip64_extra_field.rb +112 -0
  481. data/lib/omnizip/formats/zip.rb +50 -0
  482. data/lib/omnizip/formats.rb +29 -0
  483. data/lib/omnizip/implementations/base/lzma2_decoder_base.rb +75 -0
  484. data/lib/omnizip/implementations/base/lzma2_encoder_base.rb +128 -0
  485. data/lib/omnizip/implementations/base/lzma_decoder_base.rb +83 -0
  486. data/lib/omnizip/implementations/base/lzma_encoder_base.rb +108 -0
  487. data/lib/omnizip/implementations/base/state_machine_base.rb +182 -0
  488. data/lib/omnizip/implementations/base.rb +19 -0
  489. data/lib/omnizip/implementations/rust/archive.rb +93 -0
  490. data/lib/omnizip/implementations/rust/library.rb +221 -0
  491. data/lib/omnizip/implementations/rust.rb +26 -0
  492. data/lib/omnizip/implementations/seven_zip/lzma/decoder.rb +428 -0
  493. data/lib/omnizip/implementations/seven_zip/lzma/encoder.rb +456 -0
  494. data/lib/omnizip/implementations/seven_zip/lzma/match_finder.rb +285 -0
  495. data/lib/omnizip/implementations/seven_zip/lzma/range_decoder.rb +197 -0
  496. data/lib/omnizip/implementations/seven_zip/lzma/range_encoder.rb +194 -0
  497. data/lib/omnizip/implementations/seven_zip/lzma/state_machine.rb +139 -0
  498. data/lib/omnizip/implementations/seven_zip/lzma.rb +21 -0
  499. data/lib/omnizip/implementations/seven_zip/lzma2/encoder.rb +56 -0
  500. data/lib/omnizip/implementations/seven_zip/lzma2.rb +12 -0
  501. data/lib/omnizip/implementations/seven_zip.rb +11 -0
  502. data/lib/omnizip/implementations/xz_utils/lzma2/decoder.rb +547 -0
  503. data/lib/omnizip/implementations/xz_utils/lzma2/encoder.rb +748 -0
  504. data/lib/omnizip/implementations/xz_utils/lzma2.rb +13 -0
  505. data/lib/omnizip/implementations/xz_utils.rb +10 -0
  506. data/lib/omnizip/implementations.rb +25 -0
  507. data/lib/omnizip/io/buffered_input.rb +147 -0
  508. data/lib/omnizip/io/buffered_output.rb +106 -0
  509. data/lib/omnizip/io/source.rb +143 -0
  510. data/lib/omnizip/io/stream_manager.rb +117 -0
  511. data/lib/omnizip/io.rb +15 -0
  512. data/lib/omnizip/link_handler/hard_link.rb +79 -0
  513. data/lib/omnizip/link_handler/symbolic_link.rb +74 -0
  514. data/lib/omnizip/link_handler.rb +129 -0
  515. data/lib/omnizip/metadata/archive_metadata.rb +114 -0
  516. data/lib/omnizip/metadata/entry_metadata.rb +153 -0
  517. data/lib/omnizip/metadata/metadata_editor.rb +169 -0
  518. data/lib/omnizip/metadata/metadata_registry.rb +71 -0
  519. data/lib/omnizip/metadata/metadata_validator.rb +101 -0
  520. data/lib/omnizip/metadata.rb +58 -0
  521. data/lib/omnizip/models/.keep +0 -0
  522. data/lib/omnizip/models/algorithm_metadata.rb +41 -0
  523. data/lib/omnizip/models/attribute_apply.rb +40 -0
  524. data/lib/omnizip/models/compression_options.rb +53 -0
  525. data/lib/omnizip/models/conversion_options.rb +79 -0
  526. data/lib/omnizip/models/conversion_result.rb +141 -0
  527. data/lib/omnizip/models/eta_result.rb +45 -0
  528. data/lib/omnizip/models/extraction_rule.rb +115 -0
  529. data/lib/omnizip/models/filter_chain.rb +142 -0
  530. data/lib/omnizip/models/filter_config.rb +148 -0
  531. data/lib/omnizip/models/match_result.rb +141 -0
  532. data/lib/omnizip/models/optimization_suggestion.rb +95 -0
  533. data/lib/omnizip/models/parallel_options.rb +116 -0
  534. data/lib/omnizip/models/performance_result.rb +85 -0
  535. data/lib/omnizip/models/profile_report.rb +116 -0
  536. data/lib/omnizip/models/progress_options.rb +39 -0
  537. data/lib/omnizip/models/split_options.rb +116 -0
  538. data/lib/omnizip/optimization_registry.rb +45 -0
  539. data/lib/omnizip/parallel/engine.rb +52 -0
  540. data/lib/omnizip/parallel/job_queue.rb +209 -0
  541. data/lib/omnizip/parallel/job_scheduler.rb +225 -0
  542. data/lib/omnizip/parallel/parallel_compressor.rb +326 -0
  543. data/lib/omnizip/parallel/parallel_extractor.rb +238 -0
  544. data/lib/omnizip/parallel/thread_pool.rb +60 -0
  545. data/lib/omnizip/parallel/worker_pool.rb +227 -0
  546. data/lib/omnizip/parallel.rb +156 -0
  547. data/lib/omnizip/parity/chunked_block_processor.rb +194 -0
  548. data/lib/omnizip/parity/galois16.rb +145 -0
  549. data/lib/omnizip/parity/models/creator_packet.rb +71 -0
  550. data/lib/omnizip/parity/models/file_description_packet.rb +131 -0
  551. data/lib/omnizip/parity/models/ifsc_packet.rb +111 -0
  552. data/lib/omnizip/parity/models/main_packet.rb +126 -0
  553. data/lib/omnizip/parity/models/packet.rb +156 -0
  554. data/lib/omnizip/parity/models/packet_registry.rb +102 -0
  555. data/lib/omnizip/parity/models/recovery_slice_packet.rb +76 -0
  556. data/lib/omnizip/parity/models.rb +27 -0
  557. data/lib/omnizip/parity/par2_creator.rb +496 -0
  558. data/lib/omnizip/parity/par2_repairer.rb +409 -0
  559. data/lib/omnizip/parity/par2_verifier.rb +373 -0
  560. data/lib/omnizip/parity/par2cmdline_algorithm.rb +108 -0
  561. data/lib/omnizip/parity/par2cmdline_coefficients.rb +78 -0
  562. data/lib/omnizip/parity/reed_solomon_decoder.rb +263 -0
  563. data/lib/omnizip/parity/reed_solomon_encoder.rb +108 -0
  564. data/lib/omnizip/parity/reed_solomon_matrix.rb +339 -0
  565. data/lib/omnizip/parity.rb +207 -0
  566. data/lib/omnizip/password/encryption_registry.rb +26 -0
  567. data/lib/omnizip/password/encryption_strategy.rb +96 -0
  568. data/lib/omnizip/password/password_validator.rb +129 -0
  569. data/lib/omnizip/password/winzip_aes_strategy.rb +190 -0
  570. data/lib/omnizip/password/zip_crypto_strategy.rb +135 -0
  571. data/lib/omnizip/password.rb +88 -0
  572. data/lib/omnizip/pipe/stream_compressor.rb +124 -0
  573. data/lib/omnizip/pipe/stream_decompressor.rb +173 -0
  574. data/lib/omnizip/pipe.rb +120 -0
  575. data/lib/omnizip/platform/ntfs_streams.rb +200 -0
  576. data/lib/omnizip/platform.rb +189 -0
  577. data/lib/omnizip/profile/archive_profile.rb +36 -0
  578. data/lib/omnizip/profile/balanced_profile.rb +31 -0
  579. data/lib/omnizip/profile/binary_profile.rb +33 -0
  580. data/lib/omnizip/profile/compression_profile.rb +157 -0
  581. data/lib/omnizip/profile/custom_profile.rb +155 -0
  582. data/lib/omnizip/profile/fast_profile.rb +31 -0
  583. data/lib/omnizip/profile/maximum_profile.rb +31 -0
  584. data/lib/omnizip/profile/profile_detector.rb +108 -0
  585. data/lib/omnizip/profile/profile_registry.rb +160 -0
  586. data/lib/omnizip/profile/text_profile.rb +33 -0
  587. data/lib/omnizip/profile.rb +261 -0
  588. data/lib/omnizip/profiler/memory_profiler.rb +66 -0
  589. data/lib/omnizip/profiler/method_profiler.rb +49 -0
  590. data/lib/omnizip/profiler/report_generator.rb +158 -0
  591. data/lib/omnizip/profiler.rb +192 -0
  592. data/lib/omnizip/progress/callback_reporter.rb +34 -0
  593. data/lib/omnizip/progress/console_reporter.rb +59 -0
  594. data/lib/omnizip/progress/log_reporter.rb +89 -0
  595. data/lib/omnizip/progress/operation_progress.rb +118 -0
  596. data/lib/omnizip/progress/progress_bar.rb +156 -0
  597. data/lib/omnizip/progress/progress_reporter.rb +40 -0
  598. data/lib/omnizip/progress/progress_tracker.rb +215 -0
  599. data/lib/omnizip/progress/silent_reporter.rb +22 -0
  600. data/lib/omnizip/progress.rb +131 -0
  601. data/lib/omnizip/registry.rb +111 -0
  602. data/lib/omnizip/rubyzip_compat.rb +61 -0
  603. data/lib/omnizip/temp/safe_extract.rb +124 -0
  604. data/lib/omnizip/temp/temp_file.rb +123 -0
  605. data/lib/omnizip/temp/temp_file_pool.rb +109 -0
  606. data/lib/omnizip/temp.rb +184 -0
  607. data/lib/omnizip/version.rb +5 -0
  608. data/lib/omnizip/zip/entry.rb +160 -0
  609. data/lib/omnizip/zip/file.rb +485 -0
  610. data/lib/omnizip/zip/input_stream.rb +270 -0
  611. data/lib/omnizip/zip/output_stream.rb +320 -0
  612. data/lib/omnizip/zip.rb +23 -0
  613. data/lib/omnizip.rb +157 -0
  614. data/lib/tasks/msi_test_files.rake +66 -0
  615. data/lib/tasks/platform_gems.rake +147 -0
  616. data/lib/tasks/rust_backend.rake +48 -0
  617. data/readme-docs/advanced-features.adoc +514 -0
  618. data/readme-docs/api-usage.adoc +445 -0
  619. data/readme-docs/architecture.adoc +450 -0
  620. data/readme-docs/archive-formats.adoc +479 -0
  621. data/readme-docs/cli-usage.adoc +222 -0
  622. data/readme-docs/compression-algorithms.adoc +446 -0
  623. data/readme-docs/compression-profiles.adoc +247 -0
  624. data/readme-docs/encryption-checksums.adoc +328 -0
  625. data/readme-docs/format-converter.adoc +316 -0
  626. data/readme-docs/installation.adoc +228 -0
  627. data/readme-docs/par2-archives.adoc +608 -0
  628. data/readme-docs/performance-profiler.adoc +389 -0
  629. data/readme-docs/preprocessing-filters.adoc +280 -0
  630. data/vendor/libomnizip_ffi.so +0 -0
  631. data/xz-file-format-1.2.1.txt +1174 -0
  632. metadata +768 -0
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+
5
+ module Omnizip
6
+ module Formats
7
+ module Rar
8
+ module Rar5
9
+ module Encryption
10
+ # AES-256-CBC cipher for RAR5 encryption
11
+ #
12
+ # Wrapper around the existing Crypto::Aes256::Cipher that provides
13
+ # RAR5-specific encryption/decryption with proper key and IV handling.
14
+ #
15
+ # RAR5 uses:
16
+ # - AES-256 in CBC mode
17
+ # - PKCS#7 padding
18
+ # - Per-file IV generation
19
+ # - PBKDF2-HMAC-SHA256 key derivation
20
+ #
21
+ # @example Encrypt file data
22
+ # cipher = Aes256Cbc.new(key, iv)
23
+ # encrypted = cipher.encrypt(data)
24
+ class Aes256Cbc
25
+ # IV size (16 bytes = AES block size)
26
+ IV_SIZE = 16
27
+
28
+ # Key size (32 bytes for AES-256)
29
+ KEY_SIZE = 32
30
+
31
+ # @return [String] AES-256 key (32 bytes)
32
+ attr_reader :key
33
+
34
+ # @return [String] Initialization vector (16 bytes)
35
+ attr_reader :iv
36
+
37
+ # Initialize cipher with key and IV
38
+ #
39
+ # @param key [String] 32-byte AES-256 key
40
+ # @param iv [String] 16-byte initialization vector
41
+ # @raise [ArgumentError] If key or IV wrong size
42
+ def initialize(key, iv)
43
+ validate_key_iv(key, iv)
44
+ @key = key
45
+ @iv = iv
46
+ @cipher = Crypto::Aes256::Cipher.new(key, iv)
47
+ end
48
+
49
+ # Encrypt data
50
+ #
51
+ # @param plaintext [String] Data to encrypt
52
+ # @return [String] Encrypted data (with PKCS#7 padding)
53
+ def encrypt(plaintext)
54
+ @cipher.encrypt(plaintext)
55
+ end
56
+
57
+ # Decrypt data
58
+ #
59
+ # @param ciphertext [String] Encrypted data
60
+ # @return [String] Decrypted data (padding removed)
61
+ def decrypt(ciphertext)
62
+ @cipher.decrypt(ciphertext)
63
+ end
64
+
65
+ # Generate random IV
66
+ #
67
+ # @return [String] 16-byte random IV
68
+ def self.generate_iv
69
+ SecureRandom.random_bytes(IV_SIZE)
70
+ end
71
+
72
+ private
73
+
74
+ # Validate key and IV sizes
75
+ #
76
+ # @param key [String] Key to validate
77
+ # @param iv [String] IV to validate
78
+ # @return [void]
79
+ # @raise [ArgumentError] If key or IV wrong size
80
+ def validate_key_iv(key, iv)
81
+ if key.bytesize != KEY_SIZE
82
+ raise ArgumentError,
83
+ "Key must be #{KEY_SIZE} bytes, got #{key.bytesize}"
84
+ end
85
+
86
+ return unless iv.bytesize != IV_SIZE
87
+
88
+ raise ArgumentError,
89
+ "IV must be #{IV_SIZE} bytes, got #{iv.bytesize}"
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require "lutaml/model"
5
+ rescue LoadError, ArgumentError
6
+ # lutaml-model not available, using simple classes
7
+ end
8
+
9
+ require "base64"
10
+
11
+ module Omnizip
12
+ module Formats
13
+ module Rar
14
+ module Rar5
15
+ module Encryption
16
+ # RAR5 encryption header
17
+ #
18
+ # This model stores encryption parameters needed for password verification
19
+ # and decryption. The header is written at the beginning of encrypted
20
+ # archive sections.
21
+ #
22
+ # RAR5 encryption header contains:
23
+ # - Version (always 0 for AES-256)
24
+ # - KDF iteration count
25
+ # - Salt for key derivation
26
+ # - IV for AES-CBC
27
+ # - Check value for password verification
28
+ #
29
+ # @example Create encryption header
30
+ # header = EncryptionHeader.new(
31
+ # version: 0,
32
+ # kdf_iterations: 262_144,
33
+ # salt: salt,
34
+ # iv: iv,
35
+ # check_value: check
36
+ # )
37
+ class EncryptionHeader < Lutaml::Model::Serializable
38
+ # Encryption version (0 for AES-256)
39
+ attribute :version, :integer, default: 0
40
+
41
+ # PBKDF2 iteration count
42
+ attribute :kdf_iterations, :integer, default: 262_144
43
+
44
+ # Salt for key derivation (16 bytes, base64 encoded for serialization)
45
+ attribute :salt, :string
46
+
47
+ # Initialization vector (16 bytes, base64 encoded for serialization)
48
+ attribute :iv, :string
49
+
50
+ # Password check value (first 8 bytes of encrypted data)
51
+ # Used to verify password before full decryption
52
+ attribute :check_value, :string
53
+
54
+ # Validate header
55
+ #
56
+ # @raise [ArgumentError] If validation fails
57
+ def validate!
58
+ if version != 0
59
+ raise ArgumentError, "Only AES-256 (version 0) is supported"
60
+ end
61
+
62
+ if kdf_iterations < 65_536 || kdf_iterations > 1_048_576
63
+ raise ArgumentError,
64
+ "KDF iterations must be between 65,536 and 1,048,576"
65
+ end
66
+
67
+ # Validate salt (base64 decoded should be 16 bytes)
68
+ decoded_salt = Base64.strict_decode64(salt)
69
+ if decoded_salt.bytesize != 16
70
+ raise ArgumentError, "Salt must be 16 bytes"
71
+ end
72
+
73
+ # Validate IV (base64 decoded should be 16 bytes)
74
+ decoded_iv = Base64.strict_decode64(iv)
75
+ if decoded_iv.bytesize != 16
76
+ raise ArgumentError, "IV must be 16 bytes"
77
+ end
78
+ rescue ArgumentError => e
79
+ raise ArgumentError, "Invalid encryption header: #{e.message}"
80
+ end
81
+
82
+ # Get salt as binary
83
+ #
84
+ # @return [String] 16-byte binary salt
85
+ def salt_binary
86
+ Base64.strict_decode64(salt)
87
+ end
88
+
89
+ # Get IV as binary
90
+ #
91
+ # @return [String] 16-byte binary IV
92
+ def iv_binary
93
+ Base64.strict_decode64(iv)
94
+ end
95
+
96
+ # Set salt from binary
97
+ #
98
+ # @param binary_salt [String] 16-byte binary salt
99
+ def salt_binary=(binary_salt)
100
+ self.salt = Base64.strict_encode64(binary_salt)
101
+ end
102
+
103
+ # Set IV from binary
104
+ #
105
+ # @param binary_iv [String] 16-byte binary IV
106
+ def iv_binary=(binary_iv)
107
+ self.iv = Base64.strict_encode64(binary_iv)
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,162 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Formats
5
+ module Rar
6
+ module Rar5
7
+ module Encryption
8
+ # Encryption manager for RAR5 archives
9
+ #
10
+ # This manager coordinates the encryption process:
11
+ # 1. Generate salt and IV
12
+ # 2. Derive key from password using PBKDF2
13
+ # 3. Encrypt file data with AES-256-CBC
14
+ # 4. Create encryption header with metadata
15
+ #
16
+ # @example Encrypt file data
17
+ # manager = EncryptionManager.new("SecurePassword", kdf_iterations: 262_144)
18
+ # result = manager.encrypt_file_data(file_data)
19
+ # # result[:encrypted_data] = encrypted bytes
20
+ # # result[:header] = EncryptionHeader with salt, IV, etc.
21
+ class EncryptionManager
22
+ # @return [String] Password for encryption
23
+ attr_reader :password
24
+
25
+ # @return [Integer] PBKDF2 iteration count
26
+ attr_reader :kdf_iterations
27
+
28
+ # @return [String, nil] Optional pre-generated salt
29
+ attr_reader :salt
30
+
31
+ # @return [String, nil] Optional pre-generated IV
32
+ attr_reader :iv
33
+
34
+ # Initialize encryption manager
35
+ #
36
+ # @param password [String] Encryption password
37
+ # @param options [Hash] Options
38
+ # @option options [Integer] :kdf_iterations PBKDF2 iterations (default: 262,144)
39
+ # @option options [String] :salt Pre-generated salt (16 bytes, optional)
40
+ # @option options [String] :iv Pre-generated IV (16 bytes, optional)
41
+ def initialize(password, options = {})
42
+ @password = password
43
+ @kdf_iterations = options[:kdf_iterations] || KeyDerivation::DEFAULT_ITERATIONS
44
+ @salt = options[:salt]
45
+ @iv = options[:iv]
46
+
47
+ validate_password!
48
+ validate_iterations!
49
+ end
50
+
51
+ # Encrypt file data
52
+ #
53
+ # @param plaintext [String] File data to encrypt
54
+ # @return [Hash] Encryption result
55
+ # @option result [String] :encrypted_data Encrypted bytes
56
+ # @option result [EncryptionHeader] :header Encryption metadata
57
+ # @option result [String] :key Derived encryption key (for debugging)
58
+ def encrypt_file_data(plaintext)
59
+ # Generate or use provided salt and IV
60
+ salt = @salt || KeyDerivation.generate_salt
61
+ iv = @iv || Aes256Cbc.generate_iv
62
+
63
+ # Derive key from password
64
+ key = KeyDerivation.derive_key(@password, salt, @kdf_iterations)
65
+
66
+ # Encrypt data
67
+ cipher = Aes256Cbc.new(key, iv)
68
+ encrypted = cipher.encrypt(plaintext)
69
+
70
+ # Create encryption header
71
+ header = create_encryption_header(salt, iv)
72
+
73
+ {
74
+ encrypted_data: encrypted,
75
+ header: header,
76
+ key: key, # Include for verification if needed
77
+ }
78
+ end
79
+
80
+ # Decrypt file data
81
+ #
82
+ # @param ciphertext [String] Encrypted data
83
+ # @param header [EncryptionHeader] Encryption metadata
84
+ # @return [String] Decrypted data
85
+ # @raise [ArgumentError] If password incorrect
86
+ def decrypt_file_data(ciphertext, header)
87
+ # Extract salt and IV
88
+ salt = header.salt_binary
89
+ iv = header.iv_binary
90
+
91
+ # Derive key from password
92
+ key = KeyDerivation.derive_key(@password, salt,
93
+ header.kdf_iterations)
94
+
95
+ # Decrypt data
96
+ cipher = Aes256Cbc.new(key, iv)
97
+ cipher.decrypt(ciphertext)
98
+ rescue OpenSSL::Cipher::CipherError => e
99
+ raise ArgumentError,
100
+ "Decryption failed (wrong password?): #{e.message}"
101
+ end
102
+
103
+ # Verify password without full decryption
104
+ #
105
+ # This checks if the derived key can decrypt the check value.
106
+ # Faster than decrypting entire file.
107
+ #
108
+ # @param header [EncryptionHeader] Encryption metadata
109
+ # @return [Boolean] true if password correct
110
+ def verify_password(_header)
111
+ # For now, we'll need a small encrypted sample to verify
112
+ # This is a simplified check - full implementation would use
113
+ # the check_value field properly
114
+ true # Placeholder
115
+ rescue StandardError
116
+ false
117
+ end
118
+
119
+ private
120
+
121
+ # Create encryption header
122
+ #
123
+ # @param salt [String] 16-byte salt
124
+ # @param iv [String] 16-byte IV
125
+ # @return [EncryptionHeader] Header object
126
+ def create_encryption_header(salt, iv)
127
+ header = EncryptionHeader.new
128
+ header.version = 0 # AES-256
129
+ header.kdf_iterations = @kdf_iterations
130
+ header.salt_binary = salt
131
+ header.iv_binary = iv
132
+ header.check_value = "" # Placeholder for password check
133
+ header
134
+ end
135
+
136
+ # Validate password
137
+ #
138
+ # @raise [ArgumentError] If password invalid
139
+ def validate_password!
140
+ if @password.nil? || @password.empty?
141
+ raise ArgumentError, "Password cannot be empty"
142
+ end
143
+ end
144
+
145
+ # Validate iteration count
146
+ #
147
+ # @raise [ArgumentError] If iterations invalid
148
+ def validate_iterations!
149
+ min = KeyDerivation::MIN_ITERATIONS
150
+ max = KeyDerivation::MAX_ITERATIONS
151
+
152
+ return if @kdf_iterations.between?(min, max)
153
+
154
+ raise ArgumentError,
155
+ "KDF iterations must be between #{min} and #{max}"
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openssl"
4
+ require "securerandom"
5
+
6
+ module Omnizip
7
+ module Formats
8
+ module Rar
9
+ module Rar5
10
+ module Encryption
11
+ # RAR5 password-based key derivation
12
+ #
13
+ # RAR5 uses PBKDF2-HMAC-SHA256 for key derivation, which is more
14
+ # secure than 7-Zip's iterative SHA-256 approach.
15
+ #
16
+ # The process:
17
+ # 1. Generate random salt (16 bytes)
18
+ # 2. Apply PBKDF2-HMAC-SHA256 with configurable iterations
19
+ # 3. Derive 32-byte AES-256 key
20
+ #
21
+ # @example Derive key from password
22
+ # salt = SecureRandom.random_bytes(16)
23
+ # key = KeyDerivation.derive_key("password", salt, 262_144)
24
+ class KeyDerivation
25
+ # Default PBKDF2 iterations (262,144 = 2^18)
26
+ # This provides good security while maintaining reasonable performance
27
+ DEFAULT_ITERATIONS = 262_144
28
+
29
+ # Minimum iterations (2^16 = 65,536)
30
+ MIN_ITERATIONS = 65_536
31
+
32
+ # Maximum iterations (2^20 = 1,048,576)
33
+ MAX_ITERATIONS = 1_048_576
34
+
35
+ # Salt size (16 bytes)
36
+ SALT_SIZE = 16
37
+
38
+ # Key size (32 bytes for AES-256)
39
+ KEY_SIZE = 32
40
+
41
+ # Derive AES-256 key from password using PBKDF2-HMAC-SHA256
42
+ #
43
+ # @param password [String] User password
44
+ # @param salt [String] Random salt (16 bytes)
45
+ # @param iterations [Integer] Number of PBKDF2 iterations
46
+ # @return [String] 32-byte AES-256 key
47
+ # @raise [ArgumentError] If password empty or salt wrong size
48
+ def self.derive_key(password, salt, iterations = DEFAULT_ITERATIONS)
49
+ validate_inputs(password, salt, iterations)
50
+
51
+ # PBKDF2-HMAC-SHA256
52
+ OpenSSL::PKCS5.pbkdf2_hmac(
53
+ password,
54
+ salt,
55
+ iterations,
56
+ KEY_SIZE,
57
+ OpenSSL::Digest.new("SHA256"),
58
+ )
59
+ end
60
+
61
+ # Generate random salt
62
+ #
63
+ # @return [String] 16-byte random salt
64
+ def self.generate_salt
65
+ SecureRandom.random_bytes(SALT_SIZE)
66
+ end
67
+
68
+ # Validate key derivation inputs
69
+ #
70
+ # @param password [String] Password to validate
71
+ # @param salt [String] Salt to validate
72
+ # @param iterations [Integer] Iteration count to validate
73
+ # @return [void]
74
+ # @raise [ArgumentError] If inputs are invalid
75
+ def self.validate_inputs(password, salt, iterations)
76
+ if password.nil? || password.empty?
77
+ raise ArgumentError, "Password cannot be empty"
78
+ end
79
+
80
+ if salt.bytesize != SALT_SIZE
81
+ raise ArgumentError,
82
+ "Salt must be #{SALT_SIZE} bytes, got #{salt.bytesize}"
83
+ end
84
+
85
+ return if iterations.between?(MIN_ITERATIONS, MAX_ITERATIONS)
86
+
87
+ raise ArgumentError,
88
+ "Iterations must be between #{MIN_ITERATIONS} and #{MAX_ITERATIONS}"
89
+ end
90
+
91
+ private_class_method :validate_inputs
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,208 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omnizip
4
+ module Formats
5
+ module Rar
6
+ module Rar5
7
+ # Header types
8
+ HEADER_TYPE_MAIN = 1
9
+ HEADER_TYPE_FILE = 2
10
+ HEADER_TYPE_SERVICE = 3
11
+ HEADER_TYPE_ENCRYPTION = 4
12
+ HEADER_TYPE_END = 5
13
+
14
+ # Header flags (common)
15
+ FLAG_EXTRA_AREA = 0x0001
16
+ FLAG_DATA_AREA = 0x0002
17
+
18
+ # Base class for RAR5 headers
19
+ class Header
20
+ attr_reader :type, :flags, :extra_area, :data_area_size, :header_data
21
+
22
+ def initialize(type, flags: 0, extra_area: nil, data_area_size: nil,
23
+ header_data: "")
24
+ @type = type
25
+ @flags = flags
26
+ @flags |= FLAG_EXTRA_AREA if extra_area
27
+ @flags |= FLAG_DATA_AREA if data_area_size
28
+ @extra_area = extra_area
29
+ @data_area_size = data_area_size
30
+ @header_data = header_data
31
+ end
32
+
33
+ def encode
34
+ # Build header without CRC
35
+ header_bytes = build_header_bytes
36
+
37
+ # Calculate CRC32
38
+ crc = CRC32.calculate(header_bytes.pack("C*"))
39
+
40
+ # Prepend CRC (little-endian)
41
+ [crc].pack("V") + header_bytes.pack("C*")
42
+ end
43
+
44
+ private
45
+
46
+ def build_header_bytes
47
+ bytes = []
48
+
49
+ # Header size (placeholder - will calculate)
50
+ size_bytes = []
51
+
52
+ # Type
53
+ type_bytes = VINT.encode(@type)
54
+ size_bytes.concat(type_bytes)
55
+
56
+ # Flags
57
+ flags_bytes = VINT.encode(@flags)
58
+ size_bytes.concat(flags_bytes)
59
+
60
+ # Extra area size (if present)
61
+ if @flags.anybits?(FLAG_EXTRA_AREA)
62
+ extra_size_bytes = VINT.encode(@extra_area.bytesize)
63
+ size_bytes.concat(extra_size_bytes)
64
+ end
65
+
66
+ # Data area size (if present)
67
+ if @flags.anybits?(FLAG_DATA_AREA)
68
+ data_size_bytes = VINT.encode(@data_area_size)
69
+ size_bytes.concat(data_size_bytes)
70
+ end
71
+
72
+ # Header data
73
+ size_bytes.concat(@header_data.bytes)
74
+
75
+ # Extra area
76
+ size_bytes.concat(@extra_area.bytes) if @extra_area
77
+
78
+ # Calculate total header size (excluding CRC)
79
+ header_size = size_bytes.size
80
+ header_size_vint = VINT.encode(header_size)
81
+
82
+ # Build final header
83
+ bytes.concat(header_size_vint)
84
+ bytes.concat(size_bytes)
85
+
86
+ bytes
87
+ end
88
+ end
89
+
90
+ # Main archive header
91
+ class MainHeader < Header
92
+ # Archive flags: 0x0001 volume, 0x0002 volume number
93
+ # present, 0x0004 solid, 0x0008 recovery, 0x0010 locked
94
+ ARCHIVE_FLAG_VOLUME = 0x0001
95
+ ARCHIVE_FLAG_VOLUME_NUMBER = 0x0002
96
+
97
+ def initialize(archive_flags: 0, volume_number: nil)
98
+ data = VINT.encode(archive_flags)
99
+ if archive_flags.anybits?(ARCHIVE_FLAG_VOLUME_NUMBER)
100
+ data.concat(VINT.encode(volume_number.to_i))
101
+ end
102
+
103
+ super(HEADER_TYPE_MAIN, header_data: data.pack("C*"))
104
+ end
105
+ end
106
+
107
+ # File header
108
+ class FileHeader < Header
109
+ # File header flags. Per the RAR 5.0 spec, 0x0001 marks a
110
+ # directory entry (what this codebase once mislabeled as
111
+ # "has attributes" — attributes are an always-present field)
112
+ FILE_IS_DIRECTORY = 0x0001
113
+ FILE_HAS_MTIME = 0x0002
114
+ FILE_HAS_CRC32 = 0x0004
115
+
116
+ # Compression information field layout (RAR 5.0 spec):
117
+ # bits 0-5 algorithm version (0), bit 7 solid,
118
+ # bits 8-10 method (0=store, 1-5=LZMA), bits 11-15
119
+ # dictionary size (128 KB * 2^N).
120
+ DICT_BASE = 128 * 1024
121
+
122
+ def initialize(filename:, file_size:, compressed_size:,
123
+ compression_method: 0, dict_size: 0,
124
+ flags: 0, mtime: nil, crc32: nil,
125
+ directory: false, extra_area: nil)
126
+ # Build file flags based on what's provided
127
+ file_flags = 0
128
+ file_flags |= FILE_IS_DIRECTORY if directory
129
+ file_flags |= FILE_HAS_MTIME if mtime
130
+ file_flags |= FILE_HAS_CRC32 if crc32
131
+
132
+ # Build header data with file information
133
+ data = build_file_data(filename, file_size,
134
+ compression_method, dict_size,
135
+ file_flags, mtime, crc32,
136
+ directory: directory)
137
+ super(HEADER_TYPE_FILE, flags: flags, data_area_size: compressed_size, header_data: data, extra_area: extra_area)
138
+ end
139
+
140
+ private
141
+
142
+ def build_file_data(filename, file_size, compression_method,
143
+ dict_size, file_flags, mtime, crc32,
144
+ directory: false)
145
+ data = []
146
+
147
+ # File flags (VINT)
148
+ data.concat(VINT.encode(file_flags))
149
+
150
+ # Unpacked size (VINT)
151
+ data.concat(VINT.encode(file_size))
152
+
153
+ # Attributes (VINT) - ALWAYS present in RAR5.
154
+ # Unix host: directory mode for directory entries,
155
+ # regular-file 0o100644 otherwise.
156
+ data.concat(VINT.encode(directory ? 0o040755 : 0o100644))
157
+
158
+ # mtime (optional) - only if FILE_HAS_MTIME flag is set
159
+ # RAR5 stores mtime as Unix timestamp (seconds since epoch)
160
+ # Format: 4 bytes little-endian (NOT a VINT)
161
+ if file_flags.anybits?(FILE_HAS_MTIME) && mtime
162
+ data.concat([mtime.to_i].pack("V").bytes)
163
+ end
164
+
165
+ # Data CRC32 (optional) - only if FILE_HAS_CRC32 flag is set
166
+ # Format: 4 bytes little-endian (NOT a VINT)
167
+ if file_flags.anybits?(FILE_HAS_CRC32) && crc32
168
+ data.concat([crc32].pack("V").bytes)
169
+ end
170
+
171
+ # Compression information (VINT): version 0 in bits 0-5,
172
+ # method in bits 8-10, dictionary size in bits 11-15
173
+ # (128 KB * 2^N).
174
+ dict_bits = if dict_size.positive?
175
+ Math.log2(dict_size / DICT_BASE).round.clamp(0, 15)
176
+ else
177
+ 0
178
+ end
179
+ compression_info = (compression_method << 8) | (dict_bits << 11)
180
+ data.concat(VINT.encode(compression_info))
181
+
182
+ # Host OS (VINT) - 1 = Unix
183
+ data.concat(VINT.encode(1))
184
+
185
+ # Name length (VINT) and name
186
+ name_bytes = filename.encode("UTF-8").bytes
187
+ data.concat(VINT.encode(name_bytes.size))
188
+ data.concat(name_bytes)
189
+
190
+ data.pack("C*")
191
+ end
192
+ end
193
+
194
+ # End of archive header
195
+ class EndHeader < Header
196
+ # End of archive flags: 0x0001 volume and not the last
197
+ # volume in the set
198
+ END_FLAG_VOLUME_NEXT = 0x0001
199
+
200
+ def initialize(end_flags: 0)
201
+ super(HEADER_TYPE_END,
202
+ header_data: VINT.encode(end_flags).pack("C*"))
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
208
+ end