Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,14 @@ jobs:
php-version: ["7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2"]
os: [ubuntu-latest]
experimental: [false]
php-extensions: ["bcmath, imagick, gd"]
php-extensions: ["bcmath, curl, imagick, gd"]
coverage-extension: ["none"]
# Add more specific tests
include:
- { php-version: '5.5', experimental: false, os: ubuntu-latest, php-extensions: 'bcmath, imagick, gd', coverage-extension: 'xdebug' }
- { php-version: '5.6', experimental: false, os: ubuntu-latest, php-extensions: 'bcmath, imagick, gd', coverage-extension: 'xdebug' }
- { php-version: '7.0', experimental: false, os: ubuntu-latest, php-extensions: 'bcmath, imagick, gd', coverage-extension: 'xdebug' }
#- { php-version: '8.2', experimental: false, os: macos-latest, php-extensions: 'bcmath, imagick, gd', coverage-extension: 'none' }
- { php-version: '8.2', experimental: false, os: windows-latest, php-extensions: 'bcmath, imagick, gd', coverage-extension: 'none' }
- { php-version: '8.3', experimental: true, os: ubuntu-latest, php-extensions: 'bcmath, imagick, gd', coverage-extension: 'pcov' }
- { php-version: 'nightly', experimental: true, os: ubuntu-latest, php-extensions: 'bcmath, imagick, gd', coverage-extension: 'pcov' }
#- { php-version: '8.2', experimental: false, os: macos-latest, php-extensions: 'bcmath, curl, imagick, gd', coverage-extension: 'none' }
- { php-version: '8.2', experimental: false, os: windows-latest, php-extensions: 'bcmath, curl, imagick, gd', coverage-extension: 'none' }
- { php-version: '8.3', experimental: true, os: ubuntu-latest, php-extensions: 'bcmath, curl, imagick, gd', coverage-extension: 'pcov' }
- { php-version: 'nightly', experimental: true, os: ubuntu-latest, php-extensions: 'bcmath, curl, imagick, gd', coverage-extension: 'pcov' }
env:
PDFINFO_BINARY: ${{ (matrix.os == 'ubuntu-latest') && '/usr/bin/pdfinfo' || ((matrix.os == 'macos-latest') && '/usr/local/bin/pdfinfo' || 'C:\ProgramData\Chocolatey\bin\pdfinfo.exe') }}
steps:
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.TXT
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
6.8.0 (2024-12-23)
- Requires PHP 7.1+ and curl extension.
- Escape error message.
- Use strict time-constant function to compare TCPDF-tag hashes.
- Add K_CURLOPTS config array to set custom cURL options (NOTE: some defaults have changed).
- Add some addTTFfont fixes from tc-lib-pdf-font.

