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

GitHub

GitHub CopilotWrite better code with AI | MCP RegistryIntegrate external tools | ActionsAutomate any workflow | CodespacesInstant dev environments | IssuesPlan and track work | Code ReviewManage code changes | Code QualityEnforce quality at merge | Why GitHub | Marketplace | View all features | Enterprises | Small and medium teams | Startups | View all use cases | View all industries | View all solutions | AI | Software Development | DevOps | Security | View all topics | Customer stories | Events & webinars | Ebooks & reports | Business insights | Trust center | Partners | View all resources

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

17991799withself.assertRaises(TypeError):

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

180118011802+deftest_unpack_archive_zip_badpaths(self):

1803+srcdir=self.mkdtemp()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1820+1821+dstdir=os.path.join(self.mkdtemp(), 'dst')

1822+unpack_archive(zipname, dstdir)

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

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

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

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

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

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

1829+ifos.name!='nt':

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

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

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

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

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

1835+ifos.pardir=='..':

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

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

1838+else:

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

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

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

1842+1843+dstdir2=os.path.join(self.mkdtemp(), 'dst')

1844+os.mkdir(dstdir2)

1845+withos_helper.change_cwd(dstdir2):

1846+unpack_archive(zipname, '')

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

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

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

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

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

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

1853+ifos.name!='nt':

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

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

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

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

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

1859+ifos.pardir=='..':

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

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

1862+else:

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

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

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

1866+18021867deftest_unpack_registry(self):

1803186818041869formats=get_unpack_formats()