dfindexeddb 20241105__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 +148 -125
  3. dfindexeddb/indexeddb/chromium/record.py +426 -324
  4. dfindexeddb/indexeddb/chromium/v8.py +100 -78
  5. dfindexeddb/indexeddb/cli.py +122 -118
  6. dfindexeddb/indexeddb/firefox/definitions.py +7 -4
  7. dfindexeddb/indexeddb/firefox/gecko.py +98 -74
  8. dfindexeddb/indexeddb/firefox/record.py +66 -24
  9. dfindexeddb/indexeddb/safari/definitions.py +5 -3
  10. dfindexeddb/indexeddb/safari/record.py +68 -51
  11. dfindexeddb/indexeddb/safari/webkit.py +85 -71
  12. dfindexeddb/indexeddb/types.py +4 -1
  13. dfindexeddb/leveldb/cli.py +146 -138
  14. dfindexeddb/leveldb/definitions.py +6 -2
  15. dfindexeddb/leveldb/descriptor.py +70 -56
  16. dfindexeddb/leveldb/ldb.py +39 -33
  17. dfindexeddb/leveldb/log.py +41 -30
  18. dfindexeddb/leveldb/plugins/chrome_notifications.py +30 -18
  19. dfindexeddb/leveldb/plugins/interface.py +5 -6
  20. dfindexeddb/leveldb/plugins/manager.py +10 -9
  21. dfindexeddb/leveldb/record.py +71 -62
  22. dfindexeddb/leveldb/utils.py +21 -13
  23. dfindexeddb/utils.py +36 -31
  24. dfindexeddb/version.py +2 -2
  25. dfindexeddb-20251109.dist-info/METADATA +222 -0
  26. dfindexeddb-20251109.dist-info/RECORD +40 -0
  27. {dfindexeddb-20241105.dist-info → dfindexeddb-20251109.dist-info}/WHEEL +1 -1
  28. dfindexeddb-20241105.dist-info/AUTHORS +0 -12
  29. dfindexeddb-20241105.dist-info/METADATA +0 -424
  30. dfindexeddb-20241105.dist-info/RECORD +0 -41
  31. {dfindexeddb-20241105.dist-info → dfindexeddb-20251109.dist-info}/entry_points.txt +0 -0
  32. {dfindexeddb-20241105.dist-info → dfindexeddb-20251109.dist-info/licenses}/LICENSE +0 -0
  33. {dfindexeddb-20241105.dist-info → dfindexeddb-20251109.dist-info}/top_level.txt +0 -0
@@ -13,11 +13,11 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  """Safari IndexedDB records."""
16
- from dataclasses import dataclass
17
16
  import plistlib
18
17
  import sqlite3
19
18
  import sys
20
19
  import traceback
20
+ from dataclasses import dataclass
21
21
  from typing import Any, Generator, Optional
22
22
 
23
23
  from dfindexeddb import errors
@@ -35,6 +35,7 @@ class ObjectStoreInfo:
35
35
  auto_inc: True if the object store uses auto incrementing IDs.
36
36
  database_name: the database name from the IDBDatabaseInfo table.
37
37
  """
38
+
38
39
  id: int
39
40
  name: str
40
41
  key_path: str
@@ -54,6 +55,7 @@ class IndexedDBRecord:
54
55
  database_name: the IndexedDB database name from the IDBDatabaseInfo table.
55
56
  record_id: the record ID from the Record table.
56
57
  """
58
+
57
59
  key: Any
58
60
  value: Any
59
61
  object_store_id: int
