dfindexeddb 20241031__py3-none-any.whl → 20251109__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.
Files changed (33) hide show
  1. dfindexeddb/indexeddb/chromium/blink.py +116 -74
  2. dfindexeddb/indexeddb/chromium/definitions.py +152 -124
  3. dfindexeddb/indexeddb/chromium/record.py +536 -348
  4. dfindexeddb/indexeddb/chromium/v8.py +112 -141
  5. dfindexeddb/indexeddb/cli.py +125 -114
  6. dfindexeddb/indexeddb/firefox/definitions.py +7 -4
  7. dfindexeddb/indexeddb/firefox/gecko.py +103 -79
  8. dfindexeddb/indexeddb/firefox/record.py +66 -24
  9. dfindexeddb/indexeddb/safari/definitions.py +12 -10
  10. dfindexeddb/indexeddb/safari/record.py +68 -51
  11. dfindexeddb/indexeddb/safari/webkit.py +112 -189
  12. dfindexeddb/indexeddb/types.py +5 -2
  13. dfindexeddb/leveldb/cli.py +146 -131
  14. dfindexeddb/leveldb/definitions.py +6 -2
  15. dfindexeddb/leveldb/descriptor.py +75 -45
  16. dfindexeddb/leveldb/ldb.py +39 -30
  17. dfindexeddb/leveldb/log.py +44 -27
  18. dfindexeddb/leveldb/plugins/chrome_notifications.py +30 -18
  19. dfindexeddb/leveldb/plugins/interface.py +5 -6
  20. dfindexeddb/leveldb/plugins/manager.py +11 -10
  21. dfindexeddb/leveldb/record.py +71 -62
  22. dfindexeddb/leveldb/utils.py +21 -13
  23. dfindexeddb/utils.py +35 -30
  24. dfindexeddb/version.py +2 -2
  25. dfindexeddb-20251109.dist-info/METADATA +222 -0
  26. dfindexeddb-20251109.dist-info/RECORD +40 -0
  27. {dfindexeddb-20241031.dist-info → dfindexeddb-20251109.dist-info}/WHEEL +1 -1
  28. dfindexeddb-20241031.dist-info/AUTHORS +0 -12
  29. dfindexeddb-20241031.dist-info/METADATA +0 -424
  30. dfindexeddb-20241031.dist-info/RECORD +0 -41
  31. {dfindexeddb-20241031.dist-info → dfindexeddb-20251109.dist-info}/entry_points.txt +0 -0
  32. {dfindexeddb-20241031.dist-info → dfindexeddb-20251109.dist-info/licenses}/LICENSE +0 -0
  33. {dfindexeddb-20241031.dist-info → dfindexeddb-20251109.dist-info}/top_level.txt +0 -0
@@ -14,26 +14,32 @@
14
14
  # limitations under the License.
15
15
  """Parses Chromium IndexedDb structures."""
16
16
  from __future__ import annotations
17
- from dataclasses import dataclass, field
18
- from datetime import datetime
17
+
19
18
  import io
20
19
  import pathlib
21
20
  import sys
22
21
  import traceback
23
- from typing import Any, BinaryIO, Generator, Optional, Tuple, Type, TypeVar, \
24
- Union
22
+ from dataclasses import dataclass, field
23
+ from datetime import datetime
24
+ from typing import (
25
+ Any,
26
+ BinaryIO,
27
+ Generator,
28
+ Optional,
29
+ Tuple,
30
+ Type,
31
+ TypeVar,
32
+ Union,
33
+ )
25
34
 
26
35
  from dfindexeddb import errors
27
- from dfindexeddb.indexeddb.chromium import blink
28
- from dfindexeddb.indexeddb.chromium import definitions
29
- from dfindexeddb.leveldb import record
30
- from dfindexeddb.leveldb import utils
31
-
36
+ from dfindexeddb.indexeddb.chromium import blink, definitions
37
+ from dfindexeddb.leveldb import record, utils
32
38
 
33
- T = TypeVar('T')
39
+ T = TypeVar("T")
34
40
 
35
41
 
36
- @dataclass
42
+ @dataclass(frozen=True)
37
43
  class KeyPrefix(utils.FromDecoderMixin):
38
44
  """The IndexedDB key prefix.
39
45
 
@@ -43,6 +49,7 @@ class KeyPrefix(utils.FromDecoderMixin):
43
49
  object_store_id: the object store ID.
44
50
  index_id: the index ID.
45
51
  """
52
+
46
53
  offset: int = field(compare=False)
47
54
  database_id: int
48
55
  object_store_id: int
@@ -50,7 +57,8 @@ class KeyPrefix(utils.FromDecoderMixin):
50
57
 
51
58
  @classmethod
52
59
  def FromDecoder(
53
- cls, decoder: utils.LevelDBDecoder, base_offset: int = 0) -> KeyPrefix:
60
+ cls, decoder: utils.LevelDBDecoder, base_offset: int = 0
61
+ ) -> KeyPrefix:
54
62
  """Decodes a KeyPrefix from the current position of a LevelDBDecoder.
55
63
 
56
64
  Args:
@@ -71,23 +79,24 @@ class KeyPrefix(utils.FromDecoderMixin):
71
79
  index_id_length = (raw_prefix[0] & 0x03) + 1
72
80
 
73
81
  if database_id_length < 1 or database_id_length > 8:
74
- raise errors.ParserError('Invalid database ID length')
82
+ raise errors.ParserError("Invalid database ID length")
75
83
 
76
84
  if object_store_id_length < 1 or object_store_id_length > 8:
77
- raise errors.ParserError('Invalid object store ID length')
85
+ raise errors.ParserError("Invalid object store ID length")
78
86
 
79
87
  if index_id_length < 1 or index_id_length > 4:
80
- raise errors.ParserError('Invalid index ID length')
88
+ raise errors.ParserError("Invalid index ID length")
81
89
 
82
- _, database_id = decoder.DecodeInt(database_id_length)
83
- _, object_store_id = decoder.DecodeInt(object_store_id_length)
84
- _, index_id = decoder.DecodeInt(index_id_length)
90
+ _, database_id = decoder.DecodeInt(database_id_length, signed=False)
91
+ _, object_store_id = decoder.DecodeInt(object_store_id_length, signed=False)
92
+ _, index_id = decoder.DecodeInt(index_id_length, signed=False)
85
93
 
86
94
  return cls(
87
95
  offset=base_offset + offset,
88
96
  database_id=database_id,
89
97
  object_store_id=object_store_id,
90
- index_id=index_id)
98
+ index_id=index_id,
99
+ )
91
100
 
92
101
  def GetKeyPrefixType(self) -> definitions.KeyPrefixType:
93
102
  """Returns the KeyPrefixType.
@@ -110,7 +119,8 @@ class KeyPrefix(utils.FromDecoderMixin):
110
119
  if self.index_id >= 30:
111
120
  return definitions.KeyPrefixType.INDEX_DATA
112
121
  raise errors.ParserError(
113
- f'Unknown KeyPrefixType (index_id={self.index_id})')
122
+ f"Unknown KeyPrefixType (index_id={self.index_id})"
123
+ )
114
124
 
115
125
 
116
126
  @dataclass
@@ -122,9 +132,10 @@ class IDBKey(utils.FromDecoderMixin):
122
132
  type: the type of the IDBKey.
123
133
  value: the value of the IDBKey.
124
134
  """
135
+
125
136
  offset: int = field(compare=False)
126
137
  type: definitions.IDBKeyType
127
- value: Union[list, bytes, str, float, datetime, None]
138
+ value: Union[list[Any], bytes, str, float, datetime, None]
128
139
 
129
140
  _MAXIMUM_DEPTH = 2000
130
141
 
@@ -132,7 +143,7 @@ class IDBKey(utils.FromDecoderMixin):
132
143
  def FromDecoder(
133
144
  cls,
134
145
  decoder: utils.LevelDBDecoder,
135
- base_offset: int = 0 #pylint: disable=unused-argument
146
+ base_offset: int = 0, # pylint: disable=unused-argument
136
147
  ) -> IDBKey:
137
148
  """Decodes an IDBKey from the current position of a LevelDBDecoder.
138
149
 
@@ -149,9 +160,13 @@ class IDBKey(utils.FromDecoderMixin):
149
160
  RecursionError: if maximum depth encountered during parsing.
150
161
  """
151
162
 
152
- def RecursiveParse(depth: int) -> Tuple[
153
- int, definitions.IDBKeyType, Union[
154
- list, bytes, str, float, datetime, None]]:
163
+ def RecursiveParse(
164
+ depth: int,
165
+ ) -> Tuple[
166
+ int,
167
+ definitions.IDBKeyType,
168
+ Union[list[Any], bytes, str, float, datetime, None],
169
+ ]:
155
170
  """Recursively parses IDBKeys.
156
171
 
157
172
  Args:
@@ -167,16 +182,17 @@ class IDBKey(utils.FromDecoderMixin):
167
182
  RecursionError: if maximum depth encountered during parsing.
168
183
  """
169
184
  if depth == cls._MAXIMUM_DEPTH:
170
- raise RecursionError('Maximum recursion depth encountered during parse')
185
+ raise RecursionError("Maximum recursion depth encountered during parse")
171
186
  offset, key_type_value = decoder.DecodeInt(1)
172
187
  key_type = definitions.IDBKeyType(key_type_value)
188
+ value: Any = None
173
189
 
174
190
  if key_type == definitions.IDBKeyType.NULL:
175
191
  value = None
176
192
  elif key_type == definitions.IDBKeyType.ARRAY:
177
193
  _, length = decoder.DecodeVarint()
178
194
  if length < 0:
179
- raise errors.ParserError('Invalid length encountered')
195
+ raise errors.ParserError("Invalid length encountered")
180
196
  value = []
181
197
  while length:
182
198
  entry = RecursiveParse(depth + 1)
@@ -188,13 +204,13 @@ class IDBKey(utils.FromDecoderMixin):
188
204
  _, value = decoder.DecodeStringWithLength()
189
205
  elif key_type == definitions.IDBKeyType.DATE:
190
206
  _, raw_value = decoder.DecodeDouble()
191
- value = datetime.utcfromtimestamp(raw_value/1000.0)
207
+ value = datetime.utcfromtimestamp(raw_value / 1000.0)
192
208
  elif key_type == definitions.IDBKeyType.NUMBER:
193
209
  _, value = decoder.DecodeDouble()
194
210
  elif key_type == definitions.IDBKeyType.MIN_KEY:
195
211
  value = None
196
212
  else:
197
- raise errors.ParserError('Invalid IndexedDbKeyType')
213
+ raise errors.ParserError("Invalid IndexedDbKeyType")
198
214
  return offset, key_type, value
199
215
 
200
216
  offset, key_type, value = RecursiveParse(0)
@@ -210,13 +226,15 @@ class IDBKeyPath(utils.FromDecoderMixin):
210
226
  type: the IDBKeyPath type.
211
227
  value: the IDBKeyPath value.
212
228
  """