6.7.8 (2024-12-13)
- Improve SVG detection by checking for (mandatory) namespace.
- Use late state binding now that minimum PHP version is 5.5.
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6.7.8
6.8.0
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"barcodes"
],
"homepage": "http://www.tcpdf.org/",
"version": "6.7.8",
"version": "6.8.0",
"license": "LGPL-3.0-or-later",
"authors": [
{
Expand All @@ -22,7 +22,8 @@
}
],
"require": {
"php": ">=5.5.0"
"php": ">=7.1.0",
"ext-curl": "*"
},
"autoload": {
"classmap": [
Expand Down
43 changes: 22 additions & 21 deletions include/tcpdf_fonts.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<?php
//============================================================+
// File name : tcpdf_fonts.php
// Version : 1.1.0
// Version : 1.1.1
// Begin : 2008-01-01
// Last Update : 2014-12-10
// Last Update : 2024-12-23
// 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) 2008-2014 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2008-2024 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
Expand Down Expand Up @@ -42,7 +42,7 @@
* @class TCPDF_FONTS
* Font methods for TCPDF library.
* @package com.tecnick.tcpdf
* @version 1.1.0
* @version 1.1.1
* @author Nicola Asuni - info@tecnick.com
*/
class TCPDF_FONTS {
Expand Down Expand Up @@ -191,29 +191,30 @@ public static function addTTFfont($fontfile, $fonttype='', $enc='', $flags=32, $
fclose($fp);
// get font info
$fmetric['Flags'] = $flags;
preg_match ('#/FullName[\s]*\(([^\)]*)#', $font, $matches);
preg_match ('#/FullName[\s]*+\(([^\)]*+)#', $font, $matches);
$fmetric['name'] = preg_replace('/[^a-zA-Z0-9_\-]/', '', $matches[1]);
preg_match('#/FontBBox[\s]*{([^}]*)#', $font, $matches);
$fmetric['bbox'] = trim($matches[1]);
$bv = explode(' ', $fmetric['bbox']);
$fmetric['Ascent'] = intval($bv[3]);
$fmetric['Descent'] = intval($bv[1]);
preg_match('#/ItalicAngle[\s]*([0-9\+\-]*)#', $font, $matches);
preg_match('#/FontBBox[\s]*+{([^}]*+)#', $font, $matches);
$rawbvl = explode(' ', trim($matches[1]));
$bvl = [(int) $rawbvl[0], (int) $rawbvl[1], (int) $rawbvl[2], (int) $rawbvl[3]];
$fmetric['bbox'] = implode(' ', $bvl);
$fmetric['Ascent'] = $bvl[3];
$fmetric['Descent'] = $bvl[1];
preg_match('#/ItalicAngle[\s]*+([0-9\+\-]*+)#', $font, $matches);
$fmetric['italicAngle'] = intval($matches[1]);
if ($fmetric['italicAngle'] != 0) {
$fmetric['Flags'] |= 64;
}
preg_match('#/UnderlinePosition[\s]*([0-9\+\-]*)#', $font, $matches);
preg_match('#/UnderlinePosition[\s]*+([0-9\+\-]*+)#', $font, $matches);
$fmetric['underlinePosition'] = intval($matches[1]);
preg_match('#/UnderlineThickness[\s]*([0-9\+\-]*)#', $font, $matches);
preg_match('#/UnderlineThickness[\s]*+([0-9\+\-]*+)#', $font, $matches);
$fmetric['underlineThickness'] = intval($matches[1]);
preg_match('#/isFixedPitch[\s]*([^\s]*)#', $font, $matches);
preg_match('#/isFixedPitch[\s]*+([^\s]*+)#', $font, $matches);
if ($matches[1] == 'true') {
$fmetric['Flags'] |= 1;
}
// get internal map
$imap = array();
if (preg_match_all('#dup[\s]([0-9]+)[\s]*/([^\s]*)[\s]put#sU', $font, $fmap, PREG_SET_ORDER) > 0) {
if (preg_match_all('#dup[\s]([0-9]+)[\s]*+/([^\s]*+)[\s]put#sU', $font, $fmap, PREG_SET_ORDER) > 0) {
foreach ($fmap as $v) {
$imap[$v[2]] = $v[1];
}
Expand All @@ -229,22 +230,22 @@ public static function addTTFfont($fontfile, $fonttype='', $enc='', $flags=32, $
$eplain .= chr($chr ^ ($r >> 8));
$r = ((($chr + $r) * $c1 + $c2) % 65536);
}
if (preg_match('#/ForceBold[\s]*([^\s]*)#', $eplain, $matches) > 0) {
if (preg_match('#/ForceBold[\s]*+([^\s]*+)#', $eplain, $matches) > 0) {
if ($matches[1] == 'true') {
$fmetric['Flags'] |= 0x40000;
}
}
if (preg_match('#/StdVW[\s]*\[([^\]]*)#', $eplain, $matches) > 0) {
if (preg_match('#/StdVW[\s]*+\[([^\]]*+)#', $eplain, $matches) > 0) {
$fmetric['StemV'] = intval($matches[1]);
} else {
$fmetric['StemV'] = 70;
}
if (preg_match('#/StdHW[\s]*\[([^\]]*)#', $eplain, $matches) > 0) {
if (preg_match('#/StdHW[\s]*+\[([^\]]*+)#', $eplain, $matches) > 0) {
$fmetric['StemH'] = intval($matches[1]);
} else {
$fmetric['StemH'] = 30;
}
if (preg_match('#/BlueValues[\s]*\[([^\]]*)#', $eplain, $matches) > 0) {
if (preg_match('#/BlueValues[\s]*+\[([^\]]*+)#', $eplain, $matches) > 0) {
$bv = explode(' ', $matches[1]);
if (count($bv) >= 6) {
$v1 = intval($bv[2]);
Expand All @@ -265,15 +266,15 @@ public static function addTTFfont($fontfile, $fonttype='', $enc='', $flags=32, $
$fmetric['CapHeight'] = 700;
}
// get the number of random bytes at the beginning of charstrings
if (preg_match('#/lenIV[\s]*([0-9]*)#', $eplain, $matches) > 0) {
if (preg_match('#/lenIV[\s]*+([\d]*+)#', $eplain, $matches) > 0) {
$lenIV = intval($matches[1]);
} else {
$lenIV = 4;
}
$fmetric['Leading'] = 0;
// get charstring data
$eplain = substr($eplain, (strpos($eplain, '/CharStrings') + 1));
preg_match_all('#/([A-Za-z0-9\.]*)[\s][0-9]+[\s]RD[\s](.*)[\s]ND#sU', $eplain, $matches, PREG_SET_ORDER);
preg_match_all('#/([A-Za-z0-9\.]*+)[\s][0-9]+[\s]RD[\s](.*)[\s]ND#sU', $eplain, $matches, PREG_SET_ORDER);
if (!empty($enc) AND isset(TCPDF_FONT_DATA::$encmap[$enc])) {
$enc_map = TCPDF_FONT_DATA::$encmap[$enc];
} else {
Expand Down
93 changes: 56 additions & 37 deletions include/tcpdf_static.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<?php
//============================================================+
// File name : tcpdf_static.php
// Version : 1.1.4
// Version : 1.1.5
// Begin : 2002-08-03
// Last Update : 2023-09-06
// Last Update : 2024-12-23
// 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-2023 Nicola Asuni - Tecnick.com LTD
// Copyright (C) 2002-2024 Nicola Asuni - Tecnick.com LTD
//
// This file is part of TCPDF software library.
//
Expand Down Expand Up @@ -38,15 +38,15 @@
* This is a PHP class that contains static methods for the TCPDF class.<br>
* @package com.tecnick.tcpdf
* @author Nicola Asuni
* @version 1.1.2
* @version 1.1.5
*/

/**
* @class TCPDF_STATIC
* Static methods used by the TCPDF class.
* @package com.tecnick.tcpdf
* @brief PHP class for generating PDF documents without requiring external extensions.
* @version 1.1.1
* @version 1.1.5
* @author Nicola Asuni - info@tecnick.com
*/
class TCPDF_STATIC {
Expand All @@ -55,7 +55,7 @@ class TCPDF_STATIC {
* Current TCPDF version.
* @private static
*/
private static $tcpdf_version = '6.7.8';
private static $tcpdf_version = '6.8.0';

/**
* String alias for total number of pages.
Expand Down Expand Up @@ -106,6 +106,31 @@ class TCPDF_STATIC {
*/
public static $pageboxes = array('MediaBox', 'CropBox', 'BleedBox', 'TrimBox', 'ArtBox');

/**
* Array of default cURL options for curl_setopt_array.
*
* @var array<int, bool|int|string> cURL options.
*/
protected const CURLOPT_DEFAULT = [
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_MAXREDIRS => 5,
CURLOPT_PROTOCOLS => CURLPROTO_HTTPS | CURLPROTO_HTTP | CURLPROTO_FTP | CURLPROTO_FTPS,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_USERAGENT => 'tcpdf',
];

/**
* Array of fixed cURL options for curl_setopt_array.
*
* @var array<int, bool|int|string> cURL options.
*/
protected const CURLOPT_FIXED = [
CURLOPT_FAILONERROR => true,
CURLOPT_RETURNTRANSFER => true,
];

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

/**
Expand Down Expand Up @@ -1823,23 +1848,19 @@ public static function fopenLocal($filename, $mode) {
*/
public static function url_exists($url) {
$crs = curl_init();
// encode query params in URL to get right response form the server
$url = self::encodeUrlQuery($url);
curl_setopt($crs, CURLOPT_URL, $url);
curl_setopt($crs, CURLOPT_NOBODY, true);
curl_setopt($crs, CURLOPT_FAILONERROR, true);
if ((ini_get('open_basedir') == '') && (!ini_get('safe_mode'))) {
curl_setopt($crs, CURLOPT_FOLLOWLOCATION, true);
}
curl_setopt($crs, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($crs, CURLOPT_TIMEOUT, 30);
curl_setopt($crs, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($crs, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($crs, CURLOPT_USERAGENT, 'tc-lib-file');
curl_setopt($crs, CURLOPT_MAXREDIRS, 5);
if (defined('CURLOPT_PROTOCOLS')) {
curl_setopt($crs, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS | CURLPROTO_HTTP | CURLPROTO_FTP | CURLPROTO_FTPS);
}
$curlopts = [];
if (
(ini_get('open_basedir') == '')
&& (ini_get('safe_mode') === ''
|| ini_get('safe_mode') === false)
) {
$curlopts[CURLOPT_FOLLOWLOCATION] = true;
}
$curlopts = array_replace($curlopts, self::CURLOPT_DEFAULT);
$curlopts = array_replace($curlopts, K_CURLOPTS);
$curlopts = array_replace($curlopts, self::CURLOPT_FIXED);
$curlopts[CURLOPT_URL] = $url;
curl_setopt_array($crs, $curlopts);
curl_exec($crs);
$code = curl_getinfo($crs, CURLINFO_HTTP_CODE);
curl_close($crs);
Expand Down Expand Up @@ -1960,21 +1981,19 @@ public static function fileGetContents($file) {
) {
// try to get remote file data using cURL
$crs = curl_init();
curl_setopt($crs, CURLOPT_URL, $path);
curl_setopt($crs, CURLOPT_FAILONERROR, true);
curl_setopt($crs, CURLOPT_RETURNTRANSFER, true);
if ((ini_get('open_basedir') == '') && (!ini_get('safe_mode'))) {
curl_setopt($crs, CURLOPT_FOLLOWLOCATION, true);
}
curl_setopt($crs, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($crs, CURLOPT_TIMEOUT, 30);
curl_setopt($crs, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($crs, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($crs, CURLOPT_USERAGENT, 'tc-lib-file');
curl_setopt($crs, CURLOPT_MAXREDIRS, 5);
if (defined('CURLOPT_PROTOCOLS')) {
curl_setopt($crs, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS | CURLPROTO_HTTP | CURLPROTO_FTP | CURLPROTO_FTPS);
$curlopts = [];
if (
(ini_get('open_basedir') == '')
&& (ini_get('safe_mode') === ''
|| ini_get('safe_mode') === false)
) {
$curlopts[CURLOPT_FOLLOWLOCATION] = true;
}
$curlopts = array_replace($curlopts, self::CURLOPT_DEFAULT);
$curlopts = array_replace($curlopts, K_CURLOPTS);
$curlopts = array_replace($curlopts, self::CURLOPT_FIXED);
$curlopts[CURLOPT_URL] = $url;
curl_setopt_array($crs, $curlopts);
$ret = curl_exec($crs);
curl_close($crs);
if ($ret !== false) {
Expand Down
15 changes: 8 additions & 7 deletions tcpdf.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?php
//============================================================+
// File name : tcpdf.php
// Version : 6.7.8
// Version : 6.8.0
// Begin : 2002-08-03
// Last Update : 2024-12-13
// Last Update : 2024-12-23
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// -------------------------------------------------------------------
Expand Down Expand Up @@ -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.7.8
* @version 6.8.0
*/

// TCPDF configuration
Expand All @@ -128,7 +128,7 @@
* 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.7.8
* @version 6.8.0
* @author Nicola Asuni - info@tecnick.com
* @IgnoreAnnotation("protected")
* @IgnoreAnnotation("public")
Expand Down Expand Up @@ -3007,6 +3007,7 @@ public function setAllowLocalFiles($allowLocalFiles) {
public function Error($msg) {
// unset all class variables
$this->_destroy(true);
$msg = htmlspecialchars($msg, ENT_QUOTES, 'UTF-8');
if (defined('K_TCPDF_THROW_EXCEPTION_ERROR') AND !K_TCPDF_THROW_EXCEPTION_ERROR) {
die('<strong>TCPDF ERROR: </strong>'.$msg);
} else {
Expand Down Expand Up @@ -17259,7 +17260,7 @@ protected function unserializeTCPDFtag($data) {
$hlen = intval(substr($data, 0, $hpos));
$hash = substr($data, $hpos + 1, $hlen);
$encoded = substr($data, $hpos + 2 + $hlen);
if ($hash != $this->hashTCPDFtag($encoded)) {
if (!hash_equals( $this->hashTCPDFtag($encoded), $hash)) {
$this->Error('Invalid parameters');
}
return json_decode(urldecode($encoded), true);
Expand Down Expand Up @@ -19124,7 +19125,7 @@ protected function openHTMLTagHandler($dom, $key, $cell) {
$imglink = '';
if (isset($this->HREF['url']) AND !TCPDF_STATIC::empty_string($this->HREF['url'])) {
$imglink = $this->HREF['url'];
if ($imglink[0] == '#') {
if ($imglink[0] == '#' AND is_numeric($imglink[1])) {
// convert url to internal link
$lnkdata = explode(',', $imglink);
if (isset($lnkdata[0])) {
Expand Down Expand Up @@ -23485,7 +23486,7 @@ protected function setSVGStyles($svgstyle, $prevsvgstyle, $x=0, $y=0, $w=1, $h=1
if (preg_match('/font-family[\s]*:[\s]*([^\;\"]*)/si', $svgstyle['font'], $regs)) {
$font_family = $this->getFontFamilyName($regs[1]);
} else {
$font_family = $svgstyle['font-family'];
$font_family = $this->getFontFamilyName($svgstyle['font-family']);
}
if (preg_match('/font-size[\s]*:[\s]*([^\s\;\"]*)/si', $svgstyle['font'], $regs)) {
$font_size = trim($regs[1]);
Expand Down
5 changes: 5 additions & 0 deletions tcpdf_autoconfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@
define('K_TIMEZONE', @date_default_timezone_get());
}

// Custom cURL options for curl_setopt_array.
if (!defined('K_CURLOPTS')) {
define('K_CURLOPTS', array());
}

//============================================================+
// END OF FILE
//============================================================+
Loading
Loading