@@ -80,24 +82,28 @@ class FileReader:
80
82
  """
81
83
  self.filename = filename
82
84
 
83
- with sqlite3.connect(f'file:{self.filename}?mode=ro', uri=True) as conn:
85
+ with sqlite3.connect(f"file:{self.filename}?mode=ro", uri=True) as conn:
84
86
  cursor = conn.execute(
85
- 'SELECT value FROM IDBDatabaseInfo WHERE key = "DatabaseVersion"')
87
+ 'SELECT value FROM IDBDatabaseInfo WHERE key = "DatabaseVersion"'
88
+ )
86
89
  result = cursor.fetchone()
87
90
  self.database_version = result[0]
88
91
 
89
92
  cursor = conn.execute(
90
- 'SELECT value FROM IDBDatabaseInfo WHERE key = "MetadataVersion"')
93
+ 'SELECT value FROM IDBDatabaseInfo WHERE key = "MetadataVersion"'
94
+ )
91
95
  result = cursor.fetchone()
92
96
  self.metadata_version = result[0]
93
97
 
94
98
  cursor = conn.execute(
95
- 'SELECT value FROM IDBDatabaseInfo WHERE key = "DatabaseName"')
99
+ 'SELECT value FROM IDBDatabaseInfo WHERE key = "DatabaseName"'
100
+ )
96
101
  result = cursor.fetchone()
97
102
  self.database_name = result[0]
98
103
 
99
104
  cursor = conn.execute(
100
- 'SELECT value FROM IDBDatabaseInfo WHERE key = "MaxObjectStoreID"')
105
+ 'SELECT value FROM IDBDatabaseInfo WHERE key = "MaxObjectStoreID"'
106
+ )
101
107
  result = cursor.fetchone()
102
108
  self.max_object_store_id = result[0]
103
109
 
@@ -107,9 +113,10 @@ class FileReader:
107
113
  Yields:
108
114
  ObjectStoreInfo instances.
109
115
  """
110
- with sqlite3.connect(f'file:{self.filename}?mode=ro', uri=True) as conn:
116
+ with sqlite3.connect(f"file:{self.filename}?mode=ro", uri=True) as conn:
111
117
  cursor = conn.execute(
112
- 'SELECT id, name, keypath, autoinc FROM ObjectStoreInfo')
118
+ "SELECT id, name, keypath, autoinc FROM ObjectStoreInfo"
119
+ )
113
120
  results = cursor.fetchall()
114
121
  for result in results:
115
122
  key_path = plistlib.loads(result[2])
@@ -118,22 +125,25 @@ class FileReader:
118
125
  name=result[1],
119
126
  key_path=key_path,
120
127
  auto_inc=result[3],
121
- database_name=self.database_name)
128
+ database_name=self.database_name,
129
+ )
122
130
 
123
131
  def RecordById(self, record_id: int) -> Optional[IndexedDBRecord]:
124
132
  """Returns an IndexedDBRecord for the given record_id.
125
133
 
126
134
  Returns:
127
- the IndexedDBRecord or None if the record_id does not exist in the
135
+ the IndexedDBRecord or None if the record_id does not exist in the
128
136
  database.
129
137
  """
130
- with sqlite3.connect(f'file:{self.filename}?mode=ro', uri=True) as conn:
138
+ with sqlite3.connect(f"file:{self.filename}?mode=ro", uri=True) as conn:
131
139
  conn.text_factory = bytes
132
140
  cursor = conn.execute(
133
- 'SELECT r.key, r.value, r.objectStoreID, o.name, r.recordID FROM '
134
- 'Records r '
135
- 'JOIN ObjectStoreInfo o ON r.objectStoreID == o.id '
136
- 'WHERE r.recordID = ?', (record_id, ))
141
+ "SELECT r.key, r.value, r.objectStoreID, o.name, r.recordID FROM "
142
+ "Records r "
143
+ "JOIN ObjectStoreInfo o ON r.objectStoreID == o.id "
144
+ "WHERE r.recordID = ?",
145
+ (record_id,),
146
+ )
137
147
  row = cursor.fetchone()
138
148
  if not row:
139
149
  return None
@@ -143,52 +153,56 @@ class FileReader:
143
153
  key=key,
144
154
  value=value,
145
155
  object_store_id=row[2],
146
- object_store_name=row[3].decode('utf-8'),
156
+ object_store_name=row[3].decode("utf-8"),
147
157
  database_name=self.database_name,
148
- record_id=row[4])
158
+ record_id=row[4],
159
+ )
149
160
 
150
161
  def RecordsByObjectStoreName(
151
- self,
152
- name: str
162
+ self, name: str
153
163
  ) -> Generator[IndexedDBRecord, None, None]:
154
164
  """Returns IndexedDBRecords for the given ObjectStore name.
155
165
 
156
166
  Yields:
157
167
  IndexedDBRecord instances.
158
168
  """
159
- with sqlite3.connect(f'file:{self.filename}?mode=ro', uri=True) as conn:
169
+ with sqlite3.connect(f"file:{self.filename}?mode=ro", uri=True) as conn:
160
170
  conn.text_factory = bytes
