浏览代码

Attempt to make the archive metadata resync more robust

Jonas Borgström 11 年之前
父节点
当前提交
90fe318809
共有 2 个文件被更改,包括 12 次插入3 次删除
  1. 12 2
      attic/archive.py
  2. 0 1
      attic/testsuite/repository.py

+ 12 - 2
attic/archive.py

@@ -404,6 +404,8 @@ class Archive:
 class RobustUnpacker():
 class RobustUnpacker():
     """A restartable/robust version of the streaming msgpack unpacker
     """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):
     def __init__(self, validator):
         super(RobustUnpacker, self).__init__()
         super(RobustUnpacker, self).__init__()
         self.validator = validator
         self.validator = validator
@@ -430,10 +432,18 @@ class RobustUnpacker():
             while self._resync:
             while self._resync:
                 if not data:
                 if not data:
                     raise StopIteration
                     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:]
                     data = data[1:]
                     continue
                     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 = msgpack.Unpacker(object_hook=StableDict)
                 self._unpacker.feed(data)
                 self._unpacker.feed(data)
                 try:
                 try:

+ 0 - 1
attic/testsuite/repository.py

@@ -304,7 +304,6 @@ class RepositoryCheckTestCase(RepositoryTestCaseBase):
 
 
     def test_crash_before_compact(self):
     def test_crash_before_compact(self):
         self.repository.put(bytes(32), b'data')
         self.repository.put(bytes(32), b'data')
-#        self.repository.commit()
         self.repository.put(bytes(32), b'data2')
         self.repository.put(bytes(32), b'data2')
         # Simulate a crash before compact
         # Simulate a crash before compact
         with patch.object(Repository, 'compact_segments') as compact:
         with patch.object(Repository, 'compact_segments') as compact: