]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #21775: shutil.copytree(): fix crash when copying to VFAT
authorBerker Peksag <berker.peksag@gmail.com>
Wed, 10 Dec 2014 00:50:32 +0000 (02:50 +0200)
committerBerker Peksag <berker.peksag@gmail.com>
Wed, 10 Dec 2014 00:50:32 +0000 (02:50 +0200)
An exception handler assumed that that OSError objects always have a
'winerror' attribute. That is not the case, so the exception handler
itself raised AttributeError when run on Linux (and, presumably, any
other non-Windows OS).

Patch by Greg Ward.

Lib/shutil.py
Lib/test/test_shutil.py
Misc/NEWS

index 22958f42046f7d74e4b978f95712285ad3238141..ac06ae5e6cd84689580b81d7c0c1fac6d0a0acc8 100644 (file)
@@ -337,7 +337,7 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,
         copystat(src, dst)
     except OSError as why:
         # Copying file access times may fail on Windows
-        if why.winerror is None:
+        if getattr(why, 'winerror', None) is None:
             errors.append((src, dst, str(why)))
     if errors:
         raise Error(errors)
index 349036291b24ca459298fcd77fd50a1b2935074a..9325bc7dc15821da4694c5ada9bd11b29a3559f6 100644 (file)
@@ -1,6 +1,7 @@
 # Copyright (C) 2003 Python Software Foundation
 
 import unittest
+import unittest.mock
 import shutil
 import tempfile
 import sys
@@ -758,6 +759,20 @@ class TestShutil(unittest.TestCase):
         self.assertEqual(os.stat(restrictive_subdir).st_mode,
                           os.stat(restrictive_subdir_dst).st_mode)
 
+    @unittest.mock.patch('os.chmod')
+    def test_copytree_winerror(self, mock_patch):
+        # When copying to VFAT, copystat() raises OSError. On Windows, the
+        # exception object has a meaningful 'winerror' attribute, but not
+        # on other operating systems. Do not assume 'winerror' is set.
+        src_dir = tempfile.mkdtemp()
+        dst_dir = os.path.join(tempfile.mkdtemp(), 'destination')
+        self.addCleanup(shutil.rmtree, src_dir)
+        self.addCleanup(shutil.rmtree, os.path.dirname(dst_dir))
+
+        mock_patch.side_effect = PermissionError('ka-boom')
+        with self.assertRaises(shutil.Error):
+            shutil.copytree(src_dir, dst_dir)
+
     @unittest.skipIf(os.name == 'nt', 'temporarily disabled on Windows')
     @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link')
     def test_dont_copy_file_onto_link_to_itself(self):
index 6c0c1f2baa4749a42232c8004161cfb384d65086..4807dc4065e1622f67253f2139837e0eaa00cc61 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -39,6 +39,12 @@ Core and Builtins
 Library
 -------
 
+- Issue #21775: shutil.copytree(): fix crash when copying to VFAT. An exception
+  handler assumed that that OSError objects always have a 'winerror' attribute.
+  That is not the case, so the exception handler itself raised AttributeError
+  when run on Linux (and, presumably, any other non-Windows OS).
+  Patch by Greg Ward.
+
 - Issue #1218234: Fix inspect.getsource() to load updated source of
   reloaded module. Initial patch by Berker Peksag.