ccl_chrome_indexeddb: ValueError: Didn't get version tag in the header

Hello,

I’ve been trying to retrieve the key/value information from a specific leveldb on Chrome IndexedDB and I keep getting a ValueError exception.

ValueError: Didn't get version tag in the header

This happens on the records iteration and it crashes on the following verification:

def _read_header(self) -> int:
        tag = self._read_tag()
        if tag != Constants.token_kVersion:
            raise ValueError("Didn't get version tag in the header")
        version = self._read_le_varint()[0]
        return version

Apparently my version tag value is 0x01 and it should be 0xff.

This only appears with one specific leveldb. Do you know why is the version tag with this value? Shouldn’t it be the 0xff instead of 0x01

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 15 (9 by maintainers)

Most upvoted comments

Great, thank you for the details. I will get back to you when I’ve had a chance to have a look at some data.

@cclgroupltd Thanks for the update. I checked the most recent version and found no mistakes. I tested various records (Blink v.17, 20, 21) including the ones with externally serialized objects. As far as I see it looks pretty good, at least solved the issue I had. Great work, saved my data!

Hello,

The record structure changed in newer Blink versions. First, the IDB value wrapping, see at https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/blink/renderer/modules/indexeddb/idb_value_wrapping.cc The wrapping detection logic in IDBValueUnwrapper::IsWrapped() must be able to distinguish between SSV byte sequences produced and byte sequences expressing the fact that an IDBValue has been wrapped and requires post-processing. SSV processing command replacing the SSV data bytes with a Blob’s contents.

  1. 0xFF - kVersionTag
  2. 0x11 - kRequiresProcessingSSVPseudoVersion
  3. 0x01 - kReplaceWithBlob
  4. varint - Blob size
  5. varint - the offset of the SSV-wrapping Blob in the IDBValue list of Blobs

The python code expects a version tag in position 3 which is replaced by 0x01 in this case.

The other change in the Blink envelope, https://github.com/chromium/chromium/blob/main/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc

// These versions expect a trailer offset in the envelope.
if (version >= TrailerReader::kMinWireFormatVersion) {
      static constexpr size_t kTrailerOffsetDataSize = 1 + sizeof(uint64_t) + sizeof(uint32_t);

So in iterate_records now should be something like

                
                require_processing = record.value[val_idx]
                if require_processing == 0x01:
                    val_idx += 1
                    blob_size, varint_raw = _le_varint_from_bytes(record.value[val_idx:])
                    val_idx += len(varint_raw)
                    blob_offset, varint_raw = _le_varint_from_bytes(record.value[val_idx:])
                    val_idx += len(varint_raw)

               # trailer offset
                if blink_version >= 21:
                    val_idx += 1+8+4 # 1 + uint_64_t + uint_32_t