229
+
213
230
  offset: int = field(compare=False)
214
231
  type: definitions.IDBKeyPathType
215
232
  value: Union[str, list[str], None]
216
233
 
217
234
  @classmethod
218
- def FromDecoder(cls, decoder: utils.LevelDBDecoder,
219
- base_offset: int = 0) -> IDBKeyPath:
235
+ def FromDecoder(
236
+ cls, decoder: utils.LevelDBDecoder, base_offset: int = 0
237
+ ) -> IDBKeyPath:
220
238
  """Decodes an IDBKeyPath from the current position of a LevelDBDecoder.
221
239
 
222
240
  Args:
@@ -228,13 +246,15 @@ class IDBKeyPath(utils.FromDecoderMixin):
228
246
 
229
247
  Raises:
230
248
  ParserError: on insufficient bytes or invalid array length during
231
- parsing.
249
+ parsing or unsupported key path type.
232
250
  """
233
- buffer = decoder.stream.getvalue() #pytype: disable=attribute-error
251
+ buffer = decoder.stream.getvalue() # type: ignore[attr-defined]
234
252
  if len(buffer) < 3:
235
- raise errors.ParserError('Insufficient bytes to parse.')
253
+ raise errors.ParserError("Insufficient bytes to parse.")
254
+
255
+ value: str | list[str] | None = None
236
256
 
237
- if buffer[0:2] != b'\x00\x00':
257
+ if buffer[0:2] != b"\x00\x00":
238
258
  offset, value = decoder.DecodeString()
239
259
  return IDBKeyPath(offset, definitions.IDBKeyPathType.STRING, value)
240
260
 
@@ -251,10 +271,12 @@ class IDBKeyPath(utils.FromDecoderMixin):
251
271
  value = []
252
272
  offset, count = decoder.DecodeVarint()
253
273
  if count < 0:
254
- raise errors.ParserError(f'Invalid array length {count}')
274
+ raise errors.ParserError(f"Invalid array length {count}")
255
275
  for _ in range(count):
256
276
  _, entry = decoder.DecodeStringWithLength()
257
277
  value.append(entry)
278
+ else:
279
+ raise errors.ParserError(f"Unsupported key_path_type {key_path_type}.")
258
280
  return IDBKeyPath(base_offset + offset, key_path_type, value)
259
281
 
260
282
 
@@ -267,13 +289,15 @@ class BlobJournalEntry(utils.FromDecoderMixin):
267
289
  database_id (int): the database ID.
268
290
  blob_number (int): the blob number.
269
291
  """
292
+
270
293
  offset: int = field(compare=False)
271
294
  database_id: int
272
295
  blob_number: int
273
296
 
274
297
  @classmethod
275
- def FromDecoder(cls, decoder: utils.LevelDBDecoder,
276
- base_offset: int = 0) -> BlobJournalEntry:
298
+ def FromDecoder(
299
+ cls, decoder: utils.LevelDBDecoder, base_offset: int = 0
300
+ ) -> BlobJournalEntry:
277
301
  """Decodes a BlobJournalEntry from the current position of a LevelDBDecoder.
278
302
 
279
303
  Args:
@@ -285,8 +309,11 @@ class BlobJournalEntry(utils.FromDecoderMixin):
285
309
  """
286
310
  offset, database_id = decoder.DecodeUint64Varint()
287
311
  _, blob_number = decoder.DecodeUint64Varint()
288
- return cls(offset=base_offset + offset, database_id=database_id,
289
- blob_number=blob_number)
312
+ return cls(
313
+ offset=base_offset + offset,
314
+ database_id=database_id,
315
+ blob_number=blob_number,
316
+ )
290
317
 
291
318
 
292
319
  @dataclass
@@ -297,12 +324,14 @@ class BlobJournal(utils.FromDecoderMixin):
297
324
  offset (int): the offset.
298
325
  entries (list[BlobJournalEntry]): the list of blob journal entries.
299
326
  """
327
+
300
328
  offset: int = field(compare=False)
301
329
  entries: list[BlobJournalEntry]
302
330
 
303
331
  @classmethod
304
- def FromDecoder(cls, decoder: utils.LevelDBDecoder,
305
- base_offset: int = 0) -> BlobJournal:
332
+ def FromDecoder(
333
+ cls, decoder: utils.LevelDBDecoder, base_offset: int = 0
334
+ ) -> BlobJournal:
306
335
  """Decodes a BlobJournal from the current position of a LevelDBDecoder.
307
336
 
308
337
  Blob journals are zero-or-more instances of BlobJournalEntry. There is no
@@ -342,6 +371,7 @@ class BaseIndexedDBKey:
342
371
  offset: the offset of the key (after the key_prefix).
343
372
  key_prefix: the key prefix.
344
373
  """
374
+
345
375
  offset: int
346
376
  key_prefix: KeyPrefix
347
377
 
@@ -356,7 +386,7 @@ class BaseIndexedDBKey:
356
386
  Raises:
357
387
  NotImplementedError.
358
388
  """
359
- raise NotImplementedError(f'{self.__class__.__name__}.decode_value')
389
+ raise NotImplementedError(f"{self.__class__.__name__}.decode_value")
360
390
 
361
391
  def ParseValue(self, value_data: bytes) -> Any:
362
392
  """Parses the value from raw bytes.
@@ -374,11 +404,11 @@ class BaseIndexedDBKey:
374
404
 
375
405
  @classmethod
376
406
  def FromDecoder(
377
- cls: T,
407
+ cls: Type[T],
378
408
  decoder: utils.LevelDBDecoder,
379
409
  key_prefix: KeyPrefix,
380
- base_offset: int = 0
381
- ) -> T: #pylint: disable=unused-variable
410
+ base_offset: int = 0,
411
+ ) -> T: # pylint: disable=unused-variable
382
412
  """Decodes the remaining key data from the current decoder position.
383
413
 
384
414
  Args:
@@ -392,11 +422,10 @@ class BaseIndexedDBKey:
392
422
  Raises:
393
423
  NotImplementedError.
394
424
  """
395
- raise NotImplementedError(f'{cls.__class__.__name__}.decode_key')
425
+ raise NotImplementedError(f"{cls.__class__.__name__}.decode_key")
396
426
 
397
427
  @classmethod
398
- def FromStream(
399
- cls: Type[T], stream: BinaryIO, base_offset: int = 0) -> T:
428
+ def FromStream(cls: Type[T], stream: BinaryIO, base_offset: int = 0) -> T:
400
429
  """Parses the key from the current position of the binary stream.
401
430
 
402
431
  Args:
@@ -408,12 +437,12 @@ class BaseIndexedDBKey:
408
437
  """
409
438
  decoder = utils.LevelDBDecoder(stream)
410
439
  key_prefix = KeyPrefix.FromDecoder(decoder, base_offset=base_offset)
411
- return cls.FromDecoder(
412
- decoder=decoder, key_prefix=key_prefix, base_offset=base_offset)
440
+ return cls.FromDecoder( # type: ignore[no-any-return,attr-defined]
441
+ decoder=decoder, key_prefix=key_prefix, base_offset=base_offset
442
+ )
413
443
 
414
444
  @classmethod
415
- def FromBytes(
416
- cls: Type[T], raw_data: bytes, base_offset: int = 0) -> T:
445
+ def FromBytes(cls: Type[T], raw_data: bytes, base_offset: int = 0) -> T:
417
446
  """Parses the key from the raw key bytes.
418
447
 
419
448
  Args:
@@ -424,7 +453,9 @@ class BaseIndexedDBKey:
424
453
  The decoded key.
425
454
  """
426
455
  stream = io.BytesIO(raw_data)
427
- return cls.FromStream(stream=stream, base_offset=base_offset)
456
+ return cls.FromStream( # type: ignore[no-any-return,attr-defined]
457
+ stream=stream, base_offset=base_offset
458
+ )
428
459
 
429
460
 
430
461
  @dataclass
@@ -433,17 +464,19 @@ class SchemaVersionKey(BaseIndexedDBKey):
433
464
 
434
465
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
435
466
  """Decodes the schema version value."""
436
- return decoder.DecodeVarint()[1]
467
+ return decoder.DecodeInt()[1]
437
468
 
438
469
  @classmethod
439
470
  def FromDecoder(
440
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
441
- base_offset: int = 0
471
+ cls,
472
+ decoder: utils.LevelDBDecoder,
473
+ key_prefix: KeyPrefix,
474
+ base_offset: int = 0,
442
475
  ) -> SchemaVersionKey:
443
476
  """Decodes the schema version key."""
444
477
  offset, key_type = decoder.DecodeUint8()
445
478
  if key_type != definitions.GlobalMetadataKeyType.SCHEMA_VERSION:
446
- raise errors.ParserError('Not a SchemaVersionKey')
479
+ raise errors.ParserError("Not a SchemaVersionKey")
447
480
  return cls(offset=base_offset + offset, key_prefix=key_prefix)
448
481
 
449
482
 
@@ -453,17 +486,19 @@ class MaxDatabaseIdKey(BaseIndexedDBKey):
453
486
 
454
487
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
455
488
  """Decodes the maximum database value."""
456
- return decoder.DecodeVarint()[1]
489
+ return decoder.DecodeInt()[1]
457
490
 
458
491
  @classmethod
459
492
  def FromDecoder(
460
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
461
- base_offset: int = 0
493
+ cls,
494
+ decoder: utils.LevelDBDecoder,
495
+ key_prefix: KeyPrefix,
496
+ base_offset: int = 0,
462
497
  ) -> MaxDatabaseIdKey:
463
498
  """Decodes the maximum database key."""
464
499
  offset, key_type = decoder.DecodeUint8()
465
500
  if key_type != definitions.GlobalMetadataKeyType.MAX_DATABASE_ID:
466
- raise errors.ParserError('Not a MaxDatabaseIdKey')
501
+ raise errors.ParserError("Not a MaxDatabaseIdKey")
467
502
  return cls(offset=base_offset + offset, key_prefix=key_prefix)
