From 2ac96bcd07ca615216cedbd855d641fca65853e5 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Mon, 5 Feb 2024 22:21:35 +0000 Subject: [PATCH] Upload: Fallback to `PclZip` to validate ZIP file uploads. `ZipArchive` can fail to validate ZIP files correctly and report valid files as invalid. This introduces a fallback to `PclZip` to check validity of files if `ZipArchive` fails them. This introduces the new function `wp_zip_file_is_valid()` to validate archives. Follow up to [57388]. Props audunmb, azaozz, britner, cdevroe, colorful-tones, costdev, courane01, endymion00, feastdesignco, halounsbury, jeffpaul, johnbillion, jorbin, jsandtro, karinclimber, kevincoleman, koesper, maartenbelmans, mathewemoore, melcarthus, mujuonly, nerdpressteam, olegfuture, otto42, peterwilsoncc, room34, sayful, schutzsmith, stephencronin, svitlana41319, swissspidy, tnolte, tobiasbg, vikram6, welaunchio. Fixes #60398. git-svn-id: https://develop.svn.wordpress.org/trunk@57537 602fd350-edb4-49c9-b593-d223f7449a82 --- .../includes/class-file-upload-upgrader.php | 19 +---- src/wp-admin/includes/file.php | 31 ++++++++ tests/phpunit/data/filesystem/_source-license | 33 ++++++++ .../data/filesystem/archive-comment.zip | Bin 0 -> 468 bytes .../phpunit/data/filesystem/archive-cp866.zip | Bin 0 -> 163 bytes .../filesystem/archive-directory-entry.zip | Bin 0 -> 2480 bytes .../data/filesystem/archive-encrypted.zip | Bin 0 -> 1692 bytes .../data/filesystem/archive-flags-set.zip | Bin 0 -> 1636 bytes .../phpunit/data/filesystem/archive-gnome.zip | Bin 0 -> 1193 bytes .../data/filesystem/archive-invalid-ext.md | 7 ++ .../data/filesystem/archive-invalid.zip | Bin 0 -> 1100 bytes .../phpunit/data/filesystem/archive-large.zip | Bin 0 -> 5210464 bytes .../phpunit/data/filesystem/archive-macos.zip | Bin 0 -> 2090 bytes .../filesystem/archive-ubuntu-nautilus.zip | Bin 0 -> 798 bytes .../data/filesystem/archive-uncompressed.zip | Bin 0 -> 489 bytes tests/phpunit/data/filesystem/archive.crx | Bin 0 -> 2202 bytes .../tests/filesystem/wpZipFileIsValid.php | 75 ++++++++++++++++++ 17 files changed, 147 insertions(+), 18 deletions(-) create mode 100644 tests/phpunit/data/filesystem/_source-license create mode 100644 tests/phpunit/data/filesystem/archive-comment.zip create mode 100644 tests/phpunit/data/filesystem/archive-cp866.zip create mode 100644 tests/phpunit/data/filesystem/archive-directory-entry.zip create mode 100644 tests/phpunit/data/filesystem/archive-encrypted.zip create mode 100644 tests/phpunit/data/filesystem/archive-flags-set.zip create mode 100644 tests/phpunit/data/filesystem/archive-gnome.zip create mode 100644 tests/phpunit/data/filesystem/archive-invalid-ext.md create mode 100644 tests/phpunit/data/filesystem/archive-invalid.zip create mode 100644 tests/phpunit/data/filesystem/archive-large.zip create mode 100644 tests/phpunit/data/filesystem/archive-macos.zip create mode 100644 tests/phpunit/data/filesystem/archive-ubuntu-nautilus.zip create mode 100644 tests/phpunit/data/filesystem/archive-uncompressed.zip create mode 100644 tests/phpunit/data/filesystem/archive.crx create mode 100644 tests/phpunit/tests/filesystem/wpZipFileIsValid.php diff --git a/src/wp-admin/includes/class-file-upload-upgrader.php b/src/wp-admin/includes/class-file-upload-upgrader.php index e62561518d..1201c6d188 100644 --- a/src/wp-admin/includes/class-file-upload-upgrader.php +++ b/src/wp-admin/includes/class-file-upload-upgrader.php @@ -70,24 +70,7 @@ class File_Upload_Upgrader { } if ( 'pluginzip' === $form || 'themezip' === $form ) { - $archive_is_valid = false; - - /** This filter is documented in wp-admin/includes/file.php */ - if ( class_exists( 'ZipArchive', false ) && apply_filters( 'unzip_file_use_ziparchive', true ) ) { - $archive = new ZipArchive(); - $archive_is_valid = $archive->open( $file['file'], ZIPARCHIVE::CHECKCONS ); - - if ( true === $archive_is_valid ) { - $archive->close(); - } - } else { - require_once ABSPATH . 'wp-admin/includes/class-pclzip.php'; - - $archive = new PclZip( $file['file'] ); - $archive_is_valid = is_array( $archive->properties() ); - } - - if ( true !== $archive_is_valid ) { + if ( ! wp_zip_file_is_valid( $file['file'] ) ) { wp_delete_file( $file['file'] ); wp_die( __( 'Incompatible Archive.' ) ); } diff --git a/src/wp-admin/includes/file.php b/src/wp-admin/includes/file.php index c3863ba2ea..583256955e 100644 --- a/src/wp-admin/includes/file.php +++ b/src/wp-admin/includes/file.php @@ -1563,6 +1563,37 @@ function wp_trusted_keys() { return apply_filters( 'wp_trusted_keys', $trusted_keys ); } +/** + * Determines whether the given file is a valid ZIP file. + * + * This function does not test to ensure that a file exists. Non-existent files + * are not valid ZIPs, so those will also return false. + * + * @since 6.4.4 + * + * @param string $file Full path to the ZIP file. + * @return bool Whether the file is a valid ZIP file. + */ +function wp_zip_file_is_valid( $file ) { + /** This filter is documented in wp-admin/includes/file.php */ + if ( class_exists( 'ZipArchive', false ) && apply_filters( 'unzip_file_use_ziparchive', true ) ) { + $archive = new ZipArchive(); + $archive_is_valid = $archive->open( $file, ZipArchive::CHECKCONS ); + if ( true === $archive_is_valid ) { + $archive->close(); + return true; + } + } + + // Fall through to PclZip if ZipArchive is not available, or encountered an error opening the file. + require_once ABSPATH . 'wp-admin/includes/class-pclzip.php'; + + $archive = new PclZip( $file ); + $archive_is_valid = is_array( $archive->properties() ); + + return $archive_is_valid; +} + /** * Unzips a specified ZIP file to a location on the filesystem via the WordPress * Filesystem Abstraction. diff --git a/tests/phpunit/data/filesystem/_source-license b/tests/phpunit/data/filesystem/_source-license new file mode 100644 index 0000000000..580a1492a4 --- /dev/null +++ b/tests/phpunit/data/filesystem/_source-license @@ -0,0 +1,33 @@ +The following files were sourced from https://github.com/ZJONSSON/node-unzipper a fork of https://github.com/EvanOxfeld/node-unzip + +* archive-comment.zip +* archive-cp866.zip +* archive-directory-entry.zip +* archive-encrypted.zip +* archive-flags-set.zip +* archive-invalid.zip +* archive-large.zip +* archive-uncompressed.zip +* archive.crx + +Copyright (c) 2012 - 2013 Near Infinity Corporation +Copyright (c) 2016 - 2024 Ziggy Jonsson (ziggy.jonsson.nyc@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tests/phpunit/data/filesystem/archive-comment.zip b/tests/phpunit/data/filesystem/archive-comment.zip new file mode 100644 index 0000000000000000000000000000000000000000..14a862f1f1400ff0274d798e73bdde3e36876378 GIT binary patch literal 468 zcmWIWW@Zs#U|`^2U|F*(KtkEvR}jeK2a7N;q-Ex$>XlTKoIdUEdG)kbn8qppb9&F7 zGBE@IwQ&IzF@Uv!8Bl@+NT*~L>4Q`t40acrslx_R4aA~Q6(GYs^NKT5Qe85OK(-hg zJ^~xf$Ry8z(2D9N6`*DiPymw%7ji*G7#SoOBs7g9rWjviM5hD1K_=sJHq2xJpvmSy z4DtjvQyq+sf=&PU-v~@YOhvdC)vGX5LGF!&nu_6ZY}Q~po)r{;49q|%&d9(p3CI>@ Yh{`MgnWm7DSgeq!ker{Jo0?Yw0QDzYuK)l5 literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/filesystem/archive-cp866.zip b/tests/phpunit/data/filesystem/archive-cp866.zip new file mode 100644 index 0000000000000000000000000000000000000000..04bd3c9372aa7fea2a053e034aa9ca79a4088687 GIT binary patch literal 163 zcmWIWW@h1H0D*{DWxpVWs_(o&HVAV7@uZ~>AL*4;lw5lH@zc9Uzh5eRdGPXefHxzP xJp(RHDnM-@pa3QjMsPtz7#SoOj`<$(by$3b5uFb3W@Q6uV+6t|AZ-jb0{}7tDPRBq literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/filesystem/archive-directory-entry.zip b/tests/phpunit/data/filesystem/archive-directory-entry.zip new file mode 100644 index 0000000000000000000000000000000000000000..e81a6aa7e068c4726c5f589fdd3d87c89f1efb0e GIT binary patch literal 2480 zcmZ{m2|Qcb9>)_2Qd(PMEuQ6}grGD^(ZyD~s%MC_ zx~mksa7?i#@C4ck;1vju!(&M?L@b6#48!?jNVsruHb{nsO+^F+jVH<9YohUw4Ih&^wxTALaJ5DjQFmr-TP4d- z0%DtdtFksniBIF9=Zl-eEz$en#h&;O#FdW<*LpIabakEkp_{EV{$d@8VN0*(dRlek z_(X#v2VT1?LFj20B|^QFGm%BCc=pKMIUBlAvRlk5(g$AJDa;gv^W@%oSla(?b#3!~r$@$PyiX;hj$NagedDqYHdvsT zrCyCQJEWcY9;x;Ut~JdFyf>%SOHgc?BQJ_iZnixxgKrP(XVMPC0&}VbwnW<~zX`@T zYHLh78)l_xtKDwXqE6AuN>by+--yVxlc`cv=bH%;wR42|;7=+|noBxK=MtamuZnjX z>N)whijUDO5y-7Vek4D(Gv$baMD1 zvwtgw1XH%7&P|Zj-aJF<^X?IWgd_tA5dac`BLrZ{$Y2sa zEXmpaPM?kld&T{BtU633y3X%`Vw;Uq%77qjRxajW)_$oiO-%jShM+-BXUSv4ibeee z(-~>WivednjAj;YG`IVEtVv;{S9Jm{9t1v#);Rloldv;M?~>5m6x8JYaDMJb^{*aK%|EKSa< zd&>5PMxx^*lyx7$&kd#2d)ww2JU+cu`bzIY_dod=tO7c;?8>@f%2AlMDYK_D;10|; zOVzD*Ek-J=Bh^@Z^@bI#qvJ=5{;V$==L@RdnX|2{IKr9j)jrQU(CT*)OWue0=^wh^ z%G=IiUaJaE{PFwEFXl&{eUhU)tjD{cGb&}o*<-yI1-PZl z@kVMRA7|eB@oHS&b_03~9XK~RrAJ5eZ%JCNEcYsx*VDHOu{j$016d17=~>?1s0Ljk zJ>DYZ$>RMQnc+%_eBs~%D%j;8ToW?s$4~eIhvW+s1QG-$w4-WR0tp#T47}@Netb%~#|4Bu8`npXGgf}QVFH0aZLY)(Xa?k!K18Q%(hWwWPYjrN zPv0^&dxr~Mrd^xk1uK`n8n5+TEW3@OB@7cduowv|g+$a4lgS93KlaQUX;+*dP-D`n zJ~2IjQc+>|Hc%2-JR_u{2Sa_&I8)XLBkSJu2+u*$s^X@7Dh$}*6Zl?vijJOEi5QEIx_RRdj{f8!?A_;IkukL73@p!vg* zt<()!Xq_P)CiI4x$yzG+*~kc$XiT}^7*(Rgw1{1z&oj#BHR~s8KRoL;%fGSqDbdY< zW56go6npaUD?dmIEDt3bU@aYIlv^D9{O5PDnzwENZ5icj?Sh@@)pjbKmA^jGXe4*C z?)`#0^|aM_NMV8*1Jmg&l;YaaaWl2x$Z^s@WPsKXKDu0p5%bWBd7 z=vB6^Z>$gGy~mK#kpP-1ksMPconyzj(^gLEtk_R}e8fp`aXon>PW#Fa3Lr+$*}kl)0Rh8|HS*T{sbd|ME|6 zh+EZnA!*3>8qdvftIjT036%X_4dQ0G1!9*y&AUe~oNRgdc0R&@s|Q#^`_7L5=s(9p B-P8a8 literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/filesystem/archive-encrypted.zip b/tests/phpunit/data/filesystem/archive-encrypted.zip new file mode 100644 index 0000000000000000000000000000000000000000..fd58fb4f1d7e7b8f04a7b25299a7673ec15a4618 GIT binary patch literal 1692 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 wSc+YIMvE{o0n1m+5*OL%2|%L}b06*@S+5i9m literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/filesystem/archive-gnome.zip b/tests/phpunit/data/filesystem/archive-gnome.zip new file mode 100644 index 0000000000000000000000000000000000000000..0f1fc181eab78a05f4f37a3191e773fcf7487cce GIT binary patch literal 1193 zcmWIWW@Zs#0DCrIln`Q2U`Q=X%_}L^P0Os%EyyWN&&<;g4dG>A{~zC&3d5xp z+zgB?iab22LlI+dCM3X7__mPhhc+WK}LaIQerkCi)#CQy_pRK+Rn3ml7FU< z6TKwbHc#{;bBM+^k*`XdQZCG7lr)M@8t9+@yljrg##?HSZSJh% z)864R(fN6t;Iy2H4?gekxugE?+`aYrS{u&PhEC(Pe41;Jw#qr&tFSY0^6Q(d^9#c& zn+1)y4;^Tj=EPq9ZMuT%b6$-M8Rrbgc3!W-X*bwbJ*ZjU@cPY!M~s?$FAl%VvHE@L z&s~qM*2^!F|J}ZtRj6`QrQF8uZ7zS%mXohz12d93wtDvLb2Qo-)}uDzaK!d^saw{c zIAXZRbECP9e0Rp-;QbL0Dq0PMT8vq@(XF0yV&! zkx7IZcQ%4$tG|vQ7DkdMB2z)khh;0|s0L*#82H;5fYp2q8;Q+iFpt43M)ou)CBeYo i#%sV}z_3OiLj+_op>!4C&B_Kcm>CHDfX2EqgLnY2L!_Mm literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/filesystem/archive-invalid-ext.md b/tests/phpunit/data/filesystem/archive-invalid-ext.md new file mode 100644 index 0000000000..1531b03435 --- /dev/null +++ b/tests/phpunit/data/filesystem/archive-invalid-ext.md @@ -0,0 +1,7 @@ +# Shucked + +Shucked is a 2022 musical with music and lyrics by Brandy Clark and Shane McAnally, and a book by Robert Horn. The Broadway production began previews at the Nederlander Theatre on March 8, 2023, before opening on April 4. The show received positive reviews and went on to receive nine nominations at the 76th Tony Awards, including Best Musical. Cast member Alex Newell became one of the first two openly non-binary performers to be nominated for and win a Tony Award, with their win for Best Featured Actor in a Musical. + +A U.S. tour, West End production, and feature film adaptation are currently planned. + +From Wikipedia (https://en.wikipedia.org/wiki/Shucked) under Creative Commons Attribution CC-BY-SA 3.0 (https://creativecommons.org/licenses/by-sa/3.0/legalcode) diff --git a/tests/phpunit/data/filesystem/archive-invalid.zip b/tests/phpunit/data/filesystem/archive-invalid.zip new file mode 100644 index 0000000000000000000000000000000000000000..d13ba6b7ff5c56fb89b1ea6f8acef1d8d81426fa GIT binary patch literal 1100 zcmWIWW@h1H00Gx14o5HpO0Y14%1JGB6u9D+T-j;?fFk21b@|j0_AcAY}ny z-Aq6hNVlP8+eKy|8-zuny3;aqQa$sEGgDGsGK=&|DoWtSt;00V#E1)Iq6h;M0|&!W zpovv)mrw5m+B5^`L=K>dAk*N6JOvs6!f0-a4U1lP+k)rsd957`hpRP~Nh~kv_ptR#JwzrUH2Q6?=r^TXpz`f^!!JCeT*&J#y3W?4YLXlNNZQ{vZdD^ z?Y_gjV)nJaUiH^=7!CKwFnRB;WO05e$(%PK@ny%(T`V0*3z{B&EM0L=y2|(6wcBso zZ%6%JG<`?mk>vlJ9fvFX{q-K7X|fW1ApGxiJY&hpo_$dh*PUR0kkP=X?{k6w-TbA87aD$E^>4+|DGLuy zO$oTC*48!M%uw{6YVqz`=kxp-OZ_iD;izOeH}9UX&XG$>A;&Ccwj{(@d5D~K6+5$6 zd|`+Bw95%E9v-sh5Z}O1%k@Ee)=Lcr!x;u2{%W>##NXGmnXuM#gJphI`O1&1`%NrF z4Qs<+x*M4MTCTBt@$x%9%U4^j+k81*&Z11YB**2izTPp;yDv^CrF1D6d!1r%|Ehni z;?k_mdNUTvf0Vc)XU<$OOLKXv%l6Z)?y~A?r>94+Gy2N0tIEpLFU~mM;A*QuMfFZ~ z=fiDUAH@3}YW7to}+(gTlF+rXDWQXA_go&P$F2c#w+J>o@G$t%+b4;~q>5IR3z39M=b$ZG!S9Z*kKTuL)?!wn>yTfDF z!t?K57}q80y;GWOEwW^1^OsW2O>9q>@cVwru+BQP-?#KeZpF04sgcUdTplvdn6>C) k@1{p}cNr=!s;qIJCc4pGG5?@;K;xS;M`o{ZKC!YM0P?}-)c^nh literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/filesystem/archive-large.zip b/tests/phpunit/data/filesystem/archive-large.zip new file mode 100644 index 0000000000000000000000000000000000000000..57c1635fdfa8ef17c4eba90e5876c080291bb511 GIT binary patch literal 5210464 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 literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/filesystem/archive-ubuntu-nautilus.zip b/tests/phpunit/data/filesystem/archive-ubuntu-nautilus.zip new file mode 100644 index 0000000000000000000000000000000000000000..a1d65d1771aa633347e55a5ba83355cfb6846ae7 GIT binary patch literal 798 zcmWIWW@Zs#0D*@&P7z=Rl#pOhU`Q-V&d4lF)y+#REy>I&E!Isc%Fj;C(+>^dWnd4x zvL`hbh(UB|1vdjD%L`@(1~3r-HkE^c1JzU}1_on1rsA+ouOOoUZXw7rEEdL2yzR$i zDA4x)yXG-%K2F^?LW@>+HfCIDk!V`}`jYI8wq0xAPI2vhpC_KgP`L zQsaDICj8=%Py5tW4+8fj^Chc$Z#`JSy`hh{L7OXt;QF(<&gTe(3o2Ldzn%=YTg?O&1iFtlEhikS-(i*Xr zcPq+Y1ztCe4owta_nmp(`Ze#C8uo1yag?*~Is7(EaD^&|=Hi??{(`b9Fa4(-$@;zK zz|vJ4GPWO^y!_^mpZl)9JW$T`F+t__+|y6gJ?j_)yxBQYx){8?7=h^k7-0e4j7%cT zxRVGh$^3N$v2a8o5eWuj3oOYXy8x7AVBl?I7#>@2*iK9W3h-uS16jfZgwKJrBGBs$ F3;>DiBq;y@ literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/filesystem/archive-uncompressed.zip b/tests/phpunit/data/filesystem/archive-uncompressed.zip new file mode 100644 index 0000000000000000000000000000000000000000..2d3626d6b6ff0c66cc7d57625270cd85bdb96293 GIT binary patch literal 489 zcmWIWW@h1H00Gx14o5HpO0Y14%1JGB6u9D+Sa7acKoN10%~fMg|5Jkg@<2 z-G-WN7ny;gAS?>iotBxC>X}!ZnUd;~S)^A|Q35v(WF(q#CPrKc6TN}%dB4<0gb!#M z2y*~U1epdm#1?1(2%{O2m!FcVmsPA#l%Jek3^b3CNsbwp4<&%+f`9E6; J=?5SV0|5AfQn~;D literal 0 HcmV?d00001 diff --git a/tests/phpunit/data/filesystem/archive.crx b/tests/phpunit/data/filesystem/archive.crx new file mode 100644 index 0000000000000000000000000000000000000000..c07b21c6c11446a4f845d834c9600d122d3b624f GIT binary patch literal 2202 zcmaKtcT`hZ8o*yj=yg^|a1@Xr5Q>2S8j7G0Aap@dq#K&TQY3~oG?6MYN*Sq%fFL2L zAz%QNh$AXQkS0<@r3elvgkBW{=4G6n-81X#JLmiEz3<%bckdtH`CS}QM~@Ex02K(B zz|c;BAhpE>gw<25Qr5&F5C}g2O@K)9{)_M>Kp;TZHsqG#kaWIbY*KAeSvRcG%#sY7 z7bj4$ie(y=bwcMFb*iWI=61e0i=?O;hBP=Q-V8s*s=g-GzEL3H8;O?@R;NPi3a^Mc zR4LjRB;6BiUSBvb)rnKSRkga%7caqdk6u5nF>d2EXL+mvDI#>~x#6N&(L2!^P_)*KQwYBn~J#(r)igHOF6|KRSzrYKc1G>F4*k0jNk=N61RTR51>|V9g8Zs;O8>>2^Chk--X^EEO2BNVL z7Kda`DHilut4Ic?s(97wLPrgR+f3ScpJ)UEk$ z4Y6K!O70Tkj;g+hkPEp_l{l$sf;jdBSMF#Fg^7R-0{|9oLZ-h@{zx!jH{cgY)H?1g z3_vl7NXO4$M36-R2y7K>FBoszw`yM3@v1RuDcw+T&I_48ssjRp{jEdK1^W4$2NKaF zGU-no^M7%AIwCxxG{6T40W^>pHABz444#w^UQq}n@@RiT#z6ot{&FYJ6Yk7+`eK`1 z>JNZt(Wr9S8;y41@uizCenUxeu8Vz2++y4mVT3Ovi^H-iLhKlu=pQLKTDv{|Zl*YY z&>`kmb`Lz(F1tSSji+l1C$n%Lv)4S}Lt@SN{GN~XjAa*{ovN$Gp;@b+Jkisr-ctx- zPCDJ1xffS7hqln^?>D9%e)1;gLhEGo3TmB1utj603f3zmRB6>QQ3Xx=Kd>8(N^Vk~ zU&{zuO(q}mcsn2ywRdT(<0U76eqJx1CJ~b3vW_h`S`!{GPqy*N-flD|R(J>I8i*UV zOq@cTh_dDQBSidFo1+j4GW@mu(?vm9)C0reZtArB*5}c7$xAlg9%p5@hMa$@*Ddh7 zb7D&LsUTFy8IgliKkNEL(T%3ooz};ybxr>zW#$6g@ae>pZ%|8u7 zE2#aOHgT_mA(+P=e6|lGVYtbi(9lf6WNJMdmg;jOVRRv)Vt7}S{cQicnM?27HcImz zgg5za3#UGd%s7Jn(4Jr@^M1$Hn2F^>vm7Cj={(b9+s_R(F~0K?HX{i!vnUk5#-?U= zkoBU)!()MnGi9w;esRlUwg|pIa}lCt_fm4UnD(p$vvhl_qB*WvGdro~CeQG3x zs0Lz1=66vhQ2-`idwx?bDb;%feK51qy4oNt>in$*{>OUyGMHGGNxZh+Ivqv7NguSM z-!Wj;^mxnb|4WG!Y`&?5<_HgcYC-y??a{S)0pM4(IOJE98gzb%!h&qCJQjMEqDD_P zzu%UOms3?~%X4SytO&8A46Pl!bi=g!lC{av^{TjMDeCix^ij18eW}cnr2F*NtDHNc z0(F`M)HWU^Ew(Y)PFtO$*aj2C6cEa5*UypRB2E)=y)hT}biUbdW$xZV@aZV>_40|M zRXOc&?5nQTWYOU*E)f5$-7{^3_dOnckA@HKioR`cU^VbGpgQLjDzh}j)c;^ox_9?$ zV&ec4tz_Q&ph%&SM8cX&BpN@kqLg&ae$u@_K+htt8A+GbCoV?_vjoP=B<+{a7zI6j zY#%WYLe9PE@2XU8J_^mJly+Zbja?W5$lZGx_*|L0c*U?M8jkVP?M>7QT+6LE?H)5z z!7rLu>nWD{4#Ro2i$|%}hV~PkM;Y<`*B72op7K%vG`H5mCg1&7Wt;NLpqg=vpkBBl z`@(^;>gwJ+i)f@LsVNj2(l8>J@5SLtJiRY#LF#$suGK%AtGnd5Ju9xSIaSFoI;7+E z@!V^yn)pImX@nL@%jSB~))a=(TJkVDlqUa!`ZfP3M!ROi%K2nTt-Q3hr?hfVWwQ+mCkk2(9PU?u{epY)iIwFaCvFe9?htz-MH~d1H&z9ev z$~o^9wheW(h49Hk|4y#5pd@*p6fpCe4}}){fpB6P5QoQzmY&C17-0hVCIp& oquu|9{yXFTH#!qU|Hr=|?K|#uwB;87w}CGJ6j%aBcYfaLHassertSame( $expected, wp_zip_file_is_valid( $zip_file ), "Expected archive to be {$expected_message}." ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_zip_file_validity() { + return array( + 'standard zip' => array( 'archive.zip', true ), + 'large zip' => array( 'archive-large.zip', true ), + 'commented zip' => array( 'archive-comment.zip', true ), + 'cp866 zip' => array( 'archive-cp866.zip', true ), + 'directory entry zip' => array( 'archive-directory-entry.zip', true ), + 'encrypted zip' => array( 'archive-encrypted.zip', true ), + 'flags-set zip' => array( 'archive-flags-set.zip', true ), + 'uncompressed zip' => array( 'archive-uncompressed.zip', true ), + 'crx zip' => array( 'archive.crx', true ), + 'macos generated zip' => array( 'archive-macos.zip', true ), + 'gnome generated zip' => array( 'archive-gnome.zip', true ), + 'ubuntu nautilus zip' => array( 'archive-ubuntu-nautilus.zip', true ), + + 'invalid zip file' => array( 'archive-invalid.zip', false ), + 'invalid file extension' => array( 'archive-invalid-ext.md', false ), + 'non-existent file' => array( 'archive-non-existent.zip', false ), + ); + } +}