From 4cd1d7039d1db8e4994a28eb7f7a6566dbb3b7d2 Mon Sep 17 00:00:00 2001 From: andres1gb Date: Mon, 18 Apr 2022 15:54:41 +0200 Subject: [PATCH] Fix reading of files in the root of a zip (#2731) * Fix reading of files in the root of a zip Xlsx.php relies in dirname($filename) for path generation. When path is a bare filename (i.e. files in the root of the zip file), dirname($filename) returns a relative path to the current directory ("."). This is ok for filesystems, but not when accesing contents in a zip file. Xlsx documents with files in the root of the zip container are not common, but legit. I've found it to happen in files generated by Google Campaign Manager 360. * Update Xlsx.php * Update Xlsx.php * Update CHANGELOG.md * Add files via upload * Create XlsxRootZipFilesTest.php * Update XlsxRootZipFilesTest.php * Add files via upload * Delete rootZipFiles.xlsx * Update XlsxRootZipFilesTest.php * Update Xlsx.php --- CHANGELOG.md | 2 +- src/PhpSpreadsheet/Reader/Xlsx.php | 3 +++ .../Reader/Xlsx/XlsxRootZipFilesTest.php | 24 ++++++++++++++++++ tests/data/Reader/XLSX/rootZipFiles.xlsx | Bin 0 -> 3363 bytes 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/PhpSpreadsheetTests/Reader/Xlsx/XlsxRootZipFilesTest.php create mode 100644 tests/data/Reader/XLSX/rootZipFiles.xlsx diff --git a/CHANGELOG.md b/CHANGELOG.md index e136eab6..d5ef98a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,9 +82,9 @@ and this project adheres to [Semantic Versioning](https://semver.org). Nor is this a perfect solution, as there may still be issues when function calls have array arguments that themselves contain function calls; but it's still better than the current logic. - Fix for escaping double quotes within a formula [Issue #1971](https://github.com/PHPOffice/PhpSpreadsheet/issues/1971) [PR #2651](https://github.com/PHPOffice/PhpSpreadsheet/pull/2651) +- Fix for reading files in the root directory of a ZipFile, which should not be prefixed by relative paths ("./") as dirname($filename) does by default. - Fix invalid style of cells in empty columns with columnDimensions and rows with rowDimensions in added external sheet. [PR #2739](https://github.com/PHPOffice/PhpSpreadsheet/pull/2739) - ## 1.22.0 - 2022-02-18 ### Added diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 18ed7987..a6e7fe03 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -368,6 +368,9 @@ class Xlsx extends BaseReader if (strpos($fileName, '//') !== false) { $fileName = substr($fileName, strpos($fileName, '//') + 1); } + // Relative paths generated by dirname($filename) when $filename + // has no path (i.e.files in root of the zip archive) + $fileName = (string) preg_replace('/^\.\//', '', $fileName); $fileName = File::realpath($fileName); // Sadly, some 3rd party xlsx generators don't use consistent case for filenaming diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/XlsxRootZipFilesTest.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/XlsxRootZipFilesTest.php new file mode 100644 index 00000000..110c70b0 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/XlsxRootZipFilesTest.php @@ -0,0 +1,24 @@ +load($filename); + $sheet = $spreadsheet->getActiveSheet(); + $value = $sheet->getCell('A1')->getValue(); + self::assertSame('TEST CELL', $value->getPlainText()); + } +} diff --git a/tests/data/Reader/XLSX/rootZipFiles.xlsx b/tests/data/Reader/XLSX/rootZipFiles.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..3de12790b6c7d3b026306170d2d04e83677e576a GIT binary patch literal 3363 zcmb7`c|2787soGyVQizU{gP<18`~&Jzid%yY|UgT>liA=Hj}cXWN)bOO0uPeBFZS0 zEsY7;X-uIc%Y?F2h({0o?(h_%dVY6acV74Yao(@<{hV_@=UA9RID`QJ;08Xx$e2=S zrZbEU0K(V-U@fp7IB4kYMZ$ZL95Detc%nV>1i=%F;Q=7;-S)eT!Z9w#PVfS39Ft(g zJS0D%+zg@)5C5tg!4yrGl!qG>n+hEcJtJl_T%IQKt+te>_+icQZI&%YyK|I1+~1`Z zm33rk5g&RVUo;s_l~ah8w)?2yqGW<79yy>Sz2yqdcnw1;=OTm{ z@*<_-G~4d1Sc=&UhTW$;sl3Tapul9dz+vanL>XLvzuw8uQ7HY?wn7#&IOPT1fMU&m=66;c3NEN-`S4&2D*V|n2Jxt z1}g8V>jQ#qvw#ICD-4ts0J4veG4l`q{BeP@I{M)~iK_ET?&in1K!jE($%B7fQWoYJ9t%DJc2?Wc67UWBh&C_sg)(UR39HoYNb<8-Yi`pRzBif zFrTNhbLh!ZI|+IjMNUOa;wB>7=ZuXwmacj2QM`MCqO1UuUZb0slnmY1Z-!FydLKys zE1r!&odZ&73Dc_W?Nf<;mj;_Op|cU^UM8DsXecE^n4t{zH-EphE!dQm>q9N`7yazZ zKV7l+8d)_gWajmFRKxY^?8B&O!sr*tw%Hl|4mr1c_FDI48?o`@q%Zc|j^B z`ld$&Hqb&P#xP|=#8*^7^e|WC(V_{#dNkdmq##31qbKU|k&T$TB4Gq_I1)O3!APjb z&XiQY!_cz7_d``L|MFA2G|j{pf+r4v0)PN`Y9cAX6Hh#h$CLi_m5yL*y(-n<OvwW;zcrv=q z?`WWvI$ONW`!qYXV+OI$V~wjr{mi)Z)ezenIWhogi)t&Iuq}Q{p3%^tu{Y*+2MDK& zWfRpEPBPq%7RHW4I?_$JLIm&JD%wZpJkdH=rYL*}`y|4*c7(0TST03$mfFSSF#fDu ziOvp_CDvvc>)1wVb7#0Wk5?67KH7wsc{|+crU$JnW@K3tCTko_CH2Lw45lmgVxQW+ zMy+kvF@2sy+sjP#IFjFBFG9$rH{4oJhQAW-oJrj0E{xia!?Kz57-~&k4T<6J3m&p^ z?4uDUQU}_r1U|?GXbbvvN21*O-G(>&-H2AKB1hyQ6hFkf$2_w=D02G#m+QyTjI$$k z9M<(nFAB}%*l<{itL`ZE}361N=*UfpO!v#=sMXZ3m41fTNxXvwOuOR zGRzcTU_R4H)p6RS`Px0R^l{nFc4F1mi>HoZ=Ol_B-=l2VD#+4i!D(}Ta#{$e%?Zy1 zn>G8B&9Z_I1`IxZ4GPO4z91|Zj5ONsxS!W=OulY5(+rCJQ^u@fip)3C-HBeID+z<;F1h28?L(bW>(wc@IX z`&GBzwd3Nj$0T!0{o9I9rdc>eH4;M}J9>%jq7)^q<&h4DUlUQz@5p@B3^xdto}76* zq<5*cdVnYWzfA2;dMNUGT;CdR1< zndqR<^fqC1EDhn6*>&$lOLTDN)4bvCW);rBy>Eg-n*FVis&A;OS)RC-Xe(* zlliIP>&>m<4YH`}D!p~zH#!% zx;}Hi44qGQtnHe-!^N#zoHhp}XmfWbl>~3j7M>Uhanb$q_I9g{6E?S0xBUEQ;ki*E z1W-0|-00&wjkI*aBgV8<<~o)4J;e{^P@ba_3jP-Y2jYf^LGKJJ``JXf^IEywA%tz{ zx*IL;6ok**?g}goV+7t)5UFRkl7{Rnyof4O*&=C#Fdx!W@3g`N&-gybS?X4B&s4 z7OEf4GMe+@IU AjsO4v literal 0 HcmV?d00001