CVE-2024-32489: Insufficient Information (NVD-CWE-noinfo)
value: TCPDF before 6.7.4 mishandles calls that use HTML syntax.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-04-15T06:15Z
Repository: https://github.com/tecnickcom/TCPDF
Language: PHP
Files changed: CHANGELOG.TXT, LICENSE.TXT, README.md, VERSION, config/tcpdf_config.php, examples/config/tcpdf_config_alt.php, examples/example_049.php, examples/example_066.php, include/barcodes/qrcode.php, include/tcpdf_fonts.php, include/tcpdf_static.php, phpstan.neon.dist, tcpdf.php, tcpdf_autoconfig.php, tcpdf_barcodes_1d.php, tests/composer.json
Commit date: 2024-03-25 23:52:22 +0000
Commit message: Squash multiple fixes

Diff: diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT
index 39970db3..c70e22bf 100644
--- a/CHANGELOG.TXT
+++ b/CHANGELOG.TXT
@@ -1,5 +1,29 @@
+6.7.4 (2024-03-24)
+	- Upgrade tcpdf tag encryption algorithm.
+	- Fix regression issue #699.
+	- Fix security issue.
+	- [BREAKING CHANGE] The tcpdf HTML tag syntax has changed, see example_049.php.
+	- New K_ALLOWED_TCPDF_TAGS configuration constant to set the allowed methods for the tcdpf HTML tag.
+	- Raised minimum PHP version to PHP 5.5.0.
+
+6.6.5 (2023-09-02)
+	- Fix corrupted file.
+	- Fix GitHub automation tests.
+	- Fix SPDX license ID (#591)
+	- Fix warning "array offset on value of type null" (#620)
+	- Improve the README about the status of this library (#589)
+	- Fix deprecation warning with PHP 8.1 (#614)
+	- Fixes for PHP 8.2 in tcpdf_fonts.php (#632)
+	- Fix some php 8+ edge cases (#630)
+	- Fix composite glyph output (#581)
+	- Fix "access array offset on value of type bool" with PDF/A (#583)
+	- Fix non-numeric value warning (#627)
+	- Fix issues with S25 barcode (#611)
+	- Fix return type annotations (#613)
+	- Fix some inconsistencies in type hints (#598)
+
 6.6.2 (2022-12-17)
 	- Ensure pregSplit return type is always array.
 	- Add ability to run tests on various operating systems (#566)
 	- Avoid a deprecated error from PHP8.1 (#573)
 
diff --git a/LICENSE.TXT b/LICENSE.TXT
index ec191e2a..ec7968a7 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -5,11 +5,11 @@
   TCPDF is free software: you can redistribute it and/or modify it
   under the terms of the GNU Lesser General Public License as
   published by the Free Software Foundation, either version 3 of the
   License, or (at your option) any later version.
   
-  2002-2022 Nicola Asuni - Tecnick.com LTD
+  2002-2024 Nicola Asuni - Tecnick.com LTD
 
 **********************************************************************
 **********************************************************************
 
                    GNU LESSER GENERAL PUBLIC LICENSE
diff --git a/README.md b/README.md
index cf843227..f59f6633 100644
--- a/README.md
+++ b/README.md
@@ -4,19 +4,18 @@
 [![Donate via PayPal](https://img.shields.io/badge/donate-paypal-87ceeb.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&currency_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20TCPDF%20project)
 *Please consider supporting this project by making a donation via [PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&currency_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20TCPDF%20project)*
 
 * **category**    Library
 * **author**      Nicola Asuni <info@tecnick.com>
-* **copyright**   2002-2022 Nicola Asuni - Tecnick.com LTD
+* **copyright**   2002-2024 Nicola Asuni - Tecnick.com LTD
 * **license**     http://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE.TXT)
 * **link**        http://www.tcpdf.org
 * **source**      https://github.com/tecnickcom/TCPDF
 
 
-## IMPORTANT
-A new version of this library is under development at https://github.com/tecnickcom/tc-lib-pdf and as a consequence this version will not receive any additional development or support.
-This version should be considered obsolete, new projects should use the new version as soon it will become stable.
+## NOTE
+A new version of this library is under development at https://github.com/tecnickcom/tc-lib-pdf and as a consequence this library is in support only mode.
 
 
 
 ## Description
 
diff --git a/VERSION b/VERSION
index 28179fc1..29310f45 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-6.6.2
+6.7.4
diff --git a/config/tcpdf_config.php b/config/tcpdf_config.php
index 92317b12..9888a677 100644
--- a/config/tcpdf_config.php
+++ b/config/tcpdf_config.php
@@ -210,10 +210,18 @@ define('K_THAI_TOPCHARS', true);
  * If true allows to call TCPDF methods using HTML syntax
  * IMPORTANT: For security reason, disable this feature if you are printing user HTML content.
  */
 define('K_TCPDF_CALLS_IN_HTML', false);
 
+/**
+ * List of TCPDF methods that are allowed to be called using HTML syntax.
+ * Note: each method name must end with surrounded with | (pipe) character.
+ * The constant K_TCPDF_CALLS_IN_HTML must be set to true.
+ * IMPORTANT: For security reason, disable this feature if you are allowing user HTML content.
+ */
+define('K_ALLOWED_TCPDF_TAGS', '');
+
 /**
  * If true and PHP version is greater than 5, then the Error() method throw new exception instead of terminating the execution.
  */
 define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
 
diff --git a/examples/config/tcpdf_config_alt.php b/examples/config/tcpdf_config_alt.php
index d61b1ba7..ef15ab27 100644
--- a/examples/config/tcpdf_config_alt.php
+++ b/examples/config/tcpdf_config_alt.php
@@ -210,10 +210,18 @@ define('K_THAI_TOPCHARS', true);
  * If true allows to call TCPDF methods using HTML syntax
  * IMPORTANT: For security reason, disable this feature if you are printing user HTML content.
  */
 define('K_TCPDF_CALLS_IN_HTML', true);
 
+/**
+ * List of TCPDF methods that are allowed to be called using HTML syntax.
+ * Note: each method name must end with surrounded with | (pipe) character.
+ * The constant K_TCPDF_CALLS_IN_HTML must be set to true.
+ * IMPORTANT: For security reason, disable this feature if you are allowing user HTML content.
+ */
+define('K_ALLOWED_TCPDF_TAGS', '|AddPage|Rect|SetDrawColor|write1DBarcode|');
+
 /**
  * If true and PHP version is greater than 5, then the Error() method throw new exception instead of terminating the execution.
  */
 define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
 
diff --git a/examples/example_049.php b/examples/example_049.php
index d2a46ada..5ebefc66 100644
--- a/examples/example_049.php
+++ b/examples/example_049.php
@@ -1,10 +1,10 @@
 <?php
 //============================================================+
 // File name   : example_049.php
 // Begin       : 2009-04-03
-// Last Update : 2014-12-10
+// Last Update : 2024-03-18
 //
 // Description : Example 049 for TCPDF class
 //               WriteHTML with TCPDF callback functions
 //
 // Author: Nicola Asuni
@@ -76,40 +76,42 @@ $pdf->AddPage();
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 
 IMPORTANT:
-If you are printing user-generated content, tcpdf tag can be unsafe.
-You can disable this tag by setting to false the K_TCPDF_CALLS_IN_HTML
-constant on TCPDF configuration file.
+If you are printing user-generated content, the tcpdf tag should be considered unsafe.
+This tag is disabled by default by the K_TCPDF_CALLS_IN_HTML constant on TCPDF configuration file.
+Please use this feature only if you are in control of the HTML content and you are sure that it does not contain any harmful code.
 
-For security reasons, the parameters for the 'params' attribute of TCPDF
+For security reasons, the parameters for the 'params' attribute of TCPDF 
 tag must be prepared as an array and encoded with the
 serializeTCPDFtagParameters() method (see the example below).
 
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 
 $html = '<h1>Test TCPDF Methods in HTML</h1>
 <h2 style="color:red;">IMPORTANT:</h2>
-<span style="color:red;">If you are using user-generated content, the tcpdf tag can be unsafe.<br />
-You can disable this tag by setting to false the <b>K_TCPDF_CALLS_IN_HTML</b> constant on TCPDF configuration file.</span>
+<span style="color:red;">If you are using user-generated content, the tcpdf tag should be considered unsafe.<br />
+Please use this feature only if you are in control of the HTML content and you are sure that it does not contain any harmful code.<br />
+This feature is disabled by default by the <b>K_TCPDF_CALLS_IN_HTML</b> constant on TCPDF configuration file.</span>
 <h2>write1DBarcode method in HTML</h2>';
 
-$params = $pdf->serializeTCPDFtagParameters(array('CODE 39', 'C39', '', '', 80, 30, 0.4, array('position'=>'S', 'border'=>true, 'padding'=>4, 'fgcolor'=>array(0,0,0), 'bgcolor'=>array(255,255,255), 'text'=>true, 'font'=>'helvetica', 'fontsize'=>8, 'stretchtext'=>4), 'N'));
-$html .= '<tcpdf method="write1DBarcode" params="'.$params.'" />';
+$data = $pdf->serializeTCPDFtag('write1DBarcode', array('CODE 39', 'C39', '', '', 80, 30, 0.4, array('position'=>'S', 'border'=>true, 'padding'=>4, 'fgcolor'=>array(0,0,0), 'bgcolor'=>array(255,255,255), 'text'=>true, 'font'=>'helvetica', 'fontsize'=>8, 'stretchtext'=>4), 'N'));
+$html .= '<tcpdf data="'.$data.'" />';
 
-$params = $pdf->serializeTCPDFtagParameters(array('CODE 128', 'C128', '', '', 80, 30, 0.4, array('position'=>'S', 'border'=>true, 'padding'=>4, 'fgcolor'=>array(0,0,0), 'bgcolor'=>array(255,255,255), 'text'=>true, 'font'=>'helvetica', 'fontsize'=>8, 'stretchtext'=>4), 'N'));
-$html .= '<tcpdf method="write1DBarcode" params="'.$params.'" />';
+$data = $pdf->serializeTCPDFtag('write1DBarcode', array('CODE 128', 'C128', '', '', 80, 30, 0.4, array('position'=>'S', 'border'=>true, 'padding'=>4, 'fgcolor'=>array(0,0,0), 'bgcolor'=>array(255,255,255), 'text'=>true, 'font'=>'helvetica', 'fontsize'=>8, 'stretchtext'=>4), 'N'));
+$html .= '<tcpdf data="'.$data.'" />';
 
-$html .= '<tcpdf method="AddPage" /><h2>Graphic Functions</h2>';
+$data = $pdf->serializeTCPDFtag('AddPage');
+$html .= '<tcpdf data="'.$data.'" /><h2>Graphic Functions</h2>';
 
-$params = $pdf->serializeTCPDFtagParameters(array(0));
-$html .= '<tcpdf method="SetDrawColor" params="'.$params.'" />';
+$data = $pdf->serializeTCPDFtag('SetDrawColor', array(0));
+$html .= '<tcpdf data="'.$data.'" />';
 
-$params = $pdf->serializeTCPDFtagParameters(array(50, 50, 40, 10, 'DF', array(), array(0,128,255)));
-$html .= '<tcpdf method="Rect" params="'.$params.'" />';
+$data = $pdf->serializeTCPDFtag('Rect', array(50, 50, 40, 10, 'DF', array(), array(0,128,255)));
+$html .= '<tcpdf data="'.$data.'" />';
 
 
 // output the HTML content
 $pdf->writeHTML($html, true, 0, true, 0);
 
diff --git a/examples/example_066.php b/examples/example_066.php
index c7304c7a..41b8b472 100644
--- a/examples/example_066.php
+++ b/examples/example_066.php
@@ -16,12 +16,12 @@
  * @since 2021-03-26
  * @group A-1b
  * @group pdf
  */
 
-// Load the autoloader, move one folder back from examples
-require_once __DIR__ . '/../vendor/autoload.php';
+// Include the main TCPDF library (search for installation path).
+require_once('tcpdf_include.php');
 
 // create new PDF document
 $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false, true);
 
 // set document information
diff --git a/include/barcodes/qrcode.php b/include/barcodes/qrcode.php
index 322cace3..1a64a4cb 100644
--- a/include/barcodes/qrcode.php
+++ b/include/barcodes/qrcode.php
@@ -886,10 +886,11 @@ class QRcode {
 			$row = $this->count % $this->blocks;
 			$col = (int)($this->count / $this->blocks);
 			if ($col >= $this->rsblocks[0]['dataLength']) {
 				$row += $this->b1;
 			}
+			$row = (int) $row;
 			$ret = $this->rsblocks[$row]['data'][$col];
 		} elseif ($this->count < $this->dataLength + $this->eccLength) {
 			$row = ($this->count - $this->dataLength) % $this->blocks;
 			$col = (int)(($this->count - $this->dataLength) / $this->blocks);
 			$ret = $this->rsblocks[$row]['ecc'][$col];
diff --git a/include/tcpdf_fonts.php b/include/tcpdf_fonts.php
index 30053d3e..a71c84b7 100644
--- a/include/tcpdf_fonts.php
+++ b/include/tcpdf_fonts.php
@@ -1321,47 +1321,47 @@ class TCPDF_FONTS {
 				$table[$tag]['data'] = substr($font, $table[$tag]['offset'], $table[$tag]['length']);
 				if ($tag == 'head') {
 					// set the checkSumAdjustment to 0
 					$table[$tag]['data'] = substr($table[$tag]['data'], 0, 8)."\x0\x0\x0\x0".substr($table[$tag]['data'], 12);
 				}
-				$pad = 4 - ($table[$tag]['length'] % 4);
-				if ($pad != 4) {
-					// the length of a table must be a multiple of four bytes
-					$table[$tag]['length'] += $pad;
-					$table[$tag]['data'] .= str_repeat("\x0", $pad);
-				}
 				$table[$tag]['offset'] = $offset;
 				$offset += $table[$tag]['length'];
+				$numPad = ($offset + 3 & ~3) - $offset;
+				if($numPad > 0) {
+					$table[$tag]['data'] .= str_repeat("\x0", $numPad);
+					$offset += $numPad;
+				}
 				// check sum is not changed (so keep the following line commented)
-				//$table[$tag]['checkSum'] = self::_getTTFtableChecksum($table[$tag]['data'], $table[$tag]['length']);
+				//$table[$tag]['checkSum'] = self::_getTTFtableChecksum($table[$tag]['data'], $table[$tag]['length'] + $numPad);
 			} else {
 				unset($table[$tag]);
 			}
 		}
 		// add loca
+		$table['loca'] = array();
 		$table['loca']['data'] = $loca;
 		$table['loca']['length'] = strlen($loca);
-		$pad = 4 - ($table['loca']['length'] % 4);
-		if ($pad != 4) {
-			// the length of a table must be a multiple of four bytes
-			$table['loca']['length'] += $pad;
-			$table['loca']['data'] .= str_repeat("\x0", $pad);
-		}
 		$table['loca']['offset'] = $offset;
-		$table['loca']['checkSum'] = self::_getTTFtableChecksum($table['loca']['data'], $table['loca']['length']);
 		$offset += $table['loca']['length'];
+		$numPad = ($offset + 3 & ~3) - $offset;
+		if($numPad > 0) {
+			$table['loca']['data'] .= str_repeat("\x0", $numPad);
+			$offset += $numPad;
+		}
+		$table['loca']['checkSum'] = self::_getTTFtableChecksum($table['loca']['data'], $table['loca']['length'] + $numPad);
 		// add glyf
+		$table['glyf'] = array();
 		$table['glyf']['data'] = $glyf;
 		$table['glyf']['length'] = strlen($glyf);
-		$pad = 4 - ($table['glyf']['length'] % 4);
-		if ($pad != 4) {
-			// the length of a table must be a multiple of four bytes
-			$table['glyf']['length'] += $pad;
-			$table['glyf']['data'] .= str_repeat("\x0", $pad);
-		}
 		$table['glyf']['offset'] = $offset;
-		$table['glyf']['checkSum'] = self::_getTTFtableChecksum($table['glyf']['data'], $table['glyf']['length']);
+		$offset += $table['glyf']['length'];
+		$numPad = ($offset + 3 & ~3) - $offset;
+		if($numPad > 0) {
+			$table['glyf']['data'] .= str_repeat("\x0", $numPad);
+			$offset += $numPad;
+		}
+		$table['glyf']['checkSum'] = self::_getTTFtableChecksum($table['glyf']['data'], $table['glyf']['length'] + $numPad);
 		// rebuild font
 		$font = '';
 		$font .= pack('N', 0x10000); // sfnt version
 		$numTables = count($table);
 		$font .= pack('n', $numTables); // numTables
@@ -1381,11 +1381,11 @@ class TCPDF_FONTS {
 		foreach ($table as $data) {
 			$font .= $data['data'];
 		}
 		// set checkSumAdjustment on head table
 		$checkSumAdjustment = 0xB1B0AFBA - self::_getTTFtableChecksum($font, strlen($font));
-		$font = substr($font, 0, $table['head']['offset'] + 8).pack('N', $checkSumAdjustment).substr($font, $table['head']['offset'] + 12);
+		$font = substr($font, 0, $table['head']['offset'] + $offset + 8).pack('N', $checkSumAdjustment).substr($font, $table['head']['offset'] + $offset + 12);
 		return $font;
 	}
 
 	/**
 	 * Outputs font widths
@@ -1778,13 +1778,13 @@ class TCPDF_FONTS {
 	 * @since 4.5.037 (2009-04-07)
 	 * @public static
 	 */
 	public static function UTF8ArrayToUniArray($ta, $isunicode=true) {
 		if ($isunicode) {
-			return array_map(array('TCPDF_FONTS', 'unichrUnicode'), $ta);
+			return array_map(get_called_class().'::unichrUnicode', $ta);
 		}
-		return array_map(array('TCPDF_FONTS', 'unichrASCII'), $ta);
+		return array_map(get_called_class().'::unichrASCII', $ta);
 	}
 
 	/**
 	 * Extract a slice of the $strarr array and return it as string.
 	 * @param string[] $strarr The input array of characters.
@@ -2000,11 +2000,11 @@ class TCPDF_FONTS {
 	public static function UTF8StringToArray($str, $isunicode, &$currentfont) {
 		$str = is_null($str) ? '' : $str;
 		if ($isunicode) {
 			// requires PCRE unicode support turned on
 			$chars = TCPDF_STATIC::pregSplit('//','u', $str, -1, PREG_SPLIT_NO_EMPTY);
-			$carr = array_map(array('TCPDF_FONTS', 'uniord'), $chars);
+			$carr = array_map(get_called_class().'::uniord', $chars);
 		} else {
 			$chars = str_split($str);
 			$carr = array_map('ord', $chars);
 		}
 		if (is_array($currentfont['subsetchars']) && is_array($carr)) {
diff --git a/include/tcpdf_static.php b/include/tcpdf_static.php
index 57006552..1fb3c787 100644
--- a/include/tcpdf_static.php
+++ b/include/tcpdf_static.php
@@ -1,15 +1,15 @@
 <?php
 //============================================================+
 // File name   : tcpdf_static.php
 // Version     : 1.1.4
 // Begin       : 2002-08-03
-// Last Update : 2022-08-12
+// Last Update : 2023-09-06
 // Author      : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
 // License     : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
 // -------------------------------------------------------------------
-// Copyright (C) 2002-2022 Nicola Asuni - Tecnick.com LTD
+// Copyright (C) 2002-2023 Nicola Asuni - Tecnick.com LTD
 //
 // This file is part of TCPDF software library.
 //
 // TCPDF is free software: you can redistribute it and/or modify it
 // under the terms of the GNU Lesser General Public License as
@@ -53,11 +53,11 @@ class TCPDF_STATIC {
 
 	/**
 	 * Current TCPDF version.
 	 * @private static
 	 */
-	private static $tcpdf_version = '6.6.2';
+	private static $tcpdf_version = '6.7.4';
 
 	/**
 	 * String alias for total number of pages.
 	 * @public static
 	 */
@@ -1778,11 +1778,11 @@ class TCPDF_STATIC {
 		if ((strpos($modifiers, 'u') === FALSE) OR (count(preg_split('//u', "\n\t", -1, PREG_SPLIT_NO_EMPTY)) == 2)) {
 			$ret = preg_split($pattern.$modifiers, $subject, $limit, $flags);
 			if ($ret === false) {
 				return array();
 			}
-			return $ret;
+			return is_array($ret) ? $ret : array();
 		}
 		// preg_split is bugged - try alternative solution
 		$ret = array();
 		while (($nl = strpos($subject, "\n")) !== FALSE) {
 			$ret = array_merge($ret, preg_split($pattern.$modifiers, substr($subject, 0, $nl), $limit, $flags));
@@ -2122,11 +2122,11 @@ class TCPDF_STATIC {
 
 	/**
 	 * Array of page formats
 	 * measures are calculated in this way: (inches * 72) or (millimeters * 72 / 25.4)
 	 * @public static
-	 * 
+	 *
      * @var array<string,float[]>
 	 */
 	public static $page_formats = array(
 		// ISO 216 A Series + 2 SIS 014711 extensions
 		'A0'                     => array( 2383.937,  3370.394), // = (  841 x 1189 ) mm  = ( 33.11 x 46.81 ) in
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
index a5e7a433..3f7bb1bd 100644
--- a/phpstan.neon.dist
+++ b/phpstan.neon.dist
@@ -2,12 +2,10 @@ parameters:
     level: 1
     paths:
         - ./
     excludePaths:
         - vendor/
-        # remove once https://github.com/phpstan/phpstan/issues/7955 is fixed
-        - fonts/
         - tests/
 
     scanFiles:
       - tcpdf_autoconfig.php
 
diff --git a/tcpdf.php b/tcpdf.php
index 667b004f..7f5bbfb8 100644
--- a/tcpdf.php
+++ b/tcpdf.php
@@ -1,15 +1,15 @@
 <?php
 //============================================================+
 // File name   : tcpdf.php
-// Version     : 6.6.2
+// Version     : 6.7.4
 // Begin       : 2002-08-03
-// Last Update : 2022-12-06
+// Last Update : 2024-03-18
 // Author      : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
 // License     : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
 // -------------------------------------------------------------------
-// Copyright (C) 2002-2022 Nicola Asuni - Tecnick.com LTD
+// Copyright (C) 2002-2024 Nicola Asuni - Tecnick.com LTD
 //
 // This file is part of TCPDF software library.
 //
 // TCPDF is free software: you can redistribute it and/or modify it
 // under the terms of the GNU Lesser General Public License as
@@ -102,11 +102,11 @@
  * <li>PDF/A-1b support.</li>
  * </ul>
  * Tools to encode your unicode fonts are on fonts/utils directory.</p>
  * @package com.tecnick.tcpdf
  * @author Nicola Asuni
- * @version 6.6.2
+ * @version 6.6.5
  */
 
 // TCPDF configuration
 require_once(dirname(__FILE__).'/tcpdf_autoconfig.php');
 // TCPDF static font methods and data
@@ -126,11 +126,11 @@ require_once(dirname(__FILE__).'/include/tcpdf_static.php');
  * @class TCPDF
  * PHP class for generating PDF documents without requiring external extensions.
  * TCPDF project (http://www.tcpdf.org) has been originally derived in 2002 from the Public Domain FPDF class by Olivier Plathey (http://www.fpdf.org), but now is almost entirely rewritten.<br>
  * @package com.tecnick.tcpdf
  * @brief PHP class for generating PDF documents without requiring external extensions.
- * @version 6.6.2
+ * @version 6.7.4
  * @author Nicola Asuni - info@tecnick.com
  * @IgnoreAnnotation("protected")
  * @IgnoreAnnotation("public")
  * @IgnoreAnnotation("pre")
  */
@@ -572,16 +572,18 @@ class TCPDF {
 	protected $header_xobj_autoreset = false;
 
 	/**
 	 * Minimum distance between header and top page margin.
 	 * @protected
+	 * @var float
 	 */
 	protected $header_margin;
 
 	/**
 	 * Minimum distance between footer and bottom page margin.
 	 * @protected
+	 * @var float
 	 */
 	protected $footer_margin;
 
 	/**
 	 * Original left margin value.
@@ -834,10 +836,17 @@ class TCPDF {
 	 * @protected
 	 * @since 5.0.005 (2010-05-12)
 	 */
 	protected $file_id;
 
+	/**
+	 * Internal secret used to encrypt data.
+	 * @protected
+	 * @since 6.7.4 (2024-03-21)
+	 */
+	protected $hash_key;
+
 	// --- bookmark ---
 
 	/**
 	 * Outlines for bookmark.
 	 * @protected
@@ -1876,14 +1885,14 @@ class TCPDF {
 	 */
 	public function __construct($orientation='P', $unit='mm', $format='A4', $unicode=true, $encoding='UTF-8', $diskcache=false, $pdfa=false) {
 		// set file ID for trailer
 		$serformat = (is_array($format) ? json_encode($format) : $format);
 		$this->file_id = md5(TCPDF_STATIC::getRandomSeed('TCPDF'.$orientation.$unit.$serformat.$encoding));
+		$this->hash_key = hash_hmac('sha256', TCPDF_STATIC::getRandomSeed($this->file_id), TCPDF_STATIC::getRandomSeed('TCPDF'), false);
 		$this->font_obj_ids = array();
 		$this->page_obj_id = array();
 		$this->form_obj_id = array();
-
 		// set pdf/a mode
 		if ($pdfa != false) {
 			$this->pdfa_mode = true;
 			$this->pdfa_version = $pdfa;  // 1 or 3
 		} else
@@ -2459,11 +2468,11 @@ class TCPDF {
 	 * @public
 	 * @return float
 	 */
 	public function getCellHeight($fontsize, $padding=TRUE) {
 		$height = ($fontsize * $this->cell_height_ratio);
-		if ($padding) {
+		if ($padding && !empty($this->cell_padding)) {
 			$height += ($this->cell_padding['T'] + $this->cell_padding['B']);
 		}
 		return round($height, 6);
 	}
 
@@ -3370,11 +3379,11 @@ class TCPDF {
 	}
 
 	/**
 	 * Set header margin.
 	 * (minimum distance between header and top page margin)
-	 * @param int $hm distance in user units
+	 * @param float $hm distance in user units
 	 * @public
 	 */
 	public function setHeaderMargin($hm=10) {
 		$this->header_margin = $hm;
 	}
@@ -3390,11 +3399,11 @@ class TCPDF {
 	}
 
 	/**
 	 * Set footer margin.
 	 * (minimum distance between footer and bottom page margin)
-	 * @param int $fm distance in user units
+	 * @param float $fm distance in user units
 	 * @public
 	 */
 	public function setFooterMargin($fm=10) {
 		$this->footer_margin = $fm;
 	}
@@ -4100,10 +4109,11 @@ class TCPDF {
 	 * @param string $fontname Family font. It can be either a name defined by AddFont() or one of the standard families. It is also possible to pass an empty string, in that case, the current family is retained.
 	 * @param string $fontstyle Font style. Possible values are (case insensitive):<ul><li>empty string: regular</li><li>B: bold</li><li>I: italic</li><li>U: underline</li><li>D: line-through</li><li>O: overline</li></ul> or any combination. The default value is regular.
 	 * @param float $fontsize Font size in points. The default value is the current size.
 	 * @param boolean $getarray if true returns an array of characters widths, if false returns the total length.
 	 * @return float[]|float total string length or array of characted widths
+	 * @phpstan-return ($getarray is true ? float[] : float) total string length or array of characted widths
 	 * @author Nicola Asuni
 	 * @public
 	 * @since 1.2
 	 */
 	public function GetStringWidth($s, $fontname='', $fontstyle='', $fontsize=0, $getarray=false) {
@@ -4116,10 +4126,11 @@ class TCPDF {
 	 * @param string $fontname Family font. It can be either a name defined by AddFont() or one of the standard families. It is also possible to pass an empty string, in that case, the current family is retained.
 	 * @param string $fontstyle Font style. Possible values are (case insensitive):<ul><li>empty string: regular</li><li>B: bold</li><li>I: italic</li><li>U: underline</li><li>D: line through</li><li>O: overline</li></ul> or any combination. The default value is regular.
 	 * @param float $fontsize Font size in points. The default value is the current size.
 	 * @param boolean $getarray if true returns an array of characters widths, if false returns the total length.
 	 * @return float[]|float total string length or array of characted widths
+	 * @phpstan-return ($getarray is true ? float[] : float) total string length or array of characted widths
 	 * @author Nicola Asuni
 	 * @public
 	 * @since 2.4.000 (2008-03-06)
 	 */
 	public function GetArrStringWidth($sa, $fontname='', $fontstyle='', $fontsize=0, $getarray=false) {
@@ -4421,11 +4432,11 @@ class TCPDF {
 			}
 		} else {
 			$this->Error('Unknow font type: '.$type.'');
 		}
 		// set name if unset
-		if (!isset($name) OR empty($name)) {
+		if (empty($name)) {
 			$name = $fontkey;
 		}
 		// create artificial font style variations if missing (only works with non-embedded fonts)
 		if (($type != 'core') AND $missing_style) {
 			// style variations
@@ -4464,11 +4475,11 @@ class TCPDF {
 		$this->setFontBuffer($fontkey, array('fontkey' => $fontkey, 'i' => $this->numfonts, 'type' => $type, 'name' => $name, 'desc' => $desc, 'up' => $up, 'ut' => $ut, 'cw' => $cw, 'cbbox' => $cbbox, 'dw' => $dw, 'enc' => $enc, 'cidinfo' => $cidinfo, 'file' => $file, 'ctg' => $ctg, 'subset' => $subset, 'subsetchars' => $subsetchars));
 		if ($this->inxobj) {
 			// we are inside an XObject template
 			$this->xobjects[$this->xobjid]['fonts'][$fontkey] = $this->numfonts;
 		}
-		if (isset($diff) AND (!empty($diff))) {
+		if (!empty($diff)) {
 			//Search existing encodings
 			$d = 0;
 			$nb = count($this->diffs);
 			for ($i=1; $i <= $nb; ++$i) {
 				if ($this->diffs[$i] == $diff) {
@@ -6407,11 +6418,11 @@ class TCPDF {
 		// get array of unicode values
 		$chars = TCPDF_FONTS::UTF8StringToArray($s, $this->isunicode, $this->CurrentFont);
 		// calculate maximum width for a single character on string
 		$chrw = $this->GetArrStringWidth($chars, '', '', 0, true);
 		array_walk($chrw, array($this, 'getRawCharWidth'));
-		$maxchwidth = max($chrw);
+		$maxchwidth = ((is_array($chrw) || $chrw instanceof Countable) && count($chrw) > 0) ? max($chrw) : 0;
 		// get array of chars
 		$uchars = TCPDF_FONTS::UTF8ArrayToUniArray($chars, $this->isunicode);
 		// get the number of characters
 		$nb = count($chars);
 		// replacement for SHY character (minus symbol)
@@ -6870,10 +6881,12 @@ class TCPDF {
 			}
 			$this->newline = true;
 		}
 		// resize the block to be contained on the remaining available page or column space
 		if ($fitonpage) {
+			// fallback to avoid division by zero
+			$h = $h == 0 ? 1 : $h;
 			$ratio_wh = ($w / $h);
 			if (($y + $h) > $this->PageBreakTrigger) {
 				$h = $this->PageBreakTrigger - $y;
 				$w = ($h * $ratio_wh);
 			}
@@ -9923,11 +9936,11 @@ class TCPDF {
 				foreach ($this->annotation_fonts as $fontkey => $fontid) {
 					$out .= ' /F'.$fontid.' '.$this->font_obj_ids[$fontkey].' 0 R';
 				}
 				$out .= ' >> >>';
 			}
-			$font = $this->getFontBuffer('helvetica');
+			$font = $this->getFontBuffer((($this->pdfa_mode) ? 'pdfa' : '') .'helvetica');
 			$out .= ' /DA (/F'.$font['i'].' 0 Tf 0 g)';
 			$out .= ' /Q '.(($this->rtl)?'2':'0');
 			//$out .= ' /XFA ';
 			$out .= ' >>';
 			// signatures
@@ -16381,10 +16394,57 @@ class TCPDF {
 	 * @return array
 	 * @protected
 	 * @since 3.2.000 (2008-06-20)
 	 */
 	protected function getHtmlDomArray($html) {
+		// set inheritable properties fot the first void element
+		// possible inheritable properties are: azimuth, border-collapse, border-spacing, caption-side, color, cursor, direction, empty-cells, font, font-family, font-stretch, font-size, font-size-adjust, font-style, font-variant, font-weight, letter-spacing, line-height, list-style, list-style-image, list-style-position, list-style-type, orphans, page, page-break-inside, quotes, speak, speak-header, text-align, text-indent, text-transform, volume, white-space, widows, word-spacing
+		$dom = array(
+			array(
+				'tag' => false,
+				'block' => false,
+				'value' => '',
+				'parent' => 0,
+				'hide' => false,
+				'fontname' => $this->FontFamily,
+				'fontstyle' => $this->FontStyle,
+				'fontsize' => $this->FontSizePt,
+				'font-stretch' => $this->font_stretching,
+				'letter-spacing' => $this->font_spacing,
+				'stroke' => $this->textstrokewidth,
+				'fill' => (($this->textrendermode % 2) == 0),
+				'clip' => ($this->textrendermode > 3),
+				'line-height' => $this->cell_height_ratio,
+				'bgcolor' => false,
+				'fgcolor' => $this->fgcolor, // color
+				'strokecolor' => $this->strokecolor,
+				'align' => '',
+				'listtype' => '',
+				'text-indent' => 0,
+				'text-transform' => '',
+				'border' => array(),
+				'dir' => $this->rtl?'rtl':'ltr',
+				'width' => 0,
+				'height' => 0,
+				'x' => 0,
+				'y' => 0,
+				'w' => 0,
+				'h' => 0,
+				'l' => 0,
+				't' => 0,
+				'r' => 0,
+				'b' => 0,
+				'padding' => array('T' => 0, 'R' => 0, 'B' => 0, 'L' => 0),
+				'margin' => array('T' => 0, 'R' => 0, 'B' => 0, 'L' => 0),
+				'border-spacing' => array('H' => 0, 'V' => 0),
+				'border-collapse' => 'separate',
+			)
+		);
+
+		if(empty($html)) {
+			return $dom;
+		}
 		// array of CSS styles ( selector => properties).
 		$css = array();
 		// get CSS array defined at previous call
 		$matches = array();
 		if (preg_match_all('/<cssarray>([^\<]*?)<\/cssarray>/is', $html, $matches) > 0) {
@@ -16525,41 +16585,12 @@ class TCPDF {
 		// explodes the string
 		$a = preg_split($tagpattern, $html, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
 		// count elements
 		$maxel = count($a);
 		$elkey = 0;
-		$key = 0;
-		// create an array of elements
-		$dom = array();
-		$dom[$key] = array();
-		// set inheritable properties fot the first void element
-		// possible inheritable properties are: azimuth, border-collapse, border-spacing, caption-side, color, cursor, direction, empty-cells, font, font-family, font-stretch, font-size, font-size-adjust, font-style, font-variant, font-weight, letter-spacing, line-height, list-style, list-style-image, list-style-position, list-style-type, orphans, page, page-break-inside, quotes, speak, speak-header, text-align, text-indent, text-transform, volume, white-space, widows, word-spacing
-		$dom[$key]['tag'] = false;
-		$dom[$key]['block'] = false;
-		$dom[$key]['value'] = '';
-		$dom[$key]['parent'] = 0;
-		$dom[$key]['hide'] = false;
-		$dom[$key]['fontname'] = $this->FontFamily;
-		$dom[$key]['fontstyle'] = $this->FontStyle;
-		$dom[$key]['fontsize'] = $this->FontSizePt;
-		$dom[$key]['font-stretch'] = $this->font_stretching;
-		$dom[$key]['letter-spacing'] = $this->font_spacing;
-		$dom[$key]['stroke'] = $this->textstrokewidth;
-		$dom[$key]['fill'] = (($this->textrendermode % 2) == 0);
-		$dom[$key]['clip'] = ($this->textrendermode > 3);
-		$dom[$key]['line-height'] = $this->cell_height_ratio;
-		$dom[$key]['bgcolor'] = false;
-		$dom[$key]['fgcolor'] = $this->fgcolor; // color
-		$dom[$key]['strokecolor'] = $this->strokecolor;
-		$dom[$key]['align'] = '';
-		$dom[$key]['listtype'] = '';
-		$dom[$key]['text-indent'] = 0;
-		$dom[$key]['text-transform'] = '';
-		$dom[$key]['border'] = array();
-		$dom[$key]['dir'] = $this->rtl?'rtl':'ltr';
 		$thead = false; // true when we are inside the THEAD tag
-		++$key;
+		$key = 1;
 		$level = array();
 		array_push($level, 0); // root
 		while ($elkey < $maxel) {
 			$dom[$key] = array();
 			$element = $a[$elkey];
@@ -17192,45 +17223,63 @@ class TCPDF {
 		}
 		return $spacestr;
 	}
 
 	/**
-	 * Return an hash code used to ensure that the serialized data has been generated by this TCPDF instance.
-	 * @param string $data serialized data
-	 * @return string
-	 * @public static
+	 * Calculates the hash value of the given data.
+	 *
+	 * @param string $data The data to be hashed.
+	 * @return string The hashed value of the data.
 	 */
-	protected function getHashForTCPDFtagParams($data) {
-		return md5(strlen($data).$this->file_id.$data);
+	protected function hashTCPDFtag($data) {
+		return hash_hmac('sha256', $data, $this->hash_key, false);
 	}
 
 	/**
-	 * Serialize an array of parameters to be used with TCPDF tag in HTML code.
-	 * @param array $data parameters array
-	 * @return string containing serialized data
+	 * Serialize data to be used with TCPDF tag in HTML code.
+	 * @param string $method TCPDF method name
+	 * @param array $params Method parameters
+	 * @return string Serialized data
 	 * @public static
 	 */
-	public function serializeTCPDFtagParameters($data) {
+	public function serializeTCPDFtag($method, $params=array()) {
+		$data = array('m' => $method, 'p' => $params);
 		$encoded = urlencode(json_encode($data));
-		return $this->getHashForTCPDFtagParams($encoded).$encoded;
+		$hash = $this->hashTCPDFtag($encoded);
+		return strlen($hash).'+'.$hash.'+'.$encoded;
 	}
 
 	/**
-	 * Unserialize parameters to be used with TCPDF tag in HTML code.
+	 * Unserialize data to be used with TCPDF tag in HTML code.
 	 * @param string $data serialized data
 	 * @return array containing unserialized data
 	 * @protected static
 	 */
-	protected function unserializeTCPDFtagParameters($data) {
-		$hash = substr($data, 0, 32);
-		$encoded = substr($data, 32);
-		if ($hash != $this->getHashForTCPDFtagParams($encoded)) {
+	protected function unserializeTCPDFtag($data) {
+		$hpos = strpos($data, '+');
+		$hlen = intval(substr($data, 0, $hpos));
+		$hash = substr($data, $hpos + 1, $hlen);
+		$encoded = substr($data, $hpos + 2 + $hlen);
+		if ($hash != $this->hashTCPDFtag($encoded)) {
 			$this->Error('Invalid parameters');
 		}
 		return json_decode(urldecode($encoded), true);
 	}
 
+	/**
+	 * Check if a TCPDF tag is allowed
+	 * @param string $method TCPDF method name
+	 * @return boolean
+	 * @protected
+	 */
+	protected function allowedTCPDFtag($method) {
+		if (defined('K_ALLOWED_TCPDF_TAGS')) {
+			return (strpos(K_ALLOWED_TCPDF_TAGS, '|'.$method.'|') !== false);
+		}
+		return false;
+	}
+
 	/**
 	 * Prints a cell (rectangular area) with optional borders, background color and html text string.
 	 * The upper-left corner of the cell corresponds to the current position. After the call, the current position moves to the right or to the next line.<br />
 	 * If automatic page breaking is enabled and the cell goes beyond the limit, a page break is done before outputting.
 	 * IMPORTANT: The HTML must be well formatted - try to clean-up it using an application like HTML-Tidy before submitting.
@@ -17240,12 +17289,11 @@ class TCPDF {
 	 * @param float $h Cell minimum height. The cell extends automatically if needed.
 	 * @param float|null $x upper-left corner X coordinate
 	 * @param float|null $y upper-left corner Y coordinate
 	 * @param string $html html text to print. Default value: empty string.
 	 * @param mixed $border Indicates if borders must be drawn around the cell. The value can be a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul> or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul> or an array of line styles for each border group - for example: array('LTRB' => array('width' => 2, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0)))
-	 * @param int $ln Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right (or left for RTL language)</li><li>1: to the beginning of the next line</li><li>2: below</li></ul>
-Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.
+	 * @param int $ln Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right (or left for RTL language)</li><li>1: to the beginning of the next line</li><li>2: below</li></ul> Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.
 	 * @param boolean $fill Indicates if the cell background must be painted (true) or transparent (false).
 	 * @param boolean $reseth if true reset the last cell height (default true).
 	 * @param string $align Allows to center or align the text. Possible values are:<ul><li>L : left align</li><li>C : center</li><li>R : right align</li><li>'' : empty string : left for LTR or right for RTL</li></ul>
 	 * @param boolean $autopadding if true, uses internal padding and automatically adjust it to account for line width.
 	 * @see Multicell(), writeHTML()
@@ -19502,21 +19550,18 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
 				break;
 			}
 			case 'tcpdf': {
 				if (defined('K_TCPDF_CALLS_IN_HTML') AND (K_TCPDF_CALLS_IN_HTML === true)) {
 					// Special tag used to call TCPDF methods
-					if (isset($tag['attribute']['method'])) {
-						$tcpdf_method = $tag['attribute']['method'];
-						if (method_exists($this, $tcpdf_method)) {
-							if (isset($tag['attribute']['params']) AND (!empty($tag['attribute']['params']))) {
-								$params = $this->unserializeTCPDFtagParameters($tag['attribute']['params']);
-								call_user_func_array(array($this, $tcpdf_method), $params);
-							} else {
-								$this->$tcpdf_method();
-							}
-							$this->newline = true;
+					// This tag is disabled by default by the K_TCPDF_CALLS_IN_HTML constant on TCPDF configuration file.
+					// Please use this feature only if you are in control of the HTML content and you are sure that it does not contain any harmful code.
+					if (!empty($tag['attribute']['data'])) {
+						$tcpdf_tag_data = $this->unserializeTCPDFtag($tag['attribute']['data']);
+						if ($this->allowedTCPDFtag($tcpdf_tag_data['m'])) {
+							call_user_func_array(array($this, $tcpdf_tag_data['m']), $tcpdf_tag_data['p']);
 						}
+						$this->newline = true;
 					}
 				}
 				break;
 			}
 			default: {
@@ -21859,29 +21904,27 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
 	 * @return TCPDF object.
 	 * @public
 	 * @since 4.5.029 (2009-03-19)
 	 */
 	public function rollbackTransaction($self=false) {
-		if (isset($this->objcopy)) {
-			$objcopy = $this->objcopy;
-			$this->_destroy(true, true);
-			if ($self) {
-				$objvars = get_object_vars($objcopy);
-				foreach ($objvars as $key => $value) {
-					$this->$key = $value;
-				}
-				$objcopy->_destroy(true, true);
-				/* The unique file_id should not be used during cleanup again */
-				$objcopy->file_id = NULL;
-				unset($objcopy);
-				return $this;
+		if (!isset($this->objcopy)) {
+			return $this;
+		}
+		$file_id = $this->file_id;
+		$objcopy = $this->objcopy;
+		$this->_destroy(true, true);
+		if ($self) {
+			$objvars = get_object_vars($objcopy);
+			foreach ($objvars as $key => $value) {
+				$this->$key = $value;
 			}
-			/* The unique file_id should not be used during cleanup again */
-			$this->file_id = NULL;
-			return $objcopy;
+			$objcopy->_destroy(true, true);
+			unset($objcopy);
+			return $this;
 		}
-		return $this;
+		$this->file_id = $file_id;
+		return $objcopy;
 	}
 
 	// --- MULTI COLUMNS METHODS -----------------------
 
 	/**
@@ -22053,11 +22096,11 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
 	 * @since 4.9.008 (2009-04-02)
 	 */
 	public function setTextRenderingMode($stroke=0, $fill=true, $clip=false) {
 		// Ref.: PDF 32000-1:2008 - 9.3.6 Text Rendering Mode
 		// convert text rendering parameters
-		if ($stroke < 0) {
+		if ($stroke < 0 || !is_numeric($stroke)) {
 			$stroke = 0;
 		}
 		if ($fill === true) {
 			if ($stroke > 0) {
 				if ($clip === true) {
diff --git a/tcpdf_autoconfig.php b/tcpdf_autoconfig.php
index 6ec9ce83..2bcfccb8 100644
--- a/tcpdf_autoconfig.php
+++ b/tcpdf_autoconfig.php
@@ -226,10 +226,14 @@ if (!defined('K_THAI_TOPCHARS')) {
 
 if (!defined('K_TCPDF_CALLS_IN_HTML')) {
 	define('K_TCPDF_CALLS_IN_HTML', false);
 }
 
+if (!defined('K_ALLOWED_TCPDF_TAGS')) {
+	define('K_ALLOWED_TCPDF_TAGS', '');
+}
+
 if (!defined('K_TCPDF_THROW_EXCEPTION_ERROR')) {
 	define('K_TCPDF_THROW_EXCEPTION_ERROR', false);
 }
 
 if (!defined('K_TIMEZONE')) {
diff --git a/tcpdf_barcodes_1d.php b/tcpdf_barcodes_1d.php
index 10a79a72..45d35616 100644
--- a/tcpdf_barcodes_1d.php
+++ b/tcpdf_barcodes_1d.php
@@ -826,31 +826,31 @@ class TCPDFBarcode {
 		$chr['3'] = '11101110101010';
 		$chr['4'] = '10101110101110';
 		$chr['5'] = '11101011101010';
 		$chr['6'] = '10111011101010';
 		$chr['7'] = '10101011101110';
-		$chr['8'] = '10101110111010';
+		$chr['8'] = '11101010111010';
 		$chr['9'] = '10111010111010';
 		if ($checksum) {
 			// add checksum
 			$code .= $this->checksum_s25($code);
 		}
 		if((strlen($code) % 2) != 0) {
 			// add leading zero if code-length is odd
 			$code = '0'.$code;
 		}
-		$seq = '11011010';
+		$seq = '1110111010';
 		$clen = strlen($code);
 		for ($i = 0; $i < $clen; ++$i) {
 			$digit = $code[$i];
 			if (!isset($chr[$digit])) {
 				// invalid character
 				return false;
 			}
 			$seq .= $chr[$digit];
 		}
-		$seq .= '1101011';
+		$seq .= '111010111';
 		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
 		return $this->binseq_to_array($seq, $bararray);
 	}
 
 	/**
diff --git a/tests/composer.json b/tests/composer.json
index 065fcbeb..3edd4a90 100644
--- a/tests/composer.json
+++ b/tests/composer.json
@@ -1,36 +1,26 @@
 {
     "name": "tecnickcom/tcpdf-tests",
     "type": "metapackage",
     "description": "Dependencies for the test suite",
-    "keywords": [
-        "PDF",
-        "tcpdf",
-        "test"
-    ],
     "homepage": "http://www.tcpdf.org/",
-    "license": "LGPL-3.0-only",
+    "license": "LGPL-3.0-or-later",
     "authors": [
         {
             "name": "Philippe Jausions",
             "email": "jausions@11abacus.com",
             "role": "contributor"
         }
     ],
     "require": {
         "PHP": ">=5.3.0",
-        "cs278/mktemp": "*"
+        "cs278/mktemp": "^1.2.0"
     },
     "suggest": {
         "rosell-dk/locate-binaries": "Allows to detect executables such as pdfinfo"
     },
     "autoload": {
         "psr-4": {
             "Tecnickcom\\TCPDF\\Tests\\": "src/"
         }
-    },
-    "archive": {
-        "exclude": [
-            "/examples"
-        ]
     }
 }

Vulnerable code:   2002-2022 Nicola Asuni - Tecnick.com LTD
* **copyright**   2002-2022 Nicola Asuni - Tecnick.com LTD
## IMPORTANT
A new version of this library is under development at https://github.com/tecnickcom/tc-lib-pdf and as a consequence this version will not receive any additional development or support.
This version should be considered obsolete, new projects should use the new version as soon it will become stable.
6.6.2
// Last Update : 2014-12-10
If you are printing user-generated content, tcpdf tag can be unsafe.
You can disable this tag by setting to false the K_TCPDF_CALLS_IN_HTML
constant on TCPDF configuration file.
For security reasons, the parameters for the 'params' attribute of TCPDF
<span style="color:red;">If you are using user-generated content, the tcpdf tag can be unsafe.<br />
You can disable this tag by setting to false the <b>K_TCPDF_CALLS_IN_HTML</b> constant on TCPDF configuration file.</span>
$params = $pdf->serializeTCPDFtagParameters(array('CODE 39', 'C39', '', '', 80, 30, 0.4, array('position'=>'S', 'border'=>true, 'padding'=>4, 'fgcolor'=>array(0,0,0), 'bgcolor'=>array(255,255,255), 'text'=>true, 'font'=>'helvetica', 'fontsize'=>8, 'stretchtext'=>4), 'N'));
$html .= '<tcpdf method="write1DBarcode" params="'.$params.'" />';
$params = $pdf->serializeTCPDFtagParameters(array('CODE 128', 'C128', '', '', 80, 30, 0.4, array('position'=>'S', 'border'=>true, 'padding'=>4, 'fgcolor'=>array(0,0,0), 'bgcolor'=>array(255,255,255), 'text'=>true, 'font'=>'helvetica', 'fontsize'=>8, 'stretchtext'=>4), 'N'));
$html .= '<tcpdf method="write1DBarcode" params="'.$params.'" />';
$html .= '<tcpdf method="AddPage" /><h2>Graphic Functions</h2>';
$params = $pdf->serializeTCPDFtagParameters(array(0));
$html .= '<tcpdf method="SetDrawColor" params="'.$params.'" />';
$params = $pdf->serializeTCPDFtagParameters(array(50, 50, 40, 10, 'DF', array(), array(0,128,255)));
$html .= '<tcpdf method="Rect" params="'.$params.'" />';
// Load the autoloader, move one folder back from examples
require_once __DIR__ . '/../vendor/autoload.php';
				$pad = 4 - ($table[$tag]['length'] % 4);
				if ($pad != 4) {
					// the length of a table must be a multiple of four bytes
					$table[$tag]['length'] += $pad;
					$table[$tag]['data'] .= str_repeat("\x0", $pad);
				}
				//$table[$tag]['checkSum'] = self::_getTTFtableChecksum($table[$tag]['data'], $table[$tag]['length']);
		$pad = 4 - ($table['loca']['length'] % 4);
		if ($pad != 4) {
			// the length of a table must be a multiple of four bytes
			$table['loca']['length'] += $pad;
			$table['loca']['data'] .= str_repeat("\x0", $pad);
		}
		$table['loca']['checkSum'] = self::_getTTFtableChecksum($table['loca']['data'], $table['loca']['length']);
		$pad = 4 - ($table['glyf']['length'] % 4);
		if ($pad != 4) {
			// the length of a table must be a multiple of four bytes
			$table['glyf']['length'] += $pad;
			$table['glyf']['data'] .= str_repeat("\x0", $pad);
		}
		$table['glyf']['checkSum'] = self::_getTTFtableChecksum($table['glyf']['data'], $table['glyf']['length']);
		$font = substr($font, 0, $table['head']['offset'] + 8).pack('N', $checkSumAdjustment).substr($font, $table['head']['offset'] + 12);
			return array_map(array('TCPDF_FONTS', 'unichrUnicode'), $ta);
		return array_map(array('TCPDF_FONTS', 'unichrASCII'), $ta);
			$carr = array_map(array('TCPDF_FONTS', 'uniord'), $chars);
// Last Update : 2022-08-12
// Copyright (C) 2002-2022 Nicola Asuni - Tecnick.com LTD
	private static $tcpdf_version = '6.6.2';
			return $ret;
	 * 
        # remove once https://github.com/phpstan/phpstan/issues/7955 is fixed
        - fonts/
// Version     : 6.6.2
// Last Update : 2022-12-06
// Copyright (C) 2002-2022 Nicola Asuni - Tecnick.com LTD
 * @version 6.6.2
 * @version 6.6.2

		if ($padding) {
	 * @param int $hm distance in user units
	 * @param int $fm distance in user units
		if (!isset($name) OR empty($name)) {
		if (isset($diff) AND (!empty($diff))) {
		$maxchwidth = max($chrw);
			$font = $this->getFontBuffer('helvetica');
		$key = 0;
		// create an array of elements
		$dom = array();
		$dom[$key] = array();
		// set inheritable properties fot the first void element
		// possible inheritable properties are: azimuth, border-collapse, border-spacing, caption-side, color, cursor, direction, empty-cells, font, font-family, font-stretch, font-size, font-size-adjust, font-style, font-variant, font-weight, letter-spacing, line-height, list-style, list-style-image, list-style-position, list-style-type, orphans, page, page-break-inside, quotes, speak, speak-header, text-align, text-indent, text-transform, volume, white-space, widows, word-spacing
		$dom[$key]['tag'] = false;
		$dom[$key]['block'] = false;
		$dom[$key]['value'] = '';
		$dom[$key]['parent'] = 0;
		$dom[$key]['hide'] = false;
		$dom[$key]['fontname'] = $this->FontFamily;
		$dom[$key]['fontstyle'] = $this->FontStyle;
		$dom[$key]['fontsize'] = $this->FontSizePt;
		$dom[$key]['font-stretch'] = $this->font_stretching;
		$dom[$key]['letter-spacing'] = $this->font_spacing;
		$dom[$key]['stroke'] = $this->textstrokewidth;
		$dom[$key]['fill'] = (($this->textrendermode % 2) == 0);
		$dom[$key]['clip'] = ($this->textrendermode > 3);
		$dom[$key]['line-height'] = $this->cell_height_ratio;
		$dom[$key]['bgcolor'] = false;
		$dom[$key]['fgcolor'] = $this->fgcolor; // color
		$dom[$key]['strokecolor'] = $this->strokecolor;
		$dom[$key]['align'] = '';
		$dom[$key]['listtype'] = '';
		$dom[$key]['text-indent'] = 0;
		$dom[$key]['text-transform'] = '';
		$dom[$key]['border'] = array();
		$dom[$key]['dir'] = $this->rtl?'rtl':'ltr';
		++$key;
	 * Return an hash code used to ensure that the serialized data has been generated by this TCPDF instance.
	 * @param string $data serialized data
	 * @return string
	 * @public static
	protected function getHashForTCPDFtagParams($data) {
		return md5(strlen($data).$this->file_id.$data);
	 * Serialize an array of parameters to be used with TCPDF tag in HTML code.
	 * @param array $data parameters array
	 * @return string containing serialized data
	public function serializeTCPDFtagParameters($data) {
		return $this->getHashForTCPDFtagParams($encoded).$encoded;
	 * Unserialize parameters to be used with TCPDF tag in HTML code.
	protected function unserializeTCPDFtagParameters($data) {
		$hash = substr($data, 0, 32);
		$encoded = substr($data, 32);
		if ($hash != $this->getHashForTCPDFtagParams($encoded)) {
	 * @param int $ln Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right (or left for RTL language)</li><li>1: to the beginning of the next line</li><li>2: below</li></ul>
Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.
					if (isset($tag['attribute']['method'])) {
						$tcpdf_method = $tag['attribute']['method'];
						if (method_exists($this, $tcpdf_method)) {
							if (isset($tag['attribute']['params']) AND (!empty($tag['attribute']['params']))) {
								$params = $this->unserializeTCPDFtagParameters($tag['attribute']['params']);
								call_user_func_array(array($this, $tcpdf_method), $params);
							} else {
								$this->$tcpdf_method();
							}
							$this->newline = true;
		if (isset($this->objcopy)) {
			$objcopy = $this->objcopy;
			$this->_destroy(true, true);
			if ($self) {
				$objvars = get_object_vars($objcopy);
				foreach ($objvars as $key => $value) {
					$this->$key = $value;
				}
				$objcopy->_destroy(true, true);
				/* The unique file_id should not be used during cleanup again */
				$objcopy->file_id = NULL;
				unset($objcopy);
				return $this;
			/* The unique file_id should not be used during cleanup again */
			$this->file_id = NULL;
			return $objcopy;
		return $this;
		if ($stroke < 0) {
		$chr['8'] = '10101110111010';
		$seq = '11011010';
		$seq .= '1101011';
    "keywords": [
        "PDF",
        "tcpdf",
        "test"
    ],
    "license": "LGPL-3.0-only",
        "cs278/mktemp": "*"
    },
    "archive": {
        "exclude": [
            "/examples"
        ]
Fixed code: 6.7.4 (2024-03-24)
	- Upgrade tcpdf tag encryption algorithm.
	- Fix regression issue #699.
	- Fix security issue.
	- [BREAKING CHANGE] The tcpdf HTML tag syntax has changed, see example_049.php.
	- New K_ALLOWED_TCPDF_TAGS configuration constant to set the allowed methods for the tcdpf HTML tag.
	- Raised minimum PHP version to PHP 5.5.0.

6.6.5 (2023-09-02)
	- Fix corrupted file.
	- Fix GitHub automation tests.
	- Fix SPDX license ID (#591)
	- Fix warning "array offset on value of type null" (#620)
	- Improve the README about the status of this library (#589)
	- Fix deprecation warning with PHP 8.1 (#614)
	- Fixes for PHP 8.2 in tcpdf_fonts.php (#632)
	- Fix some php 8+ edge cases (#630)
	- Fix composite glyph output (#581)
	- Fix "access array offset on value of type bool" with PDF/A (#583)
	- Fix non-numeric value warning (#627)
	- Fix issues with S25 barcode (#611)
	- Fix return type annotations (#613)
	- Fix some inconsistencies in type hints (#598)

  2002-2024 Nicola Asuni - Tecnick.com LTD
* **copyright**   2002-2024 Nicola Asuni - Tecnick.com LTD
## NOTE
A new version of this library is under development at https://github.com/tecnickcom/tc-lib-pdf and as a consequence this library is in support only mode.
6.7.4
/**
 * List of TCPDF methods that are allowed to be called using HTML syntax.
 * Note: each method name must end with surrounded with | (pipe) character.
 * The constant K_TCPDF_CALLS_IN_HTML must be set to true.
 * IMPORTANT: For security reason, disable this feature if you are allowing user HTML content.
 */
define('K_ALLOWED_TCPDF_TAGS', '');

/**
 * List of TCPDF methods that are allowed to be called using HTML syntax.
 * Note: each method name must end with surrounded with | (pipe) character.
 * The constant K_TCPDF_CALLS_IN_HTML must be set to true.
 * IMPORTANT: For security reason, disable this feature if you are allowing user HTML content.
 */
define('K_ALLOWED_TCPDF_TAGS', '|AddPage|Rect|SetDrawColor|write1DBarcode|');

// Last Update : 2024-03-18
If you are printing user-generated content, the tcpdf tag should be considered unsafe.
This tag is disabled by default by the K_TCPDF_CALLS_IN_HTML constant on TCPDF configuration file.
Please use this feature only if you are in control of the HTML content and you are sure that it does not contain any harmful code.
For security reasons, the parameters for the 'params' attribute of TCPDF 
<span style="color:red;">If you are using user-generated content, the tcpdf tag should be considered unsafe.<br />
Please use this feature only if you are in control of the HTML content and you are sure that it does not contain any harmful code.<br />
This feature is disabled by default by the <b>K_TCPDF_CALLS_IN_HTML</b> constant on TCPDF configuration file.</span>
$data = $pdf->serializeTCPDFtag('write1DBarcode', array('CODE 39', 'C39', '', '', 80, 30, 0.4, array('position'=>'S', 'border'=>true, 'padding'=>4, 'fgcolor'=>array(0,0,0), 'bgcolor'=>array(255,255,255), 'text'=>true, 'font'=>'helvetica', 'fontsize'=>8, 'stretchtext'=>4), 'N'));
$html .= '<tcpdf data="'.$data.'" />';
$data = $pdf->serializeTCPDFtag('write1DBarcode', array('CODE 128', 'C128', '', '', 80, 30, 0.4, array('position'=>'S', 'border'=>true, 'padding'=>4, 'fgcolor'=>array(0,0,0), 'bgcolor'=>array(255,255,255), 'text'=>true, 'font'=>'helvetica', 'fontsize'=>8, 'stretchtext'=>4), 'N'));
$html .= '<tcpdf data="'.$data.'" />';
$data = $pdf->serializeTCPDFtag('AddPage');
$html .= '<tcpdf data="'.$data.'" /><h2>Graphic Functions</h2>';
$data = $pdf->serializeTCPDFtag('SetDrawColor', array(0));
$html .= '<tcpdf data="'.$data.'" />';
$data = $pdf->serializeTCPDFtag('Rect', array(50, 50, 40, 10, 'DF', array(), array(0,128,255)));
$html .= '<tcpdf data="'.$data.'" />';
// Include the main TCPDF library (search for installation path).
require_once('tcpdf_include.php');
			$row = (int) $row;
				$numPad = ($offset + 3 & ~3) - $offset;
				if($numPad > 0) {
					$table[$tag]['data'] .= str_repeat("\x0", $numPad);
					$offset += $numPad;
				}
				//$table[$tag]['checkSum'] = self::_getTTFtableChecksum($table[$tag]['data'], $table[$tag]['length'] + $numPad);
		$table['loca'] = array();
		$numPad = ($offset + 3 & ~3) - $offset;
		if($numPad > 0) {
			$table['loca']['data'] .= str_repeat("\x0", $numPad);
			$offset += $numPad;
		}
		$table['loca']['checkSum'] = self::_getTTFtableChecksum($table['loca']['data'], $table['loca']['length'] + $numPad);
		$table['glyf'] = array();
		$offset += $table['glyf']['length'];
		$numPad = ($offset + 3 & ~3) - $offset;
		if($numPad > 0) {
			$table['glyf']['data'] .= str_repeat("\x0", $numPad);
			$offset += $numPad;
		}
		$table['glyf']['checkSum'] = self::_getTTFtableChecksum($table['glyf']['data'], $table['glyf']['length'] + $numPad);
		$font = substr($font, 0, $table['head']['offset'] + $offset + 8).pack('N', $checkSumAdjustment).substr($font, $table['head']['offset'] + $offset + 12);
			return array_map(get_called_class().'::unichrUnicode', $ta);
		return array_map(get_called_class().'::unichrASCII', $ta);
			$carr = array_map(get_called_class().'::uniord', $chars);
// Last Update : 2023-09-06
// Copyright (C) 2002-2023 Nicola Asuni - Tecnick.com LTD
	private static $tcpdf_version = '6.7.4';
			return is_array($ret) ? $ret : array();
	 *
// Version     : 6.7.4
// Last Update : 2024-03-18
// Copyright (C) 2002-2024 Nicola Asuni - Tecnick.com LTD
 * @version 6.6.5
 * @version 6.7.4
	 * @var float
	 * @var float
	/**
	 * Internal secret used to encrypt data.
	 * @protected
	 * @since 6.7.4 (2024-03-21)
	 */
	protected $hash_key;

		$this->hash_key = hash_hmac('sha256', TCPDF_STATIC::getRandomSeed($this->file_id), TCPDF_STATIC::getRandomSeed('TCPDF'), false);
		if ($padding && !empty($this->cell_padding)) {
	 * @param float $hm distance in user units
	 * @param float $fm distance in user units
	 * @phpstan-return ($getarray is true ? float[] : float) total string length or array of characted widths
	 * @phpstan-return ($getarray is true ? float[] : float) total string length or array of characted widths
		if (empty($name)) {
		if (!empty($diff)) {
		$maxchwidth = ((is_array($chrw) || $chrw instanceof Countable) && count($chrw) > 0) ? max($chrw) : 0;
			// fallback to avoid division by zero
			$h = $h == 0 ? 1 : $h;
			$font = $this->getFontBuffer((($this->pdfa_mode) ? 'pdfa' : '') .'helvetica');
		// set inheritable properties fot the first void element
		// possible inheritable properties are: azimuth, border-collapse, border-spacing, caption-side, color, cursor, direction, empty-cells, font, font-family, font-stretch, font-size, font-size-adjust, font-style, font-variant, font-weight, letter-spacing, line-height, list-style, list-style-image, list-style-position, list-style-type, orphans, page, page-break-inside, quotes, speak, speak-header, text-align, text-indent, text-transform, volume, white-space, widows, word-spacing
		$dom = array(
			array(
				'tag' => false,
				'block' => false,
				'value' => '',
				'parent' => 0,
				'hide' => false,
				'fontname' => $this->FontFamily,
				'fontstyle' => $this->FontStyle,
				'fontsize' => $this->FontSizePt,
				'font-stretch' => $this->font_stretching,
				'letter-spacing' => $this->font_spacing,
				'stroke' => $this->textstrokewidth,
				'fill' => (($this->textrendermode % 2) == 0),
				'clip' => ($this->textrendermode > 3),
				'line-height' => $this->cell_height_ratio,
				'bgcolor' => false,
				'fgcolor' => $this->fgcolor, // color
				'strokecolor' => $this->strokecolor,
				'align' => '',
				'listtype' => '',
				'text-indent' => 0,
				'text-transform' => '',
				'border' => array(),
				'dir' => $this->rtl?'rtl':'ltr',
				'width' => 0,
				'height' => 0,
				'x' => 0,
				'y' => 0,
				'w' => 0,
				'h' => 0,
				'l' => 0,
				't' => 0,
				'r' => 0,
				'b' => 0,
				'padding' => array('T' => 0, 'R' => 0, 'B' => 0, 'L' => 0),
				'margin' => array('T' => 0, 'R' => 0, 'B' => 0, 'L' => 0),
				'border-spacing' => array('H' => 0, 'V' => 0),
				'border-collapse' => 'separate',
			)
		);

		if(empty($html)) {
			return $dom;
		}
		$key = 1;
	 * Calculates the hash value of the given data.
	 *
	 * @param string $data The data to be hashed.
	 * @return string The hashed value of the data.
	protected function hashTCPDFtag($data) {
		return hash_hmac('sha256', $data, $this->hash_key, false);
	 * Serialize data to be used with TCPDF tag in HTML code.
	 * @param string $method TCPDF method name
	 * @param array $params Method parameters
	 * @return string Serialized data
	public function serializeTCPDFtag($method, $params=array()) {
		$data = array('m' => $method, 'p' => $params);
		$hash = $this->hashTCPDFtag($encoded);
		return strlen($hash).'+'.$hash.'+'.$encoded;
	 * Unserialize data to be used with TCPDF tag in HTML code.
	protected function unserializeTCPDFtag($data) {
		$hpos = strpos($data, '+');
		$hlen = intval(substr($data, 0, $hpos));
		$hash = substr($data, $hpos + 1, $hlen);
		$encoded = substr($data, $hpos + 2 + $hlen);
		if ($hash != $this->hashTCPDFtag($encoded)) {
	/**
	 * Check if a TCPDF tag is allowed
	 * @param string $method TCPDF method name
	 * @return boolean
	 * @protected
	 */
	protected function allowedTCPDFtag($method) {
		if (defined('K_ALLOWED_TCPDF_TAGS')) {
			return (strpos(K_ALLOWED_TCPDF_TAGS, '|'.$method.'|') !== false);
		}
		return false;
	}

	 * @param int $ln Indicates where the current position should go after the call. Possible values are:<ul><li>0: to the right (or left for RTL language)</li><li>1: to the beginning of the next line</li><li>2: below</li></ul> Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: 0.
					// This tag is disabled by default by the K_TCPDF_CALLS_IN_HTML constant on TCPDF configuration file.
					// Please use this feature only if you are in control of the HTML content and you are sure that it does not contain any harmful code.
					if (!empty($tag['attribute']['data'])) {
						$tcpdf_tag_data = $this->unserializeTCPDFtag($tag['attribute']['data']);
						if ($this->allowedTCPDFtag($tcpdf_tag_data['m'])) {
							call_user_func_array(array($this, $tcpdf_tag_data['m']), $tcpdf_tag_data['p']);
						$this->newline = true;
		if (!isset($this->objcopy)) {
			return $this;
		}
		$file_id = $this->file_id;
		$objcopy = $this->objcopy;
		$this->_destroy(true, true);
		if ($self) {
			$objvars = get_object_vars($objcopy);
			foreach ($objvars as $key => $value) {
				$this->$key = $value;
			$objcopy->_destroy(true, true);
			unset($objcopy);
			return $this;
		$this->file_id = $file_id;
		return $objcopy;
		if ($stroke < 0 || !is_numeric($stroke)) {
if (!defined('K_ALLOWED_TCPDF_TAGS')) {
	define('K_ALLOWED_TCPDF_TAGS', '');
}

		$chr['8'] = '11101010111010';
		$seq = '1110111010';
		$seq .= '111010111';
    "license": "LGPL-3.0-or-later",
        "cs278/mktemp": "^1.2.0"