161
171
  for row in conn.execute(
162
- 'SELECT r.key, r.value, r.objectStoreID, o.name, r.recordID FROM '
163
- 'Records r '
164
- 'JOIN ObjectStoreInfo o ON r.objectStoreID == o.id '
165
- 'WHERE o.name = ?', (name, )):
172
+ "SELECT r.key, r.value, r.objectStoreID, o.name, r.recordID FROM "
173
+ "Records r "
174
+ "JOIN ObjectStoreInfo o ON r.objectStoreID == o.id "
175
+ "WHERE o.name = ?",
176
+ (name,),
177
+ ):
166
178
  key = webkit.IDBKeyData.FromBytes(row[0]).data
167
179
  value = webkit.SerializedScriptValueDecoder.FromBytes(row[1])
168
180
  yield IndexedDBRecord(
169
181
  key=key,
170
182
  value=value,
171
183
  object_store_id=row[2],
172
- object_store_name=row[3].decode('utf-8'),
184
+ object_store_name=row[3].decode("utf-8"),
173
185
  database_name=self.database_name,
174
- record_id=row[4])
186
+ record_id=row[4],
187
+ )
175
188
 
176
189
  def RecordsByObjectStoreId(
177
- self,
178
- object_store_id: int
190
+ self, object_store_id: int
179
191
  ) -> Generator[IndexedDBRecord, None, None]:
180
192
  """Returns IndexedDBRecords for the given ObjectStore id.
181
193
 
182
194
  Yields:
183
195
  IndexedDBRecord instances.
184
196
  """
185
- with sqlite3.connect(f'file:{self.filename}?mode=ro', uri=True) as conn:
197
+ with sqlite3.connect(f"file:{self.filename}?mode=ro", uri=True) as conn:
186
198
  conn.text_factory = bytes
187
199
  cursor = conn.execute(
188
- 'SELECT r.key, r.value, r.objectStoreID, o.name, r.recordID '
189
- 'FROM Records r '
190
- 'JOIN ObjectStoreInfo o ON r.objectStoreID == o.id '
191
- 'WHERE o.id = ?', (object_store_id, ))
200
+ "SELECT r.key, r.value, r.objectStoreID, o.name, r.recordID "
201
+ "FROM Records r "
202
+ "JOIN ObjectStoreInfo o ON r.objectStoreID == o.id "
203
+ "WHERE o.id = ?",
204
+ (object_store_id,),
205
+ )
192
206
  for row in cursor:
193
207
  key = webkit.IDBKeyData.FromBytes(row[0]).data
194
208
  value = webkit.SerializedScriptValueDecoder.FromBytes(row[1])
@@ -196,43 +210,46 @@ class FileReader:
196
210
  key=key,
197
211
  value=value,
198
212
  object_store_id=row[2],
199
- object_store_name=row[3].decode('utf-8'),
213
+ object_store_name=row[3].decode("utf-8"),
200
214
  database_name=self.database_name,
201
- record_id=row[4])
215
+ record_id=row[4],
216
+ )
202
217
 
203
218
  def Records(self) -> Generator[IndexedDBRecord, None, None]:
204
219
  """Returns all the IndexedDBRecords."""
205
- with sqlite3.connect(f'file:{self.filename}?mode=ro', uri=True) as conn:
220
+ with sqlite3.connect(f"file:{self.filename}?mode=ro", uri=True) as conn:
206
221
  conn.text_factory = bytes
207
222
  cursor = conn.execute(
208
- 'SELECT r.key, r.value, r.objectStoreID, o.name, r.recordID '
209
- 'FROM Records r '
210
- 'JOIN ObjectStoreInfo o ON r.objectStoreID == o.id')
223
+ "SELECT r.key, r.value, r.objectStoreID, o.name, r.recordID "
224
+ "FROM Records r "
225
+ "JOIN ObjectStoreInfo o ON r.objectStoreID == o.id"
226
+ )
211
227
  for row in cursor:
212
228
  try:
213
229
  key = webkit.IDBKeyData.FromBytes(row[0]).data
214
- except(
230
+ except (
215
231
  errors.ParserError,
216
232
  errors.DecoderError,
217
- NotImplementedError) as err:
218
- print(
219
- f'Error parsing IndexedDB key: {err}', file=sys.stderr)
220
- print(f'Traceback: {traceback.format_exc()}', file=sys.stderr)
233
+ NotImplementedError,
234
+ ) as err:
235
+ print(f"Error parsing IndexedDB key: {err}", file=sys.stderr)
236
+ print(f"Traceback: {traceback.format_exc()}", file=sys.stderr)
221
237
  continue
222
238
  try:
