dfindexeddb 20240519__tar.gz → 20241031__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-20240519/dfindexeddb.egg-info → dfindexeddb-20241031}/PKG-INFO +12 -6
  2. {dfindexeddb-20240519 → dfindexeddb-20241031}/README.md +11 -5
  3. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/indexeddb/chromium/v8.py +30 -10
  4. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/indexeddb/cli.py +36 -3
  5. dfindexeddb-20241031/dfindexeddb/indexeddb/firefox/definitions.py +143 -0
  6. dfindexeddb-20241031/dfindexeddb/indexeddb/firefox/gecko.py +600 -0
  7. dfindexeddb-20241031/dfindexeddb/indexeddb/firefox/record.py +180 -0
  8. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/indexeddb/safari/webkit.py +37 -13
  9. dfindexeddb-20241031/dfindexeddb/indexeddb/types.py +71 -0
  10. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/leveldb/descriptor.py +2 -1
  11. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/utils.py +1 -1
  12. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/version.py +1 -1
  13. {dfindexeddb-20240519 → dfindexeddb-20241031/dfindexeddb.egg-info}/PKG-INFO +12 -6
  14. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb.egg-info/SOURCES.txt +4 -0
  15. {dfindexeddb-20240519 → dfindexeddb-20241031}/pyproject.toml +1 -1
  16. {dfindexeddb-20240519 → dfindexeddb-20241031}/AUTHORS +0 -0
  17. {dfindexeddb-20240519 → dfindexeddb-20241031}/LICENSE +0 -0
  18. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/__init__.py +0 -0
  19. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/errors.py +0 -0
  20. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/indexeddb/__init__.py +0 -0
  21. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/indexeddb/chromium/__init__.py +0 -0
  22. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/indexeddb/chromium/blink.py +0 -0
  23. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/indexeddb/chromium/definitions.py +0 -0
  24. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/indexeddb/chromium/record.py +0 -0
  25. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/indexeddb/firefox/__init__.py +0 -0
  26. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/indexeddb/safari/__init__.py +0 -0
  27. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/indexeddb/safari/definitions.py +0 -0
  28. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/indexeddb/safari/record.py +0 -0
  29. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/indexeddb/utils.py +0 -0
  30. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/leveldb/__init__.py +0 -0
  31. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/leveldb/cli.py +0 -0
  32. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/leveldb/definitions.py +0 -0
  33. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/leveldb/ldb.py +0 -0
  34. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/leveldb/log.py +0 -0
  35. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/leveldb/plugins/__init__.py +0 -0
  36. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/leveldb/plugins/chrome_notifications.py +0 -0
  37. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/leveldb/plugins/interface.py +0 -0
  38. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/leveldb/plugins/manager.py +0 -0
  39. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/leveldb/plugins/notification_database_data_pb2.py +0 -0
  40. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/leveldb/record.py +0 -0
  41. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb/leveldb/utils.py +0 -0
  42. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb.egg-info/dependency_links.txt +0 -0
  43. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb.egg-info/entry_points.txt +0 -0
  44. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb.egg-info/requires.txt +0 -0
  45. {dfindexeddb-20240519 → dfindexeddb-20241031}/dfindexeddb.egg-info/top_level.txt +0 -0
  46. {dfindexeddb-20240519 → dfindexeddb-20241031}/setup.cfg +0 -0
  47. {dfindexeddb-20240519 → dfindexeddb-20241031}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dfindexeddb
3
- Version: 20240519
3
+ Version: 20241031
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>
@@ -230,8 +230,7 @@ analysis of IndexedDB and LevelDB files.
230
230
 
231
231
  It parses LevelDB, IndexedDB and JavaScript structures from these files without
232
232
  requiring native libraries. (Note: only a subset of IndexedDB key types and
233
- JavaScript types for Safari and Chromium-based browsers are currently supported.
234
- Firefox is under development).
233
+ JavaScript types for Firefox, Safari and Chromium-based browsers are currently supported).
235
234
 
236
235
  The content of IndexedDB files is dependent on what a web application stores
237
236
  locally/offline using the web browser's
@@ -313,6 +312,13 @@ options:
313
312
 
314
313
  #### Examples:
315
314
 
