dfindexeddb 20241031__tar.gz → 20241105__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 (47) hide show
  1. {dfindexeddb-20241031/dfindexeddb.egg-info → dfindexeddb-20241105}/PKG-INFO +1 -1
  2. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/chromium/definitions.py +5 -0
  3. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/chromium/record.py +181 -95
  4. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/chromium/v8.py +19 -70
  5. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/cli.py +30 -23
  6. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/firefox/gecko.py +8 -8
  7. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/safari/definitions.py +7 -7
  8. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/safari/webkit.py +31 -122
  9. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/types.py +1 -1
  10. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/leveldb/cli.py +18 -11
  11. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/leveldb/descriptor.py +22 -6
  12. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/leveldb/ldb.py +5 -2
  13. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/leveldb/log.py +11 -5
  14. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/leveldb/plugins/manager.py +2 -2
  15. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/utils.py +1 -1
  16. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/version.py +1 -1
  17. {dfindexeddb-20241031 → dfindexeddb-20241105/dfindexeddb.egg-info}/PKG-INFO +1 -1
  18. {dfindexeddb-20241031 → dfindexeddb-20241105}/pyproject.toml +1 -1
  19. {dfindexeddb-20241031 → dfindexeddb-20241105}/AUTHORS +0 -0
  20. {dfindexeddb-20241031 → dfindexeddb-20241105}/LICENSE +0 -0
  21. {dfindexeddb-20241031 → dfindexeddb-20241105}/README.md +0 -0
  22. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/__init__.py +0 -0
  23. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/errors.py +0 -0
  24. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/__init__.py +0 -0
  25. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/chromium/__init__.py +0 -0
  26. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/chromium/blink.py +0 -0
  27. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/firefox/__init__.py +0 -0
  28. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/firefox/definitions.py +0 -0
  29. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/firefox/record.py +0 -0
  30. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/safari/__init__.py +0 -0
  31. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/safari/record.py +0 -0
  32. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/indexeddb/utils.py +0 -0
  33. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/leveldb/__init__.py +0 -0
  34. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/leveldb/definitions.py +0 -0
  35. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/leveldb/plugins/__init__.py +0 -0
  36. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/leveldb/plugins/chrome_notifications.py +0 -0
  37. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/leveldb/plugins/interface.py +0 -0
  38. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/leveldb/plugins/notification_database_data_pb2.py +0 -0
  39. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/leveldb/record.py +0 -0
  40. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb/leveldb/utils.py +0 -0
  41. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb.egg-info/SOURCES.txt +0 -0
  42. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb.egg-info/dependency_links.txt +0 -0
  43. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb.egg-info/entry_points.txt +0 -0
  44. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb.egg-info/requires.txt +0 -0
  45. {dfindexeddb-20241031 → dfindexeddb-20241105}/dfindexeddb.egg-info/top_level.txt +0 -0
  46. {dfindexeddb-20241031 → dfindexeddb-20241105}/setup.cfg +0 -0
  47. {dfindexeddb-20241031 → dfindexeddb-20241105}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dfindexeddb
3
- Version: 20241031
3
+ Version: 20241105
4
4
  Summary: dfindexeddb is an experimental Python tool for performing digital forensic analysis of IndexedDB and leveldb files.
5
5
  Author-email: Syd Pleno <sydp@google.com>
6
6
  Maintainer-email: dfIndexeddb Developers <dfindexeddb-dev@googlegroups.com>
@@ -16,6 +16,11 @@
16
16
  from enum import Enum, IntEnum, IntFlag
17
17
 
18
18
 
19
+ REQUIRES_PROCESSING_SSV_PSEUDO_VERSION = 0x11
20
+ REPLACE_WITH_BLOB = 0x01
21
+ COMPRESSED_WITH_SNAPPY = 0x02
22
+
23
+
19
24
  class DatabaseMetaDataKeyType(IntEnum):
20
25
  """Database Metadata key types."""
21
26
  ORIGIN_NAME = 0
@@ -14,6 +14,7 @@
14
14
  # limitations under the License.
15
15
  """Parses Chromium IndexedDb structures."""
16
16
  from __future__ import annotations
17
+
17
18
  from dataclasses import dataclass, field
18
19
  from datetime import datetime
19
20
  import io
@@ -23,6 +24,8 @@ import traceback
23
24
  from typing import Any, BinaryIO, Generator, Optional, Tuple, Type, TypeVar, \
24
25
  Union
25
26
 
27
+ import snappy
28
+
26
29
  from dfindexeddb import errors
27
30
  from dfindexeddb.indexeddb.chromium import blink
28
31
  from dfindexeddb.indexeddb.chromium import definitions
@@ -50,7 +53,10 @@ class KeyPrefix(utils.FromDecoderMixin):
50
53
 
51
54
  @classmethod
52
55
  def FromDecoder(
53
- cls, decoder: utils.LevelDBDecoder, base_offset: int = 0) -> KeyPrefix:
56
+ cls,
57
+ decoder: utils.LevelDBDecoder,
58
+ base_offset: int = 0
59
+ ) -> KeyPrefix:
54
60
  """Decodes a KeyPrefix from the current position of a LevelDBDecoder.
55
61
 
56
62
  Args:
@@ -151,7 +157,8 @@ class IDBKey(utils.FromDecoderMixin):
151
157
 
152
158
  def RecursiveParse(depth: int) -> Tuple[
153
159
  int, definitions.IDBKeyType, Union[
154
- list, bytes, str, float, datetime, None]]:
160
+ list, bytes, str, float, datetime, None
161
+ ]]:
155
162
  """Recursively parses IDBKeys.
156
163
 
157
164
  Args:
@@ -215,8 +222,11 @@ class IDBKeyPath(utils.FromDecoderMixin):
215
222
  value: Union[str, list[str], None]
216
223
 
217
224
  @classmethod
218
- def FromDecoder(cls, decoder: utils.LevelDBDecoder,
219
- base_offset: int = 0) -> IDBKeyPath:
225
+ def FromDecoder(
226
+ cls,
227
+ decoder: utils.LevelDBDecoder,
228
+ base_offset: int = 0
229
+ ) -> IDBKeyPath:
220
230
  """Decodes an IDBKeyPath from the current position of a LevelDBDecoder.
221
231
 
222
232
  Args:
@@ -228,7 +238,7 @@ class IDBKeyPath(utils.FromDecoderMixin):
228
238
 
229
239
  Raises:
230
240
  ParserError: on insufficient bytes or invalid array length during
231
- parsing.
241
+ parsing or unsupported key path type.
232
242
  """
233
243
  buffer = decoder.stream.getvalue() #pytype: disable=attribute-error
234
244
  if len(buffer) < 3:
@@ -255,6 +265,8 @@ class IDBKeyPath(utils.FromDecoderMixin):
255
265
  for _ in range(count):
256
266
  _, entry = decoder.DecodeStringWithLength()
257
267
  value.append(entry)
268
+ else:
269
+ raise errors.ParserError(f'Unsupported key_path_type {key_path_type}.')
258
270
  return IDBKeyPath(base_offset + offset, key_path_type, value)
259
271
 
260
272
 
@@ -272,8 +284,11 @@ class BlobJournalEntry(utils.FromDecoderMixin):
272
284
  blob_number: int
273
285
 
274
286
  @classmethod
275
- def FromDecoder(cls, decoder: utils.LevelDBDecoder,
276
- base_offset: int = 0) -> BlobJournalEntry:
287
+ def FromDecoder(
288
+ cls,
289
+ decoder: utils.LevelDBDecoder,
290
+ base_offset: int = 0
291
+ ) -> BlobJournalEntry:
277
292
  """Decodes a BlobJournalEntry from the current position of a LevelDBDecoder.
278
293
 
279
294
  Args:
@@ -301,8 +316,11 @@ class BlobJournal(utils.FromDecoderMixin):
301
316
  entries: list[BlobJournalEntry]
302
317
 
303
318
  @classmethod
304
- def FromDecoder(cls, decoder: utils.LevelDBDecoder,
305
- base_offset: int = 0) -> BlobJournal:
319
+ def FromDecoder(
320
+ cls,
321
+ decoder: utils.LevelDBDecoder,
322
+ base_offset: int = 0
323
+ ) -> BlobJournal:
306
324
  """Decodes a BlobJournal from the current position of a LevelDBDecoder.
307
325
 
308
326
  Blob journals are zero-or-more instances of BlobJournalEntry. There is no
@@ -395,8 +413,7 @@ class BaseIndexedDBKey:
395
413
  raise NotImplementedError(f'{cls.__class__.__name__}.decode_key')
396
414
 
397
415
  @classmethod
398
- def FromStream(
399
- cls: Type[T], stream: BinaryIO, base_offset: int = 0) -> T:
416
+ def FromStream(cls: Type[T], stream: BinaryIO, base_offset: int = 0) -> T:
400
417
  """Parses the key from the current position of the binary stream.
401
418
 
402
419
  Args:
@@ -412,8 +429,7 @@ class BaseIndexedDBKey:
412
429
  decoder=decoder, key_prefix=key_prefix, base_offset=base_offset)
413
430
 
414
431
  @classmethod
415
- def FromBytes(
416
- cls: Type[T], raw_data: bytes, base_offset: int = 0) -> T:
432
+ def FromBytes(cls: Type[T], raw_data: bytes, base_offset: int = 0) -> T:
417
433
  """Parses the key from the raw key bytes.
418
434
 
419
435
  Args:
@@ -433,11 +449,13 @@ class SchemaVersionKey(BaseIndexedDBKey):
433
449
 
434
450
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
435
451
  """Decodes the schema version value."""
436
- return decoder.DecodeVarint()[1]
452
+ return decoder.DecodeInt()[1]
437
453
 
438
454
  @classmethod
439
455
  def FromDecoder(
440
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
456
+ cls,
457
+ decoder: utils.LevelDBDecoder,
458
+ key_prefix: KeyPrefix,
441
459
  base_offset: int = 0
442
460
  ) -> SchemaVersionKey:
443
461
  """Decodes the schema version key."""
@@ -453,11 +471,13 @@ class MaxDatabaseIdKey(BaseIndexedDBKey):
453
471
 
454
472
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
455
473
  """Decodes the maximum database value."""
456
- return decoder.DecodeVarint()[1]
474
+ return decoder.DecodeInt()[1]
457
475
 
458
476
  @classmethod
459
477
  def FromDecoder(
460
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
478
+ cls,
479
+ decoder: utils.LevelDBDecoder,
480
+ key_prefix: KeyPrefix,
461
481
  base_offset: int = 0
462
482
  ) -> MaxDatabaseIdKey:
463
483
  """Decodes the maximum database key."""
@@ -473,11 +493,13 @@ class DataVersionKey(BaseIndexedDBKey):
473
493
 
474
494
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
475
495
  """Decodes the data version value."""
476
- return decoder.DecodeUint64Varint()[1]
496
+ return decoder.DecodeInt()[1]
477
497
 
478
498
  @classmethod
479
499
  def FromDecoder(
480
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
500
+ cls,
501
+ decoder: utils.LevelDBDecoder,
502
+ key_prefix: KeyPrefix,
481
503
  base_offset: int = 0
482
504
  ) -> DataVersionKey:
483
505
  """Decodes the data version key."""
@@ -497,7 +519,9 @@ class RecoveryBlobJournalKey(BaseIndexedDBKey):
497
519
 
498
520
  @classmethod
499
521
  def FromDecoder(
500
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
522
+ cls,
523
+ decoder: utils.LevelDBDecoder,
524
+ key_prefix: KeyPrefix,
501
525
  base_offset: int = 0
502
526
  ) -> RecoveryBlobJournalKey:
503
527
  """Decodes the recovery blob journal key."""
@@ -517,7 +541,9 @@ class ActiveBlobJournalKey(BaseIndexedDBKey):
517
541
 
518
542
  @classmethod
519
543
  def FromDecoder(
520
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
544
+ cls,
545
+ decoder: utils.LevelDBDecoder,
546
+ key_prefix: KeyPrefix,
521
547
  base_offset: int = 0
522
548
  ) -> ActiveBlobJournalKey:
523
549
  """Decodes the active blob journal value."""
@@ -538,7 +564,9 @@ class EarliestSweepKey(BaseIndexedDBKey):
538
564
 
539
565
  @classmethod
540
566
  def FromDecoder(
541
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
567
+ cls,
568
+ decoder: utils.LevelDBDecoder,
569
+ key_prefix: KeyPrefix,
542
570
  base_offset: int = 0
543
571
  ) -> EarliestSweepKey:
544
572
  """Decodes the earliest sweep value."""
@@ -559,7 +587,9 @@ class EarliestCompactionTimeKey(BaseIndexedDBKey):
559
587
 
560
588
  @classmethod
561
589
  def FromDecoder(
562
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
590
+ cls,
591
+ decoder: utils.LevelDBDecoder,
592
+ key_prefix: KeyPrefix,
563
593
  base_offset: int = 0
564
594
  ) -> EarliestCompactionTimeKey:
565
595
  """Decodes the earliest compaction time key."""
@@ -581,7 +611,9 @@ class ScopesPrefixKey(BaseIndexedDBKey):
581
611
 
582
612
  @classmethod
583
613
  def FromDecoder(
584
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
614
+ cls,
615
+ decoder: utils.LevelDBDecoder,
616
+ key_prefix: KeyPrefix,
585
617
  base_offset: int = 0
586
618
  ) -> ScopesPrefixKey:
587
619
  """Decodes the scopes prefix key."""
@@ -606,7 +638,9 @@ class DatabaseFreeListKey(BaseIndexedDBKey):
606
638
 
607
639
  @classmethod
608
640
  def FromDecoder(
609
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
641
+ cls,
642
+ decoder: utils.LevelDBDecoder,
643
+ key_prefix: KeyPrefix,
610
644
  base_offset: int = 0
611
645
  ) -> DatabaseFreeListKey:
612
646
  """Decodes the database free list key."""
@@ -635,11 +669,13 @@ class DatabaseNameKey(BaseIndexedDBKey):
635
669
 
636
670
  The value is the corresponding database ID.
637
671
  """
638
- return decoder.DecodeVarint()[1]
672
+ return decoder.DecodeInt()[1]
639
673
 
640
674
  @classmethod
641
675
  def FromDecoder(
642
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
676
+ cls,
677
+ decoder: utils.LevelDBDecoder,
678
+ key_prefix: KeyPrefix,
643
679
  base_offset: int = 0
644
680
  ) -> DatabaseNameKey:
645
681
  """Decodes the database name key."""
@@ -659,25 +695,26 @@ class GlobalMetaDataKey(BaseIndexedDBKey):
659
695
 
660
696
  METADATA_TYPE_TO_CLASS = {
661
697
  definitions.GlobalMetadataKeyType
662
- .SCHEMA_VERSION: SchemaVersionKey,
698
+ .ACTIVE_BLOB_JOURNAL: ActiveBlobJournalKey,
663
699
  definitions.GlobalMetadataKeyType
664
- .MAX_DATABASE_ID: MaxDatabaseIdKey,
700
+ .DATA_VERSION: DataVersionKey,
665
701
  definitions.GlobalMetadataKeyType
666
- .DATA_VERSION: DataVersionKey,
702
+ .DATABASE_FREE_LIST: DatabaseFreeListKey,
667
703
  definitions.GlobalMetadataKeyType
668
- .RECOVERY_BLOB_JOURNAL: RecoveryBlobJournalKey,
704
+ .DATABASE_NAME: DatabaseNameKey,
669
705
  definitions.GlobalMetadataKeyType
670
- .ACTIVE_BLOB_JOURNAL: ActiveBlobJournalKey,
706
+ .EARLIEST_COMPACTION_TIME: EarliestCompactionTimeKey,
671
707
  definitions.GlobalMetadataKeyType
672
708
  .EARLIEST_SWEEP: EarliestSweepKey,
673
709
  definitions.GlobalMetadataKeyType
674
- .EARLIEST_COMPACTION_TIME: EarliestCompactionTimeKey,
710
+ .MAX_DATABASE_ID: MaxDatabaseIdKey,
675
711
  definitions.GlobalMetadataKeyType
676
- .SCOPES_PREFIX: ScopesPrefixKey,
712
+ .RECOVERY_BLOB_JOURNAL: RecoveryBlobJournalKey,
677
713
  definitions.GlobalMetadataKeyType
678
- .DATABASE_FREE_LIST: DatabaseFreeListKey,
714
+ .SCHEMA_VERSION: SchemaVersionKey,
679
715
  definitions.GlobalMetadataKeyType
680
- .DATABASE_NAME: DatabaseNameKey}
716
+ .SCOPES_PREFIX: ScopesPrefixKey,
717
+ }
681
718
 
682
719
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> Any:
683
720
  """Decodes the value from the current position of the LevelDBDecoder.
@@ -688,18 +725,20 @@ class GlobalMetaDataKey(BaseIndexedDBKey):
688
725
 
689
726
  @classmethod
690
727
  def FromDecoder(
691
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
728
+ cls,
729
+ decoder: utils.LevelDBDecoder,
730
+ key_prefix: KeyPrefix,
692
731
  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]]:
732
+ ) -> Union[ActiveBlobJournalKey,
733
+ DataVersionKey,
734
+ DatabaseFreeListKey,
735
+ DatabaseNameKey,
736
+ EarliestSweepKey,
737
+ EarliestCompactionTimeKey,
738
+ MaxDatabaseIdKey,
739
+ RecoveryBlobJournalKey,
740
+ SchemaVersionKey,
741
+ ScopesPrefixKey]:
703
742
  """Decodes the global metadata key.
704
743
 
705
744
  Raises:
@@ -712,7 +751,7 @@ class GlobalMetaDataKey(BaseIndexedDBKey):
712
751
  if not key_class:
713
752
  raise errors.ParserError('Unknown metadata key type')
714
753
  return key_class.FromDecoder(
715
- decoder, key_prefix, base_offset) #pytype: disable=bad-return-type
754
+ decoder, key_prefix, base_offset)
716
755
 
717
756
 
718
757
  @dataclass
@@ -730,7 +769,9 @@ class ObjectStoreFreeListKey(BaseIndexedDBKey):
730
769
 
731
770
  @classmethod
732
771
  def FromDecoder(
733
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
772
+ cls,
773
+ decoder: utils.LevelDBDecoder,
774
+ key_prefix: KeyPrefix,
734
775
  base_offset: int = 0
735
776
  ) -> ObjectStoreFreeListKey:
736
777
  """Decodes the object store free list key."""
@@ -758,7 +799,9 @@ class IndexFreeListKey(BaseIndexedDBKey):
758
799
 
759
800
  @classmethod
760
801
  def FromDecoder(
761
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
802
+ cls,
803
+ decoder: utils.LevelDBDecoder,
804
+ key_prefix: KeyPrefix,
762
805
  base_offset: int = 0
763
806
  ) -> IndexFreeListKey:
764
807
  """Decodes the index free list key."""
@@ -782,11 +825,14 @@ class ObjectStoreNamesKey(BaseIndexedDBKey):
782
825
 
783
826
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
784
827
  """Decodes the object store names value."""
785
- return decoder.DecodeVarint()[1]
828
+ return decoder.DecodeInt()[1]
786
829
 
787
830
  @classmethod
788
- def FromDecoder(cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
789
- base_offset: int = 0) -> ObjectStoreNamesKey:
831
+ def FromDecoder(
832
+ cls, decoder: utils.LevelDBDecoder,
833
+ key_prefix: KeyPrefix,
834
+ base_offset: int = 0
835
+ ) -> ObjectStoreNamesKey:
790
836
  """Decodes the object store names key."""
791
837
  offset, key_type = decoder.DecodeUint8()
792
838
  if key_type != definitions.DatabaseMetaDataKeyType.OBJECT_STORE_NAMES:
@@ -807,11 +853,15 @@ class IndexNamesKey(BaseIndexedDBKey):
807
853
 
808
854
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
809
855
  """Decodes the index names value."""
810
- return decoder.DecodeVarint()[1]
856
+ return decoder.DecodeInt()[1]
811
857
 
812
858
  @classmethod
813
- def FromDecoder(cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
814
- base_offset: int = 0) -> IndexNamesKey:
859
+ def FromDecoder(
860
+ cls,
861
+ decoder: utils.LevelDBDecoder,
862
+ key_prefix: KeyPrefix,
863
+ base_offset: int = 0
864
+ ) -> IndexNamesKey:
815
865
  """Decodes the index names key."""
816
866
  offset, key_type = decoder.DecodeUint8()
817
867
  if key_type != definitions.DatabaseMetaDataKeyType.INDEX_NAMES:
@@ -844,7 +894,7 @@ class DatabaseMetaDataKey(BaseIndexedDBKey):
844
894
  return decoder.DecodeString()[1]
845
895
  if (self.metadata_type ==
846
896
  definitions.DatabaseMetaDataKeyType.MAX_ALLOCATED_OBJECT_STORE_ID):
847
- return decoder.DecodeVarint()[1]
897
+ return decoder.DecodeInt()[1]
848
898
  if (self.metadata_type ==
849
899
  definitions.DatabaseMetaDataKeyType.IDB_INTEGER_VERSION):
850
900
  return decoder.DecodeVarint()[1]
@@ -919,7 +969,9 @@ class ObjectStoreMetaDataKey(BaseIndexedDBKey):
919
969
  metadata_type: definitions.ObjectStoreMetaDataKeyType
920
970
 
921
971
  def DecodeValue(
922
- self, decoder: utils.LevelDBDecoder) -> Union[IDBKeyPath, str, bool, int]:
972
+ self,
973
+ decoder: utils.LevelDBDecoder
974
+ ) -> Union[IDBKeyPath, str, bool, int]:
923
975
  """Decodes the object store metadata value."""
924
976
  if (self.metadata_type ==
925
977
  definitions.ObjectStoreMetaDataKeyType.OBJECT_STORE_NAME):
@@ -948,7 +1000,9 @@ class ObjectStoreMetaDataKey(BaseIndexedDBKey):
948
1000
 
949
1001
  @classmethod
950
1002
  def FromDecoder(
951
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
1003
+ cls,
1004
+ decoder: utils.LevelDBDecoder,
1005
+ key_prefix: KeyPrefix,
952
1006
  base_offset: int = 0
953
1007
  ) -> ObjectStoreMetaDataKey:
954
1008
  """Decodes the object store metadata key."""
@@ -969,13 +1023,13 @@ class ObjectStoreDataValue:
969
1023
  """The parsed values from an ObjectStoreDataKey.
970
1024
 
971
1025
  Attributes:
972
- unknown: an unknown integer (possibly a sequence number?).
1026
+ version: the version prefix.
973
1027
  is_wrapped: True if the value was wrapped.
974
1028
  blob_size: the blob size, only valid if wrapped.
975
1029
  blob_offset: the blob offset, only valid if wrapped.
976
1030
  value: the blink serialized value, only valid if not wrapped.
977
1031
  """
978
- unknown: int
1032
+ version: int
979
1033
  is_wrapped: bool
980
1034
  blob_size: Optional[int]
981
1035
  blob_offset: Optional[int]
@@ -992,37 +1046,54 @@ class ObjectStoreDataKey(BaseIndexedDBKey):
992
1046
  encoded_user_key: IDBKey
993
1047
 
994
1048
  def DecodeValue(
995
- self, decoder: utils.LevelDBDecoder) -> ObjectStoreDataValue:
1049
+ self,
1050
+ decoder: utils.LevelDBDecoder
1051
+ ) -> ObjectStoreDataValue:
996
1052
  """Decodes the object store data value."""
997
- _, unknown_integer = decoder.DecodeVarint()
1053
+ _, version = decoder.DecodeVarint()
998
1054
 
999
1055
  _, wrapped_header_bytes = decoder.PeekBytes(3)
1000
1056
  if len(wrapped_header_bytes) != 3:
1001
1057
  raise errors.DecoderError('Insufficient bytes')
1002
1058
 
1003
- if (wrapped_header_bytes[0] == definitions.BlinkSerializationTag.VERSION and
1004
- wrapped_header_bytes[1] == 0x11 and
1005
- wrapped_header_bytes[2] == 0x01):
1059
+ if (wrapped_header_bytes[0] ==
1060
+ definitions.BlinkSerializationTag.VERSION and
1061
+ wrapped_header_bytes[1] ==
1062
+ definitions.REQUIRES_PROCESSING_SSV_PSEUDO_VERSION and
1063
+ wrapped_header_bytes[2] == definitions.REPLACE_WITH_BLOB):
1064
+ _ = decoder.ReadBytes(3)
1006
1065
  _, blob_size = decoder.DecodeVarint()
1007
1066
  _, blob_offset = decoder.DecodeVarint()
1008
1067
  return ObjectStoreDataValue(
1009
- unknown=unknown_integer,
1068
+ version=version,
1010
1069
  is_wrapped=True,
1011
1070
  blob_size=blob_size,
1012
1071
  blob_offset=blob_offset,
1013
1072
  value=None)
1014
1073
  _, blink_bytes = decoder.ReadBytes()
1074
+ is_wrapped = False
1075
+ if (
1076
+ wrapped_header_bytes[0] ==
1077
+ definitions.BlinkSerializationTag.VERSION and
1078
+ wrapped_header_bytes[1] ==
1079
+ definitions.REQUIRES_PROCESSING_SSV_PSEUDO_VERSION and
1080
+ wrapped_header_bytes[2] == definitions.COMPRESSED_WITH_SNAPPY):
1081
+ is_wrapped = True
1082
+ # ignore the wrapped header bytes when decompressing
1083
+ blink_bytes = snappy.decompress(blink_bytes[3:])
1015
1084
  blink_value = blink.V8ScriptValueDecoder.FromBytes(blink_bytes)
1016
1085
  return ObjectStoreDataValue(
1017
- unknown=unknown_integer,
1018
- is_wrapped=False,
1086
+ version=version,
1087
+ is_wrapped=is_wrapped,
1019
1088
  blob_size=None,
1020
1089
  blob_offset=None,
1021
1090
  value=blink_value)
1022
1091
 
1023
1092
  @classmethod
1024
1093
  def FromDecoder(
1025
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
1094
+ cls,
1095
+ decoder: utils.LevelDBDecoder,
1096
+ key_prefix: KeyPrefix,
1026
1097
  base_offset: int = 0
1027
1098
  ) -> ObjectStoreDataKey:
1028
1099
  """Decodes the object store data key."""
@@ -1052,13 +1123,14 @@ class ExistsEntryKey(BaseIndexedDBKey):
1052
1123
 
1053
1124
  @classmethod
1054
1125
  def FromDecoder(
1055
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
1126
+ cls,
1127
+ decoder: utils.LevelDBDecoder,
1128
+ key_prefix: KeyPrefix,
1056
1129
  base_offset: int = 0
1057
1130
  ) -> ExistsEntryKey:
1058
1131
  """Decodes the exists entry key."""
1059
1132
  offset = decoder.stream.tell()
1060
1133
  encoded_user_key = IDBKey.FromDecoder(decoder, offset)
1061
-
1062
1134
  return cls(
1063
1135
  offset=base_offset + offset,
1064
1136
  key_prefix=key_prefix, encoded_user_key=encoded_user_key)
@@ -1084,8 +1156,12 @@ class IndexDataKey(BaseIndexedDBKey):
1084
1156
  return version, idb_key
1085
1157
 
1086
1158
  @classmethod
1087
- def FromDecoder(cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
1088
- base_offset: int = 0) -> IndexDataKey:
1159
+ def FromDecoder(
1160
+ cls,
1161
+ decoder: utils.LevelDBDecoder,
1162
+ key_prefix: KeyPrefix,
1163
+ base_offset: int = 0
1164
+ ) -> IndexDataKey:
1089
1165
  """Decodes the index data key."""
1090
1166
  offset = decoder.stream.tell()
1091
1167
  encoded_user_key = IDBKey.FromDecoder(decoder, offset)
@@ -1120,13 +1196,17 @@ class BlobEntryKey(BaseIndexedDBKey):
1120
1196
  user_key: IDBKey
1121
1197
 
1122
1198
  def DecodeValue(
1123
- self, decoder: utils.LevelDBDecoder) -> IndexedDBExternalObject:
1199
+ self,
1200
+ decoder: utils.LevelDBDecoder
1201
+ ) -> IndexedDBExternalObject:
1124
1202
  """Decodes the blob entry value."""
1125
1203
  return IndexedDBExternalObject.FromDecoder(decoder)
1126
1204
 
1127
1205
  @classmethod
1128
1206
  def FromDecoder(
1129
- cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
1207
+ cls,
1208
+ decoder: utils.LevelDBDecoder,
1209
+ key_prefix: KeyPrefix,
1130
1210
  base_offset: int = 0
1131
1211
  ) -> BlobEntryKey:
1132
1212
  """Decodes the blob entry key."""
@@ -1145,13 +1225,13 @@ class IndexedDbKey(BaseIndexedDBKey):
1145
1225
  """