468
503
 
469
504
 
@@ -473,17 +508,19 @@ class DataVersionKey(BaseIndexedDBKey):
473
508
 
474
509
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
475
510
  """Decodes the data version value."""
476
- return decoder.DecodeUint64Varint()[1]
511
+ return decoder.DecodeInt()[1]
477
512
 
478
513
  @classmethod
479
514
  def FromDecoder(
480
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
481
- base_offset: int = 0
515
+ cls,
516
+ decoder: utils.LevelDBDecoder,
517
+ key_prefix: KeyPrefix,
518
+ base_offset: int = 0,
482
519
  ) -> DataVersionKey:
483
520
  """Decodes the data version key."""
484
521
  offset, key_type = decoder.DecodeUint8()
485
522
  if key_type != definitions.GlobalMetadataKeyType.DATA_VERSION:
486
- raise errors.ParserError('Not a DataVersionKey')
523
+ raise errors.ParserError("Not a DataVersionKey")
487
524
  return cls(offset=base_offset + offset, key_prefix=key_prefix)
488
525
 
489
526
 
@@ -497,13 +534,15 @@ class RecoveryBlobJournalKey(BaseIndexedDBKey):
497
534
 
498
535
  @classmethod
499
536
  def FromDecoder(
500
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
501
- base_offset: int = 0
537
+ cls,
538
+ decoder: utils.LevelDBDecoder,
539
+ key_prefix: KeyPrefix,
540
+ base_offset: int = 0,
502
541
  ) -> RecoveryBlobJournalKey:
503
542
  """Decodes the recovery blob journal key."""
504
543
  offset, key_type = decoder.DecodeUint8()
505
544
  if key_type != definitions.GlobalMetadataKeyType.RECOVERY_BLOB_JOURNAL:
506
- raise errors.ParserError('Not a RecoveryBlobJournalKey')
545
+ raise errors.ParserError("Not a RecoveryBlobJournalKey")
507
546
  return cls(offset=base_offset + offset, key_prefix=key_prefix)
508
547
 
509
548
 
@@ -517,13 +556,15 @@ class ActiveBlobJournalKey(BaseIndexedDBKey):
517
556
 
518
557
  @classmethod
519
558
  def FromDecoder(
520
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
521
- base_offset: int = 0
559
+ cls,
560
+ decoder: utils.LevelDBDecoder,
561
+ key_prefix: KeyPrefix,
562
+ base_offset: int = 0,
522
563
  ) -> ActiveBlobJournalKey:
523
564
  """Decodes the active blob journal value."""
524
565
  offset, key_type = decoder.DecodeUint8()
525
566
  if key_type != definitions.GlobalMetadataKeyType.ACTIVE_BLOB_JOURNAL:
526
- raise errors.ParserError('Not a ActiveBlobJournalKey')
567
+ raise errors.ParserError("Not a ActiveBlobJournalKey")
527
568
  return cls(offset=base_offset + offset, key_prefix=key_prefix)
528
569
 
529
570
 
@@ -534,17 +575,19 @@ class EarliestSweepKey(BaseIndexedDBKey):
534
575
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
535
576
  """Decodes the earliest sweep value."""
536
577
  _, data = decoder.ReadBytes()
537
- return int.from_bytes(data, byteorder='little', signed=False)
578
+ return int.from_bytes(data, byteorder="little", signed=False)
538
579
 
539
580
  @classmethod
540
581
  def FromDecoder(
541
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
542
- base_offset: int = 0
582
+ cls,
583
+ decoder: utils.LevelDBDecoder,
584
+ key_prefix: KeyPrefix,
585
+ base_offset: int = 0,
543
586
  ) -> EarliestSweepKey:
544
587
  """Decodes the earliest sweep value."""
545
588
  offset, key_type = decoder.DecodeUint8()
546
589
  if key_type != definitions.GlobalMetadataKeyType.EARLIEST_SWEEP:
547
- raise errors.ParserError('Not a EarliestSweepKey')
590
+ raise errors.ParserError("Not a EarliestSweepKey")
548
591
  return cls(offset=base_offset + offset, key_prefix=key_prefix)
549
592
 
550
593
 
@@ -555,17 +598,19 @@ class EarliestCompactionTimeKey(BaseIndexedDBKey):
555
598
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
556
599
  """Decodes the earliest compaction time value."""
557
600
  _, data = decoder.ReadBytes()
558
- return int.from_bytes(data, byteorder='little', signed=False)
601
+ return int.from_bytes(data, byteorder="little", signed=False)
559
602
 
560
603
  @classmethod
561
604
  def FromDecoder(
562
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
563
- base_offset: int = 0
605
+ cls,
606
+ decoder: utils.LevelDBDecoder,
607
+ key_prefix: KeyPrefix,
608
+ base_offset: int = 0,
564
609
  ) -> EarliestCompactionTimeKey:
565
610
  """Decodes the earliest compaction time key."""
566
611
  offset, key_type = decoder.DecodeUint8()
567
612
  if key_type != definitions.GlobalMetadataKeyType.EARLIEST_COMPACTION_TIME:
568
- raise errors.ParserError('Not a EarliestCompactionTimeKey')
613
+ raise errors.ParserError("Not a EarliestCompactionTimeKey")
569
614
  return cls(offset=base_offset + offset, key_prefix=key_prefix)
570
615
 
571
616
 
@@ -575,19 +620,21 @@ class ScopesPrefixKey(BaseIndexedDBKey):
575
620
 
576
621
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> Optional[bytes]:
577
622
  """Decodes the scopes prefix value."""
578
- if decoder.NumRemainingBytes:
623
+ if decoder.NumRemainingBytes():
579
624
  return decoder.ReadBytes()[1]
580
625
  return None
581
626
 
582
627
  @classmethod
583
628
  def FromDecoder(
584
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
585
- base_offset: int = 0
629
+ cls,
630
+ decoder: utils.LevelDBDecoder,
631
+ key_prefix: KeyPrefix,
632
+ base_offset: int = 0,
586
633
  ) -> ScopesPrefixKey:
587
634
  """Decodes the scopes prefix key."""
588
635
  offset, key_type = decoder.DecodeUint8()
589
636
  if key_type != definitions.GlobalMetadataKeyType.SCOPES_PREFIX:
590
- raise errors.ParserError('Not a ScopesPrefixKey')
637
+ raise errors.ParserError("Not a ScopesPrefixKey")
591
638
  return cls(offset=base_offset + offset, key_prefix=key_prefix)
592
639
 
593
640
 
@@ -598,25 +645,30 @@ class DatabaseFreeListKey(BaseIndexedDBKey):
598
645
  Attributes:
599
646
  database_id: the database ID.
600
647
  """
648
+
601
649
  database_id: int
602
650
 
603
- def DecodeValue(self, decoder: utils.LevelDBDecoder):
651
+ def DecodeValue(self, decoder: utils.LevelDBDecoder) -> None:
604
652
  """Decodes the database free list value."""
605
- raise NotImplementedError('DatabaseFreeListKey.decode_value')
653
+ raise NotImplementedError("DatabaseFreeListKey.decode_value")
606
654
 
607
655
  @classmethod
608
656
  def FromDecoder(
609
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
610
- base_offset: int = 0
657
+ cls,
658
+ decoder: utils.LevelDBDecoder,
659
+ key_prefix: KeyPrefix,
660
+ base_offset: int = 0,
611
661
  ) -> DatabaseFreeListKey:
612
662
  """Decodes the database free list key."""
613
663
  offset, key_type = decoder.DecodeUint8()
614
664
  if key_type != definitions.GlobalMetadataKeyType.DATABASE_FREE_LIST:
615
- raise errors.ParserError('Not a DatabaseFreeListKey')
665
+ raise errors.ParserError("Not a DatabaseFreeListKey")
616
666
  _, database_id = decoder.DecodeVarint()
617
667
  return cls(
618
- offset=base_offset + offset, key_prefix=key_prefix,
619
- database_id=database_id)
668
+ offset=base_offset + offset,
669
+ key_prefix=key_prefix,
670
+ database_id=database_id,
671
+ )
620
672
 
621
673
 
622
674
  @dataclass
@@ -627,6 +679,7 @@ class DatabaseNameKey(BaseIndexedDBKey):
627
679
  origin: the origin of the database.
628
680
  database_name: the database name.
629
681
  """
682
+
630
683
  origin: str
631
684
  database_name: str
632
685
 
@@ -635,49 +688,47 @@ class DatabaseNameKey(BaseIndexedDBKey):
635
688
 
636
689
  The value is the corresponding database ID.
