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.
- dfindexeddb/indexeddb/chromium/blink.py +116 -74
- dfindexeddb/indexeddb/chromium/definitions.py +152 -124
- dfindexeddb/indexeddb/chromium/record.py +536 -348
- dfindexeddb/indexeddb/chromium/v8.py +112 -141
- dfindexeddb/indexeddb/cli.py +125 -114
- dfindexeddb/indexeddb/firefox/definitions.py +7 -4
- dfindexeddb/indexeddb/firefox/gecko.py +103 -79
- dfindexeddb/indexeddb/firefox/record.py +66 -24
- dfindexeddb/indexeddb/safari/definitions.py +12 -10
- dfindexeddb/indexeddb/safari/record.py +68 -51
- dfindexeddb/indexeddb/safari/webkit.py +112 -189
- dfindexeddb/indexeddb/types.py +5 -2
- dfindexeddb/leveldb/cli.py +146 -131
- dfindexeddb/leveldb/definitions.py +6 -2
- dfindexeddb/leveldb/descriptor.py +75 -45
- dfindexeddb/leveldb/ldb.py +39 -30
- dfindexeddb/leveldb/log.py +44 -27
- dfindexeddb/leveldb/plugins/chrome_notifications.py +30 -18
- dfindexeddb/leveldb/plugins/interface.py +5 -6
- dfindexeddb/leveldb/plugins/manager.py +11 -10
- dfindexeddb/leveldb/record.py +71 -62
- dfindexeddb/leveldb/utils.py +21 -13
- dfindexeddb/utils.py +35 -30
- dfindexeddb/version.py +2 -2
- dfindexeddb-20251109.dist-info/METADATA +222 -0
- dfindexeddb-20251109.dist-info/RECORD +40 -0
- {dfindexeddb-20241031.dist-info → dfindexeddb-20251109.dist-info}/WHEEL +1 -1
- dfindexeddb-20241031.dist-info/AUTHORS +0 -12
- dfindexeddb-20241031.dist-info/METADATA +0 -424
- dfindexeddb-20241031.dist-info/RECORD +0 -41
- {dfindexeddb-20241031.dist-info → dfindexeddb-20251109.dist-info}/entry_points.txt +0 -0
- {dfindexeddb-20241031.dist-info → dfindexeddb-20251109.dist-info/licenses}/LICENSE +0 -0
- {dfindexeddb-20241031.dist-info → dfindexeddb-20251109.dist-info}/top_level.txt +0 -0
|
@@ -15,20 +15,33 @@
|
|
|
15
15
|
"""Parsers for v8 javascript serialized objects."""
|
|
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 os
|
|
22
|
-
from
|
|
23
|
-
|
|
24
|
-
from
|
|
25
|
-
|
|
20
|
+
from dataclasses import dataclass
|
|
21
|
+
from datetime import datetime
|
|
22
|
+
from typing import (
|
|
23
|
+
TYPE_CHECKING,
|
|
24
|
+
Any,
|
|
25
|
+
BinaryIO,
|
|
26
|
+
Dict,
|
|
27
|
+
Optional,
|
|
28
|
+
Set,
|
|
29
|
+
Tuple,
|
|
30
|
+
Union,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
from dfindexeddb import errors, utils
|
|
34
|
+
from dfindexeddb.indexeddb import types
|
|
26
35
|
from dfindexeddb.indexeddb.chromium import definitions
|
|
27
36
|
|
|
37
|
+
if TYPE_CHECKING:
|
|
38
|
+
from dfindexeddb.indexeddb.chromium import blink
|
|
39
|
+
|
|
28
40
|
|
|
29
41
|
@dataclass
|
|
30
42
|
class ArrayBufferView:
|
|
31
43
|
"""A parsed Javascript ArrayBufferView."""
|
|
44
|
+
|
|
32
45
|
buffer: bytes
|
|
33
46
|
tag: definitions.V8ArrayBufferViewTag
|
|
34
47
|
offset: int
|
|
@@ -36,61 +49,6 @@ class ArrayBufferView:
|
|
|
36
49
|
flags: int
|
|
37
50
|
|
|
38
51
|
|
|
39
|
-
@dataclass
|
|
40
|
-
class JSArray:
|
|
41
|
-
"""A parsed Javascript array.
|
|
42
|
-
|
|
43
|
-
A Javascript array behaves like a Python list but allows assigning arbitrary
|
|
44
|
-
properties. The array is stored in the attribute __array__.
|
|
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)
|
|
52
|
-
|
|
53
|
-
def __repr__(self):
|
|
54
|
-
array_entries = ", ".join(
|
|
55
|
-
[str(entry) for entry in list(self.__array__)])
|
|
56
|
-
properties = ", ".join(
|
|
57
|
-
f'{key}: {value}' for key, value in self.properties.items())
|
|
58
|
-
return f'[{array_entries}, {properties}]'
|
|
59
|
-
|
|
60
|
-
@property
|
|
61
|
-
def properties(self) -> Dict[str, Any]:
|
|
62
|
-
"""Returns the object properties."""
|
|
63
|
-
return self.__dict__
|
|
64
|
-
|
|
65
|
-
def __eq__(self, other: JSArray):
|
|
66
|
-
return (
|
|
67
|
-
self.__array__ == other.__array__
|
|
68
|
-
and self.properties == other.properties)
|
|
69
|
-
|
|
70
|
-
def __contains__(self, item):
|
|
71
|
-
return item in self.__dict__
|
|
72
|
-
|
|
73
|
-
def __getitem__(self, name):
|
|
74
|
-
return self.__dict__[name]
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@dataclass
|
|
78
|
-
class Null:
|
|
79
|
-
"""A parsed Javascript Null."""
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
@dataclass
|
|
83
|
-
class RegExp:
|
|
84
|
-
"""A parsed Javascript RegExp."""
|
|
85
|
-
pattern: str
|
|
86
|
-
flags: int
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
@dataclass(frozen=True)
|
|
90
|
-
class Undefined:
|
|
91
|
-
"""A parsed Javascript undef."""
|
|
92
|
-
|
|
93
|
-
|
|
94
52
|
class ValueDeserializer:
|
|
95
53
|
"""A class to deserialize v8 Javascript values/objects.
|
|
96
54
|
|
|
@@ -106,7 +64,7 @@ class ValueDeserializer:
|
|
|
106
64
|
|
|
107
65
|
LATEST_VERSION = 15
|
|
108
66
|
|
|
109
|
-
def __init__(self, stream: BinaryIO, delegate):
|
|
67
|
+
def __init__(self, stream: BinaryIO, delegate: blink.V8ScriptValueDecoder):
|
|
110
68
|
"""Initializes a ValueDeserializer.
|
|
111
69
|
|
|
112
70
|
Args:
|
|
@@ -117,8 +75,8 @@ class ValueDeserializer:
|
|
|
117
75
|
self.decoder = utils.StreamDecoder(stream)
|
|
118
76
|
self.delegate = delegate
|
|
119
77
|
self.next_id = 0
|
|
120
|
-
self.objects = {}
|
|
121
|
-
self.version =
|
|
78
|
+
self.objects: dict[int, Any] = {}
|
|
79
|
+
self.version = 0
|
|
122
80
|
|
|
123
81
|
def GetWireFormatVersion(self) -> int:
|
|
124
82
|
"""Returns the underlying wire format version.
|
|
@@ -136,22 +94,23 @@ class ValueDeserializer:
|
|
|
136
94
|
return False
|
|
137
95
|
return True
|
|
138
96
|
|
|
139
|
-
def ReadObjectWrapper(self):
|
|
97
|
+
def ReadObjectWrapper(self) -> Any:
|
|
140
98
|
"""Deserializes a V8 object from the current decoder position."""
|
|
141
99
|
original_position = self.decoder.stream.tell()
|
|
142
100
|
result = self._ReadObject()
|
|
143
101
|
if result is None and self.version == 13:
|
|
144
102
|
self.decoder.stream.seek(original_position, os.SEEK_SET)
|
|
145
103
|
result = self._ReadObject()
|
|
146
|
-
raise NotImplementedError(
|
|
104
|
+
raise NotImplementedError("ValueDeserializer.ReadObjectWrapper v13")
|
|
147
105
|
return result
|
|
148
106
|
|
|
149
|
-
def ReadObjectUsingEntireBufferForLegacyFormat(self):
|
|
107
|
+
def ReadObjectUsingEntireBufferForLegacyFormat(self) -> Any:
|
|
150
108
|
"""Reads an object, consuming the entire buffer."""
|
|
151
109
|
raise NotImplementedError(
|
|
152
|
-
|
|
110
|
+
"ValueDeserializer.ReadObjectUsingEntireBufferForLegacyFormat"
|
|
111
|
+
)
|
|
153
112
|
|
|
154
|
-
def ReadValue(self):
|
|
113
|
+
def ReadValue(self) -> Any:
|
|
155
114
|
"""Reads the Javascript value."""
|
|
156
115
|
if self.GetWireFormatVersion() > 0:
|
|
157
116
|
return self.ReadObjectWrapper()
|
|
@@ -171,8 +130,9 @@ class ValueDeserializer:
|
|
|
171
130
|
return definitions.V8SerializationTag(tag_value[0])
|
|
172
131
|
except ValueError as error:
|
|
173
132
|
raise errors.ParserError(
|
|
174
|
-
f
|
|
175
|
-
f
|
|
133
|
+
f"Invalid v8 tag value {tag_value!r} at offset"
|
|
134
|
+
f" {self.decoder.stream.tell()}"
|
|
135
|
+
) from error
|
|
176
136
|
|
|
177
137
|
def _ReadTag(self) -> definitions.V8SerializationTag:
|
|
178
138
|
"""Returns the next non-padding serialization tag.
|
|
@@ -185,11 +145,13 @@ class ValueDeserializer:
|
|
|
185
145
|
try:
|
|
186
146
|
tag = definitions.V8SerializationTag(tag_value[0])
|
|
187
147
|
except ValueError as error:
|
|
188
|
-
raise errors.ParserError(
|
|
148
|
+
raise errors.ParserError(
|
|
149
|
+
f"Invalid v8 tag value {tag_value!r}"
|
|
150
|
+
) from error
|
|
189
151
|
if tag != definitions.V8SerializationTag.PADDING:
|
|
190
152
|
return tag
|
|
191
153
|
|
|
192
|
-
def _ConsumeTag(self, peeked_tag: definitions.V8SerializationTag):
|
|
154
|
+
def _ConsumeTag(self, peeked_tag: definitions.V8SerializationTag) -> None:
|
|
193
155
|
"""Consumes the next serialization tag.
|
|
194
156
|
|
|
195
157
|
Args:
|
|
@@ -200,9 +162,9 @@ class ValueDeserializer:
|
|
|
200
162
|
"""
|
|
201
163
|
tag = self._ReadTag()
|
|
202
164
|
if tag != peeked_tag:
|
|
203
|
-
raise errors.ParserError(f
|
|
165
|
+
raise errors.ParserError(f"Unexpected tag {tag} found.")
|
|
204
166
|
|
|
205
|
-
def _ReadObject(self):
|
|
167
|
+
def _ReadObject(self) -> Any:
|
|
206
168
|
"""Reads a Javascript object from the current position."""
|
|
207
169
|
_, result = self._ReadObjectInternal()
|
|
208
170
|
tag = self._PeekTag()
|
|
@@ -219,13 +181,15 @@ class ValueDeserializer:
|
|
|
219
181
|
a tuple of the serialization tag and the parsed object.
|
|
220
182
|
"""
|
|
221
183
|
tag = self._ReadTag()
|
|
184
|
+
parsed_object: Any = None
|
|
185
|
+
|
|
222
186
|
if tag == definitions.V8SerializationTag.VERIFY_OBJECT_COUNT:
|
|
223
187
|
_ = self.decoder.DecodeUint32Varint()
|
|
224
188
|
parsed_object = self._ReadObject()
|
|
225
189
|
elif tag == definitions.V8SerializationTag.UNDEFINED:
|
|
226
|
-
parsed_object = Undefined()
|
|
190
|
+
parsed_object = types.Undefined()
|
|
227
191
|
elif tag == definitions.V8SerializationTag.NULL:
|
|
228
|
-
parsed_object = Null()
|
|
192
|
+
parsed_object = types.Null()
|
|
229
193
|
elif tag == definitions.V8SerializationTag.TRUE:
|
|
230
194
|
parsed_object = True
|
|
231
195
|
elif tag == definitions.V8SerializationTag.FALSE:
|
|
@@ -260,7 +224,8 @@ class ValueDeserializer:
|
|
|
260
224
|
definitions.V8SerializationTag.FALSE_OBJECT,
|
|
261
225
|
definitions.V8SerializationTag.NUMBER_OBJECT,
|
|
262
226
|
definitions.V8SerializationTag.BIGINT_OBJECT,
|
|
263
|
-
definitions.V8SerializationTag.STRING_OBJECT
|
|
227
|
+
definitions.V8SerializationTag.STRING_OBJECT,
|
|
228
|
+
):
|
|
264
229
|
parsed_object = self._ReadJSPrimitiveWrapper(tag)
|
|
265
230
|
elif tag == definitions.V8SerializationTag.REGEXP:
|
|
266
231
|
parsed_object = self._ReadJSRegExp()
|
|
@@ -270,25 +235,29 @@ class ValueDeserializer:
|
|
|
270
235
|
parsed_object = self._ReadJSSet()
|
|
271
236
|
elif tag == definitions.V8SerializationTag.ARRAY_BUFFER:
|
|
272
237
|
parsed_object = self._ReadJSArrayBuffer(
|
|
273
|
-
is_shared=False, is_resizable=False
|
|
238
|
+
is_shared=False, is_resizable=False
|
|
239
|
+
)
|
|
274
240
|
elif tag == definitions.V8SerializationTag.RESIZABLE_ARRAY_BUFFER:
|
|
275
241
|
parsed_object = self._ReadJSArrayBuffer(
|
|
276
|
-
is_shared=False, is_resizable=True
|
|
242
|
+
is_shared=False, is_resizable=True
|
|
243
|
+
)
|
|
277
244
|
elif tag == definitions.V8SerializationTag.SHARED_ARRAY_BUFFER:
|
|
278
245
|
parsed_object = self._ReadJSArrayBuffer(
|
|
279
|
-
is_shared=True, is_resizable=False
|
|
246
|
+
is_shared=True, is_resizable=False
|
|
247
|
+
)
|
|
280
248
|
elif tag == definitions.V8SerializationTag.ERROR:
|
|
281
|
-
|
|
249
|
+
self._ReadJSError()
|
|
282
250
|
elif tag == definitions.V8SerializationTag.WASM_MODULE_TRANSFER:
|
|
283
|
-
|
|
251
|
+
self._ReadWasmModuleTransfer()
|
|
284
252
|
elif tag == definitions.V8SerializationTag.WASM_MEMORY_TRANSFER:
|
|
285
|
-
|
|
253
|
+
self._ReadWasmMemory()
|
|
286
254
|
elif tag == definitions.V8SerializationTag.HOST_OBJECT:
|
|
287
255
|
parsed_object = self.ReadHostObject()
|
|
288
256
|
elif (
|
|
289
|
-
tag == definitions.V8SerializationTag.SHARED_OBJECT
|
|
290
|
-
|
|
291
|
-
|
|
257
|
+
tag == definitions.V8SerializationTag.SHARED_OBJECT
|
|
258
|
+
and self.version >= 15
|
|
259
|
+
):
|
|
260
|
+
self.ReadSharedObject()
|
|
292
261
|
elif self.version < 13:
|
|
293
262
|
self.decoder.stream.seek(-1, os.SEEK_CUR)
|
|
294
263
|
parsed_object = self.ReadHostObject()
|
|
@@ -307,7 +276,7 @@ class ValueDeserializer:
|
|
|
307
276
|
|
|
308
277
|
str_obj = self._ReadObject()
|
|
309
278
|
if not isinstance(str_obj, str):
|
|
310
|
-
raise errors.ParserError(
|
|
279
|
+
raise errors.ParserError("Not a string")
|
|
311
280
|
return str_obj
|
|
312
281
|
|
|
313
282
|
def ReadBigInt(self) -> int:
|
|
@@ -322,7 +291,7 @@ class ValueDeserializer:
|
|
|
322
291
|
"""Reads a UTF-8 string from the current position."""
|
|
323
292
|
count = self.decoder.DecodeUint32Varint()[1]
|
|
324
293
|
buffer = self.decoder.ReadBytes(count=count)[1]
|
|
325
|
-
return buffer.decode(
|
|
294
|
+
return buffer.decode("utf-8")
|
|
326
295
|
|
|
327
296
|
def ReadOneByteString(self) -> str:
|
|
328
297
|
"""Reads a one-byte string from the current position.
|
|
@@ -331,13 +300,13 @@ class ValueDeserializer:
|
|
|
331
300
|
"""
|
|
332
301
|
length = self.decoder.DecodeUint32Varint()[1]
|
|
333
302
|
buffer = self.decoder.ReadBytes(count=length)[1]
|
|
334
|
-
return buffer.decode(
|
|
303
|
+
return buffer.decode("latin-1")
|
|
335
304
|
|
|
336
305
|
def ReadTwoByteString(self) -> str:
|
|
337
306
|
"""Reads a UTF-16-LE string from the current position."""
|
|
338
307
|
length = self.decoder.DecodeUint32Varint()[1]
|
|
339
308
|
buffer = self.decoder.ReadBytes(count=length)[1]
|
|
340
|
-
return buffer.decode(
|
|
309
|
+
return buffer.decode("utf-16-le")
|
|
341
310
|
|
|
342
311
|
def ReadExpectedString(self) -> Optional[str]:
|
|
343
312
|
"""Reads a string from the current position, None if there is no tag or
|
|
@@ -357,14 +326,14 @@ class ValueDeserializer:
|
|
|
357
326
|
_, raw_bytes = self.decoder.ReadBytes(count=byte_length)
|
|
358
327
|
|
|
359
328
|
if tag == definitions.V8SerializationTag.ONE_BYTE_STRING:
|
|
360
|
-
return raw_bytes.decode(
|
|
329
|
+
return raw_bytes.decode("latin-1")
|
|
361
330
|
if tag == definitions.V8SerializationTag.TWO_BYTE_STRING:
|
|
362
|
-
return raw_bytes.decode(
|
|
331
|
+
return raw_bytes.decode("utf-16-le")
|
|
363
332
|
if tag == definitions.V8SerializationTag.UTF8_STRING:
|
|
364
|
-
return raw_bytes.decode(
|
|
365
|
-
raise errors.ParserError(f
|
|
333
|
+
return raw_bytes.decode("utf-8")
|
|
334
|
+
raise errors.ParserError(f"Unexpected serialization tag {tag}.")
|
|
366
335
|
|
|
367
|
-
def _ReadJSObject(self) -> Dict:
|
|
336
|
+
def _ReadJSObject(self) -> Dict[int, Any]:
|
|
368
337
|
"""Reads a JSObject from the current position.
|
|
369
338
|
|
|
370
339
|
Raises:
|
|
@@ -372,21 +341,22 @@ class ValueDeserializer:
|
|
|
372
341
|
read.
|
|
373
342
|
"""
|
|
374
343
|
next_id = self._GetNextId()
|
|
375
|
-
js_object = {}
|
|
344
|
+
js_object: Dict[int, Any] = {}
|
|
376
345
|
|
|
377
346
|
num_properties = self._ReadJSObjectProperties(
|
|
378
|
-
js_object, definitions.V8SerializationTag.END_JS_OBJECT
|
|
347
|
+
js_object, definitions.V8SerializationTag.END_JS_OBJECT
|
|
348
|
+
)
|
|
379
349
|
_, expected_number_properties = self.decoder.DecodeUint32Varint()
|
|
380
350
|
if expected_number_properties != num_properties:
|
|
381
|
-
raise errors.ParserError(
|
|
351
|
+
raise errors.ParserError("Unexpected number of properties")
|
|
382
352
|
|
|
383
353
|
self.objects[next_id] = js_object
|
|
384
354
|
return js_object
|
|
385
355
|
|
|
386
356
|
def _ReadJSObjectProperties(
|
|
387
357
|
self,
|
|
388
|
-
js_object: Union[Dict, JSArray],
|
|
389
|
-
end_tag: definitions.V8SerializationTag
|
|
358
|
+
js_object: Union[Dict[int, Any], types.JSArray],
|
|
359
|
+
end_tag: definitions.V8SerializationTag,
|
|
390
360
|
) -> int:
|
|
391
361
|
"""Reads key-value properties and sets them to the given js_object.
|
|
392
362
|
|
|
@@ -415,7 +385,7 @@ class ValueDeserializer:
|
|
|
415
385
|
self.next_id += 1
|
|
416
386
|
return next_id
|
|
417
387
|
|
|
418
|
-
def ReadSparseJSArray(self) -> JSArray:
|
|
388
|
+
def ReadSparseJSArray(self) -> types.JSArray:
|
|
419
389
|
"""Reads a sparse encoded JSArray from the current position.
|
|
420
390
|
|
|
421
391
|
Raises:
|
|
@@ -423,24 +393,25 @@ class ValueDeserializer:
|
|
|
423
393
|
"""
|
|
424
394
|
next_id = self._GetNextId()
|
|
425
395
|
|
|
426
|
-
js_array = JSArray()
|
|
396
|
+
js_array = types.JSArray()
|
|
427
397
|
_, length = self.decoder.DecodeUint32Varint()
|
|
428
398
|
for _ in range(length):
|
|
429
|
-
js_array.
|
|
399
|
+
js_array.values.append(types.Undefined())
|
|
430
400
|
|
|
431
401
|
num_properties = self._ReadJSObjectProperties(
|
|
432
|
-
js_array.
|
|
402
|
+
js_array.properties, definitions.V8SerializationTag.END_SPARSE_JS_ARRAY
|
|
403
|
+
)
|
|
433
404
|
_, expected_num_properties = self.decoder.DecodeUint32Varint()
|
|
434
405
|
_, expected_length = self.decoder.DecodeUint32Varint()
|
|
435
406
|
|
|
436
407
|
if num_properties != expected_num_properties:
|
|
437
|
-
raise errors.ParserError(
|
|
408
|
+
raise errors.ParserError("Unexpected property length")
|
|
438
409
|
if length != expected_length:
|
|
439
|
-
raise errors.ParserError(
|
|
410
|
+
raise errors.ParserError("Unexpected array length")
|
|
440
411
|
self.objects[next_id] = js_array
|
|
441
412
|
return js_array
|
|
442
413
|
|
|
443
|
-
def ReadDenseJSArray(self) -> JSArray:
|
|
414
|
+
def ReadDenseJSArray(self) -> types.JSArray:
|
|
444
415
|
"""Reads a dense encoded JSArray from the current position.
|
|
445
416
|
|
|
446
417
|
Raises:
|
|
@@ -448,7 +419,7 @@ class ValueDeserializer:
|
|
|
448
419
|
"""
|
|
449
420
|
next_id = self._GetNextId()
|
|
450
421
|
|
|
451
|
-
js_array = JSArray()
|
|
422
|
+
js_array = types.JSArray()
|
|
452
423
|
_, length = self.decoder.DecodeUint32Varint()
|
|
453
424
|
for _ in range(length):
|
|
454
425
|
tag = self._PeekTag()
|
|
@@ -457,18 +428,19 @@ class ValueDeserializer:
|
|
|
457
428
|
continue
|
|
458
429
|
array_object = self._ReadObject()
|
|
459
430
|
|
|
460
|
-
if self.version < 11 and isinstance(array_object, Undefined):
|
|
431
|
+
if self.version < 11 and isinstance(array_object, types.Undefined):
|
|
461
432
|
continue
|
|
462
|
-
js_array.
|
|
433
|
+
js_array.values.append(array_object)
|
|
463
434
|
|
|
464
435
|
num_properties = self._ReadJSObjectProperties(
|
|
465
|
-
js_array.
|
|
436
|
+
js_array.properties, definitions.V8SerializationTag.END_DENSE_JS_ARRAY
|
|
437
|
+
)
|
|
466
438
|
_, expected_num_properties = self.decoder.DecodeUint32Varint()
|
|
467
439
|
_, expected_length = self.decoder.DecodeUint32Varint()
|
|
468
440
|
if num_properties != expected_num_properties:
|
|
469
|
-
raise errors.ParserError(
|
|
441
|
+
raise errors.ParserError("Unexpected property length")
|
|
470
442
|
if length != expected_length:
|
|
471
|
-
raise errors.ParserError(
|
|
443
|
+
raise errors.ParserError("Unexpected array length")
|
|
472
444
|
self.objects[next_id] = js_array
|
|
473
445
|
return js_array
|
|
474
446
|
|
|
@@ -477,13 +449,12 @@ class ValueDeserializer:
|
|
|
477
449
|
next_id = self._GetNextId()
|
|
478
450
|
|
|
479
451
|
_, value = self.decoder.DecodeDouble()
|
|
480
|
-
result = datetime.utcfromtimestamp(value/1000.0)
|
|
452
|
+
result = datetime.utcfromtimestamp(value / 1000.0)
|
|
481
453
|
self.objects[next_id] = result
|
|
482
454
|
return result
|
|
483
455
|
|
|
484
456
|
def _ReadJSPrimitiveWrapper(
|
|
485
|
-
self,
|
|
486
|
-
tag: definitions.V8SerializationTag
|
|
457
|
+
self, tag: definitions.V8SerializationTag
|
|
487
458
|
) -> Union[bool, float, int, str]:
|
|
488
459
|
"""Reads a Javascript wrapped primitive.
|
|
489
460
|
|
|
@@ -500,7 +471,7 @@ class ValueDeserializer:
|
|
|
500
471
|
next_id = self._GetNextId()
|
|
501
472
|
|
|
502
473
|
if tag == definitions.V8SerializationTag.TRUE_OBJECT:
|
|
503
|
-
value = True
|
|
474
|
+
value: Union[bool, float, int, str] = True
|
|
504
475
|
elif tag == definitions.V8SerializationTag.FALSE_OBJECT:
|
|
505
476
|
value = False
|
|
506
477
|
elif tag == definitions.V8SerializationTag.NUMBER_OBJECT:
|
|
@@ -510,17 +481,17 @@ class ValueDeserializer:
|
|
|
510
481
|
elif tag == definitions.V8SerializationTag.STRING_OBJECT:
|
|
511
482
|
value = self.ReadString()
|
|
512
483
|
else:
|
|
513
|
-
raise errors.ParserError(f
|
|
484
|
+
raise errors.ParserError(f"Invalid tag {tag}")
|
|
514
485
|
|
|
515
486
|
self.objects[next_id] = value
|
|
516
487
|
return value
|
|
517
488
|
|
|
518
|
-
def _ReadJSRegExp(self) -> RegExp:
|
|
489
|
+
def _ReadJSRegExp(self) -> types.RegExp:
|
|
519
490
|
"""Reads a Javascript regular expression from the current position."""
|
|
520
491
|
next_id = self._GetNextId()
|
|
521
492
|
pattern = self.ReadString()
|
|
522
493
|
_, flags = self.decoder.DecodeUint32Varint() # TODO: verify flags
|
|
523
|
-
regexp = RegExp(pattern=pattern, flags=flags)
|
|
494
|
+
regexp = types.RegExp(pattern=pattern, flags=str(flags))
|
|
524
495
|
self.objects[next_id] = regexp
|
|
525
496
|
return regexp
|
|
526
497
|
|
|
@@ -543,7 +514,7 @@ class ValueDeserializer:
|
|
|
543
514
|
|
|
544
515
|
_, expected_length = self.decoder.DecodeUint32Varint()
|
|
545
516
|
if len(js_map) * 2 != expected_length:
|
|
546
|
-
raise errors.ParserError(
|
|
517
|
+
raise errors.ParserError("unexpected length")
|
|
547
518
|
|
|
548
519
|
self.objects[next_id] = js_map
|
|
549
520
|
return js_map
|
|
@@ -566,13 +537,12 @@ class ValueDeserializer:
|
|
|
566
537
|
|
|
567
538
|
_, expected_length = self.decoder.DecodeUint32Varint()
|
|
568
539
|
if len(js_set) != expected_length:
|
|
569
|
-
raise ValueError(
|
|
540
|
+
raise ValueError("unexpected length")
|
|
570
541
|
|
|
571
542
|
self.objects[next_id] = js_set
|
|
572
543
|
return js_set
|
|
573
544
|
|
|
574
|
-
def _ReadJSArrayBuffer(
|
|
575
|
-
self, is_shared: bool, is_resizable: bool) -> bytes:
|
|
545
|
+
def _ReadJSArrayBuffer(self, is_shared: bool, is_resizable: bool) -> bytes:
|
|
576
546
|
"""Reads a Javascript ArrayBuffer from the current position.
|
|
577
547
|
|
|
578
548
|
Args:
|
|
@@ -580,10 +550,10 @@ class ValueDeserializer:
|
|
|
580
550
|
is_resizable: True if the buffer is resizable, False otherwise.
|
|
581
551
|
"""
|
|
582
552
|
next_id = self._GetNextId()
|
|
583
|
-
array_buffer = b
|
|
553
|
+
array_buffer = b""
|
|
584
554
|
|
|
585
555
|
if is_shared:
|
|
586
|
-
raise NotImplementedError(
|
|
556
|
+
raise NotImplementedError("Shared ArrayBuffer not supported yet")
|
|
587
557
|
|
|
588
558
|
_, byte_length = self.decoder.DecodeUint32Varint()
|
|
589
559
|
max_byte_length = byte_length
|
|
@@ -598,7 +568,7 @@ class ValueDeserializer:
|
|
|
598
568
|
self.objects[next_id] = array_buffer
|
|
599
569
|
return array_buffer
|
|
600
570
|
|
|
601
|
-
def _ReadJSArrayBufferView(self, buffer):
|
|
571
|
+
def _ReadJSArrayBufferView(self, buffer: bytes) -> ArrayBufferView:
|
|
602
572
|
"""Reads a JSArrayBufferView from the current position."""
|
|
603
573
|
_, tag = self.decoder.ReadBytes(1)
|
|
604
574
|
_, byte_offset = self.decoder.DecodeUint32Varint()
|
|
@@ -614,26 +584,27 @@ class ValueDeserializer:
|
|
|
614
584
|
tag=definitions.V8ArrayBufferViewTag(tag[0]),
|
|
615
585
|
offset=byte_offset,
|
|
616
586
|
length=byte_length,
|
|
617
|
-
flags=flags
|
|
587
|
+
flags=flags,
|
|
588
|
+
)
|
|
618
589
|
|
|
619
|
-
def _ReadJSError(self):
|
|
590
|
+
def _ReadJSError(self) -> None:
|
|
620
591
|
"""Reads a Javascript error from the current position."""
|
|
621
|
-
raise NotImplementedError(
|
|
592
|
+
raise NotImplementedError("ValueDeserializer.ReadJSError")
|
|
622
593
|
|
|
623
|
-
def _ReadWasmModuleTransfer(self):
|
|
594
|
+
def _ReadWasmModuleTransfer(self) -> None:
|
|
624
595
|
"""Reads a Wasm module transfer object from the current position."""
|
|
625
|
-
raise NotImplementedError(
|
|
596
|
+
raise NotImplementedError("ValueDeserializer.ReadWasmModuleTransfer")
|
|
626
597
|
|
|
627
|
-
def _ReadWasmMemory(self):
|
|
598
|
+
def _ReadWasmMemory(self) -> None:
|
|
628
599
|
"""Reads a Wasm memory object from the current position."""
|
|
629
|
-
raise NotImplementedError(
|
|
600
|
+
raise NotImplementedError("ValueDeserializer.ReadWasmMemory")
|
|
630
601
|
|
|
631
|
-
def ReadSharedObject(self) ->
|
|
602
|
+
def ReadSharedObject(self) -> None:
|
|
632
603
|
"""Reads a shared object from the current position."""
|
|
633
|
-
#_, shared_object_id = self.decoder.DecodeUint32Varint()
|
|
634
|
-
raise NotImplementedError(
|
|
604
|
+
# _, shared_object_id = self.decoder.DecodeUint32Varint()
|
|
605
|
+
raise NotImplementedError("ValueDeserializer.ReadSharedObject")
|
|
635
606
|
|
|
636
|
-
def ReadHostObject(self):
|
|
607
|
+
def ReadHostObject(self) -> Any:
|
|
637
608
|
"""Reads a Host object using the delegate object.
|
|
638
609
|
|
|
639
610
|
Raises:
|
|
@@ -641,7 +612,7 @@ class ValueDeserializer:
|
|
|
641
612
|
"""
|
|
642
613
|
next_id = self._GetNextId()
|
|
643
614
|
if not self.delegate:
|
|
644
|
-
raise errors.ParserError(
|
|
615
|
+
raise errors.ParserError("No delegate to read host object.")
|
|
645
616
|
host_object = self.delegate.ReadHostObject()
|
|
646
617
|
self.objects[next_id] = host_object
|
|
647
618
|
return host_object
|
|
@@ -663,5 +634,5 @@ class ValueDeserializer:
|
|
|
663
634
|
stream = io.BytesIO(data)
|
|
664
635
|
deserializer = cls(stream, delegate)
|
|
665
636
|
if not deserializer.ReadHeader():
|
|
666
|
-
raise errors.ParserError(
|
|
637
|
+
raise errors.ParserError("Invalid V8 header")
|
|
667
638
|
return deserializer.ReadObjectWrapper()
|