223
239
  value = webkit.SerializedScriptValueDecoder.FromBytes(row[1])
224
- except(
240
+ except (
225
241
  errors.ParserError,
226
242
  errors.DecoderError,
227
- NotImplementedError) as err:
228
- print(
229
- f'Error parsing IndexedDB value: {err}', file=sys.stderr)
230
- print(f'Traceback: {traceback.format_exc()}', file=sys.stderr)
243
+ NotImplementedError,
244
+ ) as err:
245
+ print(f"Error parsing IndexedDB value: {err}", file=sys.stderr)
246
+ print(f"Traceback: {traceback.format_exc()}", file=sys.stderr)
231
247
  continue
232
248
  yield IndexedDBRecord(
233
249
  key=key,
234
250
  value=value,
235
251
  object_store_id=row[2],
236
- object_store_name=row[3].decode('utf-8'),
252
+ object_store_name=row[3].decode("utf-8"),
237
253
  database_name=self.database_name,
238
- record_id=row[4])
254
+ record_id=row[4],
255
+ )
@@ -15,14 +15,13 @@
15
15
  """Parsers for WebKit encoded JavaScript values."""
16
16
  from __future__ import annotations
17
17
 
18
- from dataclasses import dataclass
19
- from datetime import datetime
20
18
  import io
21
19
  import plistlib
20
+ from dataclasses import dataclass
21
+ from datetime import datetime
22
22
  from typing import Any, Dict, List, Tuple, Union
23
23
 
24
- from dfindexeddb import errors
25
- from dfindexeddb import utils
24
+ from dfindexeddb import errors, utils
26
25
  from dfindexeddb.indexeddb import types
27
26
  from dfindexeddb.indexeddb.safari import definitions
28
27
 
@@ -37,6 +36,7 @@ class ArrayBufferView:
37
36
  offset: the offset of the view.
38
37
  length: the length of the view.
39
38
  """
39
+
40
40
  array_buffer_view_subtag: definitions.ArrayBufferViewSubtag
41
41
  buffer: bytes
42
42
  offset: int
@@ -51,6 +51,7 @@ class ResizableArrayBuffer:
51
51
  buffer: the buffer.
52
52
  max_length: the maximum length of the buffer (for resizing).
53
53
  """
54
+
54
55
  buffer: bytes
55
56
  max_length: int
56
57
 
@@ -66,6 +67,7 @@ class FileData:
66
67
  name: the file name.
67
68
  last_modified: the last modified timestamp.
68
69
  """
70
+
69
71
  path: str
70
72
  url: str
71
73
  type: str
@@ -80,6 +82,7 @@ class FileList:
80
82
  Attributes:
81
83
  files: the list of files.
82
84
  """
85
+
83
86
  files: List[FileData]
84
87
 
85
88
 
@@ -92,15 +95,14 @@ class IDBKeyData(utils.FromDecoderMixin):
92
95
  key_type: the IDB Key Type.
93
96
  data: the key data.
94
97
  """
98
+
95
99
  offset: int
96
100
  key_type: definitions.SIDBKeyType
97
- data: Union[float, datetime, str, bytes, list]
101
+ data: Union[float, datetime, str, bytes, list[Any], None]
98
102
 
99
103
  @classmethod
100
104
  def FromDecoder(
101
- cls,
102
- decoder: utils.StreamDecoder,
103
- base_offset: int = 0
105
+ cls, decoder: utils.StreamDecoder, base_offset: int = 0
104
106
  ) -> IDBKeyData:
105
107
  """Decodes an IDBKeyData from the current position of decoder.
106
108
 
@@ -116,18 +118,22 @@ class IDBKeyData(utils.FromDecoderMixin):
116
118
  ParserError: when the key version is not found or an unknown key type is
117
119
  encountered or an old-style PropertyList key type is found.
118
120
  """
119
- def _DecodeKeyBuffer(key_type):
121
+
122
+ def _DecodeKeyBuffer(
123
+ key_type: definitions.SIDBKeyType,
124
+ ) -> Union[float, datetime, str, bytes, list[Any], None]:
125
+ data: Union[float, datetime, str, bytes, list[Any], None] = None
120
126
  if key_type == definitions.SIDBKeyType.MIN:
121
127
  data = None
122
128
  if key_type == definitions.SIDBKeyType.NUMBER:
123
129
  _, data = decoder.DecodeDouble()
124
130
  elif key_type == definitions.SIDBKeyType.DATE:
125
131
  _, timestamp = decoder.DecodeDouble()
126
- data = datetime.utcfromtimestamp(timestamp/1000)
132
+ data = datetime.utcfromtimestamp(timestamp / 1000)
127
133
  elif key_type == definitions.SIDBKeyType.STRING:
128
134
  _, length = decoder.DecodeUint32()
129
- _, raw_data = decoder.ReadBytes(length*2)
130
- data = raw_data.decode('utf-16-le')
135
+ _, raw_data = decoder.ReadBytes(length * 2)
136
+ data = raw_data.decode("utf-16-le")
131
137
  elif key_type == definitions.SIDBKeyType.BINARY:
132
138
  _, length = decoder.DecodeUint32()
133
139
  _, data = decoder.ReadBytes(length)
@@ -135,33 +141,30 @@ class IDBKeyData(utils.FromDecoderMixin):
135
141
  _, length = decoder.DecodeUint64()
136
142
  data = []
137
143
  for _ in range(length):
138
- _, key_type = decoder.DecodeUint8()
139
- element = _DecodeKeyBuffer(key_type)
144
+ _, next_key_type = decoder.DecodeUint8()
145
+ element = _DecodeKeyBuffer(definitions.SIDBKeyType(next_key_type))
140
146
  data.append(element)
141
147
  else:
142
- raise errors.ParserError('Unknown definitions.SIDBKeyType found.')
148
+ raise errors.ParserError("Unknown definitions.SIDBKeyType found.")
143
149
  return data
144
150
 
145
151
  offset, version_header = decoder.DecodeUint8()
146
152
  if version_header != definitions.SIDB_KEY_VERSION:
147
- raise errors.ParserError('SIDBKeyVersion not found.')
153
+ raise errors.ParserError("SIDBKeyVersion not found.")
148
154
 
149
155
  _, raw_key_type = decoder.DecodeUint8()
150
- key_type = definitions.SIDBKeyType(raw_key_type)
151
156
 
152
157
  # "Old-style key is characterized by this magic character that
153
158
  # begins serialized PropertyLists
154
- if key_type == b'b':
155
- raise errors.ParserError('Old-style PropertyList key type found.')
159
+ if raw_key_type == ord(b"b"):
160
+ raise errors.ParserError("Old-style PropertyList key type found.")
161
+ key_type = definitions.SIDBKeyType(raw_key_type)
156
162
  data = _DecodeKeyBuffer(key_type)
157
163
 
158
- return cls(
159
- offset=offset+base_offset,
160
- key_type=key_type,
161
- data=data)
164
+ return cls(offset=offset + base_offset, key_type=key_type, data=data)
162
165
 
163
166
 
164
- class SerializedScriptValueDecoder():
167
+ class SerializedScriptValueDecoder:
165
168
  """Decodes a Serialized Script Value from a stream of bytes.
166
169
 
167
170
  Attributes:
@@ -170,16 +173,17 @@ class SerializedScriptValueDecoder():
170
173
  constant_pool: the constant pool.
171
174
  object_pool: the object pool.
172
175
  """
176
+
173
177
  def __init__(self, stream: io.BytesIO):
174
178
  self.decoder = utils.StreamDecoder(stream)
175
- self.version = None
176
- self.constant_pool = []
177
- self.object_pool = []
179
+ self.version: int = 0
180
+ self.constant_pool: list[str] = []
181
+ self.object_pool: list[Any] = []
178
182
 
179
183
  def PeekTag(self) -> int:
180
184
  """Peeks a tag from the current position."""
181
185
  _, peeked_bytes = self.decoder.PeekBytes(4)
182
- return int.from_bytes(peeked_bytes, byteorder='little')
186
+ return int.from_bytes(peeked_bytes, byteorder="little")
183
187
 
184
188
  def PeekSerializationTag(self) -> definitions.SerializationTag:
185
189
  """Peeks a SerializationTag from the current position.
@@ -192,7 +196,7 @@ class SerializedScriptValueDecoder():
192
196
  return definitions.SerializationTag(terminal_byte[0])
193
197
  except ValueError as error:
194
198
  raise errors.ParserError(
195
- f'Invalid SerializationTag {terminal_byte} at offset {offset}'
199
+ f"Invalid SerializationTag {terminal_byte!r} at offset {offset}"
196
200
  ) from error
197
201
 
198
202
  def DecodeSerializationTag(self) -> Tuple[int, definitions.SerializationTag]:
