1<?php 2/** 3 * This file is part of FPDI 4 * 5 * @package setasign\Fpdi 6 * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com) 7 * @license http://opensource.org/licenses/mit-license The MIT License 8 */ 9 10namespace setasign\Fpdi\PdfParser\Filter; 11 12/** 13 * Class for handling zlib/deflate encoded data 14 * 15 * @package setasign\Fpdi\PdfParser\Filter 16 */ 17class Flate implements FilterInterface 18{ 19 /** 20 * Checks whether the zlib extension is loaded. 21 * 22 * Used for testing purpose. 23 * 24 * @return boolean 25 * @internal 26 */ 27 protected function extensionLoaded() 28 { 29 return \extension_loaded('zlib'); 30 } 31 32 /** 33 * Decodes a flate compressed string. 34 * 35 * @param string $data The input string 36 * @return string 37 * @throws FlateException 38 */ 39 public function decode($data) 40 { 41 if ($this->extensionLoaded()) { 42 $oData = $data; 43 $data = @((\strlen($data) > 0) ? \gzuncompress($data) : ''); 44 if ($data === false) { 45 // let's try if the checksum is CRC32 46 $fh = fopen('php://temp', 'w+b'); 47 fwrite($fh, "\x1f\x8b\x08\x00\x00\x00\x00\x00" . $oData); 48 stream_filter_append($fh, 'zlib.inflate', STREAM_FILTER_READ, ['window' => 30]); 49 fseek($fh, 0); 50 $data = stream_get_contents($fh); 51 fclose($fh); 52 53 if ($data) { 54 return $data; 55 } 56 57 // Try this fallback 58 $tries = 0; 59 60 $oDataLen = strlen($oData); 61 while ($tries < 6 && ($data === false || (strlen($data) < (strlen($oDataLen) - $tries - 1)))) { 62 $data = @(gzinflate(substr($oData, $tries))); 63 $tries++; 64 } 65 66 // let's use this fallback only if the $data is longer than the original data 67 if (strlen($data) > ($oDataLen - $tries - 1)) { 68 return $data; 69 } 70 71 if (!$data) { 72 throw new FlateException( 73 'Error while decompressing stream.', 74 FlateException::DECOMPRESS_ERROR 75 ); 76 } 77 } 78 } else { 79 throw new FlateException( 80 'To handle FlateDecode filter, enable zlib support in PHP.', 81 FlateException::NO_ZLIB 82 ); 83 } 84 85 return $data; 86 } 87} 88