dissect.target 3.16.dev24__py3-none-any.whl → 3.16.dev25__py3-none-any.whl

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.
@@ -1588,5 +1588,7 @@ register("btrfs", "BtrfsFilesystem")
1588
1588
  register("exfat", "ExfatFilesystem")
1589
1589
  register("squashfs", "SquashFSFilesystem")
1590
1590
  register("zip", "ZipFilesystem")
1591
+ register("tar", "TarFilesystem")
1592
+ register("cpio", "CpioFilesystem")
1591
1593
  register("ad1", "AD1Filesystem")
1592
1594
  register("jffs", "JFFSFilesystem")
@@ -0,0 +1,18 @@
1
+ from typing import BinaryIO, Optional
2
+
3
+ from dissect.util import cpio
4
+
5
+ from dissect.target.filesystems.tar import TarFilesystem
6
+ from dissect.target.helpers.fsutil import open_decompress
7
+
8
+
9
+ class CpioFilesystem(TarFilesystem):
10
+ __type__ = "cpio"
11
+
12
+ def __init__(self, fh: BinaryIO, base: Optional[str] = None, *args, **kwargs):
13
+ super().__init__(open_decompress(fileobj=fh), base, tarinfo=cpio.CpioInfo, *args, **kwargs)
14
+
15
+ @staticmethod
16
+ def _detect(fh: BinaryIO) -> bool:
17
+ """Detect a cpio file on a given file-like object."""
18
+ return cpio.detect_header(open_decompress(fileobj=fh)) != cpio.FORMAT_CPIO_UNKNOWN
@@ -20,6 +20,13 @@ try:
20
20
  except ImportError:
21
21
  HAVE_BZ2 = False
22
22
 
23
+ try:
24
+ import zstandard
25
+
26
+ HAVE_ZSTD = True
27
+ except ImportError:
28
+ HAVE_ZSTD = False
29
+
23
30
  import dissect.target.filesystem as filesystem
24
31
  from dissect.target.exceptions import FileNotFoundError, SymlinkRecursionError
25
32
  from dissect.target.helpers.polypath import (
@@ -445,17 +452,22 @@ def resolve_link(
445
452
 
446
453
 
447
454
  def open_decompress(
448
- path: TargetPath,
455
+ path: Optional[TargetPath] = None,
449
456
  mode: str = "rb",
457
+ *,
458
+ fileobj: Optional[BinaryIO] = None,
450
459
  encoding: Optional[str] = "UTF-8",
451
460
  errors: Optional[str] = "backslashreplace",
452
461
  newline: Optional[str] = None,
453
462
  ) -> Union[BinaryIO, TextIO]:
454
- """Open and decompress a file. Handles gz and bz2 files. Uncompressed files are opened as-is.
463
+ """Open and decompress a file. Handles gz, bz2 and zstd files. Uncompressed files are opened as-is.
464
+
465
+ When passing in an already opened ``fileobj``, the mode, encoding, errors and newline arguments are ignored.
455
466
 
456
467
  Args:
457
468
  path: The path to the file to open and decompress. It is assumed this path exists.
458
469
  mode: The mode in which to open the file.
470
+ fileobj: The file-like object to open and decompress. This is mutually exclusive with path.
459
471
  encoding: The decoding for text streams. By default UTF-8 encoding is used.
460
472
  errors: The error handling for text streams. By default we're more lenient and use ``backslashreplace``.
461
473
  newline: How newlines are handled for text streams.
@@ -469,7 +481,17 @@ def open_decompress(
469
481
  for line in open_decompress(Path("/dir/file.gz"), "rt"):
470
482
  print(line)
471
483
  """
472
- file = path.open()
484
+ if path and fileobj:
485
+ raise ValueError("path and fileobj are mutually exclusive")
486
+
487
+ if not path and not fileobj:
488
+ raise ValueError("path or fileobj is required")
489
+
490
+ if path:
491
+ file = path.open("rb")
492
+ else:
493
+ file = fileobj
494
+
473
495
  magic = file.read(4)
474
496
  file.seek(0)
475
497
 
@@ -480,13 +502,22 @@ def open_decompress(
480
502
 
481
503
  if magic[:2] == b"\x1f\x8b":
482
504
  return gzip.open(file, mode, encoding=encoding, errors=errors, newline=newline)
483
- # In a valid bz2 header the 4th byte is in the range b'1' ... b'9'.
484
- elif HAVE_BZ2 and magic[:3] == b"BZh" and 0x31 <= magic[3] <= 0x39:
505
+
506
+ if HAVE_BZ2 and magic[:3] == b"BZh" and 0x31 <= magic[3] <= 0x39:
507
+ # In a valid bz2 header the 4th byte is in the range b'1' ... b'9'.
485
508
  return bz2.open(file, mode, encoding=encoding, errors=errors, newline=newline)
486
- else:
509
+
510
+ if HAVE_ZSTD and magic[:4] in [b"\xfd\x2f\xb5\x28", b"\x28\xb5\x2f\xfd"]:
511
+ # stream_reader is not seekable, so we have to resort to the less
512
+ # efficient decompressor which returns bytes.
513
+ return io.BytesIO(zstandard.decompress(file.read()))
514
+
515
+ if path:
487
516
  file.close()
488
517
  return path.open(mode, encoding=encoding, errors=errors, newline=newline)
489
518
 
519
+ return file
520
+
490
521
 
491
522
  def reverse_readlines(fh: TextIO, chunk_size: int = 1024 * 1024 * 8) -> Iterator[str]:
492
523
  """Like iterating over a ``TextIO`` file-like object, but starting from the end of the file.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.target
3
- Version: 3.16.dev24
3
+ Version: 3.16.dev25
4
4
  Summary: This module ties all other Dissect modules together, it provides a programming API and command line tools which allow easy access to various data sources inside disk images or file collections (a.k.a. targets)
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License: Affero General Public License v3
@@ -1,7 +1,7 @@
1
1
  dissect/target/__init__.py,sha256=Oc7ounTgq2hE4nR6YcNabetc7SQA40ldSa35VEdZcQU,63
2
2
  dissect/target/container.py,sha256=9ixufT1_0WhraqttBWwQjG80caToJqvCX8VjFk8d5F0,9307
3
3
  dissect/target/exceptions.py,sha256=VVW_Rq_vQinapz-2mbJ3UkxBEZpb2pE_7JlhMukdtrY,2877
4
- dissect/target/filesystem.py,sha256=aLkvZMgeah39Nhlscawh77cm2mzFYI9J5h3uT3Rigtc,53876
4
+ dissect/target/filesystem.py,sha256=VuWp_nxaG5WI9xvhEjl0M6X37_sVdclzgt3pZvtZ3hE,53944
5
5
  dissect/target/loader.py,sha256=0-LcZNi7S0qsXR7XGtrzxpuCh9BsLcqNR1T15O7SnBM,7257
6
6
  dissect/target/plugin.py,sha256=bwtTPASgJBUHBZ7Nr8eb5eXDOHMWfumduWj7loB0FP0,48605
7
7
  dissect/target/report.py,sha256=06uiP4MbNI8cWMVrC1SasNS-Yg6ptjVjckwj8Yhe0Js,7958
@@ -25,6 +25,7 @@ dissect/target/filesystems/ad1.py,sha256=nEPzaaRsb6bL4ItFo0uLdmdLvrmK9BjqHeD3FOp
25
25
  dissect/target/filesystems/btrfs.py,sha256=5MBi193ZvclkEQcxDr_sDHfj_FYU_hyYNRL4YqpDu4M,6243
26
26
  dissect/target/filesystems/cb.py,sha256=6LcoJiwsYu1Han31IUzVpZVDTifhTLTx_gLfNpB_p6k,5329
27
27
  dissect/target/filesystems/config.py,sha256=C2JnzBzMqbAjchGFDwURItCeUY7uxkhw1Gen-6cGkAc,11432
28
+ dissect/target/filesystems/cpio.py,sha256=ssVCjkAtLn2FqmNxeo6U5boyUdSYFxLWfXpytHYGPqs,641
28
29
  dissect/target/filesystems/dir.py,sha256=7GRvojL151_Vk9e3vqgZbWE3I8IL9bU6LUKc_xjk6D4,4050
29
30
  dissect/target/filesystems/exfat.py,sha256=PRkZPUVN5NlgB1VetFtywdNgF6Yj5OBtF5a25t-fFvw,5917
30
31
  dissect/target/filesystems/extfs.py,sha256=9Cke-H0CL-SPd3-xvdAgfc3YA5hYso0sq6hm0C9vGII,4640
@@ -46,7 +47,7 @@ dissect/target/helpers/configutil.py,sha256=t_UNvcWuMMT5C1tut_PgTwCnVUodf6RjhfXP
46
47
  dissect/target/helpers/cyber.py,sha256=Ki5oSU0GgQxjgC_yWoeieGP7GOY5blQCzNX7vy7Pgas,16782
47
48
  dissect/target/helpers/descriptor_extensions.py,sha256=uT8GwznfDAiIgMM7JKKOY0PXKMv2c0GCqJTCkWFgops,2605
48
49
  dissect/target/helpers/docs.py,sha256=J5U65Y3yOTqxDEZRCdrEmO63XQCeDzOJea1PwPM6Cyc,5146
49
- dissect/target/helpers/fsutil.py,sha256=jGinb11-w6TvbzH7z-9F6J09X5CY3_yxBoNsKxsFAXE,18637
50
+ dissect/target/helpers/fsutil.py,sha256=NKwpAq_NlbFDvGGV9ahC5flPda_5jUBDqtF-Ch5ASDs,19543
50
51
  dissect/target/helpers/hashutil.py,sha256=SD24rcV_y0sBEl7M9T-isjm-VzJvCiTN2BoWMqAOAVI,2160
51
52
  dissect/target/helpers/keychain.py,sha256=wYH0sf7eaxP0bZTo80RF_BQMWulCWmIQ8Tzt9K5TSNQ,3611
52
53
  dissect/target/helpers/lazy.py,sha256=823VtmdWsbJyVZvNWopDhQdqq2i1xtj6b8IKfveboKw,1771
@@ -330,10 +331,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
330
331
  dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
331
332
  dissect/target/volumes/md.py,sha256=j1K1iKmspl0C_OJFc7-Q1BMWN2OCC5EVANIgVlJ_fIE,1673
332
333
  dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
333
- dissect.target-3.16.dev24.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
334
- dissect.target-3.16.dev24.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
335
- dissect.target-3.16.dev24.dist-info/METADATA,sha256=YEzNiCmNzVb-pJ0NEOgbTYAzsICnqeq-J9kJiqBURAs,11113
336
- dissect.target-3.16.dev24.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
337
- dissect.target-3.16.dev24.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
338
- dissect.target-3.16.dev24.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
339
- dissect.target-3.16.dev24.dist-info/RECORD,,
334
+ dissect.target-3.16.dev25.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
335
+ dissect.target-3.16.dev25.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
336
+ dissect.target-3.16.dev25.dist-info/METADATA,sha256=dlfz79OtrmH132ugeqPIQsRDdu-FgcSqIbt0i1AdSgo,11113
337
+ dissect.target-3.16.dev25.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
338
+ dissect.target-3.16.dev25.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
339
+ dissect.target-3.16.dev25.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
340
+ dissect.target-3.16.dev25.dist-info/RECORD,,