RestoreHelper: Prevent endless loop if both indexes contain a list:// entry
authorThomas Jarosch <thomas.jarosch@intra2net.com>
Mon, 2 Apr 2018 11:15:30 +0000 (13:15 +0200)
committerThomas Jarosch <thomas.jarosch@intra2net.com>
Mon, 2 Apr 2018 11:26:57 +0000 (13:26 +0200)
This completes the control flow refactoring from Philipp
in commit 7273719cca856677d25102d805f6f96e36173731

deltatar/deltatar.py

index 0edc28a..124ebe4 100644 (file)
@@ -1495,30 +1495,33 @@ class RestoreHelper(object):
         # Right now we support diff backups, only. No incremental backups.
         # As a result _data[0] is always the diff backup index
         # and _data[1] the full backup index.
-        if len(self._data) > 1:
+        if len(self._data) == 2:
             data = self._data[1]
-            while True:
-                d, l_no, dpath = self.find_path_in_index(data, upath)
-                if not d:
-                    self._deltatar.logger.warning('Error restoring file %s from '
-                                               'index, not found in index %s' % (path, data['path']))
-                    return
-
-                cur_path = d.get('path', '')
-                if cur_path.startswith('delete://'):
-                    self._deltatar.logger.warning(('Strange thing happened, file '
-                                                '%s was listed in first index but deleted by another '
-                                                'one. Path was ignored and untouched.') % path)
-                    return
-                elif cur_path.startswith('snapshot://'):
-                    # this code path is reached when the file is unchanged
-                    # in the newest index and therefore of type 'list://'
-                    self.restore_file(d, data, path, l_no, dpath)
-
-                    # now we restore parent_directory mtime
-                    os.utime(parent_dir, (parent_dir_mtime, parent_dir_mtime))
-                    return
+            d, l_no, dpath = self.find_path_in_index(data, upath)
+            if not d:
+                self._deltatar.logger.warning('Error restoring file %s from '
+                                            'index, not found in index %s' % (path, data['path']))
+                return
+
+            cur_path = d.get('path', '')
+            if cur_path.startswith('delete://'):
+                self._deltatar.logger.warning(('Strange thing happened, file '
+                                            '%s was listed in first index but deleted by another '
+                                            'one. Path was ignored and untouched.') % path)
+                return
+            elif cur_path.startswith('snapshot://'):
+                # this code path is reached when the file is unchanged
+                # in the newest index and therefore of type 'list://'
+                self.restore_file(d, data, path, l_no, dpath)
+
+                # now we restore parent_directory mtime
+                os.utime(parent_dir, (parent_dir_mtime, parent_dir_mtime))
+                return
 
+        # error code path is reached when:
+        # a) we have more than two indexes (unsupported atm)
+        # b) both indexes contain a list:// entry (logic error)
+        # c) we have just one index and it also contains list://
         self._deltatar.logger.warning(('Error restoring file %s from index, '
                                     'snapshot not found in any index') % path)