@@ -209,7 +213,8 @@ class SerializedScriptValueDecoder():
209
213
  return offset, definitions.SerializationTag(terminal_byte)
210
214
  except ValueError as error:
211
215
  raise errors.ParserError(
212
- f'Invalid terminal {terminal_byte} at offset {offset}') from error
216
+ f"Invalid terminal {terminal_byte} at offset {offset}"
217
+ ) from error
213
218
 
214
219
  def DecodeArray(self) -> types.JSArray:
215
220
  """Decodes an Array value.
@@ -230,7 +235,7 @@ class SerializedScriptValueDecoder():
230
235
 
231
236
  offset, terminator_tag = self.decoder.DecodeUint32()
232
237
  if terminator_tag != definitions.TERMINATOR_TAG:
233
- raise errors.ParserError(f'Terminator tag not found at offset {offset}.')
238
+ raise errors.ParserError(f"Terminator tag not found at offset {offset}.")
234
239
 
235
240
  offset, tag = self.decoder.DecodeUint32()
236
241
  if tag == definitions.NON_INDEX_PROPERTIES_TAG:
@@ -240,13 +245,13 @@ class SerializedScriptValueDecoder():
240
245
  _, tag = self.decoder.DecodeUint32()
241
246
  array.properties[name] = value
242
247
  elif tag != definitions.TERMINATOR_TAG:
243
- raise errors.ParserError(f'Terminator tag not found at offset {offset}.')
248
+ raise errors.ParserError(f"Terminator tag not found at offset {offset}.")
244
249
  return array
245
250
 
246
251
  def DecodeObject(self) -> Dict[str, Any]:
247
252
  """Decodes an Object value."""
248
253
  tag = self.PeekTag()
249
- js_object = {}
254
+ js_object: dict[str, Any] = {}
250
255
  self.object_pool.append(js_object)
251
256
  while tag != definitions.TERMINATOR_TAG:
252
257
  name = self.DecodeStringData()
@@ -271,37 +276,37 @@ class SerializedScriptValueDecoder():
271
276
  """
272
277
  peeked_tag = self.PeekTag()
273
278
  if peeked_tag == definitions.TERMINATOR_TAG:
274
- raise errors.ParserError('Unexpected TerminatorTag found')
279
+ raise errors.ParserError("Unexpected TerminatorTag found")
275
280
 
276
281
  if peeked_tag == definitions.STRING_POOL_TAG:
277
282
  _ = self.decoder.DecodeUint32()
278
- if len(self.constant_pool) <= 0xff:
283
+ if len(self.constant_pool) <= 0xFF:
279
284
  _, cp_index = self.decoder.DecodeUint8()
280
- elif len(self.constant_pool) <= 0xffff:
285
+ elif len(self.constant_pool) <= 0xFFFF:
281
286
  _, cp_index = self.decoder.DecodeUint16()
282
- elif len(self.constant_pool) <= 0xffffffff:
287
+ elif len(self.constant_pool) <= 0xFFFFFFFF:
283
288
  _, cp_index = self.decoder.DecodeUint32()
284
289
  else:
285
- raise errors.ParserError('Unexpected constant pool size value.')
290
+ raise errors.ParserError("Unexpected constant pool size value.")
286
291
  return self.constant_pool[cp_index]
287
292
 
288
293
  _, length_with_8bit_flag = self.decoder.DecodeUint32()
289
294
  if length_with_8bit_flag == definitions.TERMINATOR_TAG:
290
- raise errors.ParserError('Disallowed string length found.')
295
+ raise errors.ParserError("Disallowed string length found.")
291
296
 
292
297
  length = length_with_8bit_flag & 0x7FFFFFFF
293
298
  is_8bit = length_with_8bit_flag & definitions.STRING_DATA_IS_8BIT_FLAG
294
299
 
295
300
  if is_8bit:
296
301
  _, characters = self.decoder.ReadBytes(length)
297
- value = characters.decode('latin-1')
302
+ value = characters.decode("latin-1")
298
303
  else:
299
- _, characters = self.decoder.ReadBytes(2*length)
304
+ _, characters = self.decoder.ReadBytes(2 * length)
300
305
  try:
301
- value = characters.decode('utf-16-le')
306
+ value = characters.decode("utf-16-le")
302
307
  except UnicodeDecodeError as exc:
303
308
  raise errors.ParserError(
304
- f'Unable to decode {len(characters)} characters as utf-16-le'
309
+ f"Unable to decode {len(characters)} characters as utf-16-le"
305
310
  ) from exc
