dissect.hypervisor 3.16.dev2__tar.gz → 3.17.dev1__tar.gz

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 (84) hide show
  1. {dissect_hypervisor-3.16.dev2/dissect.hypervisor.egg-info → dissect_hypervisor-3.17.dev1}/PKG-INFO +1 -1
  2. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/disk/vmdk.py +23 -7
  3. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1/dissect.hypervisor.egg-info}/PKG-INFO +1 -1
  4. dissect_hypervisor-3.17.dev1/tests/test_vmdk.py +199 -0
  5. dissect_hypervisor-3.16.dev2/tests/test_vmdk.py +0 -93
  6. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/COPYRIGHT +0 -0
  7. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/LICENSE +0 -0
  8. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/MANIFEST.in +0 -0
  9. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/README.md +0 -0
  10. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/__init__.py +0 -0
  11. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/descriptor/__init__.py +0 -0
  12. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/descriptor/c_hyperv.py +0 -0
  13. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/descriptor/hyperv.py +0 -0
  14. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/descriptor/ovf.py +0 -0
  15. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/descriptor/pvs.py +0 -0
  16. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/descriptor/vbox.py +0 -0
  17. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/descriptor/vmx.py +0 -0
  18. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/disk/__init__.py +0 -0
  19. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/disk/c_hdd.py +0 -0
  20. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/disk/c_qcow2.py +0 -0
  21. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/disk/c_vdi.py +0 -0
  22. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/disk/c_vhd.py +0 -0
  23. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/disk/c_vhdx.py +0 -0
  24. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/disk/c_vmdk.py +0 -0
  25. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/disk/hdd.py +0 -0
  26. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/disk/qcow2.py +0 -0
  27. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/disk/vdi.py +0 -0
  28. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/disk/vhd.py +0 -0
  29. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/disk/vhdx.py +0 -0
  30. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/exceptions.py +0 -0
  31. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/tools/__init__.py +0 -0
  32. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/tools/envelope.py +0 -0
  33. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/util/__init__.py +0 -0
  34. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/util/envelope.py +0 -0
  35. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect/hypervisor/util/vmtar.py +0 -0
  36. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect.hypervisor.egg-info/SOURCES.txt +0 -0
  37. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect.hypervisor.egg-info/dependency_links.txt +0 -0
  38. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect.hypervisor.egg-info/entry_points.txt +0 -0
  39. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect.hypervisor.egg-info/requires.txt +0 -0
  40. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/dissect.hypervisor.egg-info/top_level.txt +0 -0
  41. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/pyproject.toml +0 -0
  42. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/setup.cfg +0 -0
  43. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/__init__.py +0 -0
  44. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/conftest.py +0 -0
  45. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/differencing.avhdx.gz +0 -0
  46. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/dynamic.vhd.gz +0 -0
  47. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/dynamic.vhdx.gz +0 -0
  48. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/encrypted.vmx +0 -0
  49. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/encryption.info +0 -0
  50. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/expanding.hdd/DiskDescriptor.xml +0 -0
  51. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/expanding.hdd/expanding.hdd +0 -0
  52. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/expanding.hdd/expanding.hdd.0.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
  53. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/fixed.vhd.gz +0 -0
  54. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/fixed.vhdx.gz +0 -0
  55. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/local.tgz.ve +0 -0
  56. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/plain.hdd/DiskDescriptor.xml +0 -0
  57. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/plain.hdd/plain.hdd +0 -0
  58. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/plain.hdd/plain.hdd.0.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
  59. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/sesparse.vmdk.gz +0 -0
  60. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/split.hdd/DiskDescriptor.xml +0 -0
  61. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/split.hdd/split.hdd +0 -0
  62. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/split.hdd/split.hdd.0.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
  63. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/split.hdd/split.hdd.1.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
  64. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/split.hdd/split.hdd.2.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
  65. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/split.hdd/split.hdd.3.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
  66. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/split.hdd/split.hdd.4.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
  67. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/split.hdd/split.hdd.5.{5fbaabe3-6958-40ff-92a7-860e329aab41}.hds.gz +0 -0
  68. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/test.VMRS +0 -0
  69. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/test.vgz +0 -0
  70. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/data/test.vmcx +0 -0
  71. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/docs/Makefile +0 -0
  72. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/docs/conf.py +0 -0
  73. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/docs/index.rst +0 -0
  74. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/test_envelope.py +0 -0
  75. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/test_hdd.py +0 -0
  76. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/test_hyperv.py +0 -0
  77. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/test_ovf.py +0 -0
  78. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/test_pvs.py +0 -0
  79. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/test_vbox.py +0 -0
  80. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/test_vhd.py +0 -0
  81. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/test_vhdx.py +0 -0
  82. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/test_vmtar.py +0 -0
  83. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tests/test_vmx.py +0 -0
  84. {dissect_hypervisor-3.16.dev2 → dissect_hypervisor-3.17.dev1}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.hypervisor
3
- Version: 3.16.dev2
3
+ Version: 3.17.dev1
4
4
  Summary: A Dissect module implementing parsers for various hypervisor disk, backup and configuration files
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License: Affero General Public License v3
@@ -4,6 +4,7 @@ import ctypes
4
4
  import io
5
5
  import logging
6
6
  import os
7
+ import re
7
8
  import textwrap
8
9
  import zlib
9
10
  from bisect import bisect_right
@@ -401,8 +402,25 @@ class SparseExtentHeader:
401
402
  return getattr(self.hdr, attr)
402
403
 
403
404
 
405
+ RE_EXTENT_DESCRIPTOR = re.compile(
406
+ r"""
407
+ ^
408
+ (?P<access_mode>RW|RDONLY|NOACCESS)\s
409
+ (?P<sectors>\d+)\s
410
+ (?P<type>SPARSE|ZERO|FLAT|VMFS|VMFSSPARSE|VMFSRDM|VMFSRAW)
411
+ (\s(?P<filename>\".+\"))?
412
+ (\s(?P<start_sector>\d+))?
413
+ (\s(?P<partition_uuid>\S+))?
414
+ (\s(?P<device_identifier>\S+))?
415
+ $
416
+ """,
417
+ re.VERBOSE,
418
+ )
419
+
420
+
404
421
  @dataclass
405
422
  class ExtentDescriptor:
423
+ raw: str
406
424
  access_mode: str
407
425
  sectors: int
408
426
  type: str
@@ -412,7 +430,6 @@ class ExtentDescriptor:
412
430
  device_identifier: str | None = None
413
431
 
414
432
  def __post_init__(self) -> None:
415
- self._raw = " ".join(map(str, [v for v in self.__dict__.values() if v is not None]))
416
433
  self.sectors = int(self.sectors)
417
434
 
418
435
  if self.filename:
@@ -422,10 +439,10 @@ class ExtentDescriptor:
422
439
  self.start_sector = int(self.start_sector)
423
440
 
424
441
  def __repr__(self) -> str:
425
- return f"<ExtentDescriptor {self._raw}>"
442
+ return f"<ExtentDescriptor {self.raw}>"
426
443
 
427
444
  def __str__(self) -> str:
428
- return self._raw
445
+ return self.raw
429
446
 
430
447
 
431
448
  class DiskDescriptor:
@@ -458,14 +475,13 @@ class DiskDescriptor:
458
475
  continue
459
476
 
460
477
  if line.startswith("RW ") or line.startswith("RDONLY ") or line.startswith("NOACCESS "):
461
- # Extent descriptors can have up to seven values according to libvmdk documentation.
462
- parts = line.split(" ", maxsplit=6)
478
+ match = RE_EXTENT_DESCRIPTOR.search(line)
463
479
 
464
- if len(parts) < 3:
480
+ if not match:
465
481
  log.warning("Unexpected ExtentDescriptor format in vmdk config: %s, ignoring", line)
