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); } } }