306
311
  self.constant_pool.append(value)
307
312
  return value
@@ -309,7 +314,7 @@ class SerializedScriptValueDecoder():
309
314
  def DecodeDate(self) -> datetime:
310
315
  """Decodes a Date value."""
311
316
  _, timestamp = self.decoder.DecodeDouble()
312
- value = datetime.utcfromtimestamp(timestamp/1000)
317
+ value = datetime.utcfromtimestamp(timestamp / 1000)
313
318
  return value
314
319
 
315
320
  def DecodeFileData(self) -> FileData:
@@ -325,7 +330,8 @@ class SerializedScriptValueDecoder():
325
330
  url=url,
326
331
  type=file_type,
327
332
  name=name,
328
- last_modified=last_modified)
333
+ last_modified=last_modified,
334
+ )
329
335
 
330
336
  def DecodeFileList(self) -> FileList:
331
337
  """Decodes a FileList value."""
@@ -349,11 +355,11 @@ class SerializedScriptValueDecoder():
349
355
 
350
356
  # TODO: make this a dataclass?
351
357
  return {
352
- 'width': width,
353
- 'height': height,
354
- 'length': length,
355
- 'data': data,
356
- 'color_space': color_space
358
+ "width": width,
359
+ "height": height,
360
+ "length": length,
361
+ "data": data,
362
+ "color_space": color_space,
357
363
  }
358
364
 
359
365
  def DecodeBlob(self) -> Dict[str, Any]:
@@ -368,10 +374,10 @@ class SerializedScriptValueDecoder():
368
374
 
369
375
  # TODO: make this a dataclass?
370
376
  return {
371
- 'url': url,
372
- 'blob_type': blob_type,
373
- 'size': size,
374
- 'memory_cost': memory_cost
377
+ "url": url,
378
+ "blob_type": blob_type,
379
+ "size": size,
380
+ "memory_cost": memory_cost,
375
381
  }
376
382
 
377
383
  def DecodeRegExp(self) -> types.RegExp:
@@ -380,10 +386,12 @@ class SerializedScriptValueDecoder():
380
386
  flags = self.DecodeStringData()
381
387
  return types.RegExp(pattern=pattern, flags=flags)
382
388
 
383
- def DecodeMapData(self) -> dict:
389
+ def DecodeMapData(self) -> dict[str, Any]:
384
390
  """Decodes a Map value."""
385
391
  tag = self.PeekSerializationTag()
386
- js_map = {} # TODO: make this into a JSMap (like JSArray/JSSet)
392
+ js_map: dict[str, Any] = (
393
+ {}
394
+ ) # TODO: make this into a JSMap (like JSArray/JSSet)
387
395
  self.object_pool.append(js_map)
388
396
 
389
397
  while tag != definitions.SerializationTag.NON_MAP_PROPERTIES:
@@ -402,7 +410,7 @@ class SerializedScriptValueDecoder():
402
410
  js_map[name] = value
403
411
  pool_tag = self.PeekTag()
404
412
 
405
- _, tag = self.decoder.DecodeUint32()
413
+ _, _ = self.decoder.DecodeUint32()
406
414
  return js_map
407
415
 
408
416
  def DecodeSetData(self) -> types.JSSet:
@@ -424,13 +432,13 @@ class SerializedScriptValueDecoder():
424
432
  name = self.DecodeStringData()
425
433
  value = self.DecodeValue()
426
434
  js_set.properties[name] = value
427
- pool_tag = self.decoder.PeekBytes(4)
435
+ pool_tag = self.PeekTag()
428
436
 
429
437
  # consume the TerminatorTag
430
- _, tag = self.decoder.DecodeUint32()
438
+ _, _ = self.decoder.DecodeUint32()
431
439
  return js_set
432
440
 
433
- def DecodeCryptoKey(self) -> bytes:
441
+ def DecodeCryptoKey(self) -> Any:
434
442
  """Decodes a CryptoKey value."""
435
443
  _, wrapped_key_length = self.decoder.DecodeUint32()
436
444
  _, wrapped_key = self.decoder.ReadBytes(wrapped_key_length)
@@ -441,11 +449,11 @@ class SerializedScriptValueDecoder():
441
449
  """Decodes a BigIntData value."""
442
450
  _, sign = self.decoder.DecodeUint8()
443
451
  _, number_of_elements = self.decoder.DecodeUint32()