315
+ To parse IndexedDB records from an sqlite file for Firefox and output the
316
+ results as JSON, use the following command:
317
+
318
+ ```
319
+ dfindexeddb db -s SOURCE --format firefox -o json
320
+ ```
321
+
316
322
  To parse IndexedDB records from an sqlite file for Safari and output the
317
323
  results as JSON-L, use the following command:
318
324
 
@@ -376,7 +382,7 @@ To parse records from a LevelDB folder, use the following command:
376
382
  dfleveldb db -s SOURCE
377
383
  ```
378
384
 
379
- To parse records from a LevelDB folder, and use the sequence number to
385
+ To parse records from a LevelDB folder, and use the sequence number to
380
386
  determine recovered records and output as JSON, use the
381
387
  following command:
382
388
 
@@ -409,8 +415,8 @@ $ dfleveldb descriptor -s SOURCE [-o {json,jsonl,repr}] [-t {blocks,physical_rec
409
415
 
410
416
  #### Plugins
411
417
 
412
- To apply a plugin parser for a leveldb file/folder, add the
413
- `--plugin [Plugin Name]` argument. Currently, there is support for the
418
+ To apply a plugin parser for a leveldb file/folder, add the
419
+ `--plugin [Plugin Name]` argument. Currently, there is support for the
414
420
  following artifacts:
415
421
 
416
422
  | Plugin Name | Artifact Name |
@@ -5,8 +5,7 @@ analysis of IndexedDB and LevelDB files.
5
5
 
6
6
  It parses LevelDB, IndexedDB and JavaScript structures from these files without
7
7
  requiring native libraries. (Note: only a subset of IndexedDB key types and
8
- JavaScript types for Safari and Chromium-based browsers are currently supported.
9
- Firefox is under development).
8
+ JavaScript types for Firefox, Safari and Chromium-based browsers are currently supported).
10
9
 
11
10
  The content of IndexedDB files is dependent on what a web application stores
12
11
  locally/offline using the web browser's
@@ -88,6 +87,13 @@ options:
88
87
 
89
88
  #### Examples:
90
89
 
90
+ To parse IndexedDB records from an sqlite file for Firefox and output the
91
+ results as JSON, use the following command:
92
+
93
+ ```
94
+ dfindexeddb db -s SOURCE --format firefox -o json
95
+ ```
96
+
91
97
  To parse IndexedDB records from an sqlite file for Safari and output the
92
98
  results as JSON-L, use the following command:
93
99
 
@@ -151,7 +157,7 @@ To parse records from a LevelDB folder, use the following command:
151
157
  dfleveldb db -s SOURCE
152
158
  ```
153
159
 
154
- To parse records from a LevelDB folder, and use the sequence number to
160
+ To parse records from a LevelDB folder, and use the sequence number to
155
161
  determine recovered records and output as JSON, use the
156
162
  following command:
157
163
 
@@ -184,8 +190,8 @@ $ dfleveldb descriptor -s SOURCE [-o {json,jsonl,repr}] [-t {blocks,physical_rec
184
190
 
185
191
  #### Plugins
186
192
 
187
- To apply a plugin parser for a leveldb file/folder, add the
188
- `--plugin [Plugin Name]` argument. Currently, there is support for the
193
+ To apply a plugin parser for a leveldb file/folder, add the
194
+ `--plugin [Plugin Name]` argument. Currently, there is support for the
189
195
  following artifacts:
190
196
 
191
197
  | Plugin Name | Artifact Name |
@@ -13,6 +13,8 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  """Parsers for v8 javascript serialized objects."""
16
+ from __future__ import annotations
17
+
16
18
  from dataclasses import dataclass
17
19
  from datetime import datetime
18
20
  import io
@@ -25,8 +27,8 @@ from dfindexeddb.indexeddb.chromium import definitions
25
27
 
26
28
 
27
29
  @dataclass
28
- class BufferArrayView:
29
- """A parsed Javascript BufferArrayView."""
30
+ class ArrayBufferView:
31
+ """A parsed Javascript ArrayBufferView."""
30
32
  buffer: bytes
31
33
  tag: definitions.V8ArrayBufferViewTag
32
34
  offset: int
@@ -34,15 +36,23 @@ class BufferArrayView:
34
36
  flags: int
35
37
 
36
38
 
37
- class JSArray(list):
39
+ @dataclass
40
+ class JSArray:
38
41
  """A parsed Javascript array.
39
42
 
40
- This is a wrapper around a standard Python list to allow assigning arbitrary
41
- properties as is possible in the Javascript equivalent.
43
+ A Javascript array behaves like a Python list but allows assigning arbitrary
44
+ properties. The array is stored in the attribute __array__.
42
45
  """
46
+ def __init__(self):
47
+ self.__array__ = []
48
+
49
+ def Append(self, element: Any):
50
+ """Appends a new element to the array."""
51
+ self.__array__.append(element)
43
52
 
44
53
  def __repr__(self):
45
- array_entries = ", ".join([str(entry) for entry in list(self)])
54
+ array_entries = ", ".join(
55
+ [str(entry) for entry in list(self.__array__)])
46
56
  properties = ", ".join(
47
57
  f'{key}: {value}' for key, value in self.properties.items())
48
58
  return f'[{array_entries}, {properties}]'
@@ -52,6 +62,11 @@ class JSArray(list):
52
62
  """Returns the object properties."""
53
63
  return self.__dict__
54
64
 
65
+ def __eq__(self, other: JSArray):
66
+ return (
67
+ self.__array__ == other.__array__
68
+ and self.properties == other.properties)
69
+
55
70
  def __contains__(self, item):
56
71
  return item in self.__dict__
57
72
 
@@ -194,6 +209,7 @@ class ValueDeserializer:
194
209
  if tag and tag == definitions.V8SerializationTag.ARRAY_BUFFER_VIEW:
195
210
  self._ConsumeTag(tag)
196
211
  result = self._ReadJSArrayBufferView(result)
212
+ self.objects[self._GetNextId()] = result
197
213
  return result
198
214
 
199
215
  def _ReadObjectInternal(self) -> Tuple[definitions.V8SerializationTag, Any]:
@@ -385,7 +401,10 @@ class ValueDeserializer:
385
401
  while self._PeekTag() != end_tag:
386
402
  key = self._ReadObject()
387
403
  value = self._ReadObject()
388
- js_object[key] = value
404
+ if isinstance(js_object, dict):
405
+ js_object[key] = value
406
+ else:
407
+ js_object.properties[key] = value
389
408
  num_properties += 1
390
409
  self._ConsumeTag(end_tag)
391
410
  return num_properties
@@ -407,7 +426,7 @@ class ValueDeserializer:
407
426
  js_array = JSArray()
408
427
  _, length = self.decoder.DecodeUint32Varint()
409
428
  for _ in range(length):
410
- js_array.append(Undefined())
429
+ js_array.Append(Undefined())
411
430
 
412
431
  num_properties = self._ReadJSObjectProperties(
413
432
  js_array.__dict__, definitions.V8SerializationTag.END_SPARSE_JS_ARRAY)
@@ -440,7 +459,7 @@ class ValueDeserializer:
440
459
 
441
460
  if self.version < 11 and isinstance(array_object, Undefined):
442
461
  continue
443
- js_array.append(array_object)
462
+ js_array.Append(array_object)
444
463
 
445
464
  num_properties = self._ReadJSObjectProperties(
446
465
  js_array.__dict__, definitions.V8SerializationTag.END_DENSE_JS_ARRAY)
@@ -571,6 +590,7 @@ class ValueDeserializer:
571
590
  if is_resizable:
572
591
  _, max_byte_length = self.decoder.DecodeUint32Varint()
573
592
  if byte_length > max_byte_length:
593
+ self.objects[next_id] = array_buffer
574
594
  return array_buffer
575
595
  if byte_length:
576
596
  _, array_buffer = self.decoder.ReadBytes(byte_length)
@@ -589,7 +609,7 @@ class ValueDeserializer:
589
609
  else:
590
610
  flags = 0
591
611
 
592
- return BufferArrayView(
612
+ return ArrayBufferView(
593
613
  buffer=buffer,
594
614
  tag=definitions.V8ArrayBufferViewTag(tag[0]),
595
615
  offset=byte_offset,
@@ -25,6 +25,8 @@ from dfindexeddb import version
25
25
  from dfindexeddb.indexeddb.chromium import blink
26
26
  from dfindexeddb.indexeddb.chromium import record as chromium_record
27
27
  from dfindexeddb.indexeddb.chromium import v8
28
+ from dfindexeddb.indexeddb.firefox import gecko
29
+ from dfindexeddb.indexeddb.firefox import record as firefox_record
28
30
  from dfindexeddb.indexeddb.safari import record as safari_record
29
31
 
30
32
 
@@ -39,7 +41,7 @@ class Encoder(json.JSONEncoder):
39
41
  if dataclasses.is_dataclass(o):
40
42
  o_dict = utils.asdict(o)
41
43
  return o_dict
42
- if isinstance(o, bytes):
44
+ if isinstance(o, (bytes, bytearray)):
43
45
  out = []
44
46
  for x in o:
45
47
  if chr(x) not in _VALID_PRINTABLE_CHARACTERS:
@@ -51,6 +53,8 @@ class Encoder(json.JSONEncoder):
51
53
  return o.isoformat()
52
54
  if isinstance(o, v8.Undefined):
53
55
  return "<undefined>"
56
+ if isinstance(o, v8.JSArray):
57
+ return o.__dict__
54
58
  if isinstance(o, v8.Null):
55
59
  return "<null>"
56
60
  if isinstance(o, set):
@@ -73,13 +77,21 @@ def _Output(structure, output):
73
77
 
74
78
 
75
79
  def BlinkCommand(args):
76
- """The CLI for processing a file as a blink value."""
80
+ """The CLI for processing a file as a blink-encoded value."""
77
81
  with open(args.source, 'rb') as fd:
78
82
  buffer = fd.read()
79
83
  blink_value = blink.V8ScriptValueDecoder.FromBytes(buffer)
80
84
  _Output(blink_value, output=args.output)
81
85
 
82
86
 
87
+ def GeckoCommand(args):
88
+ """The CLI for processing a file as a gecko-encoded value."""
89
+ with open(args.source, 'rb') as fd:
90
+ buffer = fd.read()
91
+ blink_value = gecko.JSStructuredCloneDecoder.FromBytes(buffer)
92
+ _Output(blink_value, output=args.output)
93
+
94
+
83
95
  def DbCommand(args):
84
96
  """The CLI for processing a directory as IndexedDB."""
85
97
  if args.format in ('chrome', 'chromium'):
@@ -88,6 +100,9 @@ def DbCommand(args):
88
100
  use_manifest=args.use_manifest,
89
101
  use_sequence_number=args.use_sequence_number):
90
102
  _Output(db_record, output=args.output)
103
+ elif args.format == 'firefox':
104
+ for db_record in firefox_record.FileReader(args.source).Records():
105
+ _Output(db_record, output=args.output)
91
106
  elif args.format == 'safari':
92
107
  for db_record in safari_record.FileReader(args.source).Records():
93
108
  _Output(db_record, output=args.output)
@@ -133,6 +148,24 @@ def App():
133
148
  help='Output format. Default is json')
134
149
  parser_blink.set_defaults(func=BlinkCommand)
135
150
 
151
+ parser_gecko = subparsers.add_parser(
152
+ 'gecko', help='Parse a file as a gecko-encoded value.')
153
+ parser_gecko.add_argument(
154
+ '-s', '--source',
155
+ required=True,
156
+ type=pathlib.Path,
157
+ help='The source file.')
158
+ parser_gecko.add_argument(
159
+ '-o',
160
+ '--output',
161
+ choices=[
162
+ 'json',
163
+ 'jsonl',
164
+ 'repr'],
165
+ default='json',
166
+ help='Output format. Default is json')
167
+ parser_gecko.set_defaults(func=GeckoCommand)
168
+
136
169
  parser_db = subparsers.add_parser(
137
170
  'db', help='Parse a directory as IndexedDB.')
138
171
  parser_db.add_argument(
@@ -156,7 +189,7 @@ def App():
156
189
  parser_db.add_argument(
157
190
  '--format',
158
191
  required=True,
159
- choices=['chromium', 'chrome', 'safari'],
192
+ choices=['chromium', 'chrome', 'firefox', 'safari'],
160
193
  help='The type of IndexedDB to parse.')
161
194
  parser_db.add_argument(
162
195
  '-o',
@@ -0,0 +1,143 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright 2024 Google LLC
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # https://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ """Definitions for Firefox IndexedDB."""
16
+ from enum import IntEnum
17
+
18
+
19
+ class IndexedDBKeyType(IntEnum):
20
+ """IndexedDB Key Types."""
21
+ TERMINATOR = 0
22
+ FLOAT = 0x10
23
+ DATE = 0x20
24
+ STRING = 0x30
25
+ BINARY = 0x40
26
+ ARRAY = 0x50
27
+
28
+
29
+ MAX_ARRAY_COLLAPSE = 3
30
+ MAX_RECURSION_DEPTH = 64
31
+ MAX_LENGTH = (1 << 30) - 2
32
+ ONE_BYTE_LIMIT = 0x7E
33
+ TWO_BYTE_LIMIT = 0x3FFF + 0x7F
34
+ ONE_BYTE_ADJUST = 1
35
+ TWO_BYTE_ADJUST = -0x7F
36
+ THREE_BYTE_SHIFT = 6
37
+
38
+
39
+ class StructuredDataType(IntEnum):
40
+ """Structured Data Types."""
41
+ FLOAT_MAX = 0xFFF00000
42
+ HEADER = 0xFFF10000
43
+ NULL = 0xFFFF0000
44
+ UNDEFINED = 0xFFFF0001
45
+ BOOLEAN = 0xFFFF0002
46
+ INT32 = 0xFFFF0003
47
+ STRING = 0xFFFF0004
48
+ DATE_OBJECT = 0xFFFF0005
49
+ REGEXP_OBJECT = 0xFFFF0006
50
+ ARRAY_OBJECT = 0xFFFF0007
51
+ OBJECT_OBJECT = 0xFFFF0008
52
+ ARRAY_BUFFER_OBJECT_V2 = 0xFFFF0009
53
+ BOOLEAN_OBJECT = 0xFFFF000A
54
+ STRING_OBJECT = 0xFFFF000B
55
+ NUMBER_OBJECT = 0xFFFF000C
56
+ BACK_REFERENCE_OBJECT = 0xFFFF000D
57
+ DO_NOT_USE_1 = 0xFFFF000E
58
+ DO_NOT_USE_2 = 0xFFFF000F
59
+ TYPED_ARRAY_OBJECT_V2 = 0xFFFF0010
60
+ MAP_OBJECT = 0xFFFF0011
61
+ SET_OBJECT = 0xFFFF0012
62
+ END_OF_KEYS = 0xFFFF0013
63
+ DO_NOT_USE_3 = 0xFFFF0014
64
+ DATA_VIEW_OBJECT_V2 = 0xFFFF0015
65
+ SAVED_FRAME_OBJECT = 0xFFFF0016
66
+ JSPRINCIPALS = 0xFFFF0017
67
+ NULL_JSPRINCIPALS = 0xFFFF0018
68
+ RECONSTRUCTED_SAVED_FRAME_PRINCIPALS_IS_SYSTEM = 0xFFFF0019
69
+ RECONSTRUCTED_SAVED_FRAME_PRINCIPALS_IS_NOT_SYSTEM = 0xFFFF001A
70
+ SHARED_ARRAY_BUFFER_OBJECT = 0xFFFF001B
71
+ SHARED_WASM_MEMORY_OBJECT = 0xFFFF001C
72
+ BIGINT = 0xFFFF001D
73
+ BIGINT_OBJECT = 0xFFFF001E
74
+ ARRAY_BUFFER_OBJECT = 0xFFFF001F
75
+ TYPED_ARRAY_OBJECT = 0xFFFF0020
76
+ DATA_VIEW_OBJECT = 0xFFFF0021
77
+ ERROR_OBJECT = 0xFFFF0022
78
+ RESIZABLE_ARRAY_BUFFER_OBJECT = 0xFFFF0023
79
+ GROWABLE_SHARED_ARRAY_BUFFER_OBJECT = 0xFFFF0024
80
+ TYPED_ARRAY_V1_INT8 = 0xFFFF0100
81
+ TYPED_ARRAY_V1_UINT8 = 0xFFFF0101
82
+ TYPED_ARRAY_V1_INT16 = 0xFFFF0102
83
+ TYPED_ARRAY_V1_UINT16 = 0xFFFF0103
84
+ TYPED_ARRAY_V1_INT32 = 0xFFFF0104
85
+ TYPED_ARRAY_V1_UINT32 = 0xFFFF0105
86
+ TYPED_ARRAY_V1_FLOAT32 = 0xFFFF0106
87
+ TYPED_ARRAY_V1_FLOAT64 = 0xFFFF0107
88
+ TYPED_ARRAY_V1_UINT8_CLAMPED = 0xFFFF0108
89
+ TRANSFER_MAP_HEADER = 0xFFFF0200
90
+ TRANSFER_MAP_PENDING_ENTRY = 0xFFFF0201
91
+ TRANSFER_MAP_ARRAY_BUFFER = 0xFFFF0202
92
+ TRANSFER_MAP_STORED_ARRAY_BUFFER = 0xFFFF0203
93
+ TRANSFER_MAP_END_OF_BUILTIN_TYPES = 0xFFFF0204
94
+
95
+
96
+ class StructuredCloneTags(IntEnum):
97
+ """Structured Clone Tags."""
98
+ BLOB = 0xFFFF8001
99
+ FILE_WITHOUT_LASTMODIFIEDDATE = 0xFFFF8002
100
+ FILELIST = 0xFFFF8003
101
+ MUTABLEFILE = 0xFFFF8004
102
+ FILE = 0xFFFF8005
103
+ WASM_MODULE = 0xFFFF8006
104
+ IMAGEDATA = 0xFFFF8007
105
+ DOMPOINT = 0xFFFF8008
106
+ DOMPOINTREADONLY = 0xFFFF8009
107
+ CRYPTOKEY = 0xFFFF800A
108
+ NULL_PRINCIPAL = 0xFFFF800B
109
+ SYSTEM_PRINCIPAL = 0xFFFF800C
110
+ CONTENT_PRINCIPAL = 0xFFFF800D
111
+ DOMQUAD = 0xFFFF800E
112
+ RTCCERTIFICATE = 0xFFFF800F
113
+ DOMRECT = 0xFFFF8010
114
+ DOMRECTREADONLY = 0xFFFF8011
115
+ EXPANDED_PRINCIPAL = 0xFFFF8012
116
+ DOMMATRIX = 0xFFFF8013
117
+ URLSEARCHPARAMS = 0xFFFF8014
118
+ DOMMATRIXREADONLY = 0xFFFF8015
119
+ DOMEXCEPTION = 0xFFFF80016
120
+ EMPTY_SLOT_9 = 0xFFFF8017
121
+ STRUCTUREDCLONETESTER = 0xFFFF8018
122
+ FILESYSTEMHANDLE = 0xFFFF8019
123
+ FILESYSTEMFILEHANDLE = 0xFFFF801A
124
+ FILESYSTEMDIRECTORYHANDLE = 0xFFFF801B
125
+ IMAGEBITMAP = 0xFFFF801C
126
+ MAP_MESSAGEPORT = 0xFFFF801D
127
+ FORMDATA = 0xFFFF801E
128
+ CANVAS = 0xFFFF801F # This tag is for OffscreenCanvas.
129
+ DIRECTORY = 0xFFFF8020
130
+ INPUTSTREAM = 0xFFFF8021
131
+ STRUCTURED_CLONE_HOLDER = 0xFFFF8022
132
+ BROWSING_CONTEXT = 0xFFFF8023
133
+ CLONED_ERROR_OBJECT = 0xFFFF8024
134
+ READABLESTREAM = 0xFFFF8025
135
+ WRITABLESTREAM = 0xFFFF8026
136
+ TRANSFORMSTREAM = 0xFFFF8027
137
+ VIDEOFRAME = 0xFFFF8028
138
+ ENCODEDVIDEOCHUNK = 0xFFFF8029
139
+ AUDIODATA = 0xFFFF8030
140
+ ENCODEDAUDIOCHUNK = 0xFFFF8031
141
+
142
+
143
+ FRAME_HEADER = b'\xff\x06\x00\x00sNaPpY'