637
690
  """
638
- return decoder.DecodeVarint()[1]
691
+ return decoder.DecodeInt()[1]
639
692
 
640
693
  @classmethod
641
694
  def FromDecoder(
642
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
643
- base_offset: int = 0
695
+ cls,
696
+ decoder: utils.LevelDBDecoder,
697
+ key_prefix: KeyPrefix,
698
+ base_offset: int = 0,
644
699
  ) -> DatabaseNameKey:
645
700
  """Decodes the database name key."""
646
701
  offset, key_type = decoder.DecodeUint8()
647
702
  if key_type != definitions.GlobalMetadataKeyType.DATABASE_NAME:
648
- raise errors.ParserError('Not a DatabaseNameKey')
703
+ raise errors.ParserError("Not a DatabaseNameKey")
649
704
  _, origin = decoder.DecodeStringWithLength()
650
705
  _, database_name = decoder.DecodeStringWithLength()
651
706
  return cls(
652
- offset=base_offset + offset, key_prefix=key_prefix, origin=origin,
653
- database_name=database_name)
707
+ offset=base_offset + offset,
708
+ key_prefix=key_prefix,
709
+ origin=origin,
710
+ database_name=database_name,
711
+ )
654
712
 
655
713
 
656
714
  @dataclass
657
715
  class GlobalMetaDataKey(BaseIndexedDBKey):
658
716
  """A GlobalMetaDataKey parser."""
659
717
 
718
+ # pylint: disable=line-too-long
660
719
  METADATA_TYPE_TO_CLASS = {
661
- definitions.GlobalMetadataKeyType
662
- .SCHEMA_VERSION: SchemaVersionKey,
663
- definitions.GlobalMetadataKeyType
664
- .MAX_DATABASE_ID: MaxDatabaseIdKey,
665
- definitions.GlobalMetadataKeyType
666
- .DATA_VERSION: DataVersionKey,
667
- definitions.GlobalMetadataKeyType
668
- .RECOVERY_BLOB_JOURNAL: RecoveryBlobJournalKey,
669
- definitions.GlobalMetadataKeyType
670
- .ACTIVE_BLOB_JOURNAL: ActiveBlobJournalKey,
671
- definitions.GlobalMetadataKeyType
672
- .EARLIEST_SWEEP: EarliestSweepKey,
673
- definitions.GlobalMetadataKeyType
674
- .EARLIEST_COMPACTION_TIME: EarliestCompactionTimeKey,
675
- definitions.GlobalMetadataKeyType
676
- .SCOPES_PREFIX: ScopesPrefixKey,
677
- definitions.GlobalMetadataKeyType
678
- .DATABASE_FREE_LIST: DatabaseFreeListKey,
679
- definitions.GlobalMetadataKeyType
680
- .DATABASE_NAME: DatabaseNameKey}
720
+ definitions.GlobalMetadataKeyType.ACTIVE_BLOB_JOURNAL: ActiveBlobJournalKey,
721
+ definitions.GlobalMetadataKeyType.DATA_VERSION: DataVersionKey,
722
+ definitions.GlobalMetadataKeyType.DATABASE_FREE_LIST: DatabaseFreeListKey,
723
+ definitions.GlobalMetadataKeyType.DATABASE_NAME: DatabaseNameKey,
724
+ definitions.GlobalMetadataKeyType.EARLIEST_COMPACTION_TIME: EarliestCompactionTimeKey,
725
+ definitions.GlobalMetadataKeyType.EARLIEST_SWEEP: EarliestSweepKey,
726
+ definitions.GlobalMetadataKeyType.MAX_DATABASE_ID: MaxDatabaseIdKey,
727
+ definitions.GlobalMetadataKeyType.RECOVERY_BLOB_JOURNAL: RecoveryBlobJournalKey,
728
+ definitions.GlobalMetadataKeyType.SCHEMA_VERSION: SchemaVersionKey,
729
+ definitions.GlobalMetadataKeyType.SCOPES_PREFIX: ScopesPrefixKey,
730
+ }
731
+ # pylint: enable=line-too-long
681
732
 
682
733
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> Any:
683
734
  """Decodes the value from the current position of the LevelDBDecoder.
@@ -688,18 +739,22 @@ class GlobalMetaDataKey(BaseIndexedDBKey):
688
739
 
689
740
  @classmethod
690
741
  def FromDecoder(
691
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
692
- base_offset: int = 0
693
- ) -> Union[Type[ActiveBlobJournalKey],
694
- Type[DataVersionKey],
695
- Type[DatabaseFreeListKey],
696
- Type[DatabaseNameKey],
697
- Type[EarliestSweepKey],
698
- Type[EarliestCompactionTimeKey],
699
- Type[MaxDatabaseIdKey],
700
- Type[RecoveryBlobJournalKey],
701
- Type[SchemaVersionKey],
702
- Type[ScopesPrefixKey]]:
742
+ cls,
743
+ decoder: utils.LevelDBDecoder,
744
+ key_prefix: KeyPrefix,
745
+ base_offset: int = 0,
746
+ ) -> Union[
747
+ ActiveBlobJournalKey,
748
+ DataVersionKey,
749
+ DatabaseFreeListKey,
750
+ DatabaseNameKey,
751
+ EarliestSweepKey,
752
+ EarliestCompactionTimeKey,
753
+ MaxDatabaseIdKey,
754
+ RecoveryBlobJournalKey,
755
+ SchemaVersionKey,
756
+ ScopesPrefixKey,
757
+ ]:
703
758
  """Decodes the global metadata key.
704
759
 
705
760
  Raises:
@@ -710,9 +765,10 @@ class GlobalMetaDataKey(BaseIndexedDBKey):
710
765
 
711
766
  key_class = cls.METADATA_TYPE_TO_CLASS.get(metadata_type)
712
767
  if not key_class:
713
- raise errors.ParserError('Unknown metadata key type')
714
- return key_class.FromDecoder(
715
- decoder, key_prefix, base_offset) #pytype: disable=bad-return-type
768
+ raise errors.ParserError("Unknown metadata key type")
769
+ return key_class.FromDecoder( # type: ignore[attr-defined,no-any-return]
770
+ decoder, key_prefix, base_offset
771
+ )
716
772
 
717
773
 
718
774
  @dataclass
@@ -722,25 +778,30 @@ class ObjectStoreFreeListKey(BaseIndexedDBKey):
722
778
  Attributes:
723
779
  object_store_id: the ID of the object store containing the free list.
724
780
  """
781
+
725
782
  object_store_id: int
726
783
 
727
- def DecodeValue(self, decoder: utils.LevelDBDecoder):
784
+ def DecodeValue(self, decoder: utils.LevelDBDecoder) -> None:
728
785
  """Decodes the object store free list value."""
729
- raise NotImplementedError('ObjectStoreFreeListKey.decode_value')
786
+ raise NotImplementedError("ObjectStoreFreeListKey.decode_value")
730
787
 
731
788
  @classmethod
732
789
  def FromDecoder(
733
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
734
- base_offset: int = 0
790
+ cls,
791
+ decoder: utils.LevelDBDecoder,
792
+ key_prefix: KeyPrefix,
793
+ base_offset: int = 0,
735
794
  ) -> ObjectStoreFreeListKey:
736
795
  """Decodes the object store free list key."""
737
796
  offset, key_type = decoder.DecodeUint8()
738
797
  if key_type != definitions.DatabaseMetaDataKeyType.OBJECT_STORE_FREE_LIST:
739
- raise errors.ParserError('Not am ObjectStoreFreeListKey')
798
+ raise errors.ParserError("Not am ObjectStoreFreeListKey")
740
799
  _, object_store_id = decoder.DecodeVarint()
741
800
  return cls(
742
- offset=base_offset + offset, key_prefix=key_prefix,
743
- object_store_id=object_store_id)
801
+ offset=base_offset + offset,
802
+ key_prefix=key_prefix,
803
+ object_store_id=object_store_id,
804
+ )
744
805
 
745
806
 
746
807
  @dataclass
@@ -750,25 +811,30 @@ class IndexFreeListKey(BaseIndexedDBKey):
750
811
  Attributes:
751
812
  object_store_id: the ID of the object store containing the free list.
752
813
  """
814
+
753
815
  object_store_id: int
754
816
 
755
- def DecodeValue(self, decoder: utils.LevelDBDecoder):
817
+ def DecodeValue(self, decoder: utils.LevelDBDecoder) -> None:
756
818
  """Decodes the index free list value."""
757
- raise NotImplementedError('IndexFreeListKey.decode_value')
819
+ raise NotImplementedError("IndexFreeListKey.decode_value")
758
820
 
759
821
  @classmethod
760
822
  def FromDecoder(
761
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
762
- base_offset: int = 0
763
- ) -> IndexFreeListKey:
823
+ cls,
824
+ decoder: utils.LevelDBDecoder,
825
+ key_prefix: KeyPrefix,
826
+ base_offset: int = 0,
827
+ ) -> IndexFreeListKey:
764
828
  """Decodes the index free list key."""
765
829
  offset, key_type = decoder.DecodeUint8()
766
830
  if key_type != definitions.DatabaseMetaDataKeyType.INDEX_FREE_LIST:
767
- raise errors.ParserError('Not am IndexFreeListKey')
831
+ raise errors.ParserError("Not am IndexFreeListKey")
768
832
  _, object_store_id = decoder.DecodeVarint()
769
833
  return cls(
770
- offset=base_offset + offset, key_prefix=key_prefix,
771
- object_store_id=object_store_id)
834
+ offset=base_offset + offset,
835
+ key_prefix=key_prefix,
836
+ object_store_id=object_store_id,
837
+ )
772
838
 
773
839
 
774
840
  @dataclass
@@ -778,22 +844,30 @@ class ObjectStoreNamesKey(BaseIndexedDBKey):
778
844
  Attributes:
779
845
  object_store_name: the name of the object store.
780
846
  """
847
+
781
848
  object_store_name: str
782
849
 
783
850
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
784
851
  """Decodes the object store names value."""
785
- return decoder.DecodeVarint()[1]
852
+ return decoder.DecodeInt()[1]
786
853
 
787
854
  @classmethod
788
- def FromDecoder(cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
789
- base_offset: int = 0) -> ObjectStoreNamesKey:
855
+ def FromDecoder(
856
+ cls,
857
+ decoder: utils.LevelDBDecoder,
858
+ key_prefix: KeyPrefix,
859
+ base_offset: int = 0,
860
+ ) -> ObjectStoreNamesKey:
790
861
  """Decodes the object store names key."""
791
862
  offset, key_type = decoder.DecodeUint8()
792
863
  if key_type != definitions.DatabaseMetaDataKeyType.OBJECT_STORE_NAMES:
793
- raise errors.ParserError('Not am ObjectStoreNamesKey')
864
+ raise errors.ParserError("Not am ObjectStoreNamesKey")
794
865
  _, object_store_name = decoder.DecodeStringWithLength()
795
- return cls(key_prefix=key_prefix, offset=base_offset + offset,
796
- object_store_name=object_store_name)
866
+ return cls(
867
+ key_prefix=key_prefix,
868
+ offset=base_offset + offset,
869
+ object_store_name=object_store_name,
870
+ )
797
871
 
798
872
 
799
873
  @dataclass
@@ -803,22 +877,30 @@ class IndexNamesKey(BaseIndexedDBKey):
803
877
  Attributes:
804
878
  index_name: the name of the index.
805
879
  """
880
+
806
881
  index_name: str
807
882
 
808
883
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
809
884
  """Decodes the index names value."""
810
- return decoder.DecodeVarint()[1]
885
+ return decoder.DecodeInt()[1]
811
886
 
812
887
  @classmethod
813
- def FromDecoder(cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
814
- base_offset: int = 0) -> IndexNamesKey:
888
+ def FromDecoder(
889
+ cls,
890
+ decoder: utils.LevelDBDecoder,
891
+ key_prefix: KeyPrefix,
892
+ base_offset: int = 0,
893
+ ) -> IndexNamesKey:
815
894
  """Decodes the index names key."""
816
895
  offset, key_type = decoder.DecodeUint8()
817
896
  if key_type != definitions.DatabaseMetaDataKeyType.INDEX_NAMES:
818
- raise errors.ParserError('Not am IndexNamesKey')
897
+ raise errors.ParserError("Not am IndexNamesKey")
819
898
  _, index_name = decoder.DecodeStringWithLength()
820
- return cls(key_prefix=key_prefix, offset=base_offset + offset,
821
- index_name=index_name)
899
+ return cls(
900
+ key_prefix=key_prefix,
901
+ offset=base_offset + offset,
902
+ index_name=index_name,
903
+ )
822
904
 
823
905
 
824
906
  @dataclass
@@ -828,39 +910,45 @@ class DatabaseMetaDataKey(BaseIndexedDBKey):
828
910
  Attributes:
829
911
  metadata_type: the type of metadata that the key value contains.
830
912
  """