466
482
  continue
467
483
 
468
- extent = ExtentDescriptor(*parts)
484
+ extent = ExtentDescriptor(raw=line, **match.groupdict())
469
485
  sectors += extent.sectors
470
486
  extents.append(extent)
471
487
  continue
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.hypervisor
3
- Version: 3.16.dev2
3
+ Version: 3.17.dev1
4
4
  Summary: A Dissect module implementing parsers for various hypervisor disk, backup and configuration files
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License: Affero General Public License v3
@@ -0,0 +1,199 @@
1
+ import pytest
2
+
3
+ from dissect.hypervisor.disk.c_vmdk import c_vmdk
4
+ from dissect.hypervisor.disk.vmdk import VMDK, DiskDescriptor, ExtentDescriptor
5
+
6
+
7
+ def test_vmdk_sesparse(sesparse_vmdk):
8
+ vmdk = VMDK(sesparse_vmdk)
9
+
10
+ disk = vmdk.disks[0]
11
+
12
+ assert disk.is_sesparse
13
+ assert disk._grain_directory_size == 0x20000
14
+ assert disk._grain_table_size == 0x1000
15
+ assert disk._grain_entry_type == c_vmdk.uint64
16
+ assert disk._grain_directory[0] == 0x1000000000000000
17
+
18
+ header = disk.header
19
+ assert header.magic == c_vmdk.SESPARSE_CONST_HEADER_MAGIC
20
+ assert header.version == 0x200000001
21
+
22
+ assert vmdk.read(0x1000000) == b"a" * 0x1000000
23
+
24
+
25
+ @pytest.mark.parametrize(
26
+ "extent_description, expected_extents",
27
+ [
28
+ (
29
+ 'RW 123456789 SPARSE "disk.vmdk"',
30
+ [
31
+ ExtentDescriptor(
32
+ raw='RW 123456789 SPARSE "disk.vmdk"',
33
+ access_mode="RW",
34
+ sectors=123456789,
35
+ type="SPARSE",
36
+ filename='"disk.vmdk"',
37
+ start_sector=None,
38
+ partition_uuid=None,
39
+ device_identifier=None,
40
+ ),
41
+ ],
42
+ ),
43
+ (
44
+ 'RW 123456789 FLAT "disk-flat.vmdk" 0',
45
+ [
46
+ ExtentDescriptor(
47
+ raw='RW 123456789 FLAT "disk-flat.vmdk" 0',
48
+ access_mode="RW",
49
+ sectors=123456789,
50
+ type="FLAT",
51
+ filename='"disk-flat.vmdk"',
52
+ start_sector=0,
53
+ partition_uuid=None,
54
+ device_identifier=None,
55
+ )
56
+ ],
57
+ ),
58
+ (
59
+ "RDONLY 0 ZERO",
60
+ [
61
+ ExtentDescriptor(
62
+ raw="RDONLY 0 ZERO",
63
+ access_mode="RDONLY",
64
+ sectors=0,
65
+ type="ZERO",
66
+ ),
67
+ ],
68
+ ),
69
+ (
70
+ 'NOACCESS 123456789 SPARSE "disk-sparse.vmdk" 123 partition-uuid device-id',
71
+ [
72
+ ExtentDescriptor(
73
+ raw='NOACCESS 123456789 SPARSE "disk-sparse.vmdk" 123 partition-uuid device-id',
74
+ access_mode="NOACCESS",
75
+ sectors=123456789,
76
+ type="SPARSE",
77
+ filename='"disk-sparse.vmdk"',
78
+ start_sector=123,
79
+ partition_uuid="partition-uuid",
80
+ device_identifier="device-id",
81
+ ),
82
+ ],
83
+ ),
84
+ ("RW 1234567890", []),
85
+ ('RDONLY "file.vmdk"', []),
86
+ ("NOACCESS", []),
87
+ (
88
+ 'RW 1234567890 SPARSE "disk with spaces.vmdk"',
89
+ [
90
+ ExtentDescriptor(
91
+ raw='RW 1234567890 SPARSE "disk with spaces.vmdk"',
92
+ access_mode="RW",
93
+ sectors=1234567890,
94
+ type="SPARSE",
95
+ filename='"disk with spaces.vmdk"',
96
+ start_sector=None,
97
+ partition_uuid=None,
98
+ device_identifier=None,
99
+ )
100
+ ],
101
+ ),
102
+ (
103
+ 'RW 1234567890 SPARSE "disk with spaces.vmdk" 123',
104
+ [
105
+ ExtentDescriptor(
106
+ raw='RW 1234567890 SPARSE "disk with spaces.vmdk" 123',
107
+ access_mode="RW",
108
+ sectors=1234567890,
109
+ type="SPARSE",
110
+ filename='"disk with spaces.vmdk"',
111
+ start_sector=123,
112
+ partition_uuid=None,
113
+ device_identifier=None,
114
+ )
115
+ ],
116
+ ),
117
+ (
118
+ 'RW 1234567890 SPARSE "disk with spaces.vmdk" 123 part-uuid',
119
+ [
120
+ ExtentDescriptor(
121
+ raw='RW 1234567890 SPARSE "disk with spaces.vmdk" 123 part-uuid',
122
+ access_mode="RW",
123
+ sectors=1234567890,
124
+ type="SPARSE",
125
+ filename='"disk with spaces.vmdk"',
126
+ start_sector=123,
127
+ partition_uuid="part-uuid",
128
+ device_identifier=None,
129
+ )
130
+ ],
131
+ ),
132
+ (
133
+ 'RW 1234567890 SPARSE "disk with spaces.vmdk" 123 part-uuid device-id',
134
+ [
135
+ ExtentDescriptor(
136
+ raw='RW 1234567890 SPARSE "disk with spaces.vmdk" 123 part-uuid device-id',
137
+ access_mode="RW",
138
+ sectors=1234567890,
139
+ type="SPARSE",
140
+ filename='"disk with spaces.vmdk"',
141
+ start_sector=123,
142
+ partition_uuid="part-uuid",
143
+ device_identifier="device-id",
144
+ )
145
+ ],
146
+ ),
147
+ (
148
+ r'RW 16777216 SPARSE "this is an example "\' diskëäô:)\\\'`\foo.vmdk" 123',
149
+ [
150
+ ExtentDescriptor(
151
+ raw=r'RW 16777216 SPARSE "this is an example "\' diskëäô:)\\\'`\foo.vmdk" 123',
152
+ access_mode="RW",
153
+ sectors=16777216,
154
+ type="SPARSE",
155
+ filename=r'"this is an example "\' diskëäô:)\\\'`\foo.vmdk"',
156
+ start_sector=123,
157
+ partition_uuid=None,
158
+ device_identifier=None,
159
+ )
160
+ ],
161
+ ),
162
+ (
163
+ r'RW 13371337 SPARSE "🦊 🦊 🦊.vmdk"',
164
+ [
165
+ ExtentDescriptor(
166
+ raw=r'RW 13371337 SPARSE "🦊 🦊 🦊.vmdk"',
167
+ access_mode="RW",
168
+ sectors=13371337,
169
+ type="SPARSE",
170
+ filename='"🦊 🦊 🦊.vmdk"',
171
+ )
172
+ ],
173
+ ),
174
+ ],
175
+ ids=(
176
+ "sparse",
177
+ "flat",
178
+ "zero",
179
+ "sparse-ids",
180
+ "bad-1",
181
+ "bad-2",
182
+ "bad-3",
183
+ "spaces-four-parts",
184
+ "spaces-five-parts",
185
+ "spaces-six-parts",
186
+ "spaces-seven-parts",
187
+ "specials-five-parts",
188
+ "emoji-four-parts",
189
+ ),
190
+ )
191
+ def test_vmdk_extent_description(extent_description: str, expected_extents: list) -> None:
192
+ """test if we correctly parse VMDK sparse and flat extent descriptions.
193
+
194
+ Resources:
195
+ - https://github.com/libyal/libvmdk/blob/main/documentation/VMWare%20Virtual%20Disk%20Format%20(VMDK).asciidoc#22-extent-descriptions
196
+ """ # noqa: E501
197
+
198
+ descriptor = DiskDescriptor.parse(extent_description)
199
+ assert descriptor.extents == expected_extents
@@ -1,93 +0,0 @@
1
- import pytest
2
-
3
- from dissect.hypervisor.disk.c_vmdk import c_vmdk
4
- from dissect.hypervisor.disk.vmdk import VMDK, DiskDescriptor, ExtentDescriptor
5
-
6
-
7
- def test_vmdk_sesparse(sesparse_vmdk):
8
- vmdk = VMDK(sesparse_vmdk)
9
-
10
- disk = vmdk.disks[0]
11
-
12
- assert disk.is_sesparse
13
- assert disk._grain_directory_size == 0x20000
14
- assert disk._grain_table_size == 0x1000
15
- assert disk._grain_entry_type == c_vmdk.uint64
16
- assert disk._grain_directory[0] == 0x1000000000000000
17
-
18
- header = disk.header
19
- assert header.magic == c_vmdk.SESPARSE_CONST_HEADER_MAGIC
20
- assert header.version == 0x200000001
21
-
22
- assert vmdk.read(0x1000000) == b"a" * 0x1000000
23
-
24
-
25
- @pytest.mark.parametrize(
26
- "extent_description, expected_extents",
27
- [
28
- (
29
- 'RW 123456789 SPARSE "disk.vmdk"',
30
- [
31
- ExtentDescriptor(
32
- access_mode="RW",
33
- sectors=123456789,
34
- type="SPARSE",
35
- filename="disk.vmdk",
36
- partition_uuid=None,
37
- device_identifier=None,
38
- ),
39
- ],
40
- ),
41
- (
42
- 'RW 123456789 FLAT "disk-flat.vmdk" 0',
43
- [
44
- ExtentDescriptor(
45
- access_mode="RW",
46
- sectors=123456789,
47
- type="FLAT",
48
- filename="disk-flat.vmdk",
49
- start_sector=0,
50
- partition_uuid=None,
51
- device_identifier=None,
52
- )
53
- ],
54
- ),
55
- (
56
- "RDONLY 0 ZERO",
57
- [
58
- ExtentDescriptor(
59
- access_mode="RDONLY",
60
- sectors=0,
61
- type="ZERO",
62
- ),
63
- ],
64
- ),
65
- (
66
- 'NOACCESS 123456789 SPARSE "disk-sparse.vmdk" 123 partition-uuid device-id',
67
- [
68
- ExtentDescriptor(
69
- access_mode="NOACCESS",
70
- sectors=123456789,
71
- type="SPARSE",
72
- filename="disk-sparse.vmdk",
73
- start_sector=123,
74
- partition_uuid="partition-uuid",
75
- device_identifier="device-id",
76
- ),
77
- ],
78
- ),
79
- ("RW 1234567890", []),
80
- ('RDONLY "file.vmdk"', []),
81
- ("NOACCESS", []),
82
- ],
83
- ids=("sparse", "flat", "zero", "sparse-ids", "bad-1", "bad-2", "bad-3"),
84
- )
85
- def test_vmdk_extent_description(extent_description: str, expected_extents: list) -> None:
86
- """test if we correctly parse VMDK sparse and flat extent descriptions.
87
-
88
- Resources:
89
- - https://github.com/libyal/libvmdk/blob/main/documentation/VMWare%20Virtual%20Disk%20Format%20(VMDK).asciidoc#22-extent-descriptions
90
- """ # noqa: E501
91
-
92
- descriptor = DiskDescriptor.parse(extent_description)
93
- assert descriptor.extents == expected_extents