1146
1226
 
1147
1227
  METADATA_TYPE_TO_CLASS = {
1148
- definitions.KeyPrefixType.GLOBAL_METADATA: GlobalMetaDataKey,
1228
+ definitions.KeyPrefixType.BLOB_ENTRY: BlobEntryKey,
1149
1229
  definitions.KeyPrefixType.DATABASE_METADATA: DatabaseMetaDataKey,
1150
- definitions.KeyPrefixType.OBJECT_STORE_DATA: ObjectStoreDataKey,
1151
1230
  definitions.KeyPrefixType.EXISTS_ENTRY: ExistsEntryKey,
1231
+ definitions.KeyPrefixType.GLOBAL_METADATA: GlobalMetaDataKey,
1232
+ definitions.KeyPrefixType.INVALID_TYPE: None,
1152
1233
  definitions.KeyPrefixType.INDEX_DATA: IndexDataKey,
1153
- definitions.KeyPrefixType.BLOB_ENTRY: BlobEntryKey,
1154
- definitions.KeyPrefixType.INVALID_TYPE: None
1234
+ definitions.KeyPrefixType.OBJECT_STORE_DATA: ObjectStoreDataKey,
1155
1235
  }
1156
1236
 
1157
1237
  def DecodeValue(self, decoder: utils.LevelDBDecoder) -> Any:
@@ -1167,9 +1247,13 @@ class IndexedDbKey(BaseIndexedDBKey):
1167
1247
  decoder: utils.LevelDBDecoder,
1168
1248
  key_prefix: KeyPrefix,
1169
1249
  base_offset: int = 0
1170
- ) -> Union[Type[DatabaseMetaDataKey], Type[ExistsEntryKey],
1171
- Type[BlobEntryKey], Type[GlobalMetaDataKey],
1172
- Type[IndexDataKey], Type[ObjectStoreDataKey]]:
1250
+ ) -> Union[
1251
+ BlobEntryKey,
1252
+ DatabaseMetaDataKey,
1253
+ ExistsEntryKey,
1254
+ GlobalMetaDataKey,
1255
+ IndexDataKey,
1256
+ ObjectStoreDataKey]:
1173
1257
  """Decodes the IndexedDB key."""
1174
1258
  key_type = key_prefix.GetKeyPrefixType()
1175
1259
  key_class = cls.METADATA_TYPE_TO_CLASS.get(key_type)
@@ -1195,7 +1279,9 @@ class IndexMetaDataKey(BaseIndexedDBKey):
1195
1279
  metadata_type: definitions.IndexMetaDataKeyType
1196
1280
 
1197
1281
  def DecodeValue(
1198
- self, decoder: utils.LevelDBDecoder) -> Union[bool, IDBKeyPath, str]:
1282
+ self,
1283
+ decoder: utils.LevelDBDecoder
1284
+ ) -> Union[bool, IDBKeyPath, str]:
1199
1285
  """Decodes the index metadata value."""
1200
1286
  if self.metadata_type == definitions.IndexMetaDataKeyType.INDEX_NAME:
1201
1287
  return decoder.DecodeString()[1]
@@ -1213,7 +1299,8 @@ class IndexMetaDataKey(BaseIndexedDBKey):
1213
1299
  def FromDecoder(
1214
1300
  cls,
1215
1301
  decoder: utils.LevelDBDecoder,
1216
- key_prefix: KeyPrefix, base_offset: int = 0
1302
+ key_prefix: KeyPrefix,
1303
+ base_offset: int = 0
1217
1304
  ) -> IndexMetaDataKey:
1218
1305
  """Decodes the index metadata key."""
1219
1306
  offset, key_type = decoder.DecodeUint8()
@@ -1402,21 +1489,21 @@ class FolderReader:
1402
1489
  """A IndexedDB folder reader for Chrome/Chromium.
1403
1490
 
1404
1491
  Attributes:
1405
- foldername (str): the source LevelDB folder.
1492
+ folder_name (str): the source LevelDB folder.
1406
1493
  """
1407
1494
 
1408
- def __init__(self, foldername: pathlib.Path):
1495
+ def __init__(self, folder_name: pathlib.Path):
1409
1496
  """Initializes the FileReader.
1410
1497
 
1411
1498
  Args:
1412
- foldername: the source IndexedDB folder.
1499
+ folder_name: the source IndexedDB folder.
1413
1500
 
1414
1501
  Raises:
1415
- ValueError: if foldername is None or not a directory.
1502
+ ValueError: if folder_name is None or not a directory.
1416
1503
  """
1417
- if not foldername or not foldername.is_dir():
1418
- raise ValueError(f'{foldername} is None or not a directory')
1419
- self.foldername = foldername
1504
+ if not folder_name or not folder_name.is_dir():
1505
+ raise ValueError(f'{folder_name} is None or not a directory')
1506
+ self.folder_name = folder_name
1420
1507
 
1421
1508
  def GetRecords(
1422
1509
  self,
@@ -1432,13 +1519,12 @@ class FolderReader:
1432
1519
  Yields:
1433
1520
  IndexedDBRecord.
1434
1521
  """
1435
- leveldb_folder_reader = record.FolderReader(self.foldername)
1522
+ leveldb_folder_reader = record.FolderReader(self.folder_name)
1436
1523
  for leveldb_record in leveldb_folder_reader.GetRecords(
1437
1524
  use_manifest=use_manifest,
1438
1525
  use_sequence_number=use_sequence_number):
1439
1526
  try:
1440
- yield IndexedDBRecord.FromLevelDBRecord(
1441
- leveldb_record)
1527
+ yield IndexedDBRecord.FromLevelDBRecord(leveldb_record)
1442
1528
  except(
1443
1529
  errors.ParserError,
1444
1530
  errors.DecoderError,