Skip to content

Commit d97e83e

Browse files
committed
make sure the directory is not renamed during extractall()
1 parent 2463a85 commit d97e83e

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

Lib/tarfile.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2389,20 +2389,32 @@ def extractall(self, path=".", members=None, *, numeric_owner=False,
23892389
tarinfo = self._get_extract_tarinfo(member, filter_function, path)
23902390
if tarinfo is None:
23912391
continue
2392+
self._extract_one(tarinfo, path, set_attrs=not tarinfo.isdir(),
2393+
numeric_owner=numeric_owner)
23922394
if tarinfo.isdir():
23932395
# For directories, delay setting attributes until later,
23942396
# since permissions can interfere with extraction and
23952397
# extracting contents can reset mtime.
2396-
directories.append(tarinfo)
2397-
self._extract_one(tarinfo, path, set_attrs=not tarinfo.isdir(),
2398-
numeric_owner=numeric_owner)
2398+
# We also the keep the original inode and device, to detect
2399+
# if it was changed during extraction.
2400+
dirpath = os.path.join(path, tarinfo.name)
2401+
dirpath = self._transform_destination_path(dirpath)
2402+
targetstat = os.stat(dirpath)
2403+
directories.append((tarinfo, dirpath, targetstat.st_ino,
2404+
targetstat.st_dev))
23992405

24002406
# Reverse sort directories.
2401-
directories.sort(key=lambda a: a.name, reverse=True)
2407+
directories.sort(key=lambda a: a[0].name, reverse=True)
24022408

24032409
# Set correct owner, mtime and filemode on directories.
2404-
for tarinfo in directories:
2405-
dirpath = os.path.join(path, tarinfo.name)
2410+
for tarinfo, dirpath, original_ino, original_dev in directories:
2411+
dirstat = os.stat(dirpath)
2412+
if (dirstat.st_ino != original_ino or
2413+
dirstat.st_dev != original_dev):
2414+
self._dbg(1, "tarfile: Directory renamed before its " \
2415+
"attributes could be extracted %r" % dirpath)
2416+
continue
2417+
24062418
try:
24072419
self.chown(tarinfo, dirpath, numeric_owner=numeric_owner)
24082420
self.utime(tarinfo, dirpath)

0 commit comments

Comments
 (0)