dissect.target 3.18.dev2__py3-none-any.whl → 3.18.dev3__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import platform
4
- from io import BytesIO
5
- from typing import BinaryIO, Iterable
4
+ from typing import BinaryIO, Iterator
6
5
 
7
6
  from dissect.cstruct import cstruct
8
7
  from dissect.util.stream import RangeStream
@@ -13,7 +12,11 @@ from dissect.target.plugin import export
13
12
  from dissect.target.plugins.os.unix.locate.locate import BaseLocatePlugin
14
13
 
15
14
  try:
16
- import zstandard # noqa
15
+ from zstandard import (
16
+ DECOMPRESSION_RECOMMENDED_OUTPUT_SIZE,
17
+ ZstdCompressionDict,
18
+ ZstdDecompressor,
19
+ )
17
20
 
18
21
  HAS_ZSTD = True
19
22
  except ImportError:
@@ -32,7 +35,7 @@ struct header {
32
35
  uint64_t filename_index_offset_bytes;
33
36
 
34
37
  /* Version 1 and up only. */
35
- uint32_t max_version;
38
+ uint32_t max_version; // Nominally 1 or 2, but can be increased if more features are added in a backward-compatible way.
36
39
  uint32_t zstd_dictionary_length_bytes;
37
40
  uint64_t zstd_dictionary_offset_bytes;
38
41
 
@@ -44,6 +47,7 @@ struct header {
44
47
  uint64_t conf_block_length_bytes;
45
48
  uint64_t conf_block_offset_bytes;
46
49
 
50
+ // Only if max_version >= 2.
47
51
  uint8_t check_visibility;
48
52
  char padding[7]; /* padding for alignment */
49
53
  };
@@ -51,7 +55,7 @@ struct header {
51
55
  struct file {
52
56
  char path[];
53
57
  };
54
- """
58
+ """ # noqa : E501
55
59
 
56
60
  PLocateRecord = TargetRecordDescriptor(
57
61
  "linux/locate/plocate",
@@ -104,40 +108,46 @@ class PLocateFile:
104
108
  self.dict_data = None
105
109
 
106
110
  if self.header.zstd_dictionary_offset_bytes:
107
- self.dict_data = zstandard.ZstdCompressionDict(self.fh.read(self.header.zstd_dictionary_length_bytes))
111
+ self.dict_data = ZstdCompressionDict(self.fh.read(self.header.zstd_dictionary_length_bytes))
108
112
 
109
113
  self.compressed_length_bytes = (
110
114
  self.header.filename_index_offset_bytes - self.HEADER_SIZE - self.header.zstd_dictionary_length_bytes
111
115
  )
112
- self.ctx = zstandard.ZstdDecompressor(dict_data=self.dict_data)
116
+ self.ctx = ZstdDecompressor(dict_data=self.dict_data)
113
117
  self.buf = RangeStream(self.fh, self.fh.tell(), self.compressed_length_bytes)
114
118
 
115
- def __iter__(self) -> Iterable[PLocateFile]:
119
+ def __iter__(self) -> Iterator[PLocateFile]:
116
120
  # NOTE: This is a workaround for a PyPy bug
117
121
  # We don't know what breaks, but PyPy + zstandard = unhappy times
118
122
  # You just get random garbage data back instead of the decompressed data
119
123
  # This weird dance of using a decompressobj and unused data is the only way that seems to work
120
124
  # It's more expensive on memory, but at least it doesn't break
121
125
  if platform.python_implementation() == "PyPy":
122
- obj = self.ctx.decompressobj()
123
126
  buf = self.buf.read()
124
127
 
125
- tmp = obj.decompress(buf)
126
- while unused_data := obj.unused_data:
127
- obj = self.ctx.decompressobj()
128
- tmp += obj.decompress(unused_data)
128
+ def reader(ctx: ZstdDecompressor) -> Iterator[bytes]:
129
+ obj = ctx.decompressobj()
129
130
 
130
- reader = BytesIO(tmp)
131
+ yield obj.decompress(buf)
132
+ while unused_data := obj.unused_data:
133
+ obj = self.ctx.decompressobj()
134
+ yield obj.decompress(unused_data)
135
+
136
+ it = reader(self.ctx)
131
137
  else:
132
- reader = self.ctx.stream_reader(self.buf)
133
-
134
- with reader:
135
- try:
136
- while True:
137
- file = c_plocate.file(reader)
138
- yield file.path.decode(errors="surrogateescape")
139
- except EOFError:
140
- return
138
+ # NOTE: The end of a zstandard frame does not include a final `0x00`.
139
+ # This causes the c_plocate `file` struct to parse the last path and the first path on the next frame as one
140
+ # since cstruct will read it across frame boundaries waiting for a `0x00`.
141
+ def reader() -> Iterator[bytes]:
142
+ with self.ctx.stream_reader(self.buf) as reader:
143
+ while chunk := reader.read(DECOMPRESSION_RECOMMENDED_OUTPUT_SIZE):
144
+ yield chunk
145
+
146
+ it = reader()
147
+
148
+ for chunk in it:
149
+ for path in chunk.split(b"\x00"):
150
+ yield path.decode(errors="surrogateescape")
141
151
 
142
152
  def filename_index(self) -> bytes:
143
153
  """Return the filename index of the plocate.db file."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dissect.target
3
- Version: 3.18.dev2
3
+ Version: 3.18.dev3
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
@@ -243,7 +243,7 @@ dissect/target/plugins/os/unix/locate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
243
243
  dissect/target/plugins/os/unix/locate/gnulocate.py,sha256=P-YbMFw901p2EBgTaZH6axShfIRRDrCx3APBy6Ii3lE,2934
244
244
  dissect/target/plugins/os/unix/locate/locate.py,sha256=uXFcWAqoz_3eNWHhsGoEtkkhmT5J3F1GYvr4uQxi308,122
245
245
  dissect/target/plugins/os/unix/locate/mlocate.py,sha256=DhrFgxDQF-fMZaA0WK8Z-5o9i9iDsuTHW7MHJtWwz6o,4485
246
- dissect/target/plugins/os/unix/locate/plocate.py,sha256=Skb24ba_MVzM4nuDaZHw-ZmomIEZ3TJ7g5kHCvQViko,6545
246
+ dissect/target/plugins/os/unix/locate/plocate.py,sha256=ShU-F9_31rGfMYXqaR_KrHXVxgDDRZMJ_zEMuekw57w,7229
247
247
  dissect/target/plugins/os/unix/log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
248
248
  dissect/target/plugins/os/unix/log/atop.py,sha256=DdiTf-gVJJvvPbR36khU4388lxQzABaWI-95jLCGgSw,16345
249
249
  dissect/target/plugins/os/unix/log/audit.py,sha256=OjorWTmCFvCI5RJq6m6WNW0Lhb-poB2VAggKOGZUHK4,3722
@@ -340,10 +340,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z
340
340
  dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
341
341
  dissect/target/volumes/md.py,sha256=j1K1iKmspl0C_OJFc7-Q1BMWN2OCC5EVANIgVlJ_fIE,1673
342
342
  dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
343
- dissect.target-3.18.dev2.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
344
- dissect.target-3.18.dev2.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
345
- dissect.target-3.18.dev2.dist-info/METADATA,sha256=CQlktWeUyWCrkDq9WKqNFR3gxHwKVUZ-9KDPop4n6s8,11299
346
- dissect.target-3.18.dev2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
347
- dissect.target-3.18.dev2.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
348
- dissect.target-3.18.dev2.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
349
- dissect.target-3.18.dev2.dist-info/RECORD,,
343
+ dissect.target-3.18.dev3.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
344
+ dissect.target-3.18.dev3.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
345
+ dissect.target-3.18.dev3.dist-info/METADATA,sha256=t5yUGDDtnDgTACRs1bUW1xJF2rlVMzxbFW0iWG5WRUw,11299
346
+ dissect.target-3.18.dev3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
347
+ dissect.target-3.18.dev3.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
348
+ dissect.target-3.18.dev3.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
349
+ dissect.target-3.18.dev3.dist-info/RECORD,,