913
+
831
914
  metadata_type: definitions.DatabaseMetaDataKeyType
832
915
 
833
- def DecodeValue(
834
- self, decoder: utils.LevelDBDecoder) -> Union[str, int]:
916
+ def DecodeValue(self, decoder: utils.LevelDBDecoder) -> Union[str, int]:
835
917
  """Decodes the database metadata value."""
836
- if (self.metadata_type ==
837
- definitions.DatabaseMetaDataKeyType.ORIGIN_NAME):
918
+ if self.metadata_type == definitions.DatabaseMetaDataKeyType.ORIGIN_NAME:
838
919
  return decoder.DecodeString()[1]
839
- if (self.metadata_type ==
840
- definitions.DatabaseMetaDataKeyType.DATABASE_NAME):
920
+ if self.metadata_type == definitions.DatabaseMetaDataKeyType.DATABASE_NAME:
841
921
  return decoder.DecodeString()[1]
842
- if (self.metadata_type ==
843
- definitions.DatabaseMetaDataKeyType.IDB_STRING_VERSION_DATA):
922
+ if (
923
+ self.metadata_type
924
+ == definitions.DatabaseMetaDataKeyType.IDB_STRING_VERSION_DATA
925
+ ):
844
926
  return decoder.DecodeString()[1]
845
- if (self.metadata_type ==
846
- definitions.DatabaseMetaDataKeyType.MAX_ALLOCATED_OBJECT_STORE_ID):
847
- return decoder.DecodeVarint()[1]
848
- if (self.metadata_type ==
849
- definitions.DatabaseMetaDataKeyType.IDB_INTEGER_VERSION):
927
+ if (
928
+ self.metadata_type
929
+ == definitions.DatabaseMetaDataKeyType.MAX_ALLOCATED_OBJECT_STORE_ID
930
+ ):
931
+ return decoder.DecodeInt()[1]
932
+ if (
933
+ self.metadata_type
934
+ == definitions.DatabaseMetaDataKeyType.IDB_INTEGER_VERSION
935
+ ):
850
936
  return decoder.DecodeVarint()[1]
851
- if (self.metadata_type ==
852
- definitions.DatabaseMetaDataKeyType
853
- .BLOB_NUMBER_GENERATOR_CURRENT_NUMBER):
937
+ if (
938
+ self.metadata_type
939
+ == definitions.DatabaseMetaDataKeyType.BLOB_NUMBER_GENERATOR_CURRENT_NUMBER # pylint: disable=line-too-long
940
+ ):
854
941
  return decoder.DecodeVarint()[1]
855
942
  raise errors.ParserError(
856
- f'Unknown database metadata type {self.metadata_type}')
943
+ f"Unknown database metadata type {self.metadata_type}"
944
+ )
857
945
 
858
946
  @classmethod
859
947
  def FromDecoder(
860
948
  cls,
861
949
  decoder: utils.LevelDBDecoder,
862
950
  key_prefix: KeyPrefix,
863
- base_offset: int = 0
951
+ base_offset: int = 0,
864
952
  ) -> Union[
865
953
  DatabaseMetaDataKey,
866
954
  IndexFreeListKey,
@@ -868,7 +956,8 @@ class DatabaseMetaDataKey(BaseIndexedDBKey):
868
956
  IndexNamesKey,
869
957
  ObjectStoreFreeListKey,
870
958
  ObjectStoreMetaDataKey,
871
- ObjectStoreNamesKey]:
959
+ ObjectStoreNamesKey,
960
+ ]:
872
961
  """Decodes the database metadata key."""
873
962
  offset, metadata_value = decoder.PeekBytes(1)
874
963
  metadata_type = definitions.DatabaseMetaDataKeyType(metadata_value[0])
@@ -879,32 +968,36 @@ class DatabaseMetaDataKey(BaseIndexedDBKey):
879
968
  definitions.DatabaseMetaDataKeyType.IDB_STRING_VERSION_DATA,
880
969
  definitions.DatabaseMetaDataKeyType.MAX_ALLOCATED_OBJECT_STORE_ID,
881
970
  definitions.DatabaseMetaDataKeyType.IDB_INTEGER_VERSION,
882
- definitions.DatabaseMetaDataKeyType
883
- .BLOB_NUMBER_GENERATOR_CURRENT_NUMBER):
884
- return cls(key_prefix=key_prefix, offset=base_offset + offset,
885
- metadata_type=metadata_type)
971
+ definitions.DatabaseMetaDataKeyType.BLOB_NUMBER_GENERATOR_CURRENT_NUMBER, # pylint: disable=line-too-long
972
+ ):
973
+ return cls(
974
+ key_prefix=key_prefix,
975
+ offset=base_offset + offset,
976
+ metadata_type=metadata_type,
977
+ )
886
978
  if metadata_type == definitions.DatabaseMetaDataKeyType.INDEX_META_DATA:
887
- return IndexMetaDataKey.FromDecoder(
888
- decoder, key_prefix, base_offset)
889
- if (metadata_type ==
890
- definitions.DatabaseMetaDataKeyType.OBJECT_STORE_META_DATA):
979
+ return IndexMetaDataKey.FromDecoder(decoder, key_prefix, base_offset)
980
+ if (
981
+ metadata_type
982
+ == definitions.DatabaseMetaDataKeyType.OBJECT_STORE_META_DATA
983
+ ):
891
984
  return ObjectStoreMetaDataKey.FromDecoder(
892
- decoder, key_prefix, base_offset)
893
- if (metadata_type ==
894
- definitions.DatabaseMetaDataKeyType.OBJECT_STORE_FREE_LIST):
985
+ decoder, key_prefix, base_offset
986
+ )
987
+ if (
988
+ metadata_type
989
+ == definitions.DatabaseMetaDataKeyType.OBJECT_STORE_FREE_LIST
990
+ ):
895
991
  return ObjectStoreFreeListKey.FromDecoder(
896
- decoder, key_prefix, base_offset)
992
+ decoder, key_prefix, base_offset
993
+ )
897
994
  if metadata_type == definitions.DatabaseMetaDataKeyType.INDEX_FREE_LIST:
898
- return IndexFreeListKey.FromDecoder(
899
- decoder, key_prefix, base_offset)
900
- if (metadata_type ==
901
- definitions.DatabaseMetaDataKeyType.OBJECT_STORE_NAMES):
902
- return ObjectStoreNamesKey.FromDecoder(
903
- decoder, key_prefix, base_offset)
995
+ return IndexFreeListKey.FromDecoder(decoder, key_prefix, base_offset)
996
+ if metadata_type == definitions.DatabaseMetaDataKeyType.OBJECT_STORE_NAMES:
997
+ return ObjectStoreNamesKey.FromDecoder(decoder, key_prefix, base_offset)
904
998
  if metadata_type == definitions.DatabaseMetaDataKeyType.INDEX_NAMES:
905
- return IndexNamesKey.FromDecoder(
906
- decoder, key_prefix, base_offset)
907
- raise errors.ParserError(f'unknown database metadata type {metadata_type}.')
999
+ return IndexNamesKey.FromDecoder(decoder, key_prefix, base_offset)
1000
+ raise errors.ParserError(f"unknown database metadata type {metadata_type}.")
908
1001
 
909
1002
 
910
1003
  @dataclass
@@ -915,68 +1008,91 @@ class ObjectStoreMetaDataKey(BaseIndexedDBKey):
915
1008
  object_store_id: the ID of the object store.
916
1009
  metadata_type: the object store metadata type.
