Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 1.0.0RC3

Bug #21243 small blocks ("mini stream") handling is broken
Submitted: 2017-09-26 15:12 UTC
From: tacituseu Assigned:
Status: Open Package: OLE (version 1.0.0RC3)
PHP Version: Irrelevant OS: Any
Roadmaps: (Not assigned)    
Subscription  


 [2017-09-26 15:12 UTC] tacituseu (No Pe)
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)

Comments

 [2017-09-26 15:31 UTC] tacituseu (No Pe)
2.1. $pos = $rootPos + $blockId * $this->ole->bigBlockSize; should be: $pos = $rootPos + $blockId * $this->ole->smallBlockSize;
 [2017-09-26 15:33 UTC] tacituseu (No Pe)
actually it should be: $pos = $blockId * $this->ole->smallBlockSize;
 [2018-07-17 06:15 UTC] hfig (hfig hfig)
Fix submitted as a PR - https://github.com/pear/OLE/pull/10
 [2018-10-23 09:16 UTC] sanmai (Alexey Kopytko)
Hello, may I ask you to provide that ole.xls example you used? The simpler, the better. I'm going to integrate it to our test suite. Thanks.