@@ -810,12 +810,20 @@ def open_url(self, url, warning=None): # noqa: C901 # is too complex (12)
810
810
@staticmethod
811
811
def _resolve_download_filename (url , tmpdir ):
812
812
"""
813
+ >>> import pathlib
813
814
>>> du = PackageIndex._resolve_download_filename
814
815
>>> root = getfixture('tmp_path')
815
816
>>> url = 'https://files.pythonhosted.org/packages/a9/5a/0db.../setuptools-78.1.0.tar.gz'
816
- >>> import pathlib
817
817
>>> str(pathlib.Path(du(url, root)).relative_to(root))
818
818
'setuptools-78.1.0.tar.gz'
819
+
820
+ Ensures the target is always in tmpdir.
821
+
822
+ >>> url = 'https://anyhost/%2fhome%2fuser%2f.ssh%2fauthorized_keys'
823
+ >>> du(url, root)
824
+ Traceback (most recent call last):
825
+ ...
826
+ ValueError: Invalid filename...
819
827
"""
820
828
name , _fragment = egg_info_for_url (url )
821
829
if name :
@@ -827,7 +835,13 @@ def _resolve_download_filename(url, tmpdir):
827
835
if name .endswith ('.egg.zip' ):
828
836
name = name [:- 4 ] # strip the extra .zip before download
829
837
830
- return os .path .join (tmpdir , name )
838
+ filename = os .path .join (tmpdir , name )
839
+
840
+ # ensure path resolves within the tmpdir
841
+ if not filename .startswith (str (tmpdir )):
842
+ raise ValueError (f"Invalid filename { filename } " )
843
+
844
+ return filename
831
845
832
846
def _download_url (self , url , tmpdir ):
833
847
"""
0 commit comments