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.
- dissect/target/filesystem.py +2 -0
- dissect/target/filesystems/cpio.py +18 -0
- dissect/target/helpers/fsutil.py +37 -6
- {dissect.target-3.16.dev24.dist-info → dissect.target-3.16.dev25.dist-info}/METADATA +1 -1
- {dissect.target-3.16.dev24.dist-info → dissect.target-3.16.dev25.dist-info}/RECORD +10 -9
- {dissect.target-3.16.dev24.dist-info → dissect.target-3.16.dev25.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.16.dev24.dist-info → dissect.target-3.16.dev25.dist-info}/LICENSE +0 -0
- {dissect.target-3.16.dev24.dist-info → dissect.target-3.16.dev25.dist-info}/WHEEL +0 -0
- {dissect.target-3.16.dev24.dist-info → dissect.target-3.16.dev25.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.16.dev24.dist-info → dissect.target-3.16.dev25.dist-info}/top_level.txt +0 -0
    
        dissect/target/filesystem.py
    CHANGED
    
    | @@ -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
         | 
    
        dissect/target/helpers/fsutil.py
    CHANGED
    
    | @@ -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  | 
| 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 | 
            -
                 | 
| 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 | 
            -
             | 
| 484 | 
            -
                 | 
| 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 | 
            -
             | 
| 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. | 
| 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= | 
| 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= | 
| 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. | 
| 334 | 
            -
            dissect.target-3.16. | 
| 335 | 
            -
            dissect.target-3.16. | 
| 336 | 
            -
            dissect.target-3.16. | 
| 337 | 
            -
            dissect.target-3.16. | 
| 338 | 
            -
            dissect.target-3.16. | 
| 339 | 
            -
            dissect.target-3.16. | 
| 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,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
    
        {dissect.target-3.16.dev24.dist-info → dissect.target-3.16.dev25.dist-info}/entry_points.txt
    RENAMED
    
    | 
            File without changes
         | 
| 
            File without changes
         |