cabriolet 0.1.0

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 (78) hide show
  1. checksums.yaml +7 -0
  2. data/ARCHITECTURE.md +799 -0
  3. data/CHANGELOG.md +44 -0
  4. data/LICENSE +29 -0
  5. data/README.adoc +1207 -0
  6. data/exe/cabriolet +6 -0
  7. data/lib/cabriolet/auto.rb +173 -0
  8. data/lib/cabriolet/binary/bitstream.rb +148 -0
  9. data/lib/cabriolet/binary/bitstream_writer.rb +180 -0
  10. data/lib/cabriolet/binary/chm_structures.rb +213 -0
  11. data/lib/cabriolet/binary/hlp_structures.rb +66 -0
  12. data/lib/cabriolet/binary/kwaj_structures.rb +74 -0
  13. data/lib/cabriolet/binary/lit_structures.rb +107 -0
  14. data/lib/cabriolet/binary/oab_structures.rb +112 -0
  15. data/lib/cabriolet/binary/structures.rb +56 -0
  16. data/lib/cabriolet/binary/szdd_structures.rb +60 -0
  17. data/lib/cabriolet/cab/compressor.rb +382 -0
  18. data/lib/cabriolet/cab/decompressor.rb +510 -0
  19. data/lib/cabriolet/cab/extractor.rb +357 -0
  20. data/lib/cabriolet/cab/parser.rb +264 -0
  21. data/lib/cabriolet/chm/compressor.rb +513 -0
  22. data/lib/cabriolet/chm/decompressor.rb +436 -0
  23. data/lib/cabriolet/chm/parser.rb +254 -0
  24. data/lib/cabriolet/cli.rb +776 -0
  25. data/lib/cabriolet/compressors/base.rb +34 -0
  26. data/lib/cabriolet/compressors/lzss.rb +250 -0
  27. data/lib/cabriolet/compressors/lzx.rb +581 -0
  28. data/lib/cabriolet/compressors/mszip.rb +315 -0
  29. data/lib/cabriolet/compressors/quantum.rb +446 -0
  30. data/lib/cabriolet/constants.rb +75 -0
  31. data/lib/cabriolet/decompressors/base.rb +39 -0
  32. data/lib/cabriolet/decompressors/lzss.rb +138 -0
  33. data/lib/cabriolet/decompressors/lzx.rb +726 -0
  34. data/lib/cabriolet/decompressors/mszip.rb +390 -0
  35. data/lib/cabriolet/decompressors/none.rb +27 -0
  36. data/lib/cabriolet/decompressors/quantum.rb +456 -0
  37. data/lib/cabriolet/errors.rb +39 -0
  38. data/lib/cabriolet/format_detector.rb +156 -0
  39. data/lib/cabriolet/hlp/compressor.rb +272 -0
  40. data/lib/cabriolet/hlp/decompressor.rb +198 -0
  41. data/lib/cabriolet/hlp/parser.rb +131 -0
  42. data/lib/cabriolet/huffman/decoder.rb +79 -0
  43. data/lib/cabriolet/huffman/encoder.rb +108 -0
  44. data/lib/cabriolet/huffman/tree.rb +138 -0
  45. data/lib/cabriolet/kwaj/compressor.rb +479 -0
  46. data/lib/cabriolet/kwaj/decompressor.rb +237 -0
  47. data/lib/cabriolet/kwaj/parser.rb +183 -0
  48. data/lib/cabriolet/lit/compressor.rb +255 -0
  49. data/lib/cabriolet/lit/decompressor.rb +250 -0
  50. data/lib/cabriolet/models/cabinet.rb +81 -0
  51. data/lib/cabriolet/models/chm_file.rb +28 -0
  52. data/lib/cabriolet/models/chm_header.rb +67 -0
  53. data/lib/cabriolet/models/chm_section.rb +38 -0
  54. data/lib/cabriolet/models/file.rb +119 -0
  55. data/lib/cabriolet/models/folder.rb +102 -0
  56. data/lib/cabriolet/models/folder_data.rb +21 -0
  57. data/lib/cabriolet/models/hlp_file.rb +45 -0
  58. data/lib/cabriolet/models/hlp_header.rb +37 -0
  59. data/lib/cabriolet/models/kwaj_header.rb +98 -0
  60. data/lib/cabriolet/models/lit_header.rb +55 -0
  61. data/lib/cabriolet/models/oab_header.rb +95 -0
  62. data/lib/cabriolet/models/szdd_header.rb +72 -0
  63. data/lib/cabriolet/modifier.rb +326 -0
  64. data/lib/cabriolet/oab/compressor.rb +353 -0
  65. data/lib/cabriolet/oab/decompressor.rb +315 -0
  66. data/lib/cabriolet/parallel.rb +333 -0
  67. data/lib/cabriolet/repairer.rb +288 -0
  68. data/lib/cabriolet/streaming.rb +221 -0
  69. data/lib/cabriolet/system/file_handle.rb +107 -0
  70. data/lib/cabriolet/system/io_system.rb +87 -0
  71. data/lib/cabriolet/system/memory_handle.rb +105 -0
  72. data/lib/cabriolet/szdd/compressor.rb +217 -0
  73. data/lib/cabriolet/szdd/decompressor.rb +184 -0
  74. data/lib/cabriolet/szdd/parser.rb +127 -0
  75. data/lib/cabriolet/validator.rb +332 -0
  76. data/lib/cabriolet/version.rb +5 -0
  77. data/lib/cabriolet.rb +104 -0
  78. metadata +157 -0
