CVE-2024-32489 (published 2024-04-15T06:15Z)

TCPDF before 6.7.4 mishandles calls that use HTML syntax.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/tecnickcom/TCPDF
commit_details: repo_url: https://github.com/tecnickcom/TCPDF
author: nicolaasuni
author_date: 2024-03-25 23:52:22+00:00
msg: Squash multiple fixes
repository: repo_url: https://github.com/tecnickcom/TCPDF
repo_name: tecnickcom/TCPDF
description: Official clone of PHP library to generate PDF documents and barcodes
repo_language: PHP
owner: tecnickcom
file_changes: filename: CHANGELOG.TXT
change_type: ModificationType.MODIFY
diff: @@ -1,3 +1,27 @@
+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)

programming_language: Markdown
filename: LICENSE.TXT
change_type: ModificationType.MODIFY
diff: @@ -7,7 +7,7 @@
   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
 
 **********************************************************************
 **********************************************************************

programming_language: C
filename: README.md
change_type: ModificationType.MODIFY
diff: @@ -6,15 +6,14 @@
 
 * **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.
 
 
 

programming_language: Markdown
filename: VERSION
change_type: ModificationType.MODIFY
diff: @@ -1 +1 @@
-6.6.2
+6.7.4

programming_language: SQL
filename: tcpdf_config.php
change_type: ModificationType.MODIFY
diff: @@ -212,6 +212,14 @@ define('K_THAI_TOPCHARS', true);
  */
 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.
  */

programming_language: PHP
filename: tcpdf_config_alt.php
change_type: ModificationType.MODIFY
diff: @@ -212,6 +212,14 @@ define('K_THAI_TOPCHARS', true);
  */
 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.
  */

programming_language: PHP
filename: example_049.php
change_type: ModificationType.MODIFY
diff: @@ -2,7 +2,7 @@
 //============================================================+
 // 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
@@ -78,11 +78,11 @@ $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).
 
@@ -91,23 +91,25 @@ 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

programming_language: PHP
filename: example_066.php
change_type: ModificationType.MODIFY
diff: @@ -18,8 +18,8 @@
  * @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);

programming_language: PHP
filename: qrcode.php
change_type: ModificationType.MODIFY
diff: @@ -888,6 +888,7 @@ class QRcode {
 			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;

programming_language: PHP
filename: tcpdf_fonts.php
change_type: ModificationType.MODIFY
diff: @@ -1323,43 +1323,43 @@ class TCPDF_FONTS {
 					// 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
@@ -1383,7 +1383,7 @@ class TCPDF_FONTS {
 		}
 		// 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;
 	}
 
@@ -1780,9 +1780,9 @@ class TCPDF_FONTS {
 	 */
 	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);
 	}
 
 	/**
@@ -2002,7 +2002,7 @@ class TCPDF_FONTS {
 		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);

programming_language: PHP
filename: tcpdf_static.php
change_type: ModificationType.MODIFY
diff: @@ -3,11 +3,11 @@
 // 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.
 //
@@ -55,7 +55,7 @@ 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.
@@ -1780,7 +1780,7 @@ class TCPDF_STATIC {
 			if ($ret === false) {
 				return array();
 			}
-			return $ret;
+			return is_array($ret) ? $ret : array();
 		}
 		// preg_split is bugged - try alternative solution
 		$ret = array();
@@ -2124,7 +2124,7 @@ 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(

programming_language: PHP
filename: phpstan.neon.dist
change_type: ModificationType.MODIFY
diff: @@ -4,8 +4,6 @@ parameters:
         - ./
     excludePaths:
         - vendor/
-        # remove once https://github.com/phpstan/phpstan/issues/7955 is fixed
-        - fonts/
         - tests/
 
     scanFiles:

programming_language: Batchfile
filename: tcpdf.php
change_type: ModificationType.MODIFY
diff: @@ -1,13 +1,13 @@
 <?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.
 //
@@ -104,7 +104,7 @@
  * 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
@@ -128,7 +128,7 @@ require_once(dirname(__FILE__).'/include/tcpdf_static.php');
  * 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")
@@ -574,12 +574,14 @@ class TCPDF {
 	/**
 	 * 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;
 
@@ -836,6 +838,13 @@ class TCPDF {
 	 */
 	protected $file_id;
 
+	/**
+	 * Internal secret used to encrypt data.
+	 * @protected
+	 * @since 6.7.4 (2024-03-21)
+	 */
+	protected $hash_key;
+
 	// --- bookmark ---
 
 	/**
@@ -1878,10 +1887,10 @@ class TCPDF {
 		// 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;
@@ -2461,7 +2470,7 @@ class TCPDF {
 	 */
 	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);
@@ -3372,7 +3381,7 @@ 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) {
@@ -3392,7 +3401,7 @@ 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) {
@@ -4102,6 +4111,7 @@ class TCPDF {
 	 * @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
@@ -4118,6 +4128,7 @@ class TCPDF {
 	 * @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)
@@ -4423,7 +4434,7 @@ class TCPDF {
 			$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)
@@ -4466,7 +4477,7 @@ class TCPDF {
 			// 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);
@@ -6409,7 +6420,7 @@ class TCPDF {
 		// 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
@@ -6872,6 +6883,8 @@ class TCPDF {
 		}
 		// 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;
@@ -9925,7 +9938,7 @@ class TCPDF {
 				}
 				$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 ';
@@ -16383,6 +16396,53 @@ class TCPDF {
 	 * @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
@@ -16527,37 +16587,8 @@ class TCPDF {
 		// 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) {
@@ -17194,41 +17225,59 @@ class TCPDF {
 	}
 
 	/**
-	 * 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 />
@@ -17242,8 +17291,7 @@ class TCPDF {
 	 * @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>
@@ -19504,17 +19552,14 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
 			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;
@@ -21861,25 +21906,23 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
 	 * @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 -----------------------
@@ -22055,7 +22098,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
 	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) {

programming_language: PHP
filename: tcpdf_autoconfig.php
change_type: ModificationType.MODIFY
diff: @@ -228,6 +228,10 @@ 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);
 }

programming_language: PHP
filename: tcpdf_barcodes_1d.php
change_type: ModificationType.MODIFY
diff: @@ -828,7 +828,7 @@ class TCPDFBarcode {
 		$chr['5'] = '11101011101010';
 		$chr['6'] = '10111011101010';
 		$chr['7'] = '10101011101110';
-		$chr['8'] = '10101110111010';
+		$chr['8'] = '11101010111010';
 		$chr['9'] = '10111010111010';
 		if ($checksum) {
 			// add checksum
@@ -838,7 +838,7 @@ class TCPDFBarcode {
 			// 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];
@@ -848,7 +848,7 @@ class TCPDFBarcode {
 			}
 			$seq .= $chr[$digit];
 		}
-		$seq .= '1101011';
+		$seq .= '111010111';
 		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
 		return $this->binseq_to_array($seq, $bararray);
 	}

programming_language: PHP
filename: composer.json
change_type: ModificationType.MODIFY
diff: @@ -2,13 +2,8 @@
     "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",
@@ -18,7 +13,7 @@
     ],
     "require": {
         "PHP": ">=5.3.0",
-        "cs278/mktemp": "*"
+        "cs278/mktemp": "^1.2.0"
     },
     "suggest": {
         "rosell-dk/locate-binaries": "Allows to detect executables such as pdfinfo"
@@ -27,10 +22,5 @@
         "psr-4": {
             "Tecnickcom\\TCPDF\\Tests\\": "src/"
         }
-    },
-    "archive": {
-        "exclude": [
-            "/examples"
-        ]
     }
 }

programming_language: JavaScript