Browse code

Add LHA/LZH archive support

File type magic signatures chosen based on the extensions supported
by Rust delharc crate.

See: https://docs.rs/delharc/latest/delharc/

Micah Snyder authored on 2023/11/08 13:00:30
Showing 23 changed files
... ...
@@ -18,6 +18,21 @@ dependencies = [
18 18
 ]
19 19
 
20 20
 [[package]]
21
+name = "android-tzdata"
22
+version = "0.1.1"
23
+source = "registry+https://github.com/rust-lang/crates.io-index"
24
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
25
+
26
+[[package]]
27
+name = "android_system_properties"
28
+version = "0.1.5"
29
+source = "registry+https://github.com/rust-lang/crates.io-index"
30
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
31
+dependencies = [
32
+ "libc",
33
+]
34
+
35
+[[package]]
21 36
 name = "autocfg"
22 37
 version = "1.1.0"
23 38
 source = "registry+https://github.com/rust-lang/crates.io-index"
... ...
@@ -25,9 +40,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
25 25
 
26 26
 [[package]]
27 27
 name = "base64"
28
-version = "0.21.5"
28
+version = "0.21.7"
29 29
 source = "registry+https://github.com/rust-lang/crates.io-index"
30
-checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9"
30
+checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
31 31
 
32 32
 [[package]]
33 33
 name = "bindgen"
... ...
@@ -48,7 +63,7 @@ dependencies = [
48 48
  "regex",
49 49
  "rustc-hash",
50 50
  "shlex",
51
- "syn 2.0.41",
51
+ "syn 2.0.52",
52 52
  "which",
53 53
 ]
54 54
 
... ...
@@ -66,9 +81,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
66 66
 
67 67
 [[package]]
68 68
 name = "bitflags"
69
-version = "2.4.1"
69
+version = "2.4.2"
70 70
 source = "registry+https://github.com/rust-lang/crates.io-index"
71
-checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
71
+checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
72 72
 
73 73
 [[package]]
74 74
 name = "block-buffer"
... ...
@@ -80,10 +95,16 @@ dependencies = [
80 80
 ]
81 81
 
82 82
 [[package]]
83
+name = "bumpalo"
84
+version = "3.15.3"
85
+source = "registry+https://github.com/rust-lang/crates.io-index"
86
+checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b"
87
+
88
+[[package]]
83 89
 name = "bytemuck"
84
-version = "1.14.0"
90
+version = "1.14.3"
85 91
 source = "registry+https://github.com/rust-lang/crates.io-index"
86
-checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
92
+checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f"
87 93
 
88 94
 [[package]]
89 95
 name = "byteorder"
... ...
@@ -116,6 +137,12 @@ dependencies = [
116 116
 ]
117 117
 
118 118
 [[package]]
119
+name = "cc"
120
+version = "1.0.88"
121
+source = "registry+https://github.com/rust-lang/crates.io-index"
122
+checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc"
123
+
124
+[[package]]
119 125
 name = "cexpr"
120 126
 version = "0.6.0"
121 127
 source = "registry+https://github.com/rust-lang/crates.io-index"
... ...
@@ -131,12 +158,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
131 131
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
132 132
 
133 133
 [[package]]
134
+name = "chrono"
135
+version = "0.4.34"
136
+source = "registry+https://github.com/rust-lang/crates.io-index"
137
+checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b"
138
+dependencies = [
139
+ "android-tzdata",
140
+ "iana-time-zone",
141
+ "js-sys",
142
+ "num-traits",
143
+ "wasm-bindgen",
144
+ "windows-targets 0.52.4",
145
+]
146
+
147
+[[package]]
134 148
 name = "clamav_rust"
135 149
 version = "0.0.1"
