Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Missing support for exotic names of excel-workbooks like "workbook2.xml" #1183

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Formula Parser: Wrong line count for stuff like "MyOtherSheet!A:D" [#1215](https://github.com/PHPOffice/PhpSpreadsheet/issues/1215)
- Call garbage collector after removing a column to prevent stale cached values
- Trying to remove a column that doesn't exist deletes the latest column
- Allow to read xlsx files with exotic workbook names like "workbook2.xml".

## [1.9.0] - 2019-08-17

Expand Down
63 changes: 40 additions & 23 deletions src/PhpSpreadsheet/Reader/Xlsx.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,34 +77,17 @@ public function canRead($pFilename)
{
File::assertFile($pFilename);

$xl = false;
// Load file
$result = false;
$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;
}
$workbookBasename = $this->getWorkbookBaseName($zip);
$result = !empty($workbookBasename);

break;
}
}
}
$zip->close();
}

return $xl;
return $result;
}

/**
Expand Down Expand Up @@ -357,8 +340,9 @@ public function load($pFilename)

// Read the theme first, because we need the colour scheme when reading the styles
//~ http://schemas.openxmlformats.org/package/2006/relationships"
$workbookBasename = $this->getWorkbookBaseName($zip);
$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',
Settings::getLibXmlLoaderOptions()
);
Expand Down Expand Up @@ -2026,4 +2010,37 @@ private function castXsdBooleanToBool($xsdBoolean)

return (bool) $xsdBoolean;
}

/**
* @param ZipArchive $zip Opened zip archive
* @return string basename of the used excel workbook
* @throws Exception
*/
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;
}
}