917
1010
  """
1011
+
918
1012
  object_store_id: int
919
1013
  metadata_type: definitions.ObjectStoreMetaDataKeyType
920
1014
 
921
1015
  def DecodeValue(
922
- self, decoder: utils.LevelDBDecoder) -> Union[IDBKeyPath, str, bool, int]:
1016
+ self, decoder: utils.LevelDBDecoder
1017
+ ) -> Union[IDBKeyPath, str, bool, int]:
923
1018
  """Decodes the object store metadata value."""
924
- if (self.metadata_type ==
925
- definitions.ObjectStoreMetaDataKeyType.OBJECT_STORE_NAME):
1019
+ if (
1020
+ self.metadata_type
1021
+ == definitions.ObjectStoreMetaDataKeyType.OBJECT_STORE_NAME
1022
+ ):
926
1023
  return decoder.DecodeString()[1]
927
1024
  if self.metadata_type == definitions.ObjectStoreMetaDataKeyType.KEY_PATH:
928
1025
  return IDBKeyPath.FromDecoder(decoder)
929
- if (self.metadata_type ==
930
- definitions.ObjectStoreMetaDataKeyType.AUTO_INCREMENT_FLAG):
1026
+ if (
1027
+ self.metadata_type
1028
+ == definitions.ObjectStoreMetaDataKeyType.AUTO_INCREMENT_FLAG
1029
+ ):
931
1030
  return decoder.DecodeBool()[1]
932
- if (self.metadata_type ==
933
- definitions.ObjectStoreMetaDataKeyType.IS_EVICTABLE):
1031
+ if (
1032
+ self.metadata_type
1033
+ == definitions.ObjectStoreMetaDataKeyType.IS_EVICTABLE
1034
+ ):
934
1035
  return decoder.DecodeBool()[1]
935
- if (self.metadata_type ==
936
- definitions.ObjectStoreMetaDataKeyType.LAST_VERSION_NUMBER):
1036
+ if (
1037
+ self.metadata_type
1038
+ == definitions.ObjectStoreMetaDataKeyType.LAST_VERSION_NUMBER
1039
+ ):
937
1040
  return decoder.DecodeInt(signed=False)[1]
938
- if (self.metadata_type ==
939
- definitions.ObjectStoreMetaDataKeyType.MAXIMUM_ALLOCATED_INDEX_ID):
1041
+ if (
1042
+ self.metadata_type
1043
+ == definitions.ObjectStoreMetaDataKeyType.MAXIMUM_ALLOCATED_INDEX_ID
1044
+ ):
940
1045
  return decoder.DecodeInt()[1]
941
- if (self.metadata_type ==
942
- definitions.ObjectStoreMetaDataKeyType.HAS_KEY_PATH):
1046
+ if (
1047
+ self.metadata_type
1048
+ == definitions.ObjectStoreMetaDataKeyType.HAS_KEY_PATH
1049
+ ):
943
1050
  return decoder.DecodeBool()[1]
944
- if (self.metadata_type ==
945
- definitions.ObjectStoreMetaDataKeyType.KEY_GENERATOR_CURRENT_NUMBER):
1051
+ if (
1052
+ self.metadata_type
1053
+ == definitions.ObjectStoreMetaDataKeyType.KEY_GENERATOR_CURRENT_NUMBER
1054
+ ):
946
1055
  return decoder.DecodeInt()[1]
947
- raise errors.ParserError(f'Unknown metadata type {self.metadata_type}')
1056
+ raise errors.ParserError(f"Unknown metadata type {self.metadata_type}")
948
1057
 
949
1058
  @classmethod
950
1059
  def FromDecoder(
951
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
952
- base_offset: int = 0
1060
+ cls,
1061
+ decoder: utils.LevelDBDecoder,
1062
+ key_prefix: KeyPrefix,
1063
+ base_offset: int = 0,
953
1064
  ) -> ObjectStoreMetaDataKey:
954
1065
  """Decodes the object store metadata key."""
955
1066
  offset, metadata_value = decoder.DecodeUint8()
956
- if (metadata_value !=
957
- definitions.DatabaseMetaDataKeyType.OBJECT_STORE_META_DATA):
958
- raise errors.ParserError('Not a ObjectStoreMetaDataKey')
1067
+ if (
1068
+ metadata_value
1069
+ != definitions.DatabaseMetaDataKeyType.OBJECT_STORE_META_DATA
1070
+ ):
1071
+ raise errors.ParserError("Not a ObjectStoreMetaDataKey")
959
1072
 
960
1073
  _, object_store_id = decoder.DecodeVarint()
961
1074
  _, metadata_value = decoder.DecodeUint8()
962
1075
  metadata_type = definitions.ObjectStoreMetaDataKeyType(metadata_value)
963
1076
  return cls(
964
- offset=base_offset + offset, key_prefix=key_prefix,
965
- object_store_id=object_store_id, metadata_type=metadata_type)
1077
+ offset=base_offset + offset,
1078
+ key_prefix=key_prefix,
1079
+ object_store_id=object_store_id,
1080
+ metadata_type=metadata_type,
1081
+ )
1082
+
966
1083
 
967
1084
  @dataclass
968
1085
  class ObjectStoreDataValue:
969
1086
  """The parsed values from an ObjectStoreDataKey.
970
1087
 
971
1088
  Attributes:
972
- unknown: an unknown integer (possibly a sequence number?).
973
- is_wrapped: True if the value was wrapped.
1089
+ version: the version prefix.
974
1090
  blob_size: the blob size, only valid if wrapped.
975
1091
  blob_offset: the blob offset, only valid if wrapped.
976
1092
  value: the blink serialized value, only valid if not wrapped.
977
1093
  """
978
- unknown: int
979
- is_wrapped: bool
1094
+
1095
+ version: int
980
1096
  blob_size: Optional[int]
981
1097
  blob_offset: Optional[int]
982
1098
  value: Any
@@ -989,51 +1105,59 @@ class ObjectStoreDataKey(BaseIndexedDBKey):
989
1105
  Attributes:
990
1106
  encoded_user_key: the encoded user key.
991
1107
  """
1108
+
992
1109
  encoded_user_key: IDBKey
993
1110
 
994
- def DecodeValue(
995
- self, decoder: utils.LevelDBDecoder) -> ObjectStoreDataValue:
1111
+ def DecodeValue(self, decoder: utils.LevelDBDecoder) -> ObjectStoreDataValue:
996
1112
  """Decodes the object store data value."""
997
- _, unknown_integer = decoder.DecodeVarint()
1113
+ _, version = decoder.DecodeVarint()
998
1114
 
999
1115
  _, wrapped_header_bytes = decoder.PeekBytes(3)
1000
1116
  if len(wrapped_header_bytes) != 3:
1001
- raise errors.DecoderError('Insufficient bytes')
1002
-
1003
- if (wrapped_header_bytes[0] == definitions.BlinkSerializationTag.VERSION and
1004
- wrapped_header_bytes[1] == 0x11 and
1005
- wrapped_header_bytes[2] == 0x01):
1117
+ raise errors.DecoderError("Insufficient bytes")
1118
+
1119
+ if (
1120
+ wrapped_header_bytes[0] == definitions.BlinkSerializationTag.VERSION
1121
+ and wrapped_header_bytes[1]
1122
+ == definitions.REQUIRES_PROCESSING_SSV_PSEUDO_VERSION
1123
+ and wrapped_header_bytes[2] == definitions.REPLACE_WITH_BLOB
1124
+ ):
1125
+ _ = decoder.ReadBytes(3)
1006
1126
  _, blob_size = decoder.DecodeVarint()
1007
1127
  _, blob_offset = decoder.DecodeVarint()
1008
1128
  return ObjectStoreDataValue(
1009
- unknown=unknown_integer,
1010
- is_wrapped=True,
1129
+ version=version,
1011
1130
  blob_size=blob_size,
1012
1131
  blob_offset=blob_offset,
1013
- value=None)
1132
+ value=None,
1133
+ )
1134
+
1014
1135
  _, blink_bytes = decoder.ReadBytes()
1015
1136
  blink_value = blink.V8ScriptValueDecoder.FromBytes(blink_bytes)
1016
1137
  return ObjectStoreDataValue(
1017
- unknown=unknown_integer,
1018
- is_wrapped=False,
1019
- blob_size=None,
1020
- blob_offset=None,
1021
- value=blink_value)
1138
+ version=version, blob_size=None, blob_offset=None, value=blink_value
1139
+ )
1022
1140
 
1023
1141
  @classmethod
1024
1142
  def FromDecoder(
1025
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
1026
- base_offset: int = 0
1143
+ cls,
1144
+ decoder: utils.LevelDBDecoder,
1145
+ key_prefix: KeyPrefix,
1146
+ base_offset: int = 0,
1027
1147
  ) -> ObjectStoreDataKey:
1028
1148
  """Decodes the object store data key."""
1029
- if (key_prefix.GetKeyPrefixType() !=
1030
- definitions.KeyPrefixType.OBJECT_STORE_DATA):
1031
- raise errors.ParserError('Invalid KeyPrefix for ObjectStoreDataKey')
1149
+ if (
1150
+ key_prefix.GetKeyPrefixType()
1151
+ != definitions.KeyPrefixType.OBJECT_STORE_DATA
1152
+ ):
1153
+ raise errors.ParserError("Invalid KeyPrefix for ObjectStoreDataKey")
1032
1154
  offset = decoder.stream.tell()
1033
1155
  encoded_user_key = IDBKey.FromDecoder(decoder, offset)
1034
1156
  return cls(
1035
1157
  offset=base_offset + offset,
1036
- key_prefix=key_prefix, encoded_user_key=encoded_user_key)
1158
+ key_prefix=key_prefix,
1159
+ encoded_user_key=encoded_user_key,
1160
+ )
1037
1161
 
1038
1162
 
1039
1163
  @dataclass
@@ -1043,25 +1167,29 @@ class ExistsEntryKey(BaseIndexedDBKey):
1043
1167
  Attributes:
1044
1168
  encoded_user_key: the encoded user key.
1045
1169
  """
1170
+
1046
1171
  encoded_user_key: IDBKey
1047
1172
 
1048
1173
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
1049
1174
  """Decodes the exists entry value."""
1050
1175
  _, data = decoder.ReadBytes()
1051
- return int.from_bytes(data, byteorder='little', signed=False)
1176
+ return int.from_bytes(data, byteorder="little", signed=False)
1052
1177
 
1053
1178
  @classmethod
1054
1179
  def FromDecoder(
1055
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
1056
- base_offset: int = 0
1180
+ cls,
1181
+ decoder: utils.LevelDBDecoder,
1182
+ key_prefix: KeyPrefix,
1183
+ base_offset: int = 0,
1057
1184
  ) -> ExistsEntryKey:
1058
1185
  """Decodes the exists entry key."""
1059
1186
  offset = decoder.stream.tell()
1060
1187
  encoded_user_key = IDBKey.FromDecoder(decoder, offset)
1061
-
1062
1188
  return cls(
1063
1189
  offset=base_offset + offset,
1064
- key_prefix=key_prefix, encoded_user_key=encoded_user_key)
1190
+ key_prefix=key_prefix,
1191
+ encoded_user_key=encoded_user_key,
1192
+ )
1065
1193
 
1066
1194
 
1067
1195
  @dataclass
@@ -1073,6 +1201,7 @@ class IndexDataKey(BaseIndexedDBKey):
1073
1201
  sequence_number: the sequence number of the data key.
1074
1202
  encoded_primary_key: the encoded primary key.
1075
1203
  """
1204
+
1076
1205
  encoded_user_key: IDBKey
1077
1206
  sequence_number: Optional[int]
1078
1207
  encoded_primary_key: Optional[IDBKey]
@@ -1084,8 +1213,12 @@ class IndexDataKey(BaseIndexedDBKey):
1084
1213
  return version, idb_key
1085
1214
 
1086
1215
  @classmethod
1087
- def FromDecoder(cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
1088
- base_offset: int = 0) -> IndexDataKey:
1216
+ def FromDecoder(
1217
+ cls,
1218
+ decoder: utils.LevelDBDecoder,
1219
+ key_prefix: KeyPrefix,
1220
+ base_offset: int = 0,
1221
+ ) -> IndexDataKey:
1089
1222
  """Decodes the index data key."""
1090
1223
  offset = decoder.stream.tell()
1091
1224
  encoded_user_key = IDBKey.FromDecoder(decoder, offset)
@@ -1098,7 +1231,8 @@ class IndexDataKey(BaseIndexedDBKey):
1098
1231
  if decoder.NumRemainingBytes() > 0:
1099
1232
  encoded_primary_key_offset = decoder.stream.tell()
1100
1233
  encoded_primary_key = IDBKey.FromDecoder(
1101
- decoder, encoded_primary_key_offset)
1234
+ decoder, encoded_primary_key_offset
1235
+ )
1102
1236
  else:
1103
1237
  encoded_primary_key = None