@@ -0,0 +1,332 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cabriolet
4
+ # Archive validation and integrity checking
5
+ class Validator
6
+ # Validation levels
7
+ LEVEL_QUICK = :quick # Basic structure validation
8
+ LEVEL_STANDARD = :standard # Standard validation with checksums
9
+ LEVEL_THOROUGH = :thorough # Full decompression validation
10
+
11
+ def initialize(path, level: LEVEL_STANDARD)
12
+ @path = path
13
+ @level = level
14
+ @errors = []
15
+ @warnings = []
16
+ @format = nil
17
+ end
18
+
19
+ # Validate the archive
20
+ #
21
+ # @return [ValidationReport] Validation report object
22
+ #
23
+ # @example
24
+ # validator = Cabriolet::Validator.new('archive.cab')
25
+ # report = validator.validate
26
+ # puts "Valid: #{report.valid?}"
27
+ # puts "Errors: #{report.errors}"
28
+ def validate
29
+ detect_format
30
+
31
+ case @level
32
+ when LEVEL_QUICK
33
+ validate_quick
34
+ when LEVEL_STANDARD
35
+ validate_standard
36
+ when LEVEL_THOROUGH
37
+ validate_thorough
38
+ end
39
+
40
+ ValidationReport.new(
41
+ valid: @errors.empty?,
42
+ format: @format,
43
+ level: @level,
44
+ errors: @errors,
45
+ warnings: @warnings,
46
+ path: @path,
47
+ )
48
+ end
49
+
50
+ private
51
+
52
+ def detect_format
53
+ @format = FormatDetector.detect(@path)
54
+
55
+ unless @format
56
+ @errors << "Unable to detect archive format"
57
+ return
58
+ end
59
+
60
+ @warnings << "Format detected as: #{@format}"
61
+ end
62
+
63
+ def validate_quick
64
+ return unless @format
65
+
66
+ # Basic file checks
67
+ validate_file_exists
68
+ validate_file_readable
69
+ validate_magic_bytes
70
+ end
71
+
72
+ def validate_standard
73
+ validate_quick
74
+ return unless @errors.empty?
75
+
76
+ # Structure validation
77
+ validate_structure
78
+ validate_checksums if should_validate_checksums?
79
+ end
80
+
81
+ def validate_thorough
82
+ validate_standard
83
+ return unless @errors.empty?
84
+
85
+ # Full decompression test
86
+ validate_decompression
87
+ validate_file_integrity
88
+ end
89
+
90
+ def validate_file_exists
91
+ return if File.exist?(@path)
92
+
93
+ @errors << "File does not exist: #{@path}"
94
+ end
95
+
96
+ def validate_file_readable
97
+ return if File.readable?(@path)
98
+
99
+ @errors << "File is not readable: #{@path}"
100
+ end
101
+
102
+ def validate_magic_bytes
103
+ File.open(@path, "rb") do |f|
104
+ magic = f.read(4)
105
+
106
+ expected = expected_magic_bytes(@format)
107
+ @errors << "Invalid magic bytes for #{@format} format" unless expected.any? do |m|
108
+ magic.start_with?(m)
109
+ end
110
+ end
111
+ rescue StandardError => e
112
+ @errors << "Error reading magic bytes: #{e.message}"
113
+ end
114
+
115
+ def validate_structure
116
+ parser_class = FormatDetector.format_to_parser(@format)
117
+ unless parser_class
118
+ @errors << "No parser available for format: #{@format}"
119
+ return
120
+ end
121
+
122
+ archive = parser_class.new.parse(@path)
123
+
124
+ # Format-specific structure validation
125
+ case @format
126
+ when :cab
127
+ validate_cab_structure(archive)
128
+ when :chm
129
+ validate_chm_structure(archive)
130
+ end
131
+ rescue StandardError => e
132
+ @errors << "Structure validation failed: #{e.message}"
133
+ end
134
+
135
+ def validate_cab_structure(cabinet)
136
+ # Validate CAB header
137
+ unless cabinet.respond_to?(:header)
138
+ @errors << "Missing CAB header"
139
+ return
140
+ end
141
+
142
+ header = cabinet.header
143
+
144
+ # Check version
145
+ unless header.version_major == 1 && header.version_minor >= 1
146
+ @warnings << "Unusual CAB version: #{header.version_major}.#{header.version_minor}"
147
+ end
148
+
149
+ # Check folder count
150
+ @errors << "CAB has no folders" if cabinet.folders.empty?
151
+
152
+ # Check file count
153
+ @warnings << "CAB has no files" if cabinet.files.empty?
154
+
155
+ # Validate folder indices
156
+ cabinet.files.each do |file|
157
+ @errors << "File #{file.name} references invalid folder index" if file.folder_index >= cabinet.folders.count
158
+ end
159
+ end
160
+
161
+ def validate_chm_structure(chm)
162
+ return unless chm.files.empty?
163
+
164
+ @warnings << "CHM has no files"
165
+ end
166
+
167
+ def validate_checksums
168
+ case @format
169
+ when :cab
170
+ validate_cab_checksums
171
+ end
172
+ rescue StandardError => e
173
+ @errors << "Checksum validation failed: #{e.message}"
174
+ end
175
+
176
+ def validate_cab_checksums
177
+ parser = Cabriolet::CAB::Parser.new(skip_checksum: false)
178
+ begin
179
+ parser.parse(@path)
180
+ @warnings << "All checksums valid"
181
+ rescue Cabriolet::ChecksumError => e
182
+ @errors << "Checksum error: #{e.message}"
183
+ end
184
+ end
185
+
186
+ def validate_decompression
187
+ parser_class = FormatDetector.format_to_parser(@format)
188
+ archive = parser_class.new.parse(@path)
189
+
190
+ file_count = 0
191
+ failed_count = 0
192
+
193
+ archive.files.each do |file|
194
+ file_count += 1
195
+ begin
196
+ data = file.data
197
+ if data.nil? || (file.respond_to?(:size) && data.bytesize != file.size)
198
+ @warnings << "File size mismatch: #{file.name}"
199
+ end
200
+ rescue StandardError => e
201
+ failed_count += 1
202
+ @errors << "Failed to decompress #{file.name}: #{e.message}"
203
+ end
204
+ end
205
+
206
+ if failed_count.zero?
207
+ @warnings << "All #{file_count} files decompressed successfully"
208
+ else
209
+ @errors << "#{failed_count} out of #{file_count} files failed to decompress"
210
+ end
211
+ end
212
+
213
+ def validate_file_integrity
214
+ # Additional integrity checks could be added here
215
+ # For example: path traversal detection, suspicious file names, etc.
216
+
217
+ parser_class = FormatDetector.format_to_parser(@format)
218
+ archive = parser_class.new.parse(@path)
219
+
220
+ archive.files.each do |file|
221
+ # Check for path traversal attempts
222
+ @warnings << "Suspicious path detected: #{file.name}" if file.name.include?("..") || file.name.start_with?("/")
223
+
224
+ # Check for extremely long file names
225
+ @warnings << "Unusually long filename: #{file.name[0..50]}..." if file.name.length > 255
226
+ end
227
+ end
228
+
229
+ def should_validate_checksums?
230
+ @format == :cab # Only CAB format has checksums
231
+ end
232
+
233
+ def expected_magic_bytes(format)
234
+ case format
235
+ when :cab
236
+ ["MSCF"]
237
+ when :chm
238
+ ["ITSF"]
239
+ when :hlp
240
+ ["\x3F\x5F", "\x4C\x4E"]
241
+ when :kwaj
242
+ ["KWAJ"]
243
+ when :szdd
244
+ ["SZDD", "\x88\xF0\x27\x00"]
245
+ when :lit
246
+ ["ITOLITLS"]
247
+ else
248
+ []
249
+ end
250
+ end
251
+ end
252
+
253
+ # Validation report object
254
+ class ValidationReport
255
+ attr_reader :valid, :format, :level, :errors, :warnings, :path
256
+
257
+ def initialize(valid:, format:, level:, errors:, warnings:, path:)
258
+ @valid = valid
259
+ @format = format
260
+ @level = level
261
+ @errors = errors
262
+ @warnings = warnings
263
+ @path = path
264
+ end
265
+
266
+ def valid?
267
+ @valid
268
+ end
269
+
270
+ def has_errors?
271
+ !@errors.empty?
272
+ end
273
+
274
+ def has_warnings?
275
+ !@warnings.empty?
276
+ end
277
+
278
+ def summary
279
+ status = valid? ? "VALID" : "INVALID"
280
+ "#{status} - #{@format} archive (#{@level} validation)\n" \
281
+ "Errors: #{@errors.count}, Warnings: #{@warnings.count}"
282
+ end
283
+
284
+ def detailed_report
285
+ report = ["=" * 60]
286
+ report << "Validation Report"
287
+ report << ("=" * 60)
288
+ report << "File: #{@path}"
289
+ report << "Format: #{@format}"
290
+ report << "Level: #{@level}"
291
+ report << "Status: #{valid? ? 'VALID' : 'INVALID'}"
292
+ report << ""
293
+
294
+ if has_errors?
295
+ report << "ERRORS:"
296
+ @errors.each_with_index do |error, i|
297
+ report << " #{i + 1}. #{error}"
298
+ end
299
+ report << ""
300
+ end
301
+
302
+ if has_warnings?
303
+ report << "WARNINGS:"
304
+ @warnings.each_with_index do |warning, i|
305
+ report << " #{i + 1}. #{warning}"
306
+ end
307
+ report << ""
308
+ end
309
+
310
+ report << ("=" * 60)
311
+ report.join("\n")
312
+ end
313
+
314
+ def to_h
315
+ {
316
+ valid: @valid,
317
+ format: @format,
318
+ level: @level,
319
+ path: @path,
320
+ error_count: @errors.count,
321
+ warning_count: @warnings.count,
322
+ errors: @errors,
323
+ warnings: @warnings,
324
+ }
325
+ end
326
+
327
+ def to_json(*args)
328
+ require "json"
329
+ to_h.to_json(*args)
330
+ end
331
+ end
332
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cabriolet
4
+ VERSION = "0.1.0"
5
+ end
data/lib/cabriolet.rb ADDED
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "cabriolet/version"
4
+ require_relative "cabriolet/errors"
5
+ require_relative "cabriolet/constants"
6
+
7
+ # Cabriolet is a pure Ruby library for extracting Microsoft Cabinet (.CAB) files,
8
+ # CHM (Compiled HTML Help) files, and related compression formats.
9
+ module Cabriolet
10
+ class << self
11
+ # Enable or disable verbose output
12
+ attr_accessor :verbose
13
+
14
+ # Default buffer size for I/O operations (4KB)
15
+ attr_accessor :default_buffer_size
16
+ end
17
+
18
+ self.verbose = false
19
+ self.default_buffer_size = 4096
20
+ end
21
+
22
+ # Load core components
23
+ require_relative "cabriolet/system/io_system"
24
+ require_relative "cabriolet/system/file_handle"
25
+ require_relative "cabriolet/system/memory_handle"
26
+
27
+ require_relative "cabriolet/binary/structures"
28
+ require_relative "cabriolet/binary/bitstream"
29
+ require_relative "cabriolet/binary/bitstream_writer"
30
+ require_relative "cabriolet/binary/chm_structures"
31
+ require_relative "cabriolet/binary/szdd_structures"
32
+ require_relative "cabriolet/binary/kwaj_structures"
33
+ require_relative "cabriolet/binary/hlp_structures"
34
+ require_relative "cabriolet/binary/lit_structures"
35
+ require_relative "cabriolet/binary/oab_structures"
36
+
37
+ require_relative "cabriolet/models/cabinet"
38
+ require_relative "cabriolet/models/folder"
39
+ require_relative "cabriolet/models/file"
40
+ require_relative "cabriolet/models/chm_header"
41
+ require_relative "cabriolet/models/chm_file"
42
+ require_relative "cabriolet/models/chm_section"
43
+ require_relative "cabriolet/models/szdd_header"
44
+ require_relative "cabriolet/models/kwaj_header"
45
+ require_relative "cabriolet/models/hlp_header"
46
+ require_relative "cabriolet/models/hlp_file"
47
+ require_relative "cabriolet/models/lit_header"
48
+ require_relative "cabriolet/models/oab_header"
49
+
50
+ require_relative "cabriolet/huffman/tree"
51
+ require_relative "cabriolet/huffman/decoder"
52
+ require_relative "cabriolet/huffman/encoder"
53
+
54
+ require_relative "cabriolet/decompressors/base"
55
+ require_relative "cabriolet/decompressors/none"
56
+ require_relative "cabriolet/decompressors/lzss"
57
+ require_relative "cabriolet/decompressors/mszip"
58
+ require_relative "cabriolet/decompressors/lzx"
59
+ require_relative "cabriolet/decompressors/quantum"
60
+
61
+ require_relative "cabriolet/compressors/base"
62
+ require_relative "cabriolet/compressors/lzss"
63
+ require_relative "cabriolet/compressors/mszip"
64
+ require_relative "cabriolet/compressors/lzx"
65
+ require_relative "cabriolet/compressors/quantum"
66
+
67
+ require_relative "cabriolet/cab/parser"
68
+ require_relative "cabriolet/cab/decompressor"
69
+ require_relative "cabriolet/cab/extractor"
70
+ require_relative "cabriolet/cab/compressor"
71
+
72
+ require_relative "cabriolet/chm/parser"
73
+ require_relative "cabriolet/chm/decompressor"
74
+ require_relative "cabriolet/chm/compressor"
75
+
76
+ require_relative "cabriolet/szdd/parser"
77
+ require_relative "cabriolet/szdd/decompressor"
78
+ require_relative "cabriolet/szdd/compressor"
79
+
80
+ require_relative "cabriolet/kwaj/parser"
81
+ require_relative "cabriolet/kwaj/decompressor"
82
+ require_relative "cabriolet/kwaj/compressor"
83
+
84
+ require_relative "cabriolet/hlp/parser"
85
+ require_relative "cabriolet/hlp/decompressor"
86
+ require_relative "cabriolet/hlp/compressor"
87
+
88
+ require_relative "cabriolet/lit/decompressor"
89
+ require_relative "cabriolet/lit/compressor"
90
+
91
+ require_relative "cabriolet/oab/decompressor"
92
+ require_relative "cabriolet/oab/compressor"
93
+
94
+ # Load new advanced features
95
+ require_relative "cabriolet/format_detector"
96
+ require_relative "cabriolet/auto"
97
+ require_relative "cabriolet/streaming"
98
+ require_relative "cabriolet/validator"
99
+ require_relative "cabriolet/repairer"
100
+ require_relative "cabriolet/modifier"
101
+ require_relative "cabriolet/parallel"
102
+
103
+ # Load CLI (optional, for command-line usage)
104
+ require_relative "cabriolet/cli"
metadata ADDED
@@ -0,0 +1,157 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cabriolet
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ribose Inc.
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-11-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bindata
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ description: |
42
+ Cabriolet is a pure Ruby gem for extracting Microsoft Cabinet (.CAB) files.
43
+ It supports multiple compression algorithms (MSZIP, LZX, Quantum, LZSS) and
44
+ requires no C extensions, making it portable across all Ruby platforms.
45
+ email:
46
+ - open.source@ribose.com
47
+ executables:
48
+ - cabriolet
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - ARCHITECTURE.md
53
+ - CHANGELOG.md
54
+ - LICENSE
55
+ - README.adoc
56
+ - exe/cabriolet
57
+ - lib/cabriolet.rb
58
+ - lib/cabriolet/auto.rb
59
+ - lib/cabriolet/binary/bitstream.rb
60
+ - lib/cabriolet/binary/bitstream_writer.rb
61
+ - lib/cabriolet/binary/chm_structures.rb
62
+ - lib/cabriolet/binary/hlp_structures.rb
63
+ - lib/cabriolet/binary/kwaj_structures.rb
64
+ - lib/cabriolet/binary/lit_structures.rb
65
+ - lib/cabriolet/binary/oab_structures.rb
66
+ - lib/cabriolet/binary/structures.rb
67
+ - lib/cabriolet/binary/szdd_structures.rb
68
+ - lib/cabriolet/cab/compressor.rb
69
+ - lib/cabriolet/cab/decompressor.rb
70
+ - lib/cabriolet/cab/extractor.rb
71
+ - lib/cabriolet/cab/parser.rb
72
+ - lib/cabriolet/chm/compressor.rb
73
+ - lib/cabriolet/chm/decompressor.rb
74
+ - lib/cabriolet/chm/parser.rb
75
+ - lib/cabriolet/cli.rb
76
+ - lib/cabriolet/compressors/base.rb
77
+ - lib/cabriolet/compressors/lzss.rb
78
+ - lib/cabriolet/compressors/lzx.rb
79
+ - lib/cabriolet/compressors/mszip.rb
80
+ - lib/cabriolet/compressors/quantum.rb
81
+ - lib/cabriolet/constants.rb
82
+ - lib/cabriolet/decompressors/base.rb
83
+ - lib/cabriolet/decompressors/lzss.rb
84
+ - lib/cabriolet/decompressors/lzx.rb
85
+ - lib/cabriolet/decompressors/mszip.rb
86
+ - lib/cabriolet/decompressors/none.rb
87
+ - lib/cabriolet/decompressors/quantum.rb
88
+ - lib/cabriolet/errors.rb
89
+ - lib/cabriolet/format_detector.rb
90
+ - lib/cabriolet/hlp/compressor.rb
91
+ - lib/cabriolet/hlp/decompressor.rb
92
+ - lib/cabriolet/hlp/parser.rb
93
+ - lib/cabriolet/huffman/decoder.rb
94
+ - lib/cabriolet/huffman/encoder.rb
95
+ - lib/cabriolet/huffman/tree.rb
96
+ - lib/cabriolet/kwaj/compressor.rb
97
+ - lib/cabriolet/kwaj/decompressor.rb
98
+ - lib/cabriolet/kwaj/parser.rb
99
+ - lib/cabriolet/lit/compressor.rb
100
+ - lib/cabriolet/lit/decompressor.rb
101
+ - lib/cabriolet/models/cabinet.rb
102
+ - lib/cabriolet/models/chm_file.rb
103
+ - lib/cabriolet/models/chm_header.rb
104
+ - lib/cabriolet/models/chm_section.rb
105
+ - lib/cabriolet/models/file.rb
106
+ - lib/cabriolet/models/folder.rb
107
+ - lib/cabriolet/models/folder_data.rb
108
+ - lib/cabriolet/models/hlp_file.rb
109
+ - lib/cabriolet/models/hlp_header.rb
110
+ - lib/cabriolet/models/kwaj_header.rb
111
+ - lib/cabriolet/models/lit_header.rb
112
+ - lib/cabriolet/models/oab_header.rb
113
+ - lib/cabriolet/models/szdd_header.rb
114
+ - lib/cabriolet/modifier.rb
115
+ - lib/cabriolet/oab/compressor.rb
116
+ - lib/cabriolet/oab/decompressor.rb
117
+ - lib/cabriolet/parallel.rb
118
+ - lib/cabriolet/repairer.rb
119
+ - lib/cabriolet/streaming.rb
120
+ - lib/cabriolet/system/file_handle.rb
121
+ - lib/cabriolet/system/io_system.rb
122
+ - lib/cabriolet/system/memory_handle.rb
123
+ - lib/cabriolet/szdd/compressor.rb
124
+ - lib/cabriolet/szdd/decompressor.rb
125
+ - lib/cabriolet/szdd/parser.rb
126
+ - lib/cabriolet/validator.rb
127
+ - lib/cabriolet/version.rb
128
+ homepage: https://github.com/omnizip/cabriolet
129
+ licenses:
130
+ - BSD-3-Clause
131
+ metadata:
132
+ homepage_uri: https://github.com/omnizip/cabriolet
133
+ source_code_uri: https://github.com/omnizip/cabriolet
134
+ changelog_uri: https://github.com/omnizip/cabriolet/blob/main/CHANGELOG.md
135
+ bug_tracker_uri: https://github.com/omnizip/cabriolet/issues
136
+ documentation_uri: https://rubydoc.info/gems/cabriolet
137
+ rubygems_mfa_required: 'true'
138
+ post_install_message:
139
+ rdoc_options: []
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: 2.7.0
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ requirements: []
153
+ rubygems_version: 3.5.22
154
+ signing_key:
155
+ specification_version: 4
156
+ summary: Pure Ruby implementation for extracting Microsoft Cabinet files
157
+ test_files: []