Commit adbebb3b authored by jun's avatar jun

Merge branch 'MDL-70312' of git://github.com/paulholden/moodle

parents a2ab10fc a2a410fe
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -13,10 +14,8 @@ namespace setasign\Fpdi;
* Class FpdfTpl
*
* This class adds a templating feature to FPDF.
*
* @package setasign\Fpdi
*/
class FpdfTpl extends \Fpdf
class FpdfTpl extends \FPDF
{
use FpdfTplTrait;
}
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -13,8 +14,6 @@ namespace setasign\Fpdi;
* Trait FpdfTplTrait
*
* This class adds a templating feature to tFPDF.
*
* @package setasign\Fpdi
*/
trait FpdfTplTrait
{
......@@ -61,7 +60,8 @@ trait FpdfTplTrait
$size = $this->_getpagesize($size);
if ($orientation != $this->CurOrientation
if (
$orientation != $this->CurOrientation
|| $size[0] != $this->CurPageSize[0]
|| $size[1] != $this->CurPageSize[1]
) {
......@@ -109,7 +109,7 @@ trait FpdfTplTrait
unset($x['tpl']);
\extract($x, EXTR_IF_EXISTS);
/** @noinspection NotOptimalIfConditionsInspection */
/** @noinspection CallableParameterUseCaseInTypeContextInspection */
/** @noinspection PhpConditionAlreadyCheckedInspection */
if (\is_array($x)) {
$x = 0;
}
......@@ -266,7 +266,7 @@ trait FpdfTplTrait
*/
public function endTemplate()
{
if (null === $this->currentTemplateId) {
if ($this->currentTemplateId === null) {
return false;
}
......@@ -418,7 +418,11 @@ trait FpdfTplTrait
$this->templates[$key]['objectNumber'] = $this->n;
$this->_put('<</Type /XObject /Subtype /Form /FormType 1');
$this->_put(\sprintf('/BBox[0 0 %.2F %.2F]', $template['width'] * $this->k, $template['height'] * $this->k));
$this->_put(\sprintf(
'/BBox[0 0 %.2F %.2F]',
$template['width'] * $this->k,
$template['height'] * $this->k
));
$this->_put('/Resources 2 0 R'); // default resources dictionary of FPDF
if ($this->compress) {
......@@ -463,4 +467,4 @@ trait FpdfTplTrait
parent::_out($s);
}
}
}
\ No newline at end of file
}
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -18,8 +19,6 @@ use setasign\Fpdi\PdfParser\Type\PdfNull;
* Class Fpdi
*
* This class let you import pages of existing PDF documents into a reusable structure for FPDF.
*
* @package setasign\Fpdi
*/
class Fpdi extends FpdfTpl
{
......@@ -30,7 +29,7 @@ class Fpdi extends FpdfTpl
*
* @string
*/
const VERSION = '2.2.0';
const VERSION = '2.3.5';
protected function _enddoc()
{
......@@ -113,7 +112,6 @@ class Fpdi extends FpdfTpl
while (($objectNumber = \array_pop($this->objectsToCopy[$readerId])) !== null) {
try {
$object = $parser->getIndirectObject($objectNumber);
} catch (CrossReferenceException $e) {
if ($e->getCode() === CrossReferenceException::OBJECT_NOT_FOUND) {
$object = PdfIndirectObject::create($objectNumber, 0, new PdfNull());
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -11,8 +12,6 @@ namespace setasign\Fpdi;
/**
* Base exception class for the FPDI package.
*
* @package setasign\Fpdi
*/
class FpdiException extends \Exception
{
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -41,8 +42,6 @@ use /* This namespace/class is used by the commercial FPDI PDF-Parser add-on. */
*
* This trait offers the core functionalities of FPDI. By passing them to a trait we can reuse it with e.g. TCPDF in a
* very easy way.
*
* @package setasign\Fpdi
*/
trait FpdiTrait
{
......@@ -63,7 +62,7 @@ trait FpdiTrait
/**
* The current reader id.
*
* @var string
* @var string|null
*/
protected $currentReaderId;
......@@ -104,7 +103,7 @@ trait FpdiTrait
unset($this->readers[$id]);
}
$this->createdReaders= [];
$this->createdReaders = [];
}
/**
......@@ -128,6 +127,9 @@ trait FpdiTrait
*/
protected function getPdfParserInstance(StreamReader $streamReader)
{
// note: if you get an exception here - turn off errors/warnings on not found for your autoloader.
// psr-4 (https://www.php-fig.org/psr/psr-4/) says: Autoloader implementations MUST NOT throw
// exceptions, MUST NOT raise errors of any level, and SHOULD NOT return a value.
/** @noinspection PhpUndefinedClassInspection */
if (\class_exists(FpdiPdfParser::class)) {
/** @noinspection PhpUndefinedClassInspection */
......@@ -299,7 +301,7 @@ trait FpdiTrait
if ($rotation !== 0) {
$rotation *= -1;
$angle = $rotation * M_PI/180;
$angle = $rotation * M_PI / 180;
$a = \cos($angle);
$b = \sin($angle);
$c = -$b;
......@@ -336,7 +338,8 @@ trait FpdiTrait
$contents = PdfType::resolve($contentsObject, $reader->getParser());
// just copy the stream reference if it is only a single stream
if (($contentsIsStream = ($contents instanceof PdfStream))
if (
($contentsIsStream = ($contents instanceof PdfStream))
|| ($contents instanceof PdfArray && \count($contents->value) === 1)
) {
if ($contentsIsStream) {
......@@ -494,26 +497,20 @@ trait FpdiTrait
} else {
$this->_put(\rtrim(\rtrim(\sprintf('%.5F', $value->value), '0'), '.') . ' ', false);
}
} elseif ($value instanceof PdfName) {
$this->_put('/' . $value->value . ' ', false);
} elseif ($value instanceof PdfString) {
$this->_put('(' . $value->value . ')', false);
} elseif ($value instanceof PdfHexString) {
$this->_put('<' . $value->value . '>');
} elseif ($value instanceof PdfBoolean) {
$this->_put($value->value ? 'true ' : 'false ', false);
} elseif ($value instanceof PdfArray) {
$this->_put('[', false);
foreach ($value->value as $entry) {
$this->writePdfType($entry);
}
$this->_put(']');
} elseif ($value instanceof PdfDictionary) {
$this->_put('<<', false);
foreach ($value->value as $name => $entry) {
......@@ -521,13 +518,10 @@ trait FpdiTrait
$this->writePdfType($entry);
}
$this->_put('>>');
} elseif ($value instanceof PdfToken) {
$this->_put($value->value);
} elseif ($value instanceof PdfNull) {
$this->_put('null ');
} elseif ($value instanceof PdfStream) {
/**
* @var $value PdfStream
......@@ -536,7 +530,6 @@ trait FpdiTrait
$this->_put('stream');
$this->_put($value->getStream());
$this->_put('endstream');
} elseif ($value instanceof PdfIndirectObjectReference) {
if (!isset($this->objectMap[$this->currentReaderId])) {
$this->objectMap[$this->currentReaderId] = [];
......@@ -548,10 +541,9 @@ trait FpdiTrait
}
$this->_put($this->objectMap[$this->currentReaderId][$value->value] . ' 0 R ', false);
} elseif ($value instanceof PdfIndirectObject) {
/**
* @var $value PdfIndirectObject
* @var PdfIndirectObject $value
*/
$n = $this->objectMap[$this->currentReaderId][$value->objectNumber];
$this->_newobj($n);
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -16,8 +17,6 @@ use setasign\Fpdi\PdfParser\Type\PdfTypeException;
/**
* Abstract class for cross-reference reader classes.
*
* @package setasign\Fpdi\PdfParser\CrossReference
*/
abstract class AbstractReader
{
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -21,8 +22,6 @@ use setasign\Fpdi\PdfParser\Type\PdfTypeException;
* Class CrossReference
*
* This class processes the standard cross reference of a PDF document.
*
* @package setasign\Fpdi\PdfParser\CrossReference
*/
class CrossReference
{
......@@ -31,7 +30,7 @@ class CrossReference
*
* @var int
*/
static public $trailerSearchLength = 5500;
public static $trailerSearchLength = 5500;
/**
* @var int
......@@ -206,7 +205,7 @@ class CrossReference
$this->parser->getStreamReader()->reset($offset);
$this->parser->getTokenizer()->clearStack();
$initValue = $this->parser->readValue();
return $this->initReaderInstance($initValue);
}
......@@ -235,8 +234,15 @@ class CrossReference
}
if ($initValue instanceof PdfIndirectObject) {
// check for encryption
$stream = PdfStream::ensure($initValue->value);
try {
$stream = PdfStream::ensure($initValue->value);
} catch (PdfTypeException $e) {
throw new CrossReferenceException(
'Invalid object type at xref reference offset.',
CrossReferenceException::INVALID_DATA,
$e
);
}
$type = PdfDictionary::get($stream->value, 'Type');
if ($type->value !== 'XRef') {
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -13,8 +14,6 @@ use setasign\Fpdi\PdfParser\PdfParserException;
/**
* Exception used by the CrossReference and Reader classes.
*
* @package setasign\Fpdi\PdfParser\CrossReference
*/
class CrossReferenceException extends PdfParserException
{
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -17,8 +18,6 @@ use setasign\Fpdi\PdfParser\StreamReader;
*
* This reader allows a very less overhead parsing of single entries of the cross-reference, because the main entries
* are only read when needed and not in a single run.
*
* @package setasign\Fpdi\PdfParser\CrossReference
*/
class FixedReader extends AbstractReader implements ReaderInterface
{
......@@ -63,6 +62,10 @@ class FixedReader extends AbstractReader implements ReaderInterface
public function getOffsetFor($objectNumber)
{
foreach ($this->subSections as $offset => list($startObject, $objectCount)) {
/**
* @var int $startObject
* @var int $objectCount
*/
if ($objectNumber >= $startObject && $objectNumber < ($startObject + $objectCount)) {
$position = $offset + 20 * ($objectNumber - $startObject);
$this->reader->ensure($position, 20);
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -17,8 +18,6 @@ use setasign\Fpdi\PdfParser\StreamReader;
*
* This reader class read all cross-reference entries in a single run.
* It supports reading cross-references with e.g. invalid data (e.g. entries with a length < or > 20 bytes).
*
* @package setasign\Fpdi\PdfParser\CrossReference
*/
class LineReader extends AbstractReader implements ReaderInterface
{
......@@ -72,18 +71,16 @@ class LineReader extends AbstractReader implements ReaderInterface
*/
protected function extract(StreamReader $reader)
{
$cycles = -1;
$bytesPerCycle = 100;
$reader->reset(null, $bytesPerCycle);
while (
($trailerPos = \strpos($reader->getBuffer(false), 'trailer', \max($bytesPerCycle * $cycles++, 0))) === false
) {
if ($reader->increaseLength($bytesPerCycle) === false) {
break;
}
}
$cycles = 0;
do {
// 6 = length of "trailer" - 1
$pos = \max(($bytesPerCycle * $cycles) - 6, 0);
$trailerPos = \strpos($reader->getBuffer(false), 'trailer', $pos);
$cycles++;
} while ($trailerPos === false && $reader->increaseLength($bytesPerCycle) !== false);
if ($trailerPos === false) {
throw new CrossReferenceException(
......@@ -127,44 +124,41 @@ class LineReader extends AbstractReader implements ReaderInterface
}
unset($differentLineEndings, $m);
$linesCount = \count($lines);
$start = null;
$entryCount = 0;
if (!\is_array($lines)) {
$this->offsets = [];
return;
}
$start = 0;
$offsets = [];
/** @noinspection ForeachInvariantsInspection */
for ($i = 0; $i < $linesCount; $i++) {
$line = \trim($lines[$i]);
if ($line) {
$pieces = \explode(' ', $line);
$c = \count($pieces);
switch ($c) {
case 2:
$start = (int) $pieces[0];
$entryCount += (int) $pieces[1];
break;
/** @noinspection PhpMissingBreakStatementInspection */
case 3:
switch ($pieces[2]) {
case 'n':
$offsets[$start] = [(int) $pieces[0], (int) $pieces[1]];
$start++;
break 2;
case 'f':
$start++;
break 2;
}
// fall through if pieces doesn't match
default:
throw new CrossReferenceException(
\sprintf('Unexpected data in xref table (%s)', \implode(' ', $pieces)),
CrossReferenceException::INVALID_DATA
);
}
// trim all lines and remove empty lines
$lines = \array_filter(\array_map('\trim', $lines));
foreach ($lines as $line) {
$pieces = \explode(' ', $line);
switch (\count($pieces)) {
case 2:
$start = (int) $pieces[0];
break;
case 3:
switch ($pieces[2]) {
case 'n':
$offsets[$start] = [(int) $pieces[0], (int) $pieces[1]];
$start++;
break 2;
case 'f':
$start++;
break 2;
}
// fall through if pieces doesn't match
default:
throw new CrossReferenceException(
\sprintf('Unexpected data in xref table (%s)', \implode(' ', $pieces)),
CrossReferenceException::INVALID_DATA
);
}
}
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -13,8 +14,6 @@ use setasign\Fpdi\PdfParser\Type\PdfDictionary;
/**
* ReaderInterface for cross-reference readers.
*
* @package setasign\Fpdi\PdfParser\CrossReference
*/
interface ReaderInterface
{
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -11,8 +12,6 @@ namespace setasign\Fpdi\PdfParser\Filter;
/**
* Class for handling ASCII base-85 encoded data
*
* @package setasign\Fpdi\PdfParser\Filter
*/
class Ascii85 implements FilterInterface
{
......@@ -29,6 +28,8 @@ class Ascii85 implements FilterInterface
$state = 0;
$chn = null;
$data = \preg_replace('/\s/', '', $data);
$l = \strlen($data);
/** @noinspection ForeachInvariantsInspection */
......@@ -44,13 +45,12 @@ class Ascii85 implements FilterInterface
if ($ch === 126 && isset($data[$k + 1]) && (\ord($data[$k + 1]) & 0xFF) === 62) {
break;
}
if (\preg_match('/^\s$/', \chr($ch))) {
continue;
}
if ($ch === 122 /* z */ && $state === 0) {
$out .= \chr(0) . \chr(0) . \chr(0) . \chr(0);
continue;
}
if ($ch < 33 /* ! */ || $ch > 117 /* u */) {
throw new Ascii85Exception(
'Illegal character found while ASCII85 decode.',
......@@ -86,12 +86,10 @@ class Ascii85 implements FilterInterface
if ($state === 2) {
$r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1] + 1) * 85 * 85 * 85;
$out .= \chr($r >> 24);
} elseif ($state === 3) {
$r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + ($chn[2] + 1) * 85 * 85;
$out .= \chr($r >> 24);
$out .= \chr($r >> 16);
} elseif ($state === 4) {
$r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + $chn[2] * 85 * 85 + ($chn[3] + 1) * 85;
$out .= \chr($r >> 24);
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -11,8 +12,6 @@ namespace setasign\Fpdi\PdfParser\Filter;
/**
* Exception for Ascii85 filter class
*
* @package setasign\Fpdi\PdfParser\Filter
*/
class Ascii85Exception extends FilterException
{
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -11,8 +12,6 @@ namespace setasign\Fpdi\PdfParser\Filter;
/**
* Class for handling ASCII hexadecimal encoded data
*
* @package setasign\Fpdi\PdfParser\Filter
*/
class AsciiHex implements FilterInterface
{
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -13,8 +14,6 @@ use setasign\Fpdi\PdfParser\PdfParserException;
/**
* Exception for filters
*
* @package setasign\Fpdi\PdfParser\Filter
*/
class FilterException extends PdfParserException
{
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi
* @copyright Copyright (c) 2019 Setasign - Jan Slabon (https://www.setasign.com)
* @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
* @license http://opensource.org/licenses/mit-license The MIT License
*/
......@@ -11,8 +12,6 @@ namespace setasign\Fpdi\PdfParser\Filter;
/**
* Interface for filters
*
* @package setasign\Fpdi\PdfParser\Filter
*/
interface FilterInterface
{
......
<?php
/**
* This file is part of FPDI
*
* @package setasign\Fpdi