136 150
 dependencies = [
137 151
  "base64",
138 152
  "bindgen",
139 153
  "cbindgen",
154
+ "delharc",
140 155
  "flate2",
141 156
  "hex",
142 157
  "hex-literal",
... ...
@@ -156,9 +198,9 @@ dependencies = [
156 156
 
157 157
 [[package]]
158 158
 name = "clang-sys"
159
-version = "1.6.1"
159
+version = "1.7.0"
160 160
 source = "registry+https://github.com/rust-lang/crates.io-index"
161
-checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
161
+checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1"
162 162
 dependencies = [
163 163
  "glob",
164 164
  "libc",
... ...
@@ -172,54 +214,53 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
172 172
 checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
173 173
 
174 174
 [[package]]
175
+name = "core-foundation-sys"
176
+version = "0.8.6"
177
+source = "registry+https://github.com/rust-lang/crates.io-index"
178
+checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
179
+
180
+[[package]]
175 181
 name = "cpufeatures"
176
-version = "0.2.11"
182
+version = "0.2.12"
177 183
 source = "registry+https://github.com/rust-lang/crates.io-index"
178
-checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0"
184
+checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
179 185
 dependencies = [
180 186
  "libc",
181 187
 ]
182 188
 
183 189
 [[package]]
184 190
 name = "crc32fast"
185
-version = "1.3.2"
191
+version = "1.4.0"
186 192
 source = "registry+https://github.com/rust-lang/crates.io-index"
187
-checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
193
+checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
188 194
 dependencies = [
189 195
  "cfg-if",
190 196
 ]
191 197
 
192 198
 [[package]]
193 199
 name = "crossbeam-deque"
194
-version = "0.8.4"
200
+version = "0.8.5"
195 201
 source = "registry+https://github.com/rust-lang/crates.io-index"
196
-checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751"
202
+checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
197 203
 dependencies = [
198
- "cfg-if",
199 204
  "crossbeam-epoch",
200 205
  "crossbeam-utils",
201 206
 ]
202 207
 
203 208
 [[package]]
204 209
 name = "crossbeam-epoch"
205
-version = "0.9.16"
210
+version = "0.9.18"
206 211
 source = "registry+https://github.com/rust-lang/crates.io-index"
207
-checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa"
212
+checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
208 213
 dependencies = [
209
- "autocfg",
210
- "cfg-if",
211 214
  "crossbeam-utils",
212
- "memoffset",
213 215
 ]
214 216
 
215 217
 [[package]]
216 218
 name = "crossbeam-utils"
217
-version = "0.8.17"
219
+version = "0.8.19"
218 220
 source = "registry+https://github.com/rust-lang/crates.io-index"
219
-checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f"
220
-dependencies = [
221
- "cfg-if",
222
-]
221
+checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
223 222
 
224 223
 [[package]]
225 224
 name = "crunchy"
... ...
@@ -238,6 +279,17 @@ dependencies = [
238 238
 ]
239 239
 
240 240
 [[package]]
241
+name = "delharc"
242
+version = "0.5.0"
243
+source = "registry+https://github.com/rust-lang/crates.io-index"
244
+checksum = "f420b1ede12094758715adaee221d93cb2af86dc499cef368ef81a23fea96029"
245
+dependencies = [
246
+ "bitflags 2.4.2",
247
+ "chrono",
248
+ "memchr",
249
+]
250
+
251
+[[package]]
241 252
 name = "digest"
242 253
 version = "0.10.7"
243 254
 source = "registry+https://github.com/rust-lang/crates.io-index"
... ...
@@ -249,9 +301,9 @@ dependencies = [
249 249
 
250 250
 [[package]]
251 251
 name = "either"
252
-version = "1.9.0"
252
+version = "1.10.0"
253 253
 source = "registry+https://github.com/rust-lang/crates.io-index"
254
-checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
254
+checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
255 255
 
256 256
 [[package]]
257 257
 name = "encoding_rs"
... ...
@@ -285,9 +337,9 @@ dependencies = [
285 285
 
286 286
 [[package]]
287 287
 name = "exr"
288
-version = "1.71.0"
288
+version = "1.72.0"
289 289
 source = "registry+https://github.com/rust-lang/crates.io-index"
290
-checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8"
290
+checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4"
291 291
 dependencies = [
292 292
  "bit_field",
293 293
  "flume",
... ...
@@ -307,9 +359,9 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
307 307
 
308 308
 [[package]]
309 309
 name = "fdeflate"
310
-version = "0.3.1"
310
+version = "0.3.4"
311 311
 source = "registry+https://github.com/rust-lang/crates.io-index"
312
-checksum = "64d6dafc854908ff5da46ff3f8f473c6984119a2876a383a860246dd7841a868"
312
+checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645"
313 313
 dependencies = [
314 314
  "simd-adler32",
315 315
 ]
... ...
@@ -345,9 +397,9 @@ dependencies = [
345 345
 
346 346
 [[package]]
347 347
 name = "gif"
348
-version = "0.12.0"
348
+version = "0.13.1"
349 349
 source = "registry+https://github.com/rust-lang/crates.io-index"
350
-checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045"
350
+checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2"
351 351
 dependencies = [
352 352
  "color_quant",
353 353
  "weezl",
... ...
@@ -361,10 +413,11 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
361 361
 
362 362
 [[package]]
363 363
 name = "half"
364
-version = "2.2.1"
364
+version = "2.4.0"
365 365
 source = "registry+https://github.com/rust-lang/crates.io-index"
366
-checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0"
366
+checksum = "b5eceaaeec696539ddaf7b333340f1af35a5aa87ae3e4f3ead0532f72affab2e"
367 367
 dependencies = [
368
+ "cfg-if",
368 369
  "crunchy",
369 370
 ]
370 371
 
... ...
@@ -394,18 +447,41 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46"
394 394
 
395 395
 [[package]]
396 396
 name = "home"
397
-version = "0.5.5"
397
+version = "0.5.9"
398 398
 source = "registry+https://github.com/rust-lang/crates.io-index"
399
-checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
399
+checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
400 400
 dependencies = [
401
- "windows-sys 0.48.0",
401
+ "windows-sys 0.52.0",
402
+]
403
+
404
+[[package]]
405
+name = "iana-time-zone"
406
+version = "0.1.60"
407
+source = "registry+https://github.com/rust-lang/crates.io-index"
408
+checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
409
+dependencies = [
410
+ "android_system_properties",
411
+ "core-foundation-sys",
412
+ "iana-time-zone-haiku",
413
+ "js-sys",
414
+ "wasm-bindgen",
415
+ "windows-core",
416
+]
417
+
418
+[[package]]
419
+name = "iana-time-zone-haiku"
420
+version = "0.1.2"
421
+source = "registry+https://github.com/rust-lang/crates.io-index"
422
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
423
+dependencies = [
424
+ "cc",
402 425
 ]
403 426
 
404 427
 [[package]]
405 428
 name = "image"
406
-version = "0.24.7"
429
+version = "0.24.9"
407 430
 source = "registry+https://github.com/rust-lang/crates.io-index"
408
-checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711"
431
+checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
409 432
 dependencies = [
410 433
  "bytemuck",
411 434
  "byteorder",
... ...
@@ -413,7 +489,6 @@ dependencies = [
413 413
  "exr",
414 414
  "gif",
415 415
  "jpeg-decoder",
416
- "num-rational",
417 416
  "num-traits",
418 417
  "png",
419 418
  "qoi",
... ...
@@ -447,14 +522,23 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
447 447
 
448 448
 [[package]]
449 449
 name = "jpeg-decoder"
450
-version = "0.3.0"
450
+version = "0.3.1"
451 451
 source = "registry+https://github.com/rust-lang/crates.io-index"
452
-checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e"
452
+checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0"
453 453
 dependencies = [
454 454
  "rayon",
455 455
 ]
456 456
 
457 457
 [[package]]
458
+name = "js-sys"
459
+version = "0.3.68"
460
+source = "registry+https://github.com/rust-lang/crates.io-index"
461
+checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee"
462
+dependencies = [
463
+ "wasm-bindgen",
464
+]
465
+
466
+[[package]]
458 467
 name = "lazy_static"
459 468
 version = "1.4.0"
460 469
 source = "registry+https://github.com/rust-lang/crates.io-index"
... ...
@@ -474,25 +558,25 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
474 474
 
475 475
 [[package]]
476 476
 name = "libc"
477
-version = "0.2.151"
477
+version = "0.2.153"
478 478
 source = "registry+https://github.com/rust-lang/crates.io-index"
479
-checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
479
+checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
480 480
 
481 481
 [[package]]
482 482
 name = "libloading"
483
-version = "0.7.4"
483
+version = "0.8.1"
484 484
 source = "registry+https://github.com/rust-lang/crates.io-index"
485
-checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
485
+checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161"
486 486
 dependencies = [
487 487
  "cfg-if",
488
- "winapi",
488
+ "windows-sys 0.48.0",
489 489
 ]
490 490
 
491 491
 [[package]]
492 492
 name = "linux-raw-sys"
493
-version = "0.4.12"
493
+version = "0.4.13"
494 494
 source = "registry+https://github.com/rust-lang/crates.io-index"
495
-checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
495
+checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
496 496
 
497 497
 [[package]]
498 498
 name = "lock_api"
... ...
@@ -506,24 +590,15 @@ dependencies = [
506 506
 
507 507
 [[package]]
508 508
 name = "log"
509
-version = "0.4.20"
509
+version = "0.4.21"
510 510
 source = "registry+https://github.com/rust-lang/crates.io-index"
511
-checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
511
+checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
512 512
 
513 513
 [[package]]
514 514
 name = "memchr"
515
-version = "2.6.4"
516
-source = "registry+https://github.com/rust-lang/crates.io-index"
517
-checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
518
-
519
-[[package]]
520
-name = "memoffset"
521
-version = "0.9.0"
515
+version = "2.7.1"
522 516
 source = "registry+https://github.com/rust-lang/crates.io-index"
523
-checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
524
-dependencies = [
525
- "autocfg",
526
-]
517
+checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
527 518
 
528 519
 [[package]]
529 520
 name = "minimal-lexical"
... ...
@@ -533,9 +608,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
533 533
 
534 534
 [[package]]
535 535
 name = "miniz_oxide"
536
-version = "0.7.1"
536
+version = "0.7.2"
537 537
 source = "registry+https://github.com/rust-lang/crates.io-index"
538
-checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
538
+checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
539 539
 dependencies = [
540 540
  "adler",
541 541
  "simd-adler32",
... ...
@@ -553,39 +628,27 @@ dependencies = [
553 553
 
554 554
 [[package]]
555 555
 name = "num-complex"
556
-version = "0.4.4"
556
+version = "0.4.5"
557 557
 source = "registry+https://github.com/rust-lang/crates.io-index"
558
-checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214"
558
+checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6"
559 559
 dependencies = [
560 560
  "num-traits",
561 561
 ]
562 562
 
563 563
 [[package]]
564 564
 name = "num-integer"
565
-version = "0.1.45"
565
+version = "0.1.46"
566 566
 source = "registry+https://github.com/rust-lang/crates.io-index"
567
-checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
567
+checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
568 568
 dependencies = [
569
- "autocfg",
570
- "num-traits",
571
-]
572
-
573
-[[package]]
574
-name = "num-rational"
575
-version = "0.4.1"
576
-source = "registry+https://github.com/rust-lang/crates.io-index"
577
-checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
578
-dependencies = [
579
- "autocfg",
580
- "num-integer",
581 569
  "num-traits",
582 570
 ]
583 571
 
584 572
 [[package]]
585 573
 name = "num-traits"
586
-version = "0.2.17"
574
+version = "0.2.18"
587 575
 source = "registry+https://github.com/rust-lang/crates.io-index"
588
-checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
576
+checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
589 577
 dependencies = [
590 578
  "autocfg",
591 579
 ]
... ...
@@ -626,9 +689,9 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
626 626
 
627 627
 [[package]]
628 628
 name = "png"
629
-version = "0.17.10"
629
+version = "0.17.13"
630 630
 source = "registry+https://github.com/rust-lang/crates.io-index"
631
-checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64"
631
+checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1"
632 632
 dependencies = [
633 633
  "bitflags 1.3.2",
634 634
  "crc32fast",
... ...
@@ -639,12 +702,12 @@ dependencies = [
639 639
 
640 640
 [[package]]
641 641
 name = "prettyplease"
642
-version = "0.2.15"
642
+version = "0.2.16"
643 643
 source = "registry+https://github.com/rust-lang/crates.io-index"
644
-checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d"
644
+checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5"
645 645
 dependencies = [
646 646
  "proc-macro2",
647
- "syn 2.0.41",
647
+ "syn 2.0.52",
648 648
 ]
649 649
 
650 650
 [[package]]
... ...
@@ -658,9 +721,9 @@ dependencies = [
658 658
 
659 659
 [[package]]
660 660
 name = "proc-macro2"
661
-version = "1.0.70"
661
+version = "1.0.78"
662 662
 source = "registry+https://github.com/rust-lang/crates.io-index"
663
-checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
663
+checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
664 664
 dependencies = [
665 665
  "unicode-ident",
666 666
 ]
... ...
@@ -676,18 +739,18 @@ dependencies = [
676 676
 
677 677
 [[package]]
678 678
 name = "quote"
679
-version = "1.0.33"
679
+version = "1.0.35"
680 680
 source = "registry+https://github.com/rust-lang/crates.io-index"
681
-checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
681
+checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
682 682
 dependencies = [
683 683
  "proc-macro2",
684 684
 ]
685 685
 
686 686
 [[package]]
687 687
 name = "rayon"
688
-version = "1.8.0"
688
+version = "1.9.0"
689 689
 source = "registry+https://github.com/rust-lang/crates.io-index"
690
-checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1"
690
+checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd"
691 691
 dependencies = [
692 692
  "either",
693 693
  "rayon-core",
... ...
@@ -695,28 +758,19 @@ dependencies = [
695 695
 
696 696
 [[package]]
697 697
 name = "rayon-core"
698
-version = "1.12.0"
698
+version = "1.12.1"
699 699
 source = "registry+https://github.com/rust-lang/crates.io-index"
700
-checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
700
+checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
701 701
 dependencies = [
702 702
  "crossbeam-deque",
703 703
  "crossbeam-utils",
704 704
 ]
705 705
 
706 706
 [[package]]
707
-name = "redox_syscall"
708
-version = "0.4.1"
709
-source = "registry+https://github.com/rust-lang/crates.io-index"
710
-checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
711
-dependencies = [
712
- "bitflags 1.3.2",
713
-]
714
-
715
-[[package]]
716 707
 name = "regex"
717
-version = "1.10.2"
708
+version = "1.10.3"
718 709
 source = "registry+https://github.com/rust-lang/crates.io-index"
719
-checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
710
+checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
720 711
 dependencies = [
721 712
  "aho-corasick",
722 713
  "memchr",
... ...
@@ -726,9 +780,9 @@ dependencies = [
726 726
 
727 727
 [[package]]
728 728
 name = "regex-automata"
729
-version = "0.4.3"
729
+version = "0.4.5"
730 730
 source = "registry+https://github.com/rust-lang/crates.io-index"
731
-checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
731
+checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
732 732
 dependencies = [
733 733
  "aho-corasick",
734 734
  "memchr",
... ...
@@ -758,9 +812,9 @@ dependencies = [
758 758
 
759 759
 [[package]]
760 760
 name = "rustfft"
761
-version = "6.1.0"
761
+version = "6.2.0"
762 762
 source = "registry+https://github.com/rust-lang/crates.io-index"
763
-checksum = "e17d4f6cbdb180c9f4b2a26bbf01c4e647f1e1dea22fe8eb9db54198b32f9434"
763
+checksum = "43806561bc506d0c5d160643ad742e3161049ac01027b5e6d7524091fd401d86"
764 764
 dependencies = [
765 765
  "num-complex",
766 766
  "num-integer",
... ...
@@ -773,11 +827,11 @@ dependencies = [
773 773
 
774 774
 [[package]]
775 775
 name = "rustix"
776
-version = "0.38.28"
776
+version = "0.38.31"
777 777
 source = "registry+https://github.com/rust-lang/crates.io-index"
778
-checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
778
+checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
779 779
 dependencies = [
780
- "bitflags 2.4.1",
780
+ "bitflags 2.4.2",
781 781
  "errno",
782 782
  "libc",
783 783
  "linux-raw-sys",
... ...
@@ -786,9 +840,9 @@ dependencies = [
786 786
 
787 787
 [[package]]
788 788
 name = "ryu"
789
-version = "1.0.16"
789
+version = "1.0.17"
790 790
 source = "registry+https://github.com/rust-lang/crates.io-index"
791
-checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
791
+checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
792 792
 
793 793
 [[package]]
794 794
 name = "scopeguard"
... ...
@@ -798,29 +852,29 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
798 798
 
799 799
 [[package]]
800 800
 name = "serde"
801
-version = "1.0.193"
801
+version = "1.0.197"
802 802
 source = "registry+https://github.com/rust-lang/crates.io-index"
803
-checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
803
+checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
804 804
 dependencies = [
805 805
  "serde_derive",
806 806
 ]
807 807
 
808 808
 [[package]]
809 809
 name = "serde_derive"
810
-version = "1.0.193"
810
+version = "1.0.197"
811 811
 source = "registry+https://github.com/rust-lang/crates.io-index"
812
-checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
812
+checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
813 813
 dependencies = [
814 814
  "proc-macro2",
815 815
  "quote",
816
- "syn 2.0.41",
816
+ "syn 2.0.52",
817 817
 ]
818 818
 
819 819
 [[package]]
820 820
 name = "serde_json"
821
-version = "1.0.108"
821
+version = "1.0.114"
822 822
 source = "registry+https://github.com/rust-lang/crates.io-index"
823
-checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
823
+checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
824 824
 dependencies = [
825 825
  "itoa",
826 826
  "ryu",
... ...
@@ -863,9 +917,9 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
863 863
 
864 864
 [[package]]
865 865
 name = "smallvec"
866
-version = "1.11.2"
866
+version = "1.13.1"
867 867
 source = "registry+https://github.com/rust-lang/crates.io-index"
868
-checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
868
+checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
869 869
 
870 870
 [[package]]
871 871
 name = "spin"
... ...
@@ -895,9 +949,9 @@ dependencies = [
895 895
 
896 896
 [[package]]
897 897
 name = "syn"
898
-version = "2.0.41"
898
+version = "2.0.52"
899 899
 source = "registry+https://github.com/rust-lang/crates.io-index"
900
-checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
900
+checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
901 901
 dependencies = [
902 902
  "proc-macro2",
903 903
  "quote",
... ...
@@ -906,42 +960,41 @@ dependencies = [
906 906
 
907 907
 [[package]]
908 908
 name = "tempfile"
909
-version = "3.8.1"
909
+version = "3.10.1"
910 910
 source = "registry+https://github.com/rust-lang/crates.io-index"
911
-checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5"
911
+checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
912 912
 dependencies = [
913 913
  "cfg-if",
914 914
  "fastrand",
915
- "redox_syscall",
916 915
  "rustix",
917
- "windows-sys 0.48.0",
916
+ "windows-sys 0.52.0",
918 917
 ]
919 918
 
920 919
 [[package]]
921 920
 name = "thiserror"
922
-version = "1.0.50"
921
+version = "1.0.57"
923 922
 source = "registry+https://github.com/rust-lang/crates.io-index"
924
-checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
923
+checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
925 924
 dependencies = [
926 925
  "thiserror-impl",
927 926
 ]
928 927
 
929 928
 [[package]]
930 929
 name = "thiserror-impl"
931
-version = "1.0.50"
930
+version = "1.0.57"
932 931
 source = "registry+https://github.com/rust-lang/crates.io-index"
933
-checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
932
+checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
934 933
 dependencies = [
935 934
  "proc-macro2",
936 935
  "quote",
937
- "syn 2.0.41",
936
+ "syn 2.0.52",
938 937
 ]
939 938
 
940 939
 [[package]]
941 940
 name = "tiff"
942
-version = "0.9.0"
941
+version = "0.9.1"
943 942
 source = "registry+https://github.com/rust-lang/crates.io-index"
944
-checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211"
943
+checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e"
945 944
 dependencies = [
946 945
  "flate2",
947 946
  "jpeg-decoder",
... ...
@@ -959,9 +1012,9 @@ dependencies = [
959 959
 
960 960
 [[package]]
961 961
 name = "transpose"
962
-version = "0.2.2"
962
+version = "0.2.3"
963 963
 source = "registry+https://github.com/rust-lang/crates.io-index"
964
-checksum = "e6522d49d03727ffb138ae4cbc1283d3774f0d10aa7f9bf52e6784c45daf9b23"
964
+checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e"
965 965
 dependencies = [
966 966
  "num-integer",
967 967
  "strength_reduce",
... ...
@@ -981,15 +1034,15 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
981 981
 
982 982
 [[package]]
983 983
 name = "unicode-segmentation"
984
-version = "1.10.1"
984
+version = "1.11.0"
985 985
 source = "registry+https://github.com/rust-lang/crates.io-index"
986
-checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
986
+checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
987 987
 
988 988
 [[package]]
989 989
 name = "uuid"
990
-version = "1.6.1"
990
+version = "1.7.0"
991 991
 source = "registry+https://github.com/rust-lang/crates.io-index"
992
-checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560"
992
+checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
993 993
 
994 994
 [[package]]
995 995
 name = "version_check"
... ...
@@ -998,10 +1051,64 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
998 998
 checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
999 999
 
1000 1000
 [[package]]
1001
+name = "wasm-bindgen"
1002
+version = "0.2.91"
1003
+source = "registry+https://github.com/rust-lang/crates.io-index"
1004
+checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f"
1005
+dependencies = [
1006
+ "cfg-if",
1007
+ "wasm-bindgen-macro",
1008
+]
1009
+
1010
+[[package]]
1011
+name = "wasm-bindgen-backend"
1012
+version = "0.2.91"
1013
+source = "registry+https://github.com/rust-lang/crates.io-index"
1014
+checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b"
1015
+dependencies = [
1016
+ "bumpalo",
1017
+ "log",
1018
+ "once_cell",
1019
+ "proc-macro2",
1020
+ "quote",
1021
+ "syn 2.0.52",
1022
+ "wasm-bindgen-shared",
1023
+]
1024
+
1025
+[[package]]
1026
+name = "wasm-bindgen-macro"
1027
+version = "0.2.91"
1028
+source = "registry+https://github.com/rust-lang/crates.io-index"
1029
+checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed"
1030
+dependencies = [
1031
+ "quote",
1032
+ "wasm-bindgen-macro-support",
1033
+]
1034
+
1035
+[[package]]
1036
+name = "wasm-bindgen-macro-support"
1037
+version = "0.2.91"
1038
+source = "registry+https://github.com/rust-lang/crates.io-index"
1039
+checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
1040
+dependencies = [
1041
+ "proc-macro2",
1042
+ "quote",
1043
+ "syn 2.0.52",
1044
+ "wasm-bindgen-backend",
1045
+ "wasm-bindgen-shared",
1046
+]
1047
+
1048
+[[package]]
1049
+name = "wasm-bindgen-shared"
1050
+version = "0.2.91"
1051
+source = "registry+https://github.com/rust-lang/crates.io-index"
1052
+checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838"
1053
+
1054
+[[package]]
1001 1055
 name = "weezl"
1002
-version = "0.1.7"
1056
+version = "0.1.8"
1003 1057
 source = "registry+https://github.com/rust-lang/crates.io-index"
1004
-checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
1058
+checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
1005 1059
 
1006 1060
 [[package]]
1007 1061
 name = "which"
... ...
@@ -1022,28 +1129,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1022 1022
 checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8"
1023 1023
 
1024 1024
 [[package]]
1025
-name = "winapi"
1026
-version = "0.3.9"
1025
+name = "windows-core"
1026
+version = "0.52.0"
1027 1027
 source = "registry+https://github.com/rust-lang/crates.io-index"
1028
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
1028
+checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
1029 1029
 dependencies = [
1030
- "winapi-i686-pc-windows-gnu",
1031
- "winapi-x86_64-pc-windows-gnu",
1030
+ "windows-targets 0.52.4",
1032 1031
 ]
1033 1032
 
1034 1033
 [[package]]
1035
-name = "winapi-i686-pc-windows-gnu"
1036
-version = "0.4.0"
1037
-source = "registry+https://github.com/rust-lang/crates.io-index"
1038
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
1039
-
1040
-[[package]]
1041
-name = "winapi-x86_64-pc-windows-gnu"
1042
-version = "0.4.0"
1043
-source = "registry+https://github.com/rust-lang/crates.io-index"
1044
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1045
-
1046
-[[package]]
1047 1034
 name = "windows-sys"
1048 1035
 version = "0.48.0"
1049 1036
 source = "registry+https://github.com/rust-lang/crates.io-index"
... ...
@@ -1058,7 +1152,7 @@ version = "0.52.0"
1058 1058
 source = "registry+https://github.com/rust-lang/crates.io-index"
1059 1059
 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
1060 1060
 dependencies = [
1061
- "windows-targets 0.52.0",
1061
+ "windows-targets 0.52.4",
1062 1062
 ]
1063 1063
 
1064 1064
 [[package]]
... ...
@@ -1078,17 +1172,17 @@ dependencies = [
1078 1078
 
1079 1079
 [[package]]
1080 1080
 name = "windows-targets"
1081
-version = "0.52.0"
1081
+version = "0.52.4"
1082 1082
 source = "registry+https://github.com/rust-lang/crates.io-index"
1083
-checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
1083
+checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
1084 1084
 dependencies = [
1085
- "windows_aarch64_gnullvm 0.52.0",
1086
- "windows_aarch64_msvc 0.52.0",
1087
- "windows_i686_gnu 0.52.0",
1088
- "windows_i686_msvc 0.52.0",
1089
- "windows_x86_64_gnu 0.52.0",
1090
- "windows_x86_64_gnullvm 0.52.0",
1091
- "windows_x86_64_msvc 0.52.0",
1085
+ "windows_aarch64_gnullvm 0.52.4",
1086
+ "windows_aarch64_msvc 0.52.4",
1087
+ "windows_i686_gnu 0.52.4",
1088
+ "windows_i686_msvc 0.52.4",
1089
+ "windows_x86_64_gnu 0.52.4",
1090
+ "windows_x86_64_gnullvm 0.52.4",
1091
+ "windows_x86_64_msvc 0.52.4",
1092 1092
 ]
1093 1093
 
1094 1094
 [[package]]
... ...
@@ -1099,9 +1193,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
1099 1099
 
1100 1100
 [[package]]
1101 1101
 name = "windows_aarch64_gnullvm"
1102
-version = "0.52.0"
1102
+version = "0.52.4"
1103 1103
 source = "registry+https://github.com/rust-lang/crates.io-index"
1104
-checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
1104
+checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
1105 1105
 
1106 1106
 [[package]]
1107 1107
 name = "windows_aarch64_msvc"
... ...
@@ -1111,9 +1205,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
1111 1111
 
1112 1112
 [[package]]
1113 1113
 name = "windows_aarch64_msvc"
1114
-version = "0.52.0"
1114
+version = "0.52.4"
1115 1115
 source = "registry+https://github.com/rust-lang/crates.io-index"
1116
-checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
1116
+checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
1117 1117
 
1118 1118
 [[package]]
1119 1119
 name = "windows_i686_gnu"
... ...
@@ -1123,9 +1217,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
1123 1123
 
1124 1124
 [[package]]
1125 1125
 name = "windows_i686_gnu"
1126
-version = "0.52.0"
1126
+version = "0.52.4"
1127 1127
 source = "registry+https://github.com/rust-lang/crates.io-index"
1128
-checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
1128
+checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
1129 1129
 
1130 1130
 [[package]]
1131 1131
 name = "windows_i686_msvc"
... ...
@@ -1135,9 +1229,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
1135 1135
 
1136 1136
 [[package]]
1137 1137
 name = "windows_i686_msvc"
1138
-version = "0.52.0"
1138
+version = "0.52.4"
1139 1139
 source = "registry+https://github.com/rust-lang/crates.io-index"
1140
-checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
1140
+checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
1141 1141
 
1142 1142
 [[package]]
1143 1143
 name = "windows_x86_64_gnu"
... ...
@@ -1147,9 +1241,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
1147 1147
 
1148 1148
 [[package]]
1149 1149
 name = "windows_x86_64_gnu"
1150
-version = "0.52.0"
1150
+version = "0.52.4"
1151 1151
 source = "registry+https://github.com/rust-lang/crates.io-index"
1152
-checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
1152
+checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
1153 1153
 
1154 1154
 [[package]]
1155 1155
 name = "windows_x86_64_gnullvm"
... ...
@@ -1159,9 +1253,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
1159 1159
 
1160 1160
 [[package]]
1161 1161
 name = "windows_x86_64_gnullvm"
1162
-version = "0.52.0"
1162
+version = "0.52.4"
1163 1163
 source = "registry+https://github.com/rust-lang/crates.io-index"
1164
-checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
1164
+checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
1165 1165
 
1166 1166
 [[package]]
1167 1167
 name = "windows_x86_64_msvc"
... ...
@@ -1171,9 +1265,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
1171 1171
 
1172 1172
 [[package]]
1173 1173
 name = "windows_x86_64_msvc"
1174
-version = "0.52.0"
1174
+version = "0.52.4"
1175 1175
 source = "registry+https://github.com/rust-lang/crates.io-index"
1176
-checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
1176
+checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
1177 1177
 
1178 1178
 [[package]]
1179 1179
 name = "zune-inflate"
... ...
@@ -171,7 +171,7 @@ int cli_7unz(cli_ctx *ctx, size_t offset)
171 171
                     }
172 172
                 }
173 173
             }
174
-            if (CL_VIRUS == cli_matchmeta(ctx, name, 0, f->Size, encrypted, i, f->CrcDefined ? f->Crc : 0, NULL)) {
174
+            if (CL_VIRUS == cli_matchmeta(ctx, name, 0, f->Size, encrypted, i, f->CrcDefined ? f->Crc : 0)) {
175 175
                 found = CL_VIRUS;
176 176
                 break;
177 177
             }
... ...
@@ -654,7 +654,7 @@ cl_error_t fileblobScan(const fileblob *fb)
654 654
     lseek(fb->fd, 0, SEEK_SET);
655 655
     FSTAT(fb->fd, &sb);
656 656
 
657
-    rc = cli_matchmeta(fb->ctx, fb->b.name, sb.st_size, sb.st_size, 0, 0, 0, NULL);
657
+    rc = cli_matchmeta(fb->ctx, fb->b.name, sb.st_size, sb.st_size, 0, 0, 0);
658 658
     if (rc != CL_SUCCESS) {
659 659
         return rc;
660 660
     }
... ...
@@ -159,7 +159,7 @@ cl_error_t cli_scancpio_old(cli_ctx *ctx)
159 159
         if (!filesize)
160 160
             continue;
161 161
 
162
-        status = cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL);
162
+        status = cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0);
163 163
         if (status != CL_SUCCESS) {
164 164
             goto done;
165 165
         }
... ...
@@ -249,7 +249,7 @@ cl_error_t cli_scancpio_odc(cli_ctx *ctx)
249 249
             continue;
250 250
         }
251 251
 
252
-        status = cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL);
252
+        status = cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0);
253 253
         if (status == CL_VIRUS) {
254 254
             goto done;
255 255
         }
... ...
@@ -338,7 +338,7 @@ cl_error_t cli_scancpio_newc(cli_ctx *ctx, int crc)
338 338
             continue;
339 339
         }
340 340
 
341
-        status = cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0, NULL);
341
+        status = cli_matchmeta(ctx, name, filesize, filesize, 0, file, 0);
342 342
         if (status == CL_VIRUS) {
343 343
             goto done;
344 344
         }
... ...
@@ -107,6 +107,7 @@ static struct dconf_module modules[] = {
107 107
     {"ARCHIVE", "APM", ARCH_CONF_APM, 1},
108 108
     {"ARCHIVE", "EGG", ARCH_CONF_EGG, 1},
109 109
     {"ARCHIVE", "UDF", ARCH_CONF_UDF, 1},
110
+    {"ARCHIVE", "LHA", ARCH_CONF_LHA_LZH, 1},
110 111
 
111 112
     {"DOCUMENT", "HTML", DOC_CONF_HTML, 1},
112 113
     {"DOCUMENT", "RTF", DOC_CONF_RTF, 1},
... ...
@@ -97,6 +97,7 @@ struct cli_dconf {
97 97
 #define ARCH_CONF_APM     0x2000000
98 98
 #define ARCH_CONF_EGG     0x4000000
99 99
 #define ARCH_CONF_UDF     0x8000000
100
+#define ARCH_CONF_LHA_LZH 0x10000000
100 101
 
101 102
 /* Document flags */
102 103
 #define DOC_CONF_HTML         0x1
... ...
@@ -140,6 +140,7 @@ static const struct ftmap_s {
140 140
     { "CL_TYPE_UDF",                CL_TYPE_UDF             },
141 141
     { "CL_TYPE_ONENOTE",            CL_TYPE_ONENOTE         },
142 142
     { "CL_TYPE_PYTHON_COMPILED",    CL_TYPE_PYTHON_COMPILED },
143
+    { "CL_TYPE_LHA_LZH",            CL_TYPE_LHA_LZH         },
143 144
     { NULL,                         CL_TYPE_IGNORED         }
144 145
 };
145 146
 // clang-format on
... ...
@@ -94,6 +94,7 @@ typedef enum cli_file {
94 94
     CL_TYPE_EGG,
95 95
     CL_TYPE_ONENOTE,
96 96
     CL_TYPE_PYTHON_COMPILED,
97
+    CL_TYPE_LHA_LZH,
97 98
 
98 99
     /* Section for partition types */
99 100
     CL_TYPE_PART_ANY, /* unknown partition type */
... ...
@@ -298,5 +298,8 @@ static const char *ftypes_int[] = {
298 298
     "0:0:00010d0a:PyPy 3.8 byte-compiled (.pyc):CL_TYPE_ANY:CL_TYPE_PYTHON_COMPILED:200",
299 299
     "0:0:50010d0a:PyPy 3.9 byte-compiled (.pyc):CL_TYPE_ANY:CL_TYPE_PYTHON_COMPILED:200",
300 300
     "1:0:??0d0d0a:Python 3.7 or newer byte-compiled (.pyc):CL_TYPE_ANY:CL_TYPE_PYTHON_COMPILED:200",
301
+    "1:0:????2d6c68(30|31|32|33|34|35|36|37|64|78)2d:LHA or LZH archive:CL_TYPE_ANY:CL_TYPE_LHA_LZH:210",
302
+    "1:0:????2d6c7a(73|34|35)2d:LHA archive using .LZS extension:CL_TYPE_ANY:CL_TYPE_LHA_LZH:210",
303
+    "1:0:????2d706d302d:LHA archive using PMarc (.PMA) extension:CL_TYPE_ANY:CL_TYPE_LHA_LZH:210",
301 304
     NULL};
302 305
 #endif
... ...
@@ -406,7 +406,7 @@ cl_error_t cli_scanishield(cli_ctx *ctx, off_t off, size_t sz)
406 406
             (size_t)(data - fname) >= sz - fsize) break;
407 407
 
408 408
         cli_dbgmsg("ishield: @%lx found file %s (%s) - version %s - size %lu\n", (unsigned long int)coff, fname, path, version, (unsigned long int)fsize);
409
-        if (CL_SUCCESS != cli_matchmeta(ctx, fname, fsize, fsize, 0, fc++, 0, NULL)) {
409
+        if (CL_SUCCESS != cli_matchmeta(ctx, fname, fsize, fsize, 0, fc++, 0)) {
410 410
             ret = CL_VIRUS;
411 411
             break;
412 412
         }
... ...
@@ -191,7 +191,7 @@ static cl_error_t iso_parse_dir(iso9660_t *iso, unsigned int block, unsigned int
191 191
             filesz = cli_readint32(dir + 10);
192 192
 
193 193
             cli_dbgmsg("iso_parse_dir: %s '%s': off %x - size %x - flags %x - unit size %x - gap size %x - volume %u\n", (dir[25] & 2) ? "Directory" : "File", iso->buf, fileoff, filesz, dir[25], dir[26], dir[27], cli_readint32(&dir[28]) & 0xffff);
194
-            ret = cli_matchmeta(ctx, iso->buf, filesz, filesz, 0, 0, 0, NULL);
194
+            ret = cli_matchmeta(ctx, iso->buf, filesz, filesz, 0, 0, 0);
195 195
             if (ret != CL_SUCCESS) {
196 196
                 break;
197 197
             }
... ...
@@ -301,6 +301,8 @@ CLAMAV_PRIVATE {
301 301
     fuzzy_hash_calculate_image;
302 302
     ffierror_fmt;
303 303
     cli_magic_scan_buff;
304
+    cli_checklimits;
305
+    cli_matchmeta;
304 306
 
305 307
     __cli_strcasestr;
306 308
     __cli_strndup;
... ...
@@ -383,7 +383,7 @@ cl_error_t cli_scanmscab(cli_ctx *ctx, off_t sfx_offset)
383 383
         uint64_t max_size;
384 384
 
385 385
         ret = cli_matchmeta(ctx, cab_f->filename, 0, cab_f->length, 0,
386
-                            files, 0, NULL);
386
+                            files, 0);
387 387
         if (CL_SUCCESS != ret) {
388 388
             goto done;
389 389
         }
... ...
@@ -512,7 +512,7 @@ cl_error_t cli_scanmschm(cli_ctx *ctx)
512 512
         uint64_t max_size;
513 513
 
514 514
         ret = cli_matchmeta(ctx, mschm_f->filename, 0, mschm_f->length,
515
-                            0, files, 0, NULL);
515
+                            0, files, 0);
516 516
         if (CL_SUCCESS != ret) {
517 517
             goto done;
518 518
         }
... ...
@@ -1469,14 +1469,14 @@ done:
1469 1469
             continue;                                                     \
1470 1470
     }
1471 1471
 
1472
-cl_error_t cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, int encrypted, unsigned int filepos, int res1, void *res2)
1472
+cl_error_t cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, int encrypted, unsigned int filepos, int res1)
1473 1473
 {
1474 1474
     const struct cli_cdb *cdb;
1475 1475
     cl_error_t ret = CL_SUCCESS;
1476 1476
 
1477
-    cli_dbgmsg("CDBNAME:%s:%llu:%s:%llu:%llu:%d:%u:%u:%p\n",
1477
+    cli_dbgmsg("CDBNAME:%s:%llu:%s:%llu:%llu:%d:%u:%u\n",
1478 1478
                cli_ftname(cli_recursion_stack_get_type(ctx, -1)), (long long unsigned)fsizec, fname, (long long unsigned)fsizec, (long long unsigned)fsizer,
1479
-               encrypted, filepos, res1, res2);
1479
+               encrypted, filepos, res1);
1480 1480
 
1481 1481
     if (ctx->engine && ctx->engine->cb_meta) {
1482 1482
         if (ctx->engine->cb_meta(cli_ftname(cli_recursion_stack_get_type(ctx, -1)), fsizec, fname, fsizer, encrypted, filepos, ctx->cb_ctx) == CL_VIRUS) {
... ...
@@ -375,7 +375,7 @@ cl_error_t cli_caloff(const char *offstr, const struct cli_target_info *info, un
375 375
  */
376 376
 cl_error_t cli_check_fp(cli_ctx *ctx, const char *vname);
377 377
 
378
-cl_error_t cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, int encrypted, unsigned int filepos, int res1, void *res2);
378
+cl_error_t cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, int encrypted, unsigned int filepos, int res1);
379 379
 
380 380
 /** Parse the executable headers and, if successful, populate exeinfo
381 381
  *
... ...
@@ -205,7 +205,7 @@ static cl_error_t cli_unrar_scanmetadata(unrar_metadata_t *metadata, cli_ctx *ct
205 205
                (unsigned int)metadata->unpack_size, metadata->method,
206 206
                metadata->pack_size ? (unsigned int)(metadata->unpack_size / metadata->pack_size) : 0);
207 207
 
208
-    if (CL_VIRUS == cli_matchmeta(ctx, metadata->filename, metadata->pack_size, metadata->unpack_size, metadata->encrypted, files, metadata->crc, NULL)) {
208
+    if (CL_VIRUS == cli_matchmeta(ctx, metadata->filename, metadata->pack_size, metadata->unpack_size, metadata->encrypted, files, metadata->crc)) {
209 209
         status = CL_VIRUS;
210 210
     } else if (SCAN_HEURISTIC_ENCRYPTED_ARCHIVE && metadata->encrypted) {
211 211
         cli_dbgmsg("RAR: Encrypted files found in archive.\n");
... ...
@@ -610,7 +610,7 @@ static cl_error_t cli_egg_scanmetadata(cl_egg_metadata *metadata, cli_ctx *ctx,
610 610
                (unsigned int)metadata->unpack_size,
611 611
                metadata->pack_size ? (unsigned int)(metadata->unpack_size / metadata->pack_size) : 0);
612 612
 
613
-    if (CL_VIRUS == cli_matchmeta(ctx, metadata->filename, metadata->pack_size, metadata->unpack_size, metadata->encrypted, files, 0, NULL)) {
613
+    if (CL_VIRUS == cli_matchmeta(ctx, metadata->filename, metadata->pack_size, metadata->unpack_size, metadata->encrypted, files, 0)) {
614 614
         status = CL_VIRUS;
615 615
     } else if (SCAN_HEURISTIC_ENCRYPTED_ARCHIVE && metadata->encrypted) {
616 616
         cli_dbgmsg("EGG: Encrypted files found in archive.\n");
... ...
@@ -1011,7 +1011,7 @@ static cl_error_t cli_scanarj(cli_ctx *ctx)
1011 1011
 
1012 1012
         file++;
1013 1013
 
1014
-        if (CL_VIRUS == cli_matchmeta(ctx, metadata.filename, metadata.comp_size, metadata.orig_size, metadata.encrypted, file, 0, NULL)) {
1014
+        if (CL_VIRUS == cli_matchmeta(ctx, metadata.filename, metadata.comp_size, metadata.orig_size, metadata.encrypted, file, 0)) {
1015 1015
             cli_rmdirs(dir);
1016 1016
             free(dir);
1017 1017
             return CL_VIRUS;
... ...
@@ -4587,6 +4587,11 @@ cl_error_t cli_magic_scan(cli_ctx *ctx, cli_file_t type)
4587 4587
                 ret = scan_onenote(ctx);
4588 4588
             break;
4589 4589
 
4590
+        case CL_TYPE_LHA_LZH:
4591
+            if (SCAN_PARSE_ARCHIVE && (DCONF_ARCH & ARCH_CONF_LHA_LZH))
4592
+                ret = scan_lha_lzh(ctx);
4593
+            break;
4594
+
4590 4595
         case CL_TYPE_OOXML_WORD:
4591 4596
         case CL_TYPE_OOXML_PPT:
4592 4597
         case CL_TYPE_OOXML_XL:
... ...
@@ -302,7 +302,7 @@ cl_error_t cli_untar(const char *dir, unsigned int posix, cli_ctx *ctx)
302 302
 
303 303
             strncpy(name, block, 100);
304 304
             name[100] = '\0';
305
-            if (cli_matchmeta(ctx, name, size, size, 0, files, 0, NULL) == CL_VIRUS) {
305
+            if (cli_matchmeta(ctx, name, size, size, 0, files, 0) == CL_VIRUS) {
306 306
                 return CL_VIRUS;
307 307
             }
308 308
 
... ...
@@ -671,7 +671,7 @@ static unsigned int parse_local_file_header(
671 671
     /* ZMDfmt virname:encrypted(0-1):filename(exact|*):usize(exact|*):csize(exact|*):crc32(exact|*):method(exact|*):fileno(exact|*):maxdepth(exact|*) */
672 672
 
673 673
     /* Scan file header metadata. */
674
-    if (cli_matchmeta(ctx, name, LOCAL_HEADER_csize, LOCAL_HEADER_usize, (LOCAL_HEADER_flags & F_ENCR) != 0, file_count, LOCAL_HEADER_crc32, NULL) == CL_VIRUS) {
674
+    if (cli_matchmeta(ctx, name, LOCAL_HEADER_csize, LOCAL_HEADER_usize, (LOCAL_HEADER_flags & F_ENCR) != 0, file_count, LOCAL_HEADER_crc32) == CL_VIRUS) {
675 675
         *ret = CL_VIRUS;
676 676
         goto done;
677 677
     }
... ...
@@ -861,7 +861,7 @@ parse_central_directory_file_header(
861 861
     coff += CENTRAL_HEADER_flen;
862 862
 
863 863
     /* requests do not supply a ctx; also prevent multiple scans */
864
-    if (ctx && (CL_VIRUS == cli_matchmeta(ctx, name, CENTRAL_HEADER_csize, CENTRAL_HEADER_usize, (CENTRAL_HEADER_flags & F_ENCR) != 0, file_count, CENTRAL_HEADER_crc32, NULL))) {
864
+    if (ctx && (CL_VIRUS == cli_matchmeta(ctx, name, CENTRAL_HEADER_csize, CENTRAL_HEADER_usize, (CENTRAL_HEADER_flags & F_ENCR) != 0, file_count, CENTRAL_HEADER_crc32))) {
865 865
         last = 1;
866 866
         *ret = CL_VIRUS;
867 867
         goto done;
... ...
@@ -16,12 +16,13 @@ image = "0.24"
16 16
 rustdct = "0.7"
17 17
 transpose = "0.2"
18 18
 num-traits = "0.2"
19
-base64 = "0.21.0"
20
-sha1 = "0.10.5"
21
-unicode-segmentation = "1.10.1"
19
+base64 = "0.21"
20
+sha1 = "0.10"
21
+unicode-segmentation = "1.10"
22 22
 bindgen = "0.65"
23 23
 onenote_parser = { git = "https://github.com/Cisco-Talos/onenote.rs.git", branch = "CLAM-2329-new-from-slice" }
24
-hex-literal = "0.4.1"
24
+hex-literal = "0.4"
25
+delharc = "0.5"
25 26
 
26 27
 [lib]
27 28
 crate-type = ["staticlib"]
... ...
@@ -53,6 +53,8 @@ const BINDGEN_FUNCTIONS: &[&str] = &[
53 53
     "cli_getdsig",
54 54
     "cli_get_debug_flag",
55 55
     "cli_magic_scan_buff",
56
+    "cli_checklimits",
57
+    "cli_matchmeta",
56 58
 ];
57 59
 
58 60
 // Generate bindings for these types (structs, enums):
... ...
@@ -22,17 +22,24 @@
22 22
 
23 23
 use std::{
24 24
     ffi::{c_char, CString},
25
+    io::Read,
26
+    panic,
25 27
     path::Path,
26 28
     ptr::null_mut,
27 29
 };
28 30
 
31
+use delharc::LhaDecodeReader;
29 32
 use libc::c_void;
30 33
 use log::{debug, error, warn};
31 34
 
32 35
 use crate::{
33 36
     ctx,
34 37
     onenote::OneNote,
35
-    sys::{cl_error_t, cl_error_t_CL_ERROR, cl_error_t_CL_SUCCESS, cli_ctx, cli_magic_scan_buff},
38
+    sys::{
39
+        cl_error_t, cl_error_t_CL_EFORMAT, cl_error_t_CL_ERROR, cl_error_t_CL_SUCCESS, cli_ctx,
40
+        cli_magic_scan_buff,
41
+    },
42
+    util::{check_scan_limits, scan_archive_metadata},
36 43
 };
37 44
 
38 45
 /// Rust wrapper of libclamav's cli_magic_scan_buff() function.
... ...
@@ -127,3 +134,164 @@ pub unsafe extern "C" fn scan_onenote(ctx: *mut cli_ctx) -> cl_error_t {
127 127
 
128 128
     scan_result
129 129
 }
130
+
131
+/// Scan the contents of a LHA or LZH archive
132
+///
133
+/// # Safety
134
+///
135
+/// Must be a valid ctx pointer.
136
+#[no_mangle]
137
+pub unsafe extern "C" fn scan_lha_lzh(ctx: *mut cli_ctx) -> cl_error_t {
138
+    let fmap = match ctx::current_fmap(ctx) {
139
+        Ok(fmap) => fmap,
140
+        Err(e) => {
141
+            warn!("Error getting FMap from ctx: {e}");
142
+            return cl_error_t_CL_ERROR;
143
+        }
144
+    };
145
+
146
+    let file_bytes = match fmap.need_off(0, fmap.len()) {
147
+        Ok(bytes) => bytes,
148
+        Err(err) => {
149
+            error!(
150
+                "Failed to get file bytes for fmap of size {}: {err}",
151
+                fmap.len()
152
+            );
153
+            return cl_error_t_CL_ERROR;
154
+        }
155
+    };
156
+
157
+    // Try to parse the LHA/LZH file data using the delharc crate.
158
+    debug!("Attempting to parse the LHA/LZH file data using the delharc crate.");
159
+
160
+    // Attempt to catch panics in case the parser encounter unexpected issues.
161
+    let result_result = panic::catch_unwind(
162
+        || -> Result<LhaDecodeReader<&[u8]>, delharc::decode::LhaDecodeError<&[u8]>> {
163
+            LhaDecodeReader::new(file_bytes)
164
+        },
165
+    );
166
+
167
+    // Check if it panicked. If no panic, grab the parse result.
168
+    let result = match result_result {
169
+        Ok(result) => result,
170
+        Err(_) => {
171
+            debug!("Panic occured when trying to open LHA archive with delharc crate");
172
+            return cl_error_t_CL_EFORMAT;
173
+        }
174
+    };
175
+
176
+    // Check if any issue opening the archive.
177
+    let mut decoder = match result {
178
+        Ok(result) => result,
179
+        Err(err) => {
180
+            debug!("Unable to parse LHA archive with delharc crate: {err}");
181
+            return cl_error_t_CL_EFORMAT;
182
+        }
183
+    };
184
+
185
+    debug!("Opened the LHA/LZH archive");
186
+
187
+    let mut index: usize = 0;
188
+    loop {
189
+        // Check if we've already exceeded the limits and should bail out.
190
+        let ret = check_scan_limits("LHA", ctx, 0, 0, 0);
191
+        if ret != cl_error_t_CL_SUCCESS {
192
+            debug!("Exceeded scan limits. Bailing out.");
193
+            break;
194
+        }
195
+
196
+        // Get the file header.
197
+        let header = decoder.header();
198
+
199
+        // Verify the CRC check. This is important because LHA/LZH does not have particularly identifiable magic bytes.
200
+        match decoder.crc_check() {
201
+            Ok(crc) => {
202
+                // CRC is valid.  Very likely it is indeed an LHA/LZH archive.
203
+                debug!("CRC check passed.  Very likely this is an LHA or LZH archive.  CRC: {crc}");
204
+            }
205
+            Err(err) => {
206
+                // Error checking CRC.
207
+                // Use debug-level because may not actually be an LHA/LZH archive.
208
+                // LHA/LZH does not have particularly identifiable magic bytes.
209
+                debug!("An error occured when checking the CRC of this LHA or LZH archive: {err}");
210
+                // break;
211
+            }
212
+        }
213
+
214
+        let filepath = header.parse_pathname();
215
+        let filename = filepath.to_string_lossy();
216
+        if header.is_directory() {
217
+            debug!("Skipping directory {filename}");
218
+        } else {
219
+            debug!("Found file in LHA archive: {filename}");
220
+
221
+            // Scan the archive metadata first.
222
+            if scan_archive_metadata(
223
+                ctx,
224
+                &filename,
225
+                header.compressed_size as usize,
226
+                header.original_size as usize,
227
+                false,
228
+                index,
229
+                header.file_crc as i32,
230
+            ) != cl_error_t_CL_SUCCESS
231
+            {
232
+                debug!("Extracted file '{filename}' would exceed size limits. Skipping.");
233
+            } else {
234
+                // Check if scanning the next file would exceed the limits and should be skipped.
235
+                if check_scan_limits("LHA", ctx, header.original_size, 0, 0)
236
+                    != cl_error_t_CL_SUCCESS
237
+                {
238
+                    debug!("Extracted file '{filename}' would exceed size limits. Skipping.");
239
+                } else {
240
+                    if !decoder.is_decoder_supported() {
241
+                        debug!("err: unsupported compression method");
242
+                    } else {
243
+                        // Read the file into a buffer.
244
+                        let mut file_data = Vec::<u8>::new();
245
+
246
+                        match decoder.read_to_end(&mut file_data) {
247
+                            Ok(bytes_read) => {
248
+                                if bytes_read > 0 {
249
+                                    let ret =
250
+                                        magic_scan(ctx, &file_data, Some(filename.to_string()));
251
+                                    if ret != cl_error_t_CL_SUCCESS {
252
+                                        debug!("cl_scandesc_magic returned error: {}", ret);
253
+                                        return ret;
254
+                                    }
255
+                                } else {
256
+                                    debug!("Read zero-byte file.");
257
+                                }
258
+                            }
259
+                            err => {
260
+                                debug!("Error reading file {err:?}");
261
+                            }
262
+                        }
263
+                    }
264
+                }
265
+            }
266
+
267
+            index += 1;
268
+        }
269
+
270
+        // Get the next file.
271
+        match decoder.next_file() {
272
+            Ok(true) => {
273
+                debug!("Found another file in the archive!");
274
+            }
275
+            Ok(false) => {
276
+                debug!("No more files in the archive.");
277
+                break;
278
+            }
279
+            Err(err) => {
280
+                // Error getting the next file.
281
+                // Use debug-level because may not actually be an LHA/LZH archive.
282
+                // LHA/LZH does not have particularly identifiable magic bytes.
283
+                debug!("An error occured when checking for the next file in this LHA or LZH archive: {err}");
284
+                break;
285
+            }
286
+        }
287
+    }
288
+
289
+    cl_error_t_CL_SUCCESS
290
+}
... ...
@@ -808,6 +808,15 @@ extern "C" {
808 808
     pub fn cli_dbgmsg_no_inline(str_: *const ::std::os::raw::c_char, ...);
809 809
 }
810 810
 extern "C" {
811
+    pub fn cli_checklimits(
812
+        who: *const ::std::os::raw::c_char,
813
+        ctx: *mut cli_ctx,
814
+        need1: ::std::os::raw::c_ulong,
815
+        need2: ::std::os::raw::c_ulong,
816
+        need3: ::std::os::raw::c_ulong,
817
+    ) -> cl_error_t;
818
+}
819
+extern "C" {
811 820
     #[doc = " @brief   Get the libclamav debug flag (e.g. if debug logging is enabled)\n\n This is required for unit tests to be able to link with clamav.dll and not\n directly manipulate libclamav global variables."]
812 821
     pub fn cli_get_debug_flag() -> u8;
813 822
 }
... ...
@@ -1159,6 +1168,17 @@ pub struct cli_cdb {
1159 1159
     pub next: *mut cli_cdb,
1160 1160
 }
1161 1161
 extern "C" {
1162
+    pub fn cli_matchmeta(
1163
+        ctx: *mut cli_ctx,
1164
+        fname: *const ::std::os::raw::c_char,
1165
+        fsizec: usize,
1166
+        fsizer: usize,
1167
+        encrypted: ::std::os::raw::c_int,
1168
+        filepos: ::std::os::raw::c_uint,
1169
+        res1: ::std::os::raw::c_int,
1170
+    ) -> cl_error_t;
1171
+}
1172
+extern "C" {
1162 1173
     pub fn cli_versig2(
1163 1174
         sha256: *const ::std::os::raw::c_uchar,
1164 1175
         dsig_str: *const ::std::os::raw::c_char,
... ...
@@ -22,6 +22,10 @@
22 22
 
23 23
 use std::{ffi::CStr, fs::File};
24 24
 
25
+use log::error;
26
+
27
+use crate::sys;
28
+
25 29
 /// Obtain a std::fs::File from an i32 in a platform-independent manner.
26 30
 ///
27 31
 /// On Unix-like platforms, this is done with File::from_raw_fd().
... ...
@@ -47,7 +51,7 @@ pub fn file_from_fd_or_handle(fd: i32) -> File {
47 47
     compile_error!("implemented only for unix and windows targets")
48 48
 }
49 49
 
50
-/// Get a string from a pointer
50
+/// Get a string from a pointer.
51 51
 ///
52 52
 /// # Safety
53 53
 ///
... ...
@@ -55,10 +59,72 @@ pub fn file_from_fd_or_handle(fd: i32) -> File {
55 55
 /// exceeds the lifetime of the output string.
56 56
 ///
57 57
 /// ptr must be a valid pointer to a C string.
58
-pub unsafe fn str_from_ptr(ptr: *const ::std::os::raw::c_char) -> Result<Option<&'static str>, std::str::Utf8Error> {
58
+pub unsafe fn str_from_ptr(
59
+    ptr: *const ::std::os::raw::c_char,
60
+) -> Result<Option<&'static str>, std::str::Utf8Error> {
59 61
     if ptr.is_null() {
60 62
         return Ok(None);
61 63
     }
62 64
 
63 65
     Some(unsafe { CStr::from_ptr(ptr) }.to_str()).transpose()
64 66
 }
67
+
68
+/// Check scan limits in case we need to abort the scan.
69
+///
70
+/// # Safety
71
+///
72
+/// ctx must be a valid pointer to a clamav scan context structure
73
+///
74
+pub unsafe fn check_scan_limits(
75
+    module_name: &str,
76
+    ctx: *mut sys::cli_ctx,
77
+    need1: u64,
78
+    need2: u64,
79
+    need3: u64,
80
+) -> sys::cl_error_t {
81
+    let module_name = match std::ffi::CString::new(module_name) {
82
+        Ok(name) => name,
83
+        Err(_) => {
84
+            error!("Invalid module_name: {}", module_name);
85
+            return sys::cl_error_t_CL_EFORMAT;
86
+        }
87
+    };
88
+
89
+    unsafe { sys::cli_checklimits(module_name.into_raw(), ctx, need1, need2, need3) }
90
+}
91
+
92
+/// Scan archive metadata.
93
+///
94
+/// # Safety
95
+///
96
+/// ctx must be a valid pointer to a clamav scan context structure
97
+///
98
+pub unsafe fn scan_archive_metadata(
99
+    ctx: *mut sys::cli_ctx,
100
+    filename: &str,
101
+    filesize_compressed: usize,
102
+    filesize_original: usize,
103
+    is_encrypted: bool,
104
+    filepos: usize,
105
+    res1: i32,
106
+) -> sys::cl_error_t {
107
+    let module_name = match std::ffi::CString::new(filename) {
108
+        Ok(name) => name,
109
+        Err(_) => {
110
+            error!("Invalid module_name: {}", filename);
111
+            return sys::cl_error_t_CL_EFORMAT;
112
+        }
113
+    };
114
+
115
+    unsafe {
116
+        sys::cli_matchmeta(
117
+            ctx,
118
+            module_name.into_raw(),
119
+            filesize_compressed,
120
+            filesize_original,
121
+            i32::from(is_encrypted),
122
+            filepos as u32,
123
+            res1,
124
+        )
125
+    }
126
+}