Read xlsx files with exotic workbook names like "workbook2.xml"

Some auto generated xlsx files are using other names as workbook than "workbook.xml".
This is fixed by supporting names of workbooks by regex `/workbook.*\.xml/`.

Closes #1183
This commit is contained in:
Robert Doering 2019-10-01 15:52:15 +02:00 committed by Adrien Crivelli
parent e5409f0fed
commit 6a2e0cef43
No known key found for this signature in database
GPG Key ID: B182FD79DC6DE92E
2 changed files with 43 additions and 24 deletions

View File

@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Fix ODS Reader when no DC namespace are defined [#1182](https://github.com/PHPOffice/PhpSpreadsheet/pull/1182) - Fix ODS Reader when no DC namespace are defined [#1182](https://github.com/PHPOffice/PhpSpreadsheet/pull/1182)
- Fixed Functions->ifCondition for allowing <> and empty condition [#1206](https://github.com/PHPOffice/PhpSpreadsheet/pull/1206) - Fixed Functions->ifCondition for allowing <> and empty condition [#1206](https://github.com/PHPOffice/PhpSpreadsheet/pull/1206)
- Validate XIRR inputs and return correct error values [#1120](https://github.com/PHPOffice/PhpSpreadsheet/issues/1120) - Validate XIRR inputs and return correct error values [#1120](https://github.com/PHPOffice/PhpSpreadsheet/issues/1120)
- Allow to read xlsx files with exotic workbook names like "workbook2.xml" [#1183](https://github.com/PHPOffice/PhpSpreadsheet/pull/1183)
## [1.9.0] - 2019-08-17 ## [1.9.0] - 2019-08-17

View File

@ -77,34 +77,17 @@ class Xlsx extends BaseReader
{ {
File::assertFile($pFilename); File::assertFile($pFilename);
$xl = false; $result = false;
// Load file
$zip = new ZipArchive(); $zip = new ZipArchive();
if ($zip->open($pFilename) === true) {
// check if it is an OOXML archive
$rels = simplexml_load_string(
$this->securityScanner->scan(
$this->getFromZipArchive($zip, '_rels/.rels')
),
'SimpleXMLElement',
Settings::getLibXmlLoaderOptions()
);
if ($rels !== false) {
foreach ($rels->Relationship as $rel) {
switch ($rel['Type']) {
case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument':
if (basename($rel['Target']) == 'workbook.xml') {
$xl = true;
}
break; if ($zip->open($pFilename) === true) {
} $workbookBasename = $this->getWorkbookBaseName($zip);
} $result = !empty($workbookBasename);
}
$zip->close(); $zip->close();
} }
return $xl; return $result;
} }
/** /**
@ -357,8 +340,9 @@ class Xlsx extends BaseReader
// Read the theme first, because we need the colour scheme when reading the styles // Read the theme first, because we need the colour scheme when reading the styles
//~ http://schemas.openxmlformats.org/package/2006/relationships" //~ http://schemas.openxmlformats.org/package/2006/relationships"
$workbookBasename = $this->getWorkbookBaseName($zip);
$wbRels = simplexml_load_string( $wbRels = simplexml_load_string(
$this->securityScanner->scan($this->getFromZipArchive($zip, 'xl/_rels/workbook.xml.rels')), $this->securityScanner->scan($this->getFromZipArchive($zip, "xl/_rels/${workbookBasename}.rels")),
'SimpleXMLElement', 'SimpleXMLElement',
Settings::getLibXmlLoaderOptions() Settings::getLibXmlLoaderOptions()
); );
@ -2026,4 +2010,38 @@ class Xlsx extends BaseReader
return (bool) $xsdBoolean; return (bool) $xsdBoolean;
} }
/**
* @param ZipArchive $zip Opened zip archive
*
* @return string basename of the used excel workbook
*/
private function getWorkbookBaseName(ZipArchive $zip)
{
$workbookBasename = '';
// check if it is an OOXML archive
$rels = simplexml_load_string(
$this->securityScanner->scan(
$this->getFromZipArchive($zip, '_rels/.rels')
),
'SimpleXMLElement',
Settings::getLibXmlLoaderOptions()
);
if ($rels !== false) {
foreach ($rels->Relationship as $rel) {
switch ($rel['Type']) {
case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument':
$basename = basename($rel['Target']);
if (preg_match('/workbook.*\.xml/', $basename)) {
$workbookBasename = $basename;
}
break;
}
}
}
return $workbookBasename;
}
} }