Files

196 lines
7.0 KiB
PHP

<?php
declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests\Shared;
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
use PhpOffice\PhpSpreadsheet\Shared\OLE;
use PHPUnit\Framework\TestCase;
class OLETest extends TestCase
{
public function testReadNotOle(): void
{
$this->expectException(ReaderException::class);
$this->expectExceptionMessage('File doesn\'t seem to be an OLE container.');
$ole = new OLE();
$ole->read(__FILE__);
}
public function testReadNotExist(): void
{
$this->expectException(ReaderException::class);
$this->expectExceptionMessage('Can\'t open file');
$ole = new OLE();
$ole->read(__FILE__ . '.xxx');
}
public function testReadOleStreams(): void
{
$dataDir = 'tests/data/Shared/OLERead/';
$ole = new OLE();
$oleData = $ole->read('tests/data/Reader/XLS/sample.xls');
self::assertEquals(
file_get_contents($dataDir . 'wrkbook'),
$oleData
);
self::assertSame(512, $ole->bigBlockSize);
self::assertSame(64, $ole->smallBlockSize);
self::assertSame(4096, $ole->bigBlockThreshold);
self::assertSame(1024, $ole->getBlockOffset(1));
}
// testChainedWriteMode moved to OLEPhpunit10Test
// testChainedBadPath moved to OLEPhpunit10Test
public function testOleFunctions(): void
{
$ole = new OLE();
$infile = 'tests/data/Reader/XLS/pr.4687.excel.xls';
$ole->read($infile);
self::assertSame(4, $ole->ppsTotal());
self::assertFalse($ole->isFile(0), 'root entry');
self::assertTrue($ole->isFile(1), 'workbook');
self::assertTrue($ole->isFile(2), 'summary information');
self::assertTrue($ole->isFile(3), 'document summary information');
self::assertFalse($ole->isFile(4), 'no such index');
self::assertTrue($ole->isRoot(0), 'root entry');
self::assertFalse($ole->isRoot(1), 'workbook');
self::assertFalse($ole->isRoot(2), 'summary information');
self::assertFalse($ole->isRoot(3), 'document summary information');
self::assertFalse($ole->isRoot(4), 'no such index');
self::assertSame(0, $ole->getDataLength(0), 'root entry');
self::assertSame(15712, $ole->getDataLength(1), 'workbook');
self::assertSame(4096, $ole->getDataLength(2), 'summary information');
self::assertSame(4096, $ole->getDataLength(3), 'document summary information');
self::assertSame(0, $ole->getDataLength(4), 'no such index');
self::assertSame('', $ole->getData(2, -1, 4), 'negative position');
self::assertSame('', $ole->getData(2, 5000, 4), 'position > length');
self::assertSame('feff0000', bin2hex($ole->getData(2, 0, 4)));
self::assertSame('', $ole->getData(4, 0, 4), 'no such index');
self::assertTrue($ole->hasDataByName('Workbook'));
self::assertFalse($ole->hasDataByName('Missing'));
}
public function testBadEndian(): void
{
$this->expectException(ReaderException::class);
$this->expectExceptionMessage('Only Little-Endian encoding is supported');
$ole = new OLE();
$infile = 'tests/data/Reader/XLS/pr.4687.excel.badendian.xls';
$ole->read($infile);
}
public function testReadAgileEncryptionStreams(): void
{
$ole = new OLE();
$ole->read('tests/data/Reader/XLSX/agile-encrypted-excel.xlsx');
// Fixture generated by Microsoft Excel 16.111.2; password-to-open: open.
// The encrypted workbook contains A1 = 'agile encryption fixture' and B1 = 42.
$encryptionInfo = $ole->getDataByName('EncryptionInfo');
self::assertSame('0400040040000000', bin2hex(substr($encryptionInfo, 0, 8)));
$encryptedPackage = $ole->getDataByName('EncryptedPackage');
self::assertSame(6280, strlen($encryptedPackage));
$output = tmpfile();
self::assertNotFalse($output);
try {
$ole->copyDataByName('EncryptedPackage', $output);
rewind($output);
self::assertSame($encryptedPackage, stream_get_contents($output));
} finally {
fclose($output);
}
$output = tmpfile();
self::assertNotFalse($output);
try {
$ole->copyDataByName('EncryptionInfo', $output);
rewind($output);
self::assertSame($encryptionInfo, stream_get_contents($output));
} finally {
fclose($output);
}
}
public function testNamedStreamMustExist(): void
{
$ole = new OLE();
$ole->read('tests/data/Reader/XLSX/agile-encrypted-excel.xlsx');
$this->expectException(ReaderException::class);
$this->expectExceptionMessage("OLE stream 'Missing' was not found.");
$ole->getDataByName('Missing');
}
public function testCopyNamedStreamMustExist(): void
{
$ole = new OLE();
$ole->read('tests/data/Reader/XLSX/agile-encrypted-excel.xlsx');
$output = tmpfile();
self::assertNotFalse($output);
try {
$this->expectException(ReaderException::class);
$this->expectExceptionMessage("OLE stream 'Missing' was not found.");
$ole->copyDataByName('Missing', $output);
} finally {
fclose($output);
}
}
public function testCopyNamedStreamRejectsCyclicBigBlockChain(): void
{
$ole = new OLE();
$ole->read('tests/data/Reader/XLSX/agile-encrypted-excel.xlsx');
$encryptedPackage = null;
foreach ($ole->_list as $pps) {
if ($pps->Name === 'EncryptedPackage') {
$encryptedPackage = $pps;
break;
}
}
self::assertNotNull($encryptedPackage);
$ole->bbat[$encryptedPackage->startBlock] = $encryptedPackage->startBlock;
$output = tmpfile();
self::assertNotFalse($output);
try {
$this->expectException(ReaderException::class);
$this->expectExceptionMessage("Invalid OLE stream 'EncryptedPackage'.");
$ole->copyDataByName('EncryptedPackage', $output);
} finally {
fclose($output);
}
}
public function testCopyNamedStreamRejectsDanglingBigBlockChain(): void
{
$ole = new OLE();
$ole->read('tests/data/Reader/XLSX/agile-encrypted-excel.xlsx');
$encryptedPackage = null;
foreach ($ole->_list as $pps) {
if ($pps->Name === 'EncryptedPackage') {
$encryptedPackage = $pps;
break;
}
}
self::assertNotNull($encryptedPackage);
unset($ole->bbat[$encryptedPackage->startBlock]);
$output = tmpfile();
self::assertNotFalse($output);
try {
$this->expectException(ReaderException::class);
$this->expectExceptionMessage("Invalid OLE stream 'EncryptedPackage'.");
$ole->copyDataByName('EncryptedPackage', $output);
} finally {
fclose($output);
}
}
}