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 [email protected] 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


Thread (1 message)

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