Bug #21243 [Com]: small blocks ("mini stream") handling is broken

From: Date: Tue, 26 Sep 2017 15:31:12 +0000
Subject: Bug #21243 [Com]: small blocks ("mini stream") handling is broken
References: 1  Groups: php.pear.bugs 
Request: Send a blank email to pear-bugs+get-11401@lists.php.net to get a copy of this message
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

« previous php.pear.bugs (#11401) next »