Bug #21243 [Com]: small blocks ("mini stream") handling is broken
Edit report at https://pear.php.net/bugs/bug.php?id=21243&edit=1
ID: 21243
Comment by: tacituseu at gmail dot com
Reported By: tacituseu at gmail dot com
Summary: small blocks ("mini stream") handling is broken
Status: Open
Type: Bug
Package: OLE
Operating System: Any
Package Version: 1.0.0RC3
PHP Version: Irrelevant
Roadmap Versions:
New Comment:
2.1.
$pos = $rootPos + $blockId * $this->ole->bigBlockSize;
should be:
$pos = $rootPos + $blockId * $this->ole->smallBlockSize;
Previous Comments:
------------------------------------------------------------------------
[2017-09-26 11:12:16] tacituseu
Description:
------------
In OLE\ChainedBlockStream.php::stream_open() there is this:
if (isset($this->params['size']) && $this->params['size'] <
$this->ole-
>bigBlockThreshold && $blockId != $this->ole->root->startBlock) {
// Block id refers to small blocks
$rootPos = $this->ole->_getBlockOffset($this->ole->root-
>startBlock);
while ($blockId != -2) {
$pos = $rootPos + $blockId * $this->ole-
>bigBlockSize;
$blockId = $this->ole->sbat[$blockId];
fseek($this->ole->_file_handle, $pos);
$this->data .= fread($this->ole->_file_handle,
$this->ole->bigBlockSize);
}
}
Problems:
1. small blocks ([MS-CFB].pdf: "mini stream") isn't a continuous space,
but a stream itself:
$rootPos = $this->ole->_getBlockOffset($this->ole->root->startBlock);
will work only for simple documents that don't contain entries with size
larger than $this->ole->bigBlockThreshold
what you want is in OLE.php::_readPpsWks():
$this->_list[] = $pps;
if ($type == OLE_PPS_TYPE_ROOT) {
$this->_small_handle = $this->getStream($pps->startBlock);
}
and then use it in point 2
Reference: [MS-CFB].pdf 2.6.1 Root Directory Entry
2. wrong block size used for fread
fread($this->ole->_file_handle, $this->ole->bigBlockSize);
should be:
fread($this->ole->_small_handle, $this->ole->smallBlockSize);
Test script:
---------------
$obj = new OLE();
$obj->read('ole.xls');
foreach ($obj->_list as $idx => $pps) if ($obj->isFile($idx)) {
$dlen = $olz->getDataLength($idx);
$data = $olz->getData($idx, 0, $dlen);
var_dump($data);
}
Expected result:
----------------
data corresponding to given entry
Actual result:
--------------
data corresponding to given entry for some entries (up to first big
block entry
which breaks assumption of continuity for small stream)
------------------------------------------------------------------------
--
Edit this bug report at https://pear.php.net/bugs/bug.php?id=21243&edit=1
Thread (1 message)