1104
1238
 
@@ -1107,7 +1241,8 @@ class IndexDataKey(BaseIndexedDBKey):
1107
1241
  encoded_user_key=encoded_user_key,
1108
1242
  sequence_number=sequence_number,
1109
1243
  encoded_primary_key=encoded_primary_key,
1110
- offset=base_offset + offset)
1244
+ offset=base_offset + offset,
1245
+ )
1111
1246
 
1112
1247
 
1113
1248
  @dataclass
@@ -1117,24 +1252,29 @@ class BlobEntryKey(BaseIndexedDBKey):
1117
1252
  Attributes:
1118
1253
  user_key: the user/primary key.
1119
1254
  """
1255
+
1120
1256
  user_key: IDBKey
1121
1257
 
1122
1258
  def DecodeValue(
1123
- self, decoder: utils.LevelDBDecoder) -> IndexedDBExternalObject:
1259
+ self, decoder: utils.LevelDBDecoder
1260
+ ) -> IndexedDBExternalObject:
1124
1261
  """Decodes the blob entry value."""
1125
1262
  return IndexedDBExternalObject.FromDecoder(decoder)
1126
1263
 
1127
1264
  @classmethod
1128
1265
  def FromDecoder(
1129
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
1130
- base_offset: int = 0
1266
+ cls,
1267
+ decoder: utils.LevelDBDecoder,
1268
+ key_prefix: KeyPrefix,
1269
+ base_offset: int = 0,
1131
1270
  ) -> BlobEntryKey:
1132
1271
  """Decodes the blob entry key."""
1133
1272
  offset = decoder.stream.tell()
1134
1273
  user_key = IDBKey.FromDecoder(decoder, offset)
1135
1274
 
1136
- return cls(key_prefix=key_prefix, user_key=user_key,
1137
- offset=base_offset + offset)
1275
+ return cls(
1276
+ key_prefix=key_prefix, user_key=user_key, offset=base_offset + offset
1277
+ )
1138
1278
 
1139
1279
 
1140
1280
  @dataclass
@@ -1145,13 +1285,13 @@ class IndexedDbKey(BaseIndexedDBKey):
1145
1285
  """
1146
1286
 
1147
1287
  METADATA_TYPE_TO_CLASS = {
1148
- definitions.KeyPrefixType.GLOBAL_METADATA: GlobalMetaDataKey,
1288
+ definitions.KeyPrefixType.BLOB_ENTRY: BlobEntryKey,
1149
1289
  definitions.KeyPrefixType.DATABASE_METADATA: DatabaseMetaDataKey,
1150
- definitions.KeyPrefixType.OBJECT_STORE_DATA: ObjectStoreDataKey,
1151
1290
  definitions.KeyPrefixType.EXISTS_ENTRY: ExistsEntryKey,
1291
+ definitions.KeyPrefixType.GLOBAL_METADATA: GlobalMetaDataKey,
1292
+ definitions.KeyPrefixType.INVALID_TYPE: None,
1152
1293
  definitions.KeyPrefixType.INDEX_DATA: IndexDataKey,
1153
- definitions.KeyPrefixType.BLOB_ENTRY: BlobEntryKey,
1154
- definitions.KeyPrefixType.INVALID_TYPE: None
1294
+ definitions.KeyPrefixType.OBJECT_STORE_DATA: ObjectStoreDataKey,
1155
1295
  }
1156
1296
 
1157
1297
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> Any:
@@ -1166,19 +1306,25 @@ class IndexedDbKey(BaseIndexedDBKey):
1166
1306
  cls,
1167
1307
  decoder: utils.LevelDBDecoder,
1168
1308
  key_prefix: KeyPrefix,
1169
- base_offset: int = 0
1170
- ) -> Union[Type[DatabaseMetaDataKey], Type[ExistsEntryKey],
1171
- Type[BlobEntryKey], Type[GlobalMetaDataKey],
1172
- Type[IndexDataKey], Type[ObjectStoreDataKey]]:
1309
+ base_offset: int = 0,
1310
+ ) -> Union[
1311
+ BlobEntryKey,
1312
+ DatabaseMetaDataKey,
1313
+ ExistsEntryKey,
1314
+ GlobalMetaDataKey,
1315
+ IndexDataKey,
1316
+ ObjectStoreDataKey,
1317
+ ]:
1173
1318
  """Decodes the IndexedDB key."""
1174
1319
  key_type = key_prefix.GetKeyPrefixType()
1175
1320
  key_class = cls.METADATA_TYPE_TO_CLASS.get(key_type)
1176
1321
  if not key_class:
1177
- raise errors.ParserError('Unknown KeyPrefixType')
1322
+ raise errors.ParserError("Unknown KeyPrefixType")
1178
1323
  return key_class.FromDecoder(
1179
1324
  decoder=decoder,
1180
- key_prefix=key_prefix, #pytype: disable=bad-return-type
1181
- base_offset=base_offset)
1325
+ key_prefix=key_prefix, # type: ignore[return-value]
1326
+ base_offset=base_offset,
1327
+ )
1182
1328
 
1183
1329
 
1184
1330
  @dataclass
@@ -1190,42 +1336,49 @@ class IndexMetaDataKey(BaseIndexedDBKey):
1190
1336
  index_id: the index ID.
1191
1337
  metadata_type: the metadata key type.
1192
1338
  """
1339
+
1193
1340
  object_store_id: int
1194
1341
  index_id: int
1195
1342
  metadata_type: definitions.IndexMetaDataKeyType
1196
1343
 
1197
1344
  def DecodeValue(
1198
- self, decoder: utils.LevelDBDecoder) -> Union[bool, IDBKeyPath, str]:
1345
+ self, decoder: utils.LevelDBDecoder
1346
+ ) -> Union[bool, IDBKeyPath, str]:
1199
1347
  """Decodes the index metadata value."""
1200
1348
  if self.metadata_type == definitions.IndexMetaDataKeyType.INDEX_NAME:
1201
1349
  return decoder.DecodeString()[1]
1202
1350
  if self.metadata_type == definitions.IndexMetaDataKeyType.KEY_PATH:
1203
1351
  return IDBKeyPath.FromDecoder(decoder)
1204
- if (self.metadata_type ==
1205
- definitions.IndexMetaDataKeyType.MULTI_ENTRY_FLAG):
1352
+ if self.metadata_type == definitions.IndexMetaDataKeyType.MULTI_ENTRY_FLAG:
1206
1353
  return decoder.DecodeBool()[1]
1207
1354
  if self.metadata_type == definitions.IndexMetaDataKeyType.UNIQUE_FLAG:
1208
1355
  return decoder.DecodeBool()[1]
1209
1356
  raise errors.ParserError(
1210
- f'Unknown index metadata type {self.metadata_type}')
1357
+ f"Unknown index metadata type {self.metadata_type}"
1358
+ )
1211
1359
 
1212
1360
  @classmethod
1213
1361
  def FromDecoder(
1214
1362
  cls,
1215
1363
  decoder: utils.LevelDBDecoder,
1216
- key_prefix: KeyPrefix, base_offset: int = 0
1364
+ key_prefix: KeyPrefix,
1365
+ base_offset: int = 0,
1217
1366
  ) -> IndexMetaDataKey:
1218
1367
  """Decodes the index metadata key."""
1219
1368
  offset, key_type = decoder.DecodeUint8()
1220
1369
  if key_type != definitions.DatabaseMetaDataKeyType.INDEX_META_DATA:
1221
- raise errors.ParserError('Not an IndexMetaDataKey.')
1370
+ raise errors.ParserError("Not an IndexMetaDataKey.")
1222
1371
  _, object_store_id = decoder.DecodeVarint()
1223
1372
  _, index_id = decoder.DecodeVarint()
1224
1373
  _, metadata_bytes = decoder.ReadBytes(1)
1225
1374
  metadata_type = definitions.IndexMetaDataKeyType(metadata_bytes[0])
1226
- return cls(offset=base_offset + offset, key_prefix=key_prefix,
1227
- object_store_id=object_store_id, index_id=index_id,
1228
- metadata_type=metadata_type)
1375
+ return cls(
1376
+ offset=base_offset + offset,
1377
+ key_prefix=key_prefix,
1378
+ object_store_id=object_store_id,
1379
+ index_id=index_id,
1380
+ metadata_type=metadata_type,
1381
+ )
1229
1382
 
1230
1383
 
1231
1384
  @dataclass
@@ -1244,6 +1397,7 @@ class ExternalObjectEntry(utils.FromDecoderMixin):
1244
1397
  last_modified: the last modified time if a blob or file, None otherwise.
1245
1398
  token: the token if a filesystem access handle, None otherwise.
1246
1399
  """
1400
+
1247
1401
  offset: int = field(compare=False)
1248
1402
  object_type: definitions.ExternalObjectType
1249
1403
  blob_number: Optional[int]
@@ -1255,16 +1409,15 @@ class ExternalObjectEntry(utils.FromDecoderMixin):
1255
1409
 
1256
1410
  @classmethod
1257
1411
  def FromDecoder(
1258
- cls,
1259
- decoder: utils.LevelDBDecoder,
1260
- base_offset: int = 0
1412
+ cls, decoder: utils.LevelDBDecoder, base_offset: int = 0
1261
1413
  ) -> ExternalObjectEntry:
1262
1414
  """Decodes the external object entry."""
1263
1415
  offset, object_type_value = decoder.DecodeUint8()
1264
1416
  object_type = definitions.ExternalObjectType(object_type_value)
1265
- if (object_type in
1266
- (definitions.ExternalObjectType.BLOB,
1267
- definitions.ExternalObjectType.FILE)):
1417
+ if object_type in (
1418
+ definitions.ExternalObjectType.BLOB,
1419
+ definitions.ExternalObjectType.FILE,
1420
+ ):
1268
1421
  _, blob_number = decoder.DecodeVarint()
1269
1422
  _, mime_type = decoder.DecodeStringWithLength()
1270
1423
  _, size = decoder.DecodeVarint()
@@ -1276,8 +1429,10 @@ class ExternalObjectEntry(utils.FromDecoderMixin):
1276
1429
  last_modified = None
1277
1430
  token = None
1278
1431
  else:
1279
- if (object_type ==
1280
- definitions.ExternalObjectType.FILE_SYSTEM_ACCESS_HANDLE):
1432
+ if (
1433
+ object_type
1434
+ == definitions.ExternalObjectType.FILE_SYSTEM_ACCESS_HANDLE
1435
+ ):
1281
1436
  _, token = decoder.DecodeBlobWithLength()
