[3.12] gh-146581: Fix vulnerability in shutil.unpack_archive() for ZI… · python/cpython@a6650a2

GitHub

@@ -2059,8 +2059,6 @@ def test_make_zipfile_rootdir_nodir(self):

20592059defcheck_unpack_archive(self, format, **kwargs):

20602060self.check_unpack_archive_with_converter(

20612061format, lambdapath: path, **kwargs)

2062-self.check_unpack_archive_with_converter(

2063-format, FakePath, **kwargs)

20642062self.check_unpack_archive_with_converter(format, FakePath, **kwargs)

2065206320662064defcheck_unpack_archive_with_converter(self, format, converter, **kwargs):

@@ -2116,6 +2114,71 @@ def test_unpack_archive_zip(self):

21162114withself.assertRaises(TypeError):

21172115self.check_unpack_archive('zip', filter='data')

211821162117+deftest_unpack_archive_zip_badpaths(self):

2118+srcdir=self.mkdtemp()

2119+zipname=os.path.join(srcdir, 'test.zip')

2120+abspath=os.path.join(srcdir, 'abspath')

2121+withzipfile.ZipFile(zipname, 'w') aszf:

2122+zf.writestr(abspath, 'badfile')

2123+zf.writestr(os.sep+abspath, 'badfile')

2124+zf.writestr('/abspath', 'badfile')

2125+zf.writestr('C:/abspath', 'badfile')

2126+zf.writestr('D:\\abspath', 'badfile')

2127+zf.writestr('E:abspath', 'badfile')

2128+zf.writestr('F:/G:/abspath', 'badfile')

2129+zf.writestr('//server/share/abspath', 'badfile')

2130+zf.writestr('\\\\server2\\share\\abspath', 'badfile')

2131+zf.writestr('../relpath', 'badfile')

2132+zf.writestr(os.pardir+os.sep+'relpath2', 'badfile')

2133+zf.writestr('good/file', 'goodfile')

2134+zf.writestr('good..file', 'goodfile')

2135+2136+dstdir=os.path.join(self.mkdtemp(), 'dst')

2137+unpack_archive(zipname, dstdir)

2138+self.assertTrue(os.path.isfile(os.path.join(dstdir, 'good', 'file')))

2139+self.assertTrue(os.path.isfile(os.path.join(dstdir, 'good..file')))

2140+self.assertFalse(os.path.exists(abspath))

2141+self.assertFalse(os.path.exists(os.path.join(dstdir, 'abspath')))

2142+self.assertFalse(os.path.exists(os.path.join(dstdir, 'G_')))

2143+self.assertFalse(os.path.exists(os.path.join(dstdir, 'server')))

2144+ifos.name!='nt':

2145+self.assertTrue(os.path.isfile(os.path.join(dstdir, 'C:', 'abspath')))

2146+self.assertTrue(os.path.isfile(os.path.join(dstdir, 'D:\\abspath')))

2147+self.assertTrue(os.path.isfile(os.path.join(dstdir, 'E:abspath')))

2148+self.assertTrue(os.path.isfile(os.path.join(dstdir, 'F:', 'G:', 'abspath')))

2149+self.assertTrue(os.path.isfile(os.path.join(dstdir, '\\\\server2\\share\\abspath')))

2150+ifos.pardir=='..':

2151+self.assertFalse(os.path.exists(os.path.join(dstdir, '..', 'relpath')))

2152+self.assertFalse(os.path.exists(os.path.join(dstdir, 'relpath')))

2153+else:

2154+self.assertTrue(os.path.isfile(os.path.join(dstdir, '..', 'relpath')))

2155+self.assertFalse(os.path.exists(os.path.join(dstdir, os.pardir, 'relpath2')))

2156+self.assertFalse(os.path.exists(os.path.join(dstdir, 'relpath2')))

2157+2158+dstdir2=os.path.join(self.mkdtemp(), 'dst')

2159+os.mkdir(dstdir2)

2160+withos_helper.change_cwd(dstdir2):

2161+unpack_archive(zipname, '')

2162+self.assertTrue(os.path.isfile(os.path.join('good', 'file')))

2163+self.assertTrue(os.path.isfile('good..file'))

2164+self.assertFalse(os.path.exists(abspath))

2165+self.assertFalse(os.path.exists('abspath'))

2166+self.assertFalse(os.path.exists('C_'))

2167+self.assertFalse(os.path.exists('server'))

2168+ifos.name!='nt':

2169+self.assertTrue(os.path.isfile(os.path.join('C:', 'abspath')))

2170+self.assertTrue(os.path.isfile('D:\\abspath'))

2171+self.assertTrue(os.path.isfile('E:abspath'))

2172+self.assertTrue(os.path.isfile(os.path.join('F:', 'G:', 'abspath')))

2173+self.assertTrue(os.path.isfile('\\\\server2\\share\\abspath'))

2174+ifos.pardir=='..':

2175+self.assertFalse(os.path.exists(os.path.join('..', 'relpath')))

2176+self.assertFalse(os.path.exists('relpath'))

2177+else:

2178+self.assertTrue(os.path.isfile(os.path.join('..', 'relpath')))

2179+self.assertFalse(os.path.exists(os.path.join(os.pardir, 'relpath2')))

2180+self.assertFalse(os.path.exists('relpath2'))

2181+21192182deftest_unpack_registry(self):

2120218321212184formats=get_unpack_formats()