444
- contents = []
452
+ contents = bytearray()
445
453
  for _ in range(number_of_elements):
446
454
  _, element = self.decoder.ReadBytes(8)
447
455
  contents.extend(element)
448
- value = int.from_bytes(contents, byteorder='little', signed=bool(sign))
456
+ value = int.from_bytes(contents, byteorder="little", signed=bool(sign))
449
457
  return value
450
458
 
451
459
  def DecodeArrayBuffer(self) -> bytes:
@@ -494,24 +502,28 @@ class SerializedScriptValueDecoder():
494
502
  """
495
503
  _, array_buffer_view_subtag = self.decoder.DecodeUint8()
496
504
  array_buffer_view_subtag = definitions.ArrayBufferViewSubtag(
497
- array_buffer_view_subtag)
505
+ array_buffer_view_subtag
506
+ )
498
507
  _, byte_offset = self.decoder.DecodeUint64()
499
508
  _, byte_length = self.decoder.DecodeUint64()
500
509
  _, next_serialization_tag = self.DecodeSerializationTag()
501
510
 
502
511
  if next_serialization_tag == definitions.SerializationTag.ARRAY_BUFFER:
503
512
  value = self.DecodeArrayBuffer()
504
- elif (next_serialization_tag ==
505
- definitions.SerializationTag.OBJECT_REFERENCE):
513
+ elif (
514
+ next_serialization_tag == definitions.SerializationTag.OBJECT_REFERENCE
515
+ ):
506
516
  value = self.DecodeObjectReference()
507
517
  else:
508
518
  raise errors.ParserError(
509
- f'Unexpected serialization tag {next_serialization_tag}.')
519
+ f"Unexpected serialization tag {next_serialization_tag}."
520
+ )
510
521
  return ArrayBufferView(
511
522
  array_buffer_view_subtag=array_buffer_view_subtag,
512
523
  buffer=value,
513
524
  offset=byte_offset,
514
- length=byte_length)
525
+ length=byte_length,
526
+ )
515
527
 
516
528
  def DecodeSerializedValue(self) -> Any:
517
529
  """Decodes a serialized value.
@@ -525,7 +537,8 @@ class SerializedScriptValueDecoder():
525
537
  _, current_version = self.decoder.DecodeUint32()
526
538
  if current_version != definitions.CURRENT_VERSION:
527
539
  raise errors.ParserError(
528
- f'{current_version} is not the expected CurrentVersion')
540
+ f"{current_version} is not the expected CurrentVersion"
541
+ )
529
542
  _, value = self.DecodeValue()
530
543
  return value
531
544
 
@@ -538,6 +551,7 @@ class SerializedScriptValueDecoder():
538
551
  Raises:
539
552
  ParserError when an unhandled SerializationTag is found.
540
553
  """
554
+ value: Any = None
541
555
  offset, tag = self.DecodeSerializationTag()
542
556
  if tag == definitions.SerializationTag.ARRAY:
543
557
  value = self.DecodeArray()
@@ -572,7 +586,7 @@ class SerializedScriptValueDecoder():
572
586
  elif tag == definitions.SerializationTag.STRING:
573
587
  value = self.DecodeStringData()
574
588
  elif tag == definitions.SerializationTag.EMPTY_STRING:
575
- value = ''
589
+ value = ""
576
590
  elif tag == definitions.SerializationTag.REG_EXP:
577
591
  value = self.DecodeRegExp()
578
592
  elif tag == definitions.SerializationTag.OBJECT_REFERENCE:
@@ -594,7 +608,7 @@ class SerializedScriptValueDecoder():
594
608
  value = self.DecodeStringData()
595
609
  self.object_pool.append(value)
596
610
  elif tag == definitions.SerializationTag.EMPTY_STRING_OBJECT:
597
- value = ''
611
+ value = ""
598
612
  self.object_pool.append(value)
599
613
  elif tag == definitions.SerializationTag.NUMBER_OBJECT:
600
614
  _, value = self.decoder.DecodeDouble()
@@ -613,7 +627,7 @@ class SerializedScriptValueDecoder():
613
627
  value = self.DecodeBigIntData()
614
628
  self.object_pool.append(value)
615
629
  else:
616
- raise errors.ParserError(f'Unhandled Serialization Tag {tag.name} found.')
630
+ raise errors.ParserError(f"Unhandled Serialization Tag {tag.name} found.")
617
631
  return offset, value
618
632
 
619
633
  @classmethod