1282
1437
  else:
1283
1438
  token = None
@@ -1287,9 +1442,16 @@ class ExternalObjectEntry(utils.FromDecoderMixin):
1287
1442
  filename = None
1288
1443
  last_modified = None
1289
1444
 
1290
- return cls(offset=base_offset + offset, object_type=object_type,
1291
- blob_number=blob_number, mime_type=mime_type, size=size,
1292
- filename=filename, last_modified=last_modified, token=token)
1445
+ return cls(
1446
+ offset=base_offset + offset,
1447
+ object_type=object_type,
1448
+ blob_number=blob_number,
1449
+ mime_type=mime_type,
1450
+ size=size,
1451
+ filename=filename,
1452
+ last_modified=last_modified,
1453
+ token=token,
1454
+ )
1293
1455
 
1294
1456
 
1295
1457
  @dataclass
@@ -1300,14 +1462,13 @@ class IndexedDBExternalObject(utils.FromDecoderMixin):
1300
1462
  offset: the offset of the IndexedDBExternalObject.
1301
1463
  entries: a list of external objects.
1302
1464
  """
1465
+
1303
1466
  offset: int = field(compare=False)
1304
1467
  entries: list[ExternalObjectEntry]
1305
1468
 
1306
1469
  @classmethod
1307
1470
  def FromDecoder(
1308
- cls,
1309
- decoder: utils.LevelDBDecoder,
1310
- base_offset: int = 0
1471
+ cls, decoder: utils.LevelDBDecoder, base_offset: int = 0
1311
1472
  ) -> IndexedDBExternalObject:
1312
1473
  """Decodes the external object."""
1313
1474
  entries = []
@@ -1319,20 +1480,6 @@ class IndexedDBExternalObject(utils.FromDecoderMixin):
1319
1480
  return cls(offset=base_offset + offset, entries=entries)
1320
1481
 
1321
1482
 
1322
- @dataclass
1323
- class ObjectStore:
1324
- """An IndexedDB Object Store.
1325
-
1326
- Attributes:
1327
- id: the object store ID.
1328
- name: the object store name.
1329
- records: the records in the object store.
1330
- """
1331
- id: int
1332
- name: str
1333
- records: list = field(default_factory=list, repr=False)
1334
-
1335
-
1336
1483
  @dataclass
1337
1484
  class IndexedDBRecord:
1338
1485
  """An IndexedDB Record.
@@ -1347,7 +1494,15 @@ class IndexedDBRecord:
1347
1494
  level: the leveldb level, if applicable, None can indicate the record
1348
1495
  originated from a log file or the level could not be determined.
1349
1496
  recovered: True if the record is a recovered record.
1497
+ database_id: the database ID.
1498
+ object_store_id: the object store ID.
1499
+ database_name: the name of the database, if available.
1500
+ object_store_name: the name of the object store, if available.
1501
+ blob: the blob contents, if available.
1502
+ raw_key: the raw key, if available.
1503
+ raw_value: the raw value, if available.
1350
1504
  """
1505
+
1351
1506
  path: str
1352
1507
  offset: int
1353
1508
  key: Any
@@ -1356,72 +1511,97 @@ class IndexedDBRecord:
1356
1511
  type: int
1357
1512
  level: Optional[int]
1358
1513
  recovered: Optional[bool]
1514
+ database_id: int
1515
+ object_store_id: int
1516
+ database_name: Optional[str] = None
1517
+ object_store_name: Optional[str] = None
1518
+ blob: Optional[bytes] = None
1519
+ raw_key: Optional[bytes] = None
1520
+ raw_value: Optional[bytes] = None
1359
1521
 
1360
1522
  @classmethod
1361
1523
  def FromLevelDBRecord(
1362
- cls,
1363
- db_record: record.LevelDBRecord
1524
+ cls, db_record: record.LevelDBRecord, parse_value: bool = True
1364
1525
  ) -> IndexedDBRecord:
1365
1526
  """Returns an IndexedDBRecord from a ParsedInternalKey."""
1366
1527
  idb_key = IndexedDbKey.FromBytes(
1367
- db_record.record.key, base_offset=db_record.record.offset)
1368
- idb_value = idb_key.ParseValue(db_record.record.value)
1528
+ db_record.record.key, base_offset=db_record.record.offset
1529
+ )
1530
+
1531
+ if parse_value:
1532
+ idb_value = idb_key.ParseValue(db_record.record.value)
1533
+ else:
1534
+ idb_value = None
1535
+
1369
1536
  return cls(
1370
1537
  path=db_record.path,
1371
1538
  offset=db_record.record.offset,
1372
1539
  key=idb_key,
1373
1540
  value=idb_value,
1374
- sequence_number=db_record.record.sequence_number if hasattr(
1375
- db_record.record, 'sequence_number') else None,
1541
+ sequence_number=db_record.record.sequence_number
1542
+ if hasattr(db_record.record, "sequence_number")
1543
+ else None,
1376
1544
  type=db_record.record.record_type,
1377
1545
  level=db_record.level,
1378
- recovered=db_record.recovered)
1546
+ recovered=db_record.recovered,
1547
+ database_id=idb_key.key_prefix.database_id,
1548
+ object_store_id=idb_key.key_prefix.object_store_id,
1549
+ database_name=None,
1550
+ object_store_name=None,
1551
+ blob=None,
1552
+ raw_key=db_record.record.key,
1553
+ raw_value=db_record.record.value,
1554
+ )
1379
1555
 
1380
1556
  @classmethod
1381
1557
  def FromFile(
1382
- cls,
1383
- file_path: pathlib.Path
1558
+ cls, file_path: pathlib.Path, parse_value: bool = True
1384
1559
  ) -> Generator[IndexedDBRecord, None, None]:
1385
1560
  """Yields IndexedDBRecords from a file."""
1386
1561
  for db_record in record.LevelDBRecord.FromFile(file_path):
1387
1562
  try:
1388
- yield cls.FromLevelDBRecord(db_record)
1389
- except(
1563
+ yield cls.FromLevelDBRecord(db_record, parse_value=parse_value)
1564
+ except (
1390
1565
  errors.ParserError,
1391
1566
  errors.DecoderError,
1392
- NotImplementedError) as err:
1393
- print((
1394
- 'Error parsing Indexeddb record: '
1395
- f'{err} at offset {db_record.record.offset} in '
1396
- f'{db_record.path}'),
1397
- file=sys.stderr)
1398
- print(f'Traceback: {traceback.format_exc()}', file=sys.stderr)
1567
+ NotImplementedError,
1568
+ ) as err:
1569
+ print(
1570
+ (
1571
+ "Error parsing Indexeddb record: "
1572
+ f"{err} at offset {db_record.record.offset} in "
1573
+ f"{db_record.path}"
1574
+ ),
1575
+ file=sys.stderr,
1576
+ )
1577
+ print(f"Traceback: {traceback.format_exc()}", file=sys.stderr)
1399
1578
 
1400
1579
 
1401
1580
  class FolderReader:
1402
1581
  """A IndexedDB folder reader for Chrome/Chromium.
1403
1582
 
1404
1583
  Attributes:
1405
- foldername (str): the source LevelDB folder.
1584
+ folder_name (str): the source LevelDB folder.
1406
1585
  """
1407
1586
 
1408
- def __init__(self, foldername: pathlib.Path):
1587
+ def __init__(self, folder_name: pathlib.Path):
1409
1588
  """Initializes the FileReader.
1410
1589
 
1411
1590
  Args:
1412
- foldername: the source IndexedDB folder.
1591
+ folder_name: the source IndexedDB folder.
1413
1592
 
1414
1593
  Raises:
1415
- ValueError: if foldername is None or not a directory.
1594
+ ValueError: if folder_name is None or not a directory.
1416
1595
  """
1417
- if not foldername or not foldername.is_dir():
1418
- raise ValueError(f'{foldername} is None or not a directory')
1419
- self.foldername = foldername
1596
+ if not folder_name or not folder_name.is_dir():
1597
+ raise ValueError(f"{folder_name} is None or not a directory")
1598
+ self.folder_name = folder_name
1420
1599
 
1421
1600
  def GetRecords(
1422
1601
  self,
1423
1602
  use_manifest: bool = False,
1424
- use_sequence_number: bool = False
1603
+ use_sequence_number: bool = False,
1604
+ parse_value: bool = True,
1425
1605
  ) -> Generator[IndexedDBRecord, None, None]:
1426
1606
  """Yield LevelDBRecords.
1427
1607
 
@@ -1429,23 +1609,31 @@ class FolderReader:
1429
1609
  use_manifest: True to use the current manifest in the folder as a means to
1430
1610
  find the active file set.
1431
1611
  use_sequence_number: True to use the sequence number to determine the
1612
+ recovered field.
1613
+ parse_value: True to parse values.
1614
+
1432
1615
  Yields:
1433
1616
  IndexedDBRecord.
1434
1617
  """
1435
- leveldb_folder_reader = record.FolderReader(self.foldername)
1618
+ leveldb_folder_reader = record.FolderReader(self.folder_name)
1436
1619
  for leveldb_record in leveldb_folder_reader.GetRecords(
1437
- use_manifest=use_manifest,
1438
- use_sequence_number=use_sequence_number):
1620
+ use_manifest=use_manifest, use_sequence_number=use_sequence_number
1621
+ ):
1439
1622
  try:
1440
1623
  yield IndexedDBRecord.FromLevelDBRecord(
1441
- leveldb_record)
1442
- except(
1624
+ leveldb_record, parse_value=parse_value
1625
+ )
1626
+ except (
1443
1627
  errors.ParserError,
1444
1628
  errors.DecoderError,
1445
- NotImplementedError) as err:
1446
- print((
1447
- 'Error parsing Indexeddb record: '
1448
- f'{err} at offset {leveldb_record.record.offset} in '
1449
- f'{leveldb_record.path}'),
1450
- file=sys.stderr)
1451
- print(f'Traceback: {traceback.format_exc()}', file=sys.stderr)
1629
+ NotImplementedError,
1630
+ ) as err:
1631
+ print(
1632
+ (
1633
+ "Error parsing Indexeddb record: "
1634
+ f"{err} at offset {leveldb_record.record.offset} in "
1635
+ f"{leveldb_record.path}"
1636
+ ),
1637
+ file=sys.stderr,
1638
+ )
1639
+ print(f"Traceback: {traceback.format_exc()}", file=sys.stderr)