Skip to content

Commit 3fedb1b

Browse files
authored
Updates to support additional parsing of blink serialized objects (google#37)
* Initial commit * Pytype fix * Updates * Updates * Updates * Add more tests * pylint/pytype fixes * Add more tests * Update docstring * Updates * Updates * Updates * Reformat test file * Whitespace fix
1 parent 0f6a1b9 commit 3fedb1b

File tree

8 files changed

+1675
-32
lines changed

8 files changed

+1675
-32
lines changed

dfindexeddb/indexeddb/chromium/blink.py

Lines changed: 915 additions & 18 deletions
Large diffs are not rendered by default.

dfindexeddb/indexeddb/chromium/definitions.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,12 @@ class BlinkSerializationTag(IntEnum):
141141
ENCODED_AUDIO_CHUNK = ord('y')
142142
ENCODED_VIDEO_CHUNK = ord('z')
143143
CROP_TARGET = ord('c')
144+
RESTRICTION_TARGET = ord('D')
144145
MEDIA_SOURCE_HANDLE = ord('S')
145146
DEPRECATED_DETECTED_BARCODE = ord('B')
146147
DEPRECATED_DETECTED_FACE = ord('F')
147148
DEPRECATED_DETECTED_TEXT = ord('t')
149+
FENCED_FRAME_CONFIG = ord('C')
148150
DOM_EXCEPTION = ord('x')
149151
TRAILER_OFFSET = 0xFE
150152
VERSION = 0xFF
@@ -304,3 +306,67 @@ class V8ErrorTag(IntEnum):
304306
CAUSE = ord('c')
305307
STACK = ord('s')
306308
END = ord('.')
309+
310+
311+
class ImageSerializationTag(IntEnum):
312+
"""Image Serialization tags."""
313+
END = 0
314+
PREDEFINED_COLOR_SPACE = 1
315+
CANVAS_PIXEL_FORMAT = 2
316+
IMAGE_DATA_STORAGE_FORMAT = 3
317+
ORIGIN_CLEAN = 4
318+
IS_PREMULTIPLIED = 5
319+
CANVAS_OPACITY_MODE = 6
320+
PARAMETRIC_COLOR_SPACE = 7
321+
IMAGE_ORIENTATION = 8
322+
LAST = IMAGE_ORIENTATION
323+
324+
325+
class SerializedPredefinedColorSpace(IntEnum):
326+
"""Serialized Predefined Color Space enumeration."""
327+
LEGACY_OBSOLETE = 0
328+
SRGB = 1
329+
REC2020 = 2
330+
P3 = 3
331+
REC2100HLG = 4
332+
REC2100PQ = 5
333+
SRGB_LINEAR = 6
334+
LAST = SRGB_LINEAR
335+
336+
337+
class SerializedPixelFormat(IntEnum):
338+
"""Serialized Pixel Format enumeration."""
339+
NATIVE8_LEGACY_OBSOLETE = 0
340+
F16 = 1
341+
RGBA8 = 2
342+
BGRA8 = 3
343+
RGBX8 = 4
344+
LAST = RGBX8
345+
346+
347+
class SerializedImageDataStorageFormat(IntEnum):
348+
"""The Serialized Image Data Storage Format."""
349+
UINT8CLAMPED = 0
350+
UINT16 = 1
351+
FLOAT32 = 2
352+
LAST = FLOAT32
353+
354+
355+
class SerializedOpacityMode(IntEnum):
356+
"""The Serialized Opacity Mode."""
357+
KNONOPAQUE = 0
358+
KOPAQUE = 1
359+
KLAST = KOPAQUE
360+
361+
362+
class SerializedImageOrientation(IntEnum):
363+
"""The Serialized Image Orientation."""
364+
TOP_LEFT = 0
365+
TOP_RIGHT = 1
366+
BOTTOM_RIGHT = 2
367+
BOTTOM_LEFT = 3
368+
LEFT_TOP = 4
369+
RIGHT_TOP = 5
370+
RIGHT_BOTTOM = 6
371+
LEFT_BOTTOM = 7
372+
LAST = LEFT_BOTTOM

dfindexeddb/indexeddb/chromium/record.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ def FromDecoder(
546546

547547

548548
@dataclass
549-
class EarlistCompactionTimeKey(BaseIndexedDBKey):
549+
class EarliestCompactionTimeKey(BaseIndexedDBKey):
550550
"""An earliest compaction time IndexedDB key."""
551551

552552
def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
@@ -558,11 +558,11 @@ def DecodeValue(self, decoder: utils.LevelDBDecoder) -> int:
558558
def FromDecoder(
559559
cls, decoder: utils.LevelDBDecoder, key_prefix: KeyPrefix,
560560
base_offset: int = 0
561-
) -> EarlistCompactionTimeKey:
561+
) -> EarliestCompactionTimeKey:
562562
"""Decodes the earliest compaction time key."""
563563
offset, key_type = decoder.DecodeUint8()
564564
if key_type != definitions.GlobalMetadataKeyType.EARLIEST_COMPACTION_TIME:
565-
raise errors.ParserError('Not a EarlistCompactionTimeKey')
565+
raise errors.ParserError('Not a EarliestCompactionTimeKey')
566566
return cls(offset=base_offset + offset, key_prefix=key_prefix)
567567

568568

@@ -668,7 +668,7 @@ class GlobalMetaDataKey(BaseIndexedDBKey):
668668
definitions.GlobalMetadataKeyType
669669
.EARLIEST_SWEEP: EarliestSweepKey,
670670
definitions.GlobalMetadataKeyType
671-
.EARLIEST_COMPACTION_TIME: EarlistCompactionTimeKey,
671+
.EARLIEST_COMPACTION_TIME: EarliestCompactionTimeKey,
672672
definitions.GlobalMetadataKeyType
673673
.SCOPES_PREFIX: ScopesPrefixKey,
674674
definitions.GlobalMetadataKeyType
@@ -692,7 +692,7 @@ def FromDecoder(
692692
Type[DatabaseFreeListKey],
693693
Type[DatabaseNameKey],
694694
Type[EarliestSweepKey],
695-
Type[EarlistCompactionTimeKey],
695+
Type[EarliestCompactionTimeKey],
696696
Type[MaxDatabaseIdKey],
697697
Type[RecoveryBlobJournalKey],
698698
Type[SchemaVersionKey],
@@ -972,7 +972,7 @@ class ObjectStoreDataValue:
972972
blob_offset: the blob offset, only valid if wrapped.
973973
value: the blink serialized value, only valid if not wrapped.
974974
"""
975-
unkown: int
975+
unknown: int
976976
is_wrapped: bool
977977
blob_size: Optional[int]
978978
blob_offset: Optional[int]
@@ -1003,15 +1003,15 @@ def DecodeValue(
10031003
_, blob_size = decoder.DecodeVarint()
10041004
_, blob_offset = decoder.DecodeVarint()
10051005
return ObjectStoreDataValue(
1006-
unkown=unknown_integer,
1006+
unknown=unknown_integer,
10071007
is_wrapped=True,
10081008
blob_size=blob_size,
10091009
blob_offset=blob_offset,
10101010
value=None)
10111011
_, blink_bytes = decoder.ReadBytes()
10121012
blink_value = blink.V8ScriptValueDecoder.FromBytes(blink_bytes)
10131013
return ObjectStoreDataValue(
1014-
unkown=unknown_integer,
1014+
unknown=unknown_integer,
10151015
is_wrapped=False,
10161016
blob_size=None,
10171017
blob_offset=None,

dfindexeddb/indexeddb/chromium/v8.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,12 @@ def _PeekTag(self) -> Optional[definitions.V8SerializationTag]:
152152
_, tag_value = self.decoder.PeekBytes(1)
153153
except errors.DecoderError:
154154
return None
155-
return definitions.V8SerializationTag(tag_value[0])
155+
try:
156+
return definitions.V8SerializationTag(tag_value[0])
157+
except ValueError as error:
158+
raise errors.ParserError(
159+
f'Invalid v8 tag value {tag_value} at offset'
160+
f' {self.decoder.stream.tell()}') from error
156161

157162
def _ReadTag(self) -> definitions.V8SerializationTag:
158163
"""Returns the next non-padding serialization tag.
@@ -269,7 +274,7 @@ def _ReadObjectInternal(self) -> Tuple[definitions.V8SerializationTag, Any]:
269274
self.version >= 15):
270275
parsed_object = self.ReadSharedObject()
271276
elif self.version < 13:
272-
self.decoder.stream.seek(-1)
277+
self.decoder.stream.seek(-1, os.SEEK_CUR)
273278
parsed_object = self.ReadHostObject()
274279
else:
275280
parsed_object = None
@@ -492,7 +497,7 @@ def _ReadJSPrimitiveWrapper(
492497
return value
493498

494499
def _ReadJSRegExp(self) -> RegExp:
495-
"""Reads a Javscript regular expression from the current position."""
500+
"""Reads a Javascript regular expression from the current position."""
496501
next_id = self._GetNextId()
497502
pattern = self.ReadString()
498503
_, flags = self.decoder.DecodeUint32Varint() # TODO: verify flags

dfindexeddb/indexeddb/cli.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"""A CLI tool for dfindexeddb."""
1616
import argparse
1717
import dataclasses
18+
import enum
1819
from datetime import datetime
1920
import json
2021
import pathlib
@@ -57,6 +58,8 @@ def default(self, o):
5758
return list(o)
5859
if isinstance(o, v8.RegExp):
5960
return str(o)
61+
if isinstance(o, enum.Enum):
62+
return o.name
6063
return json.JSONEncoder.default(self, o)
6164

6265

@@ -85,6 +88,7 @@ def IndexeddbCommand(args):
8588
(f'Error parsing blink value: {err} for {record.__class__.__name__} '
8689
f'at offset {record.offset} in {db_record.path}'), file=sys.stderr)
8790
print(f'Traceback: {traceback.format_exc()}', file=sys.stderr)
91+
print(f'Record: {record}', file=sys.stderr)
8892
_Output(db_record, output=args.output)
8993

9094

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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.

0 commit comments

Comments
 (0)