6.1.0 (2014-12-07)

- The method TCPDF_STATIC::getRandomSeed() was improved.
- The disk caching feature was removed.
- Bug #1003 "Backslashes become duplicated in table, using WriteHTML" was fixed.
- Bug #1002 "SVG radialGradient within non-square Rect" was fixed.
This commit is contained in:
nicolaasuni 2014-12-07 13:10:45 +00:00
parent 75e7ad3945
commit 95960170a2
6 changed files with 96 additions and 280 deletions

View File

@ -1,3 +1,9 @@
6.1.0 (2014-12-07)
- The method TCPDF_STATIC::getRandomSeed() was improved.
- The disk caching feature was removed.
- Bug #1003 "Backslashes become duplicated in table, using WriteHTML" was fixed.
- Bug #1002 "SVG radialGradient within non-square Rect" was fixed.
6.0.099 (2014-11-15) 6.0.099 (2014-11-15)
- Added basic support for nested SVG images (adapted PR from SamMousa). - Added basic support for nested SVG images (adapted PR from SamMousa).
- A bug related to setGDImageTransparency() was fixed (thanks to Maarten Boerema). - A bug related to setGDImageTransparency() was fixed (thanks to Maarten Boerema).

View File

@ -8,8 +8,8 @@ http://sourceforge.net/donate/index.php?group_id=128076
------------------------------------------------------------ ------------------------------------------------------------
Name: TCPDF Name: TCPDF
Version: 6.0.099 Version: 6.1.0
Release date: 2014-11-15 Release date: 2014-12-07
Author: Nicola Asuni Author: Nicola Asuni
Copyright (c) 2002-2014: Copyright (c) 2002-2014:

View File

