diff --git a/attic/archive.py b/attic/archive.py index e864c3fe1..3d660d207 100644 --- a/attic/archive.py +++ b/attic/archive.py @@ -404,6 +404,8 @@ def list_archives(repository, key, manifest, cache=None): class RobustUnpacker(): """A restartable/robust version of the streaming msgpack unpacker """ + item_keys = [msgpack.packb(name) for name in ('path', 'mode', 'source', 'chunks', 'rdev', 'xattrs', 'user', 'group', 'uid', 'gid', 'mtime')] + def __init__(self, validator): super(RobustUnpacker, self).__init__() self.validator = validator @@ -430,10 +432,18 @@ def __next__(self): while self._resync: if not data: raise StopIteration - # Abort early if the data does not look like a serialized item - if len(data) < 2 or ((data[0] & 0xf0) != 0x80) or ((data[1] & 0xe0) != 0xa0) or not b'\xa4path' in data: + # Abort early if the data does not look like a serialized dict + if len(data) < 2 or ((data[0] & 0xf0) != 0x80) or ((data[1] & 0xe0) != 0xa0): data = data[1:] continue + # Make sure it looks like an item dict + for pattern in self.item_keys: + if data[1:].startswith(pattern): + break + else: + data = data[1:] + continue + self._unpacker = msgpack.Unpacker(object_hook=StableDict) self._unpacker.feed(data) try: diff --git a/attic/testsuite/repository.py b/attic/testsuite/repository.py index af1aeb1f6..292867ec5 100644 --- a/attic/testsuite/repository.py +++ b/attic/testsuite/repository.py @@ -304,7 +304,6 @@ def test_repair_index_too_new(self): def test_crash_before_compact(self): self.repository.put(bytes(32), b'data') -# self.repository.commit() self.repository.put(bytes(32), b'data2') # Simulate a crash before compact with patch.object(Repository, 'compact_segments') as compact: