From d0112cf9306834b17eb5476363cb6b3b9bfb650c Mon Sep 17 00:00:00 2001 From: Anton Samarchyan Date: Thu, 1 Dec 2016 11:05:08 -0500 Subject: [PATCH] Fixed #26494 -- Made Archive.extract() preserve file permissions. --- django/utils/archive.py | 5 +++++ tests/utils_tests/archives/foobar.tar | Bin 10240 -> 5632 bytes tests/utils_tests/archives/foobar.tar.bz2 | Bin 238 -> 265 bytes tests/utils_tests/archives/foobar.tar.gz | Bin 249 -> 253 bytes tests/utils_tests/archives/foobar.zip | Bin 1130 -> 810 bytes tests/utils_tests/test_archive.py | 10 ++++++++++ 6 files changed, 15 insertions(+) diff --git a/django/utils/archive.py b/django/utils/archive.py index 13f8afa32f..f8c1a0f83b 100644 --- a/django/utils/archive.py +++ b/django/utils/archive.py @@ -164,6 +164,7 @@ class TarArchive(BaseArchive): os.makedirs(dirname) with open(filename, 'wb') as outfile: shutil.copyfileobj(extracted, outfile) + os.chmod(filename, member.mode) finally: if extracted: extracted.close() @@ -185,6 +186,7 @@ class ZipArchive(BaseArchive): leading = self.has_leading_dir(namelist) for name in namelist: data = self._archive.read(name) + info = self._archive.getinfo(name) if leading: name = self.split_leading_dir(name)[1] filename = os.path.join(to_path, name) @@ -198,6 +200,9 @@ class ZipArchive(BaseArchive): else: with open(filename, 'wb') as outfile: outfile.write(data) + # convert ZipInfo.external_attr to mode + mode = info.external_attr >> 16 + os.chmod(filename, mode) def close(self): self._archive.close() diff --git a/tests/utils_tests/archives/foobar.tar b/tests/utils_tests/archives/foobar.tar index 5418405070f1c410f2751215f73e1e6f778e8526..44886fb33becb174c984ed45a783ded067394931 100644 GIT binary patch literal 5632 zcmeH~L5{*O3`KpE+yFbVlk)^rGz(^s3P^B!oWh{)m@FKPgtKWRtBLbp`|a$H$IZ6R z8!#M*SVRIKQW07|HS!pN5=KPkj4>cdqzpj}b9ya(Ii2gQsnt{cuJi8eR)1cx_2gar zc@ABvjj(?8KhNWU0aw5k0JsB+RO)#E literal 10240 zcmeH~F%H5o3`KL4o}i6G9G`~@!C0xl{jn((Ooa@N5d16|tjf`Qv7Poqa9>fEFbCa8 zIKJ){vK5GON)ihvi%Z#+(6Rf;G{N)S7m^#i$|&IFg7U%jvQ zz(TfG|CB|{zYvEmx}QuF{JsC=PT2&1>Yw#4nEy!d?=D6Y^uuwQoM(Xf|FHj4X6+Lc zbr_)kxAX5i18V9&bGrK%)PD>8kNWqW0d@YD`j?FU-{Jx+{eRrgjx(UD|BL=75RuhC z-v9nL;OXCQ22|C5vHnlV{{Qg)Z|UD}22}Z9>ObWj{QKKS1`q%N5C8!X009sH0T2KI W5C8!X009sH0T2KI5CDN+C2#{-E1fU^ diff --git a/tests/utils_tests/archives/foobar.tar.bz2 b/tests/utils_tests/archives/foobar.tar.bz2 index 693529dcefa2a6be78daa22bc82ae352a64c20f8..5a3d8a402eda8ef240e1e6724e9200df416e0412 100644 GIT binary patch literal 265 zcmV+k0rvhvT4**gL0KkKS=D$hzW@Q^dyvq8AOJuB|9}C^`$wK&1V8`?FaasC1c^+_ zH6fEGjDr!QOd^#JNwS&%9-*P20I5+1fHD98G|BWJUo&+SCX5Jpl<^**;HR z%g`Xf3sq>N0vbdv5VU6GSx#i2ifTf_m_$Sc%QZ%jqa-#V2yi!*D_Ynkb1W%_dAfxW zL4gg63Su}etqgFnyiE%XK_u_bJGY}zVNjzdnr0joBFe>uLUOMF#@T|YRhWY06yao` zaHvi*6y;Wt1W9R)LJqw|9fS~rn*9)aBB)tCbVJ3ra4(^18Zr>_pOTQ5qhv0HS}#L< PPvY)KrwS4puLalOW3pyr=@AOKMY3=kP(9s+9~>cMe;C{sO3*_Tb3 z7OQjFzJ2b~{rh`7>yLm2J?i(!L?8S|LX>L0UPDYmI0P^_+rRsd20eQGljN&^X7_Kw z@}B>iInd{yTK*?U?%#rkf6W}|@}F<>U&Q@e(EMxn=->Z{7=8bh);(FW=@rr#Am3k^6TX$I;{h?;E-<02TlM DKc$5% literal 249 zcmV1;;5;Srf%1J$-YXsDkEYaqf6SZK>UP_C4Z)2k67nBmGS_t#o&n$X|62bse^)%thABYyw@0000000000fL}cUd&-Ya04M+emV$r2 diff --git a/tests/utils_tests/archives/foobar.zip b/tests/utils_tests/archives/foobar.zip index dc3e2fc0675de899be591ed479cff00c30e626f0..b02bb3e95a8ca95a5f3f08f53c180426dc48cf08 100644 GIT binary patch literal 810 zcmWIWW@h1HW&ncrSwCz*Gz>5T8HNFH=?*N?MhNN1h(=GCP7uun#Hkgj$)zQUNja$? zbs}I}T+!6A0M(`C=j$U(sz$Sj6{-TsEj2ilfZc=L9uBA}Nr^>Bb~U0I#EGN|$-Xu` z%7AtH?k-RqK>)~I=YUL* xyC5-!a2vKbgXjXe?F*7F6!&3^LxeVIU}}e126Q7U8%T;12rmI8oIqKD0RWKTZH)i` literal 1130 zcmWIWW@h1H0D+EKKWxAZD8a}e!(bR1!pXpF-|X!Z0mP*h+zgB?FPIq^z(fFEtwvz2 z4urJUpxMd-v^6b1UmvVn2dG;gpT*T^x>=#RA@0@!Y6W4O?nbv9rXAvTknJFhQ+qp_ z?Ho|slM;&{?zaW%wrjy-LL-_9oJb}>{9pt$0)&Zn1hNqje}G&8!Wc#{GRZOHihBuo zQdrUmVgg;m3P}lM8)FSL2IwN7F`!g|#~AczVPSx|Mu6e1V;RsGND2X(gf)H;{=!Tj zFq0SpBozVuNFeSo z(-6!wki$xlOoR9nYidIH6Wwu~DE{1zWE{k=SY5};1`H1d4j_zTVqo|M)WpC50PL2w A8vp