Skip to content

Commit

Permalink
Multiple PRs (#755)
Browse files Browse the repository at this point in the history
* Update tcpdf.php

Since the version 6.7.4, the "0" is considered like empty string and not displayed

* Update tcpdf.php

Co-authored-by: William Desportes <williamdes@wdes.fr>

* Fixed handling of transparency in PDF/A mode in addExtGState method

The condition allowed to add ExtGState in all PDF/A modes and disallowed
in default mode.

This fix inlines the condition with setExtGState to allow transparency
parameters for non-PDF/A and PDF/A > 1 documents.

The state condition is copied from 'setExtGState'.

* Encrypt /DA string when document is encrypted

When document is encrypted then /DA string must be encrypted,
without this Acrobat cannot allow fill form fields.

* Improve quality of generated seed, avoid potential security pitfall

* Try to use random_bytes() first if it's available
* Do not include the server parameters in the generated seed, as
they might contain sensitive data

As all current usages of getRandomSeed() directly hash the seed,
there should be no BC breaking changes.

The main source of entropy is more than enough on its own if
random_bytes() or openssl_random_pseudo_bytes() are available.

* Fix bug on _getannotsrefs when there are empty signature appearances but not other annot on a page

* Fix SVG coordinate parser that caused drawing artifacts

* Remove usage of xml_set_object() function

The xml_set_object() function will be deprecated in PHP 8.4 as well as
passing non-callable strings to the xml_set_*_handler() functions.

Instead of using xml_set_object(), the string method names in
xml_set_element_handler() and xml_set_character_data_handler() should be
replaced with callables.

- https://wiki.php.net/rfc/deprecations_php_8_4#xml_set_object_and_xml_set_handler_with_string_method_names

Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>

---------

Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
Co-authored-by: jlouche <61839660+jlouche@users.noreply.github.com>
Co-authored-by: William Desportes <williamdes@wdes.fr>
Co-authored-by: stollr <christian.stoller@mail.de>
Co-authored-by: Robert Jędrzejczyk <robert@prog.olsztyn.pl>
Co-authored-by: Andreas Erhard <andreas.erhard@i-med.ac.at>
Co-authored-by: Alejandro Precioso <aprecioso@bigtree.com.ar>
Co-authored-by: davidrod <david@gassiotllobet.com>
Co-authored-by: sslldavid <119080321+sslldavid@users.noreply.github.com>
Co-authored-by: Alejandro <aprecioso@gmail.com>
Co-authored-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
  • Loading branch information
11 people authored Oct 26, 2024
1 parent 4cf1ab1 commit dad9e91
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 16 deletions.
7 changes: 5 additions & 2 deletions include/tcpdf_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -379,15 +379,18 @@ public static function getRandomSeed($seed='') {
if (function_exists('posix_getpid')) {
$rnd .= posix_getpid();
}
if (function_exists('openssl_random_pseudo_bytes') AND (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) {

if (function_exists('random_bytes')) {
$rnd .= random_bytes(512);
} elseif (function_exists('openssl_random_pseudo_bytes') AND (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) {
// this is not used on windows systems because it is very slow for a know bug
$rnd .= openssl_random_pseudo_bytes(512);
} else {
for ($i = 0; $i < 23; ++$i) {
$rnd .= uniqid('', true);
}
}
return $rnd.$seed.__FILE__.serialize($_SERVER).microtime(true);
return $rnd.$seed.__FILE__.microtime(true);
}

/**
Expand Down
27 changes: 13 additions & 14 deletions tcpdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -8164,7 +8164,7 @@ protected function _putpages() {
* @since 5.0.010 (2010-05-17)
*/
protected function _getannotsrefs($n) {
if (!(isset($this->PageAnnots[$n]) OR ($this->sign AND isset($this->signature_data['cert_type'])))) {
if (!(isset($this->PageAnnots[$n]) OR count($this->empty_signature_appearance)>0 OR ($this->sign AND isset($this->signature_data['cert_type'])))) {
return '';
}
$out = ' /Annots [';
Expand Down Expand Up @@ -8532,7 +8532,7 @@ protected function _putannotsobjs() {
}
case 'freetext': {
if (isset($pl['opt']['da']) AND !empty($pl['opt']['da'])) {
$annots .= ' /DA ('.$pl['opt']['da'].')';
$annots .= ' /DA '.$this->_datastring($pl['opt']['da']);
}
if (isset($pl['opt']['q']) AND ($pl['opt']['q'] >= 0) AND ($pl['opt']['q'] <= 2)) {
$annots .= ' /Q '.intval($pl['opt']['q']);
Expand Down Expand Up @@ -8789,7 +8789,7 @@ protected function _putannotsobjs() {
$annots .= ' /AA << '.$pl['opt']['aa'].' >>';
}
if (isset($pl['opt']['da']) AND !empty($pl['opt']['da'])) {
$annots .= ' /DA ('.$pl['opt']['da'].')';
$annots .= ' /DA '.$this->_datastring($pl['opt']['da']);
}
if (isset($pl['opt']['q']) AND ($pl['opt']['q'] >= 0) AND ($pl['opt']['q'] <= 2)) {
$annots .= ' /Q '.intval($pl['opt']['q']);
Expand Down Expand Up @@ -9939,7 +9939,7 @@ protected function _putcatalog() {
$out .= ' >> >>';
}
$font = $this->getFontBuffer((($this->pdfa_mode) ? 'pdfa' : '') .'helvetica');
$out .= ' /DA (/F'.$font['i'].' 0 Tf 0 g)';
$out .= ' /DA ' . $this->_datastring('/F'.$font['i'].' 0 Tf 0 g');
$out .= ' /Q '.(($this->rtl)?'2':'0');
//$out .= ' /XFA ';
$out .= ' >>';
Expand Down Expand Up @@ -11046,7 +11046,7 @@ public function setProtection($permissions=array('print', 'modify', 'copy', 'ann
$this->encryptdata['V'] = 4;
$this->encryptdata['Length'] = 128;
$this->encryptdata['CF']['CFM'] = 'AESV2';
$this->encryptdata['CF']['Length'] = 128;
$this->encryptdata['CF']['Length'] = 16;
if ($this->encryptdata['pubkey']) {
$this->encryptdata['SubFilter'] = 'adbe.pkcs7.s5';
$this->encryptdata['Recipients'] = array();
Expand All @@ -11057,7 +11057,7 @@ public function setProtection($permissions=array('print', 'modify', 'copy', 'ann
$this->encryptdata['V'] = 5;
$this->encryptdata['Length'] = 256;
$this->encryptdata['CF']['CFM'] = 'AESV3';
$this->encryptdata['CF']['Length'] = 256;
$this->encryptdata['CF']['Length'] = 32;
if ($this->encryptdata['pubkey']) {
$this->encryptdata['SubFilter'] = 'adbe.pkcs7.s5';
$this->encryptdata['Recipients'] = array();
Expand Down Expand Up @@ -13936,8 +13936,8 @@ public function setVisibility($v) {
* @since 3.0.000 (2008-03-27)
*/
protected function addExtGState($parms) {
if ($this->pdfa_mode || $this->pdfa_version >= 2) {
// transparencies are not allowed in PDF/A mode
if (($this->pdfa_mode && $this->pdfa_version < 2) || ($this->state != 2)) {
// transparency is not allowed in PDF/A-1 mode
return;
}
// check if this ExtGState already exist
Expand Down Expand Up @@ -16440,7 +16440,7 @@ protected function getHtmlDomArray($html) {
)
);

if(empty($html)) {
if($html === '' || $html === null) {
return $dom;
}
// array of CSS styles ( selector => properties).
Expand Down Expand Up @@ -23173,14 +23173,12 @@ public function ImageSVG($file, $x=null, $y=null, $w=0, $h=0, $link='', $align='
$this->_out(sprintf('%F %F %F %F %F %F cm', $svgscale_x, 0, 0, $svgscale_y, ($e + $svgoffset_x), ($f + $svgoffset_y)));
// creates a new XML parser to be used by the other XML functions
$parser = xml_parser_create('UTF-8');
// the following function allows to use parser inside object
xml_set_object($parser, $this);
// disable case-folding for this XML parser
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
// sets the element handler functions for the XML parser
xml_set_element_handler($parser, 'startSVGElementHandler', 'endSVGElementHandler');
xml_set_element_handler($parser, [$this, 'startSVGElementHandler'], [$this, 'endSVGElementHandler']);
// sets the character data handler function for the XML parser
xml_set_character_data_handler($parser, 'segSVGContentHandler');
xml_set_character_data_handler($parser, [$this, 'segSVGContentHandler']);
// start parsing an XML document
if (!xml_parse($parser, $svgdata)) {
$error_message = sprintf('SVG Error: %s at line %d', xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser));
Expand Down Expand Up @@ -23642,7 +23640,8 @@ protected function SVGPath($d, $style='') {
$params = array();
if (isset($val[2])) {
// get curve parameters
$rawparams = preg_split('/([\,\s]+)/si', trim($val[2]));
preg_match_all('/-?\d*\.?\d+/', trim($val[2]), $matches);
$rawparams = $matches[0];
$params = array();
foreach ($rawparams as $ck => $cp) {
$params[$ck] = $this->getHTMLUnitToUnits($cp, 0, $this->svgunit, false);
Expand Down

0 comments on commit dad9e91

Please sign in to comment.