@ -1,6 +1,6 @@
{ {
"name": "tecnick.com/tcpdf", "name": "tecnick.com/tcpdf",
"version": "6.0.099", "version": "6.1.0",
"homepage": "http://www.tcpdf.org/", "homepage": "http://www.tcpdf.org/",
"type": "library", "type": "library",
"description": "TCPDF is a PHP class for generating PDF documents and barcodes.", "description": "TCPDF is a PHP class for generating PDF documents and barcodes.",

View File

@ -116,23 +116,22 @@ class TCPDF_IMAGES {
* Convert the loaded image to a PNG and then return a structure for the PDF creator. * Convert the loaded image to a PNG and then return a structure for the PDF creator.
* This function requires GD library and write access to the directory defined on K_PATH_CACHE constant. * This function requires GD library and write access to the directory defined on K_PATH_CACHE constant.
* @param $image (image) Image object. * @param $image (image) Image object.
* @param $tempfile (string) Temporary file name.
* return image PNG image object. * return image PNG image object.
* @since 4.9.016 (2010-04-20) * @since 4.9.016 (2010-04-20)
* @public static * @public static
*/ */
public static function _toPNG($image) { public static function _toPNG($image, $tempfile) {
// set temporary image file name
$tempname = TCPDF_STATIC::getObjFilename('img');
// turn off interlaced mode // turn off interlaced mode
imageinterlace($image, 0); imageinterlace($image, 0);
// create temporary PNG image // create temporary PNG image
imagepng($image, $tempname); imagepng($image, $tempfile);
// remove image from memory // remove image from memory
imagedestroy($image); imagedestroy($image);
// get PNG image data // get PNG image data
$retvars = self::_parsepng($tempname); $retvars = self::_parsepng($tempfile);
// tidy up by removing temporary image // tidy up by removing temporary image
unlink($tempname); unlink($tempfile);
return $retvars; return $retvars;
} }
@ -141,16 +140,16 @@ class TCPDF_IMAGES {
* This function requires GD library and write access to the directory defined on K_PATH_CACHE constant. * This function requires GD library and write access to the directory defined on K_PATH_CACHE constant.
* @param $image (image) Image object. * @param $image (image) Image object.
* @param $quality (int) JPEG quality. * @param $quality (int) JPEG quality.
* @param $tempfile (string) Temporary file name.
* return image JPEG image object. * return image JPEG image object.
* @public static * @public static
*/ */
public static function _toJPEG($image, $quality) { public static function _toJPEG($image, $quality, $tempfile) {
$tempname = TCPDF_STATIC::getObjFilename('img'); imagejpeg($image, $tempfile, $quality);
imagejpeg($image, $tempname, $quality);
imagedestroy($image); imagedestroy($image);
$retvars = self::_parsejpeg($tempname); $retvars = self::_parsejpeg($tempfile);
// tidy up by removing temporary image // tidy up by removing temporary image
unlink($tempname); unlink($tempfile);
return $retvars; return $retvars;
} }

View File

@ -1,9 +1,9 @@
<?php <?php
//============================================================+ //============================================================+
// File name : tcpdf_static.php // File name : tcpdf_static.php
// Version : 1.0.004 // Version : 1.0.005
// Begin : 2002-08-03 // Begin : 2002-08-03
// Last Update : 2014-09-02 // Last Update : 2014-12-07
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com // Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html) // License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -38,7 +38,7 @@
* This is a PHP class that contains static methods for the TCPDF class.<br> * This is a PHP class that contains static methods for the TCPDF class.<br>
* @package com.tecnick.tcpdf * @package com.tecnick.tcpdf
* @author Nicola Asuni * @author Nicola Asuni
* @version 1.0.004 * @version 1.0.005
*/ */
/** /**
@ -46,7 +46,7 @@
* Static methods used by the TCPDF class. * Static methods used by the TCPDF class.
* @package com.tecnick.tcpdf * @package com.tecnick.tcpdf
* @brief PHP class for generating PDF documents without requiring external extensions. * @brief PHP class for generating PDF documents without requiring external extensions.
* @version 1.0.004 * @version 1.0.005
* @author Nicola Asuni - info@tecnick.com * @author Nicola Asuni - info@tecnick.com
*/ */
class TCPDF_STATIC { class TCPDF_STATIC {
@ -55,7 +55,7 @@ class TCPDF_STATIC {
* Current TCPDF version. * Current TCPDF version.
* @private static * @private static
*/ */
private static $tcpdf_version = '6.0.099'; private static $tcpdf_version = '6.1.0';
/** /**
* String alias for total number of pages. * String alias for total number of pages.
@ -1093,12 +1093,13 @@ class TCPDF_STATIC {
/** /**
* Returns a temporary filename for caching object on filesystem. * Returns a temporary filename for caching object on filesystem.
* @param $type (string) Type of file (name of the subdir on the tcpdf cache folder). * @param $type (string) Type of file (name of the subdir on the tcpdf cache folder).
* @param $file_id (string) TCPDF file_id.
* @return string filename. * @return string filename.
* @since 4.5.000 (2008-12-31) * @since 4.5.000 (2008-12-31)
* @public static * @public static
*/ */
public static function getObjFilename($type='tmp') { public static function getObjFilename($type='tmp', $file_id='') {
return tempnam(K_PATH_CACHE, '__tcpdf_'.$type.'_'.md5(uniqid('', true).rand().microtime(true)).'_'); return tempnam(K_PATH_CACHE, '__tcpdf_'.$file_id.'_'.$type.'_'.md5(TCPDF_STATIC::getRandomSeed()).'_');
} }
/** /**
@ -1347,40 +1348,19 @@ class TCPDF_STATIC {
* @public static * @public static
*/ */
public static function getRandomSeed($seed='') { public static function getRandomSeed($seed='') {
$seed .= microtime(); $rnd = uniqid(rand().microtime(true), true);
if (function_exists('posix_getpid')) {
$rnd .= posix_getpid();
}
if (function_exists('openssl_random_pseudo_bytes') AND (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) { if (function_exists('openssl_random_pseudo_bytes') AND (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) {
// this is not used on windows systems because it is very slow for a know bug // this is not used on windows systems because it is very slow for a know bug
$seed .= openssl_random_pseudo_bytes(512); $rnd .= openssl_random_pseudo_bytes(512);
} else { } else {
for ($i = 0; $i < 23; ++$i) { for ($i = 0; $i < 23; ++$i) {
$seed .= uniqid('', true); $rnd .= uniqid('', true);
} }
} }
$seed .= uniqid('', true); return $rnd.$seed.__FILE__.serialize($_SERVER).microtime(true);
$seed .= rand();
$seed .= __FILE__;
if (isset($_SERVER['REMOTE_ADDR'])) {
$seed .= $_SERVER['REMOTE_ADDR'];
}
if (isset($_SERVER['HTTP_USER_AGENT'])) {
$seed .= $_SERVER['HTTP_USER_AGENT'];
}
if (isset($_SERVER['HTTP_ACCEPT'])) {
$seed .= $_SERVER['HTTP_ACCEPT'];
}
if (isset($_SERVER['HTTP_ACCEPT_ENCODING'])) {
$seed .= $_SERVER['HTTP_ACCEPT_ENCODING'];
}
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
$seed .= $_SERVER['HTTP_ACCEPT_LANGUAGE'];
}
if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) {
$seed .= $_SERVER['HTTP_ACCEPT_CHARSET'];
}
$seed .= rand();
$seed .= uniqid('', true);
$seed .= microtime();
return $seed;
} }
/** /**

293
tcpdf.php
View File

@ -1,9 +1,9 @@
<?php <?php
//============================================================+ //============================================================+
// File name : tcpdf.php // File name : tcpdf.php
// Version : 6.0.099 // Version : 6.1.0
// Begin : 2002-08-03 // Begin : 2002-08-03
// Last Update : 2014-11-15 // Last Update : 2014-12-07
// Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com // Author : Nicola Asuni - Tecnick.com LTD - www.tecnick.com - info@tecnick.com
// License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html) // License : GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -104,7 +104,7 @@
* Tools to encode your unicode fonts are on fonts/utils directory.</p> * Tools to encode your unicode fonts are on fonts/utils directory.</p>
* @package com.tecnick.tcpdf * @package com.tecnick.tcpdf
* @author Nicola Asuni * @author Nicola Asuni
* @version 6.0.099 * @version 6.1.0
*/ */
// TCPDF configuration // 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> * 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 * @package com.tecnick.tcpdf
* @brief PHP class for generating PDF documents without requiring external extensions. * @brief PHP class for generating PDF documents without requiring external extensions.
* @version 6.0.099 * @version 6.1.0
* @author Nicola Asuni - info@tecnick.com * @author Nicola Asuni - info@tecnick.com
*/ */
class TCPDF { class TCPDF {
@ -347,12 +347,6 @@ class TCPDF {
*/ */
protected $svg_tag_depth = 0; protected $svg_tag_depth = 0;
/**
* Array of cached files.
* @protected
*/
protected $cached_files = array();
/** /**
* Array of Annotations in pages. * Array of Annotations in pages.
* @protected * @protected
@ -1189,13 +1183,6 @@ class TCPDF {
*/ */
protected $bufferlen = 0; protected $bufferlen = 0;
/**
* If true enables disk caching.
* @protected
* @since 4.5.000 (2008-12-31)
*/
protected $diskcache = false;
/** /**
* Counts the number of fonts. * Counts the number of fonts.
* @protected * @protected
@ -1843,7 +1830,7 @@ class TCPDF {
* @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat(). * @param $format (mixed) The format used for pages. It can be either: one of the string values specified at getPageSizeFromFormat() or an array of parameters specified at setPageFormat().
* @param $unicode (boolean) TRUE means that the input text is unicode (default = true) * @param $unicode (boolean) TRUE means that the input text is unicode (default = true)
* @param $encoding (string) Charset encoding (used only when converting back html entities); default is UTF-8. * @param $encoding (string) Charset encoding (used only when converting back html entities); default is UTF-8.
* @param $diskcache (boolean) If TRUE reduce the RAM memory usage by caching temporary data on filesystem (slower). * @param $diskcache (boolean) DEPRECATED FEATURE
* @param $pdfa (boolean) If TRUE set the document to PDF/A mode. * @param $pdfa (boolean) If TRUE set the document to PDF/A mode.
* @public * @public
* @see getPageSizeFromFormat(), setPageFormat() * @see getPageSizeFromFormat(), setPageFormat()
@ -1863,8 +1850,6 @@ class TCPDF {
// set pdf/a mode // set pdf/a mode
$this->pdfa_mode = $pdfa; $this->pdfa_mode = $pdfa;
$this->force_srgb = false; $this->force_srgb = false;
// set disk caching
$this->diskcache = $diskcache ? true : false;
// set language direction // set language direction
$this->rtl = false; $this->rtl = false;
$this->tmprtl = false; $this->tmprtl = false;
@ -1998,6 +1983,9 @@ class TCPDF {
$this->default_graphic_vars = $this->getGraphicVars(); $this->default_graphic_vars = $this->getGraphicVars();
$this->header_xobj_autoreset = false; $this->header_xobj_autoreset = false;
$this->custom_xmp = ''; $this->custom_xmp = '';
// Call cleanup method after script execution finishes or exit() is called.
// NOTE: This will not be executed if the process is killed with a SIGTERM or SIGKILL signal.
register_shutdown_function(array($this, '_destroyAll'));
} }
/** /**
@ -2010,8 +1998,8 @@ class TCPDF {
if (isset($this->internal_encoding) AND !empty($this->internal_encoding)) { if (isset($this->internal_encoding) AND !empty($this->internal_encoding)) {
mb_internal_encoding($this->internal_encoding); mb_internal_encoding($this->internal_encoding);
} }
// unset all class variables // cleanup
$this->_destroy(true); $this->_destroyAll();
} }
/** /**
@ -6895,8 +6883,8 @@ class TCPDF {
if (in_array($file, $this->imagekeys)) { if (in_array($file, $this->imagekeys)) {
// get existing image data // get existing image data
$info = $this->getImageBuffer($file); $info = $this->getImageBuffer($file);
$imsize = array($info['w'], $info['h']); $imsize = array($info['w'], $info['h']);
} elseif (strpos($file, '__tcpdf_img') === FALSE) { } elseif (strpos($file, '__tcpdf_'.$this->file_id.'_img') === FALSE) {
$imgdata = TCPDF_STATIC::fileGetContents($file); $imgdata = TCPDF_STATIC::fileGetContents($file);
} }
} }
@ -6904,7 +6892,7 @@ class TCPDF {
if (!empty($imgdata)) { if (!empty($imgdata)) {
// copy image to cache // copy image to cache
$original_file = $file; $original_file = $file;
$file = TCPDF_STATIC::getObjFilename('img'); $file = TCPDF_STATIC::getObjFilename('img', $this->file_id);
$fp = fopen($file, 'w'); $fp = fopen($file, 'w');
if (!$fp) { if (!$fp) {
$this->Error('Unable to write file: '.$file); $this->Error('Unable to write file: '.$file);
@ -6916,8 +6904,6 @@ class TCPDF {
if ($imsize === FALSE) { if ($imsize === FALSE) {
unlink($file); unlink($file);
$file = $original_file; $file = $original_file;
} else {
$this->cached_files[] = $file;
} }
} }
if ($imsize === FALSE) { if ($imsize === FALSE) {
@ -6931,7 +6917,7 @@ class TCPDF {
} }
} }
// file hash // file hash
$filehash = md5($this->file_id.$file); $filehash = md5($file);
// get original image width and height in pixels // get original image width and height in pixels
list($pixw, $pixh) = $imsize; list($pixw, $pixh) = $imsize;
// calculate image width and height on document // calculate image width and height on document
@ -7021,18 +7007,18 @@ class TCPDF {
$newimage = false; $newimage = false;
// get existing image data // get existing image data
$info = $this->getImageBuffer($file); $info = $this->getImageBuffer($file);
if (strpos($file, '__tcpdf_imgmask_') === FALSE) { if (strpos($file, '__tcpdf_'.$this->file_id.'_imgmask_') === FALSE) {
// check if the newer image is larger // check if the newer image is larger
$oldsize = ($info['w'] * $info['h']); $oldsize = ($info['w'] * $info['h']);
if ((($oldsize < $newsize) AND ($resize)) OR (($oldsize < $pixsize) AND (!$resize))) { if ((($oldsize < $newsize) AND ($resize)) OR (($oldsize < $pixsize) AND (!$resize))) {
$newimage = true; $newimage = true;
} }
} }
} elseif (($ismask === false) AND ($imgmask === false) AND (strpos($file, '__tcpdf_imgmask_') === FALSE)) { } elseif (($ismask === false) AND ($imgmask === false) AND (strpos($file, '__tcpdf_'.$this->file_id.'_imgmask_') === FALSE)) {
// create temp image file (without alpha channel) // create temp image file (without alpha channel)
$tempfile_plain = K_PATH_CACHE.'__tcpdf_imgmask_plain_'.$filehash; $tempfile_plain = K_PATH_CACHE.'__tcpdf_'.$this->file_id.'_imgmask_plain_'.$filehash;
// create temp alpha file // create temp alpha file
$tempfile_alpha = K_PATH_CACHE.'__tcpdf_imgmask_alpha_'.$filehash; $tempfile_alpha = K_PATH_CACHE.'__tcpdf_'.$this->file_id.'_imgmask_alpha_'.$filehash;
// check for cached images // check for cached images
if (in_array($tempfile_plain, $this->imagekeys)) { if (in_array($tempfile_plain, $this->imagekeys)) {
// get existing image data // get existing image data
@ -7068,7 +7054,7 @@ class TCPDF {
if ((method_exists('TCPDF_IMAGES', $mtd)) AND (!($resize AND (function_exists($gdfunction) OR extension_loaded('imagick'))))) { if ((method_exists('TCPDF_IMAGES', $mtd)) AND (!($resize AND (function_exists($gdfunction) OR extension_loaded('imagick'))))) {
// TCPDF image functions // TCPDF image functions
$info = TCPDF_IMAGES::$mtd($file); $info = TCPDF_IMAGES::$mtd($file);
if (($ismask === false) AND ($imgmask === false) AND (strpos($file, '__tcpdf_imgmask_') === FALSE) if (($ismask === false) AND ($imgmask === false) AND (strpos($file, '__tcpdf_'.$this->file_id.'_imgmask_') === FALSE)
AND (($info === 'pngalpha') OR (isset($info['trns']) AND !empty($info['trns'])))) { AND (($info === 'pngalpha') OR (isset($info['trns']) AND !empty($info['trns'])))) {
return $this->ImagePngAlpha($file, $x, $y, $pixw, $pixh, $w, $h, 'PNG', $link, $align, $resize, $dpi, $palign, $filehash); return $this->ImagePngAlpha($file, $x, $y, $pixw, $pixh, $w, $h, 'PNG', $link, $align, $resize, $dpi, $palign, $filehash);
} }
@ -7087,9 +7073,9 @@ class TCPDF {
$img = $imgr; $img = $imgr;
} }
if (($type == 'gif') OR ($type == 'png')) { if (($type == 'gif') OR ($type == 'png')) {
$info = TCPDF_IMAGES::_toPNG($img); $info = TCPDF_IMAGES::_toPNG($img, TCPDF_STATIC::getObjFilename('img', $this->file_id));
} else { } else {
$info = TCPDF_IMAGES::_toJPEG($img, $this->jpeg_quality); $info = TCPDF_IMAGES::_toJPEG($img, $this->jpeg_quality, TCPDF_STATIC::getObjFilename('img', $this->file_id));
} }
} }
} catch(Exception $e) { } catch(Exception $e) {
@ -7148,7 +7134,7 @@ class TCPDF {
} }
$img->setCompressionQuality($this->jpeg_quality); $img->setCompressionQuality($this->jpeg_quality);
$img->setImageFormat('jpeg'); $img->setImageFormat('jpeg');
$tempname = TCPDF_STATIC::getObjFilename('img'); $tempname = TCPDF_STATIC::getObjFilename('img', $this->file_id);
$img->writeImage($tempname); $img->writeImage($tempname);
$info = TCPDF_IMAGES::_parsejpeg($tempname); $info = TCPDF_IMAGES::_parsejpeg($tempname);
unlink($tempname); unlink($tempname);
@ -7284,12 +7270,12 @@ class TCPDF {
protected function ImagePngAlpha($file, $x, $y, $wpx, $hpx, $w, $h, $type, $link, $align, $resize, $dpi, $palign, $filehash='') { protected function ImagePngAlpha($file, $x, $y, $wpx, $hpx, $w, $h, $type, $link, $align, $resize, $dpi, $palign, $filehash='') {
// create temp images // create temp images
if (empty($filehash)) { if (empty($filehash)) {
$filehash = md5($this->file_id.$file); $filehash = md5($file);
} }
// create temp image file (without alpha channel) // create temp image file (without alpha channel)
$tempfile_plain = K_PATH_CACHE.'__tcpdf_imgmask_plain_'.$filehash; $tempfile_plain = K_PATH_CACHE.'__tcpdf_'.$this->file_id.'_imgmask_plain_'.$filehash;
// create temp alpha file // create temp alpha file
$tempfile_alpha = K_PATH_CACHE.'__tcpdf_imgmask_alpha_'.$filehash; $tempfile_alpha = K_PATH_CACHE.'__tcpdf_'.$this->file_id.'_imgmask_alpha_'.$filehash;
$parsed = false; $parsed = false;
$parse_error = ''; $parse_error = '';
// ImageMagick extension // ImageMagick extension
@ -7366,9 +7352,6 @@ class TCPDF {
$imgmask = $this->Image($tempfile_alpha, $x, $y, $w, $h, 'PNG', '', '', $resize, $dpi, '', true, false); $imgmask = $this->Image($tempfile_alpha, $x, $y, $w, $h, 'PNG', '', '', $resize, $dpi, '', true, false);
// embed image, masked with previously embedded mask // embed image, masked with previously embedded mask
$this->Image($tempfile_plain, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, false, $imgmask); $this->Image($tempfile_plain, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, false, $imgmask);
// remove temp files
unlink($tempfile_alpha);
unlink($tempfile_plain);
} }
/** /**
@ -7614,12 +7597,6 @@ class TCPDF {
$pdfdoc = $this->getBuffer(); $pdfdoc = $this->getBuffer();
// remove last newline // remove last newline
$pdfdoc = substr($pdfdoc, 0, -1); $pdfdoc = substr($pdfdoc, 0, -1);
// Remove the original buffer
if (isset($this->diskcache) AND $this->diskcache) {
// remove buffer file from cache
unlink($this->buffer);
}
unset($this->buffer);
// remove filler space // remove filler space
$byterange_string_len = strlen(TCPDF_STATIC::$byterange_string); $byterange_string_len = strlen(TCPDF_STATIC::$byterange_string);
// define the ByteRange // define the ByteRange
@ -7634,7 +7611,7 @@ class TCPDF {
$byterange .= str_repeat(' ', ($byterange_string_len - strlen($byterange))); $byterange .= str_repeat(' ', ($byterange_string_len - strlen($byterange)));
$pdfdoc = str_replace(TCPDF_STATIC::$byterange_string, $byterange, $pdfdoc); $pdfdoc = str_replace(TCPDF_STATIC::$byterange_string, $byterange, $pdfdoc);
// write the document to a temporary folder // write the document to a temporary folder
$tempdoc = TCPDF_STATIC::getObjFilename('doc'); $tempdoc = TCPDF_STATIC::getObjFilename('doc', $this->file_id);
$f = fopen($tempdoc, 'wb'); $f = fopen($tempdoc, 'wb');
if (!$f) { if (!$f) {
$this->Error('Unable to create temporary file: '.$tempdoc); $this->Error('Unable to create temporary file: '.$tempdoc);
@ -7643,22 +7620,19 @@ class TCPDF {
fwrite($f, $pdfdoc, $pdfdoc_length); fwrite($f, $pdfdoc, $pdfdoc_length);
fclose($f); fclose($f);
// get digital signature via openssl library // get digital signature via openssl library
$tempsign = TCPDF_STATIC::getObjFilename('sig'); $tempsign = TCPDF_STATIC::getObjFilename('sig', $this->file_id);
if (empty($this->signature_data['extracerts'])) { if (empty($this->signature_data['extracerts'])) {
openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED); openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED);
} else { } else {
openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED, $this->signature_data['extracerts']); openssl_pkcs7_sign($tempdoc, $tempsign, $this->signature_data['signcert'], array($this->signature_data['privkey'], $this->signature_data['password']), array(), PKCS7_BINARY | PKCS7_DETACHED, $this->signature_data['extracerts']);
} }
unlink($tempdoc);
// read signature // read signature
$signature = file_get_contents($tempsign); $signature = file_get_contents($tempsign);
unlink($tempsign);
// extract signature // extract signature
$signature = substr($signature, $pdfdoc_length); $signature = substr($signature, $pdfdoc_length);
$signature = substr($signature, (strpos($signature, "%%EOF\n\n------") + 13)); $signature = substr($signature, (strpos($signature, "%%EOF\n\n------") + 13));
$tmparr = explode("\n\n", $signature); $tmparr = explode("\n\n", $signature);
$signature = $tmparr[1]; $signature = $tmparr[1];
unset($tmparr);
// decode signature // decode signature
$signature = base64_decode(trim($signature)); $signature = base64_decode(trim($signature));
// add TSA timestamp to signature // add TSA timestamp to signature
@ -7666,8 +7640,6 @@ class TCPDF {
// convert signature to hex // convert signature to hex
$signature = current(unpack('H*', $signature)); $signature = current(unpack('H*', $signature));
$signature = str_pad($signature, $this->signature_max_length, '0'); $signature = str_pad($signature, $this->signature_max_length, '0');
// disable disk caching
$this->diskcache = false;
// Add signature to the document // Add signature to the document
$this->buffer = substr($pdfdoc, 0, $byte_range[1]).'<'.$signature.'>'.substr($pdfdoc, $byte_range[1]); $this->buffer = substr($pdfdoc, 0, $byte_range[1]).'<'.$signature.'>'.substr($pdfdoc, $byte_range[1]);
$this->bufferlen = strlen($this->buffer); $this->bufferlen = strlen($this->buffer);
@ -7729,16 +7701,12 @@ class TCPDF {
case 'FI': case 'FI':
case 'FD': { case 'FD': {
// save PDF to a local file // save PDF to a local file
if ($this->diskcache) { $f = fopen($name, 'wb');
copy($this->buffer, $name); if (!$f) {
} else { $this->Error('Unable to create output file: '.$name);
$f = fopen($name, 'wb');
if (!$f) {
$this->Error('Unable to create output file: '.$name);
}
fwrite($f, $this->getBuffer(), $this->bufferlen);
fclose($f);
} }
fwrite($f, $this->getBuffer(), $this->bufferlen);
fclose($f);
if ($dest == 'FI') { if ($dest == 'FI') {
// send headers to browser // send headers to browser
header('Content-Type: application/pdf'); header('Content-Type: application/pdf');
@ -7798,6 +7766,13 @@ class TCPDF {
} }
return ''; return '';
} }
/**
* Destroy all objects and delete temp files.
* @protected
*/
protected function _destroyAll() {
$this->_destroy(true);
}
/** /**
* Unset all class variables except the following critical variables. * Unset all class variables except the following critical variables.
@ -7807,25 +7782,16 @@ class TCPDF {
* @since 4.5.016 (2009-02-24) * @since 4.5.016 (2009-02-24)
*/ */
public function _destroy($destroyall=false, $preserve_objcopy=false) { public function _destroy($destroyall=false, $preserve_objcopy=false) {
if ($destroyall AND isset($this->diskcache) AND $this->diskcache AND (!$preserve_objcopy) AND (!TCPDF_STATIC::empty_string($this->buffer))) { if ($destroyall AND !$preserve_objcopy) {
// remove buffer file from cache // remove all temporary files
unlink($this->buffer); array_map('unlink', glob(K_PATH_CACHE.'__tcpdf_'.$this->file_id.'_*'));
}
if ($destroyall AND !empty($this->cached_files)) {
// remove cached files
foreach ($this->cached_files as $cachefile) {
if (is_file($cachefile)) {
unlink($cachefile);
}
}
unset($this->cached_files);
} }
$preserve = array( $preserve = array(
'file_id',
'internal_encoding', 'internal_encoding',
'state', 'state',
'bufferlen', 'bufferlen',
'buffer', 'buffer',
'diskcache',
'cached_files', 'cached_files',
'sign', 'sign',
'signature_data', 'signature_data',
@ -7836,7 +7802,7 @@ class TCPDF {
); );
foreach (array_keys(get_object_vars($this)) as $val) { foreach (array_keys(get_object_vars($this)) as $val) {
if ($destroyall OR !in_array($val, $preserve)) { if ($destroyall OR !in_array($val, $preserve)) {
if ((!$preserve_objcopy OR ($val != 'objcopy')) AND isset($this->$val)) { if ((!$preserve_objcopy OR ($val != 'objcopy')) AND ($val != 'file_id') AND isset($this->$val)) {
unset($this->$val); unset($this->$val);
} }
} }
@ -8093,10 +8059,6 @@ class TCPDF {
$this->_newobj(); $this->_newobj();
$p = $this->_getrawstream($p); $p = $this->_getrawstream($p);
$this->_out('<<'.$filter.'/Length '.strlen($p).'>> stream'."\n".$p."\n".'endstream'."\n".'endobj'); $this->_out('<<'.$filter.'/Length '.strlen($p).'>> stream'."\n".$p."\n".'endstream'."\n".'endobj');
if ($this->diskcache) {
// remove temporary files
unlink($this->pages[$n]);
}
} }
//Pages root //Pages root
$out = $this->_getobj(1)."\n"; $out = $this->_getobj(1)."\n";
@ -10072,17 +10034,6 @@ class TCPDF {
$this->_out($o); $this->_out($o);
$this->_out('%%EOF'); $this->_out('%%EOF');
$this->state = 3; // end-of-doc $this->state = 3; // end-of-doc
if ($this->diskcache) {
// remove temporary files used for images
foreach ($this->imagekeys as $key) {
// remove temporary files
unlink($this->images[$key]);
}
foreach ($this->fontkeys as $key) {
// remove temporary files
unlink($this->fonts[$key]);
}
}
} }
/** /**
@ -10916,7 +10867,7 @@ class TCPDF {
// envelope data // envelope data
$envelope = $seed.$pkpermissions; $envelope = $seed.$pkpermissions;
// write the envelope data to a temporary file // write the envelope data to a temporary file
$tempkeyfile = TCPDF_STATIC::getObjFilename('key'); $tempkeyfile = TCPDF_STATIC::getObjFilename('key', $this->file_id);
$f = fopen($tempkeyfile, 'wb'); $f = fopen($tempkeyfile, 'wb');
if (!$f) { if (!$f) {
$this->Error('Unable to create temporary key file: '.$tempkeyfile); $this->Error('Unable to create temporary key file: '.$tempkeyfile);
@ -10924,14 +10875,12 @@ class TCPDF {
$envelope_length = strlen($envelope); $envelope_length = strlen($envelope);
fwrite($f, $envelope, $envelope_length); fwrite($f, $envelope, $envelope_length);
fclose($f); fclose($f);
$tempencfile = TCPDF_STATIC::getObjFilename('enc'); $tempencfile = TCPDF_STATIC::getObjFilename('enc', $this->file_id);
if (!openssl_pkcs7_encrypt($tempkeyfile, $tempencfile, $pubkey['c'], array(), PKCS7_BINARY | PKCS7_DETACHED)) { if (!openssl_pkcs7_encrypt($tempkeyfile, $tempencfile, $pubkey['c'], array(), PKCS7_BINARY | PKCS7_DETACHED)) {
$this->Error('Unable to encrypt the file: '.$tempkeyfile); $this->Error('Unable to encrypt the file: '.$tempkeyfile);
} }
unlink($tempkeyfile);
// read encryption signature // read encryption signature
$signature = file_get_contents($tempencfile, false, null, $envelope_length); $signature = file_get_contents($tempencfile, false, null, $envelope_length);
unlink($tempencfile);
// extract signature // extract signature
$signature = substr($signature, strpos($signature, 'Content-Disposition')); $signature = substr($signature, strpos($signature, 'Content-Disposition'));
$tmparr = explode("\n\n", $signature); $tmparr = explode("\n\n", $signature);
@ -16612,7 +16561,7 @@ class TCPDF {
if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) { if (($dom[$key]['value'] == 'td') OR ($dom[$key]['value'] == 'th')) {
$dom[($dom[$key]['parent'])]['content'] = $csstagarray; $dom[($dom[$key]['parent'])]['content'] = $csstagarray;
for ($i = ($dom[$key]['parent'] + 1); $i < $key; ++$i) { for ($i = ($dom[$key]['parent'] + 1); $i < $key; ++$i) {
$dom[($dom[$key]['parent'])]['content'] .= $a[$dom[$i]['elkey']]; $dom[($dom[$key]['parent'])]['content'] .= stripslashes($a[$dom[$i]['elkey']]);
} }
$key = $i; $key = $i;
// mark nested tables // mark nested tables
@ -20772,60 +20721,6 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$this->_out('Q'); $this->_out('Q');
} }
/**
* Writes data to a temporary file on filesystem.
* @param $filename (string) file name
* @param $data (mixed) data to write on file
* @param $append (boolean) if true append data, false replace.
* @param $serialize (boolean) if true serialize data.
* @since 4.5.000 (2008-12-31)
* @protected
*/
protected function writeDiskCache($filename, $data, $append=false, $serialize=false) {
if ($append) {
$fmode = 'ab+';
} else {
$fmode = 'wb+';
}
$f = @fopen($filename, $fmode);
if (!$f) {
$this->Error('Unable to write cache file: '.$filename);
}
if ($serialize) {
$data = $this->file_id.serialize($data);
}
fwrite($f, $data);
fclose($f);
// update file length (needed for transactions)
if (!isset($this->cache_file_length['_'.$filename])) {
$this->cache_file_length['_'.$filename] = strlen($data);
} else {
$this->cache_file_length['_'.$filename] += strlen($data);
}
}
/**
* Read data from a temporary file on filesystem.
* @param $filename (string) file name
* @param $unserialize (boolean) if true unserialize data.
* @return mixed retrieved data
* @since 4.5.000 (2008-12-31)
* @protected
*/
protected function readDiskCache($filename, $unserialize=false) {
$data = file_get_contents($filename);
if ($data === FALSE) {
$this->Error('Unable to read the file: '.$filename);
}
if ($unserialize) {
if (substr($data, 0, 32) != $this->file_id) {
$this->Error('Invalid cache file: '.$filename);
}
$data = unserialize(substr($data, 32));
}
return $data;
}
/** /**
* Set buffer content (always append data). * Set buffer content (always append data).
* @param $data (string) data * @param $data (string) data
@ -20834,14 +20729,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
*/ */
protected function setBuffer($data) { protected function setBuffer($data) {
$this->bufferlen += strlen($data); $this->bufferlen += strlen($data);
if ($this->diskcache) { $this->buffer .= $data;
if (!isset($this->buffer) OR TCPDF_STATIC::empty_string($this->buffer)) {
$this->buffer = TCPDF_STATIC::getObjFilename('buf');
}
$this->writeDiskCache($this->buffer, $data, true, false);
} else {
$this->buffer .= $data;
}
} }
/** /**
@ -20852,14 +20740,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
*/ */
protected function replaceBuffer($data) { protected function replaceBuffer($data) {
$this->bufferlen = strlen($data); $this->bufferlen = strlen($data);
if ($this->diskcache) { $this->buffer = $data;
if (!isset($this->buffer) OR TCPDF_STATIC::empty_string($this->buffer)) {
$this->buffer = TCPDF_STATIC::getObjFilename('buf');
}
$this->writeDiskCache($this->buffer, $data, false, false);
} else {
$this->buffer = $data;
}
} }
/** /**
@ -20869,11 +20750,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
* @since 4.5.000 (2009-01-02) * @since 4.5.000 (2009-01-02)
*/ */
protected function getBuffer() { protected function getBuffer() {
if ($this->diskcache) { return $this->buffer;
return $this->readDiskCache($this->buffer, false);
} else {
return $this->buffer;
}
} }
/** /**
@ -20885,17 +20762,10 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
* @since 4.5.000 (2008-12-31) * @since 4.5.000 (2008-12-31)
*/ */
protected function setPageBuffer($page, $data, $append=false) { protected function setPageBuffer($page, $data, $append=false) {
if ($this->diskcache) { if ($append) {
if (!isset($this->pages[$page])) { $this->pages[$page] .= $data;
$this->pages[$page] = TCPDF_STATIC::getObjFilename('page');
}
$this->writeDiskCache($this->pages[$page], $data, $append, false);
} else { } else {
if ($append) { $this->pages[$page] = $data;
$this->pages[$page] .= $data;
} else {
$this->pages[$page] = $data;
}
} }
if ($append AND isset($this->pagelen[$page])) { if ($append AND isset($this->pagelen[$page])) {
$this->pagelen[$page] += strlen($data); $this->pagelen[$page] += strlen($data);
@ -20912,9 +20782,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
* @since 4.5.000 (2008-12-31) * @since 4.5.000 (2008-12-31)
*/ */
protected function getPageBuffer($page) { protected function getPageBuffer($page) {
if ($this->diskcache) { if (isset($this->pages[$page])) {
return $this->readDiskCache($this->pages[$page], false);
} elseif (isset($this->pages[$page])) {
return $this->pages[$page]; return $this->pages[$page];
} }
return false; return false;
@ -20934,14 +20802,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
$data['i'] = $this->numimages; $data['i'] = $this->numimages;
++$this->numimages; ++$this->numimages;
} }
if ($this->diskcache) { $this->images[$image] = $data;
if (!isset($this->images[$image])) {
$this->images[$image] = TCPDF_STATIC::getObjFilename('img');
}
$this->writeDiskCache($this->images[$image], $data, false, true);
} else {
$this->images[$image] = $data;
}
return $data['i']; return $data['i'];
} }
@ -20957,13 +20818,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
if (!isset($this->images[$image])) { if (!isset($this->images[$image])) {
$this->setImageBuffer($image, array()); $this->setImageBuffer($image, array());
} }
if ($this->diskcache) { $this->images[$image][$key] = $data;
$tmpimg = $this->getImageBuffer($image);
$tmpimg[$key] = $data;
$this->writeDiskCache($this->images[$image], $tmpimg, false, true);
} else {
$this->images[$image][$key] = $data;
}
} }
/** /**
@ -20974,9 +20829,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
* @since 4.5.000 (2008-12-31) * @since 4.5.000 (2008-12-31)
*/ */
protected function getImageBuffer($image) { protected function getImageBuffer($image) {
if ($this->diskcache AND isset($this->images[$image])) { if (isset($this->images[$image])) {
return $this->readDiskCache($this->images[$image], true);
} elseif (isset($this->images[$image])) {
return $this->images[$image]; return $this->images[$image];
} }
return false; return false;
@ -20990,14 +20843,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
* @since 4.5.000 (2009-01-02) * @since 4.5.000 (2009-01-02)
*/ */
protected function setFontBuffer($font, $data) { protected function setFontBuffer($font, $data) {
if ($this->diskcache) { $this->fonts[$font] = $data;
if (!isset($this->fonts[$font])) {
$this->fonts[$font] = TCPDF_STATIC::getObjFilename('font');
}
$this->writeDiskCache($this->fonts[$font], $data, false, true);
} else {
$this->fonts[$font] = $data;
}
if (!in_array($font, $this->fontkeys)) { if (!in_array($font, $this->fontkeys)) {
$this->fontkeys[] = $font; $this->fontkeys[] = $font;
// store object ID for current font // store object ID for current font
@ -21019,13 +20865,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
if (!isset($this->fonts[$font])) { if (!isset($this->fonts[$font])) {
$this->setFontBuffer($font, array()); $this->setFontBuffer($font, array());
} }
if ($this->diskcache) { $this->fonts[$font][$key] = $data;
$tmpfont = $this->getFontBuffer($font);
$tmpfont[$key] = $data;
$this->writeDiskCache($this->fonts[$font], $tmpfont, false, true);
} else {
$this->fonts[$font][$key] = $data;
}
} }
/** /**
@ -21036,9 +20876,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
* @since 4.5.000 (2009-01-02) * @since 4.5.000 (2009-01-02)
*/ */
protected function getFontBuffer($font) { protected function getFontBuffer($font) {
if ($this->diskcache AND isset($this->fonts[$font])) { if (isset($this->fonts[$font])) {
return $this->readDiskCache($this->fonts[$font], true);
} elseif (isset($this->fonts[$font])) {
return $this->fonts[$font]; return $this->fonts[$font];
} }
return false; return false;
@ -21866,15 +21704,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
*/ */
public function rollbackTransaction($self=false) { public function rollbackTransaction($self=false) {
if (isset($this->objcopy)) { if (isset($this->objcopy)) {
if (isset($this->objcopy->diskcache) AND $this->objcopy->diskcache) { $this->_destroy(true, true); // DEBUG
// truncate files to previous values
foreach ($this->objcopy->cache_file_length as $file => $length) {
$file = substr($file, 1);
$handle = fopen($file, 'r+');
ftruncate($handle, $length);
}
}
$this->_destroy(true, true);
if ($self) { if ($self) {
$objvars = get_object_vars($this->objcopy); $objvars = get_object_vars($this->objcopy);
foreach ($objvars as $key => $value) { foreach ($objvars as $key => $value) {
@ -23396,6 +23226,7 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value:
if ($gradient['type'] == 3) { if ($gradient['type'] == 3) {
// circular gradient // circular gradient
$cy -= ($gradient['coords'][1] * ($w + $h)); $cy -= ($gradient['coords'][1] * ($w + $h));
$h = $w = max($w, $h);
} else { } else {
$cy -= $h; $cy -= $h;
} }