diff --git a/pip/_internal/utils/misc.py b/pip/_internal/utils/misc.py index 84a421f..fbdb654 100644 --- a/pip/_internal/utils/misc.py +++ b/pip/_internal/utils/misc.py @@ -532,6 +532,13 @@ def untar_file(filename, location): if leading: fn = split_leading_dir(fn)[1] path = os.path.join(location, fn) + + # Call the `data` filter for its side effect (raising exception) + try: + tarfile.data_filter(member.replace(name=fn), location) + except tarfile.LinkOutsideDestinationError: + pass + if member.isdir(): ensure_dir(path) elif member.issym(): diff --git a/pip/_vendor/distlib/util.py b/pip/_vendor/distlib/util.py index 0b14a93..8f3f12e 100644 --- a/pip/_vendor/distlib/util.py +++ b/pip/_vendor/distlib/util.py @@ -1238,6 +1238,19 @@ def unarchive(archive_filename, dest_dir, format=None, check=True): for tarinfo in archive.getmembers(): if not isinstance(tarinfo.name, text_type): tarinfo.name = tarinfo.name.decode('utf-8') + + # Limit extraction of dangerous items, if this Python + # allows it easily. If not, just trust the input. + # See: https://docs.python.org/3/library/tarfile.html#extraction-filters + def extraction_filter(member, path): + """Run tarfile.tar_fillter, but raise the expected ValueError""" + # This is only called if the current Python has tarfile filters + try: + return tarfile.tar_filter(member, path) + except tarfile.FilterError as exc: + raise ValueError(str(exc)) + archive.extraction_filter = extraction_filter + archive.extractall(dest_dir) finally: