Browse code

Fixes #377 - Avoid crashing when a file disappeared during cache generation

If cache was used, sometimes a file could have disappeared (ie be
removed), before it's md5 is calculated.
In that case, there will be an almost empty entry inside local_list for
it.
Cache updating was crashing with a KeyError in such a case.

Florent Viard authored on 2020/03/22 23:53:41
Showing 1 changed files
... ...
@@ -25,6 +25,8 @@ import re
25 25
 import errno
26 26
 import io
27 27
 
28
+PY3 = (sys.version_info >= (3, 0))
29
+
28 30
 __all__ = ["fetch_local_list", "fetch_remote_list", "compare_filelists"]
29 31
 
30 32
 def _os_walk_unicode(top):
... ...
@@ -202,7 +204,8 @@ def fetch_local_list(args, is_src = False, recursive = None):
202 202
             if counter % 1000 == 0:
203 203
                 info(u"[%d/%d]" % (counter, len_loc_list))
204 204
 
205
-            if relative_file == '-': continue
205
+            if relative_file == '-':
206
+                continue
206 207
 
207 208
             full_name = loc_list[relative_file]['full_name']
208 209
             try:
... ...
@@ -306,8 +309,16 @@ def fetch_local_list(args, is_src = False, recursive = None):
306 306
         # not.  Leave it to a non-files_from run to purge.
307 307
         if cfg.cache_file and len(cfg.files_from) == 0:
308 308
             cache.mark_all_for_purge()
309
-            for i in local_list.keys():
310
-                cache.unmark_for_purge(local_list[i]['dev'], local_list[i]['inode'], local_list[i]['mtime'], local_list[i]['size'])
309
+            if PY3:
310
+                local_list_val_iter = local_list.values()
311
+            else:
312
+                local_list_val_iter = local_list.itervalues()
313
+            for f_info in local_list_val_iter:
314
+                inode = f_info.get('inode', 0)
315
+                if not inode:
316
+                    continue
317
+                cache.unmark_for_purge(f_info['dev'], inode, f_info['mtime'],
318
+                                       f_info['size'])
311 319
             cache.purge()
312 320
             cache.save(cfg.cache_file)
313 321