diff --git a/CHANGELOG.TXT b/CHANGELOG.TXT index f49b0cb..b9bdb3c 100644 --- a/CHANGELOG.TXT +++ b/CHANGELOG.TXT @@ -1,3 +1,8 @@ +6.0.025 (2013-09-04) + - A pregSplit() bug was fixed. + - Improved content loading from URLs. + - Improved font path loading. + 6.0.024 (2013-09-02) - Bug #826 "addEmptySignatureAppearance issue" was fixed. diff --git a/README.TXT b/README.TXT index 5016cdb..e420bfe 100644 --- a/README.TXT +++ b/README.TXT @@ -8,8 +8,8 @@ http://sourceforge.net/donate/index.php?group_id=128076 ------------------------------------------------------------ Name: TCPDF -Version: 6.0.024 -Release date: 2013-09-02 +Version: 6.0.025 +Release date: 2013-09-04 Author: Nicola Asuni Copyright (c) 2002-2013: diff --git a/composer.json b/composer.json index 34208c6..5857876 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "tecnick.com/tcpdf", - "version": "6.0.024", + "version": "6.0.025", "homepage": "http://www.tcpdf.org/", "type": "library", "description": "TCPDF is a PHP class for generating PDF documents.", diff --git a/include/tcpdf_fonts.php b/include/tcpdf_fonts.php index 7aa94ad..53f4eb5 100644 --- a/include/tcpdf_fonts.php +++ b/include/tcpdf_fonts.php @@ -1,9 +1,9 @@ * @param $unicode (array) array containing UTF-8 unicode values diff --git a/include/tcpdf_static.php b/include/tcpdf_static.php index b7a0ffc..b189485 100644 --- a/include/tcpdf_static.php +++ b/include/tcpdf_static.php @@ -1,9 +1,9 @@ * @package com.tecnick.tcpdf * @author Nicola Asuni - * @version 1.0.000 + * @version 1.0.001 */ /** @@ -46,7 +46,7 @@ * Static methods used by the TCPDF class. * @package com.tecnick.tcpdf * @brief PHP class for generating PDF documents without requiring external extensions. - * @version 1.0.000 + * @version 1.0.001 * @author Nicola Asuni - info@tecnick.com */ class TCPDF_STATIC { @@ -55,7 +55,7 @@ class TCPDF_STATIC { * Current TCPDF version. * @private static */ - private static $tcpdf_version = '6.0.024'; + private static $tcpdf_version = '6.0.025'; /** * String alias for total number of pages. @@ -2748,12 +2748,88 @@ class TCPDF_STATIC { $ret[] = "\n"; $subject = substr($subject, ($nl + 1)); } - if (!empty($subject)) { + if (strlen($subject) > 0) { $ret = array_merge($ret, preg_split($pattern.$modifiers, $subject, $limit, $flags)); } return $ret; } + /** + * Reads entire file into a string. + * The file can be also an URL. + * @param $file (string) Name of the file or URL to read. + * @return The function returns the read data or FALSE on failure. + * @author Nicola Asuni + * @since 6.0.025 + * @public static + */ + public static function fileGetContents($file) { + // array of possible alternative paths/URLs + $alt = array($file); + // replace URL relative path with full real server path + if ((strlen($file) > 1) + AND ($file[0] == '/') + AND ($file[1] != '/') + AND !empty($_SERVER['DOCUMENT_ROOT']) + AND ($_SERVER['DOCUMENT_ROOT'] != '/')) { + $findroot = strpos($file, $_SERVER['DOCUMENT_ROOT']); + if (($findroot === false) OR ($findroot > 1)) { + if (substr($_SERVER['DOCUMENT_ROOT'], -1) == '/') { + $tmp = substr($_SERVER['DOCUMENT_ROOT'], 0, -1).$file; + } else { + $tmp = $_SERVER['DOCUMENT_ROOT'].$file; + } + $alt[] = htmlspecialchars_decode(urldecode($tmp)); + } + } + // URL mode + $url = $file; + // check for missing protocol + if (preg_match('%^/{2}%', $url)) { + if (preg_match('%^([^:]+:)//%i', K_PATH_URL, $match)) { + $url = $match[1].str_replace(' ', '%20', $url); + $alt[] = $url; + } + } + $urldata = @parse_url($url); + if (!isset($urldata['query']) OR (strlen($urldata['query']) <= 0)) { + if (strpos($url, K_PATH_URL) === 0) { + // convert URL to full server path + $tmp = str_replace(K_PATH_URL, K_PATH_MAIN, $url); + $tmp = htmlspecialchars_decode(urldecode($tmp)); + $alt[] = $tmp; + } + } + foreach ($alt as $f) { + $ret = @file_get_contents($f); + if (($ret === FALSE) + AND !ini_get('allow_url_fopen') + AND function_exists('curl_init') + AND preg_match('%^(https?|ftp)://%', $f)) { + // try to get remote file data using cURL + $cs = curl_init(); // curl session + curl_setopt($cs, CURLOPT_URL, $file); + curl_setopt($cs, CURLOPT_BINARYTRANSFER, true); + curl_setopt($cs, CURLOPT_FAILONERROR, true); + curl_setopt($cs, CURLOPT_RETURNTRANSFER, true); + if ((ini_get('open_basedir') == '') AND (!ini_get('safe_mode'))) { + curl_setopt($cs, CURLOPT_FOLLOWLOCATION, true); + } + curl_setopt($cs, CURLOPT_CONNECTTIMEOUT, 5); + curl_setopt($cs, CURLOPT_TIMEOUT, 30); + curl_setopt($cs, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($cs, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($cs, CURLOPT_USERAGENT, 'TCPDF'); + $ret = curl_exec($cs); + curl_close($cs); + } + if ($ret !== FALSE) { + break; + } + } + return $ret; + } + } // END OF TCPDF_STATIC CLASS //============================================================+ diff --git a/tcpdf.php b/tcpdf.php index 3673934..407f337 100644 --- a/tcpdf.php +++ b/tcpdf.php @@ -1,9 +1,9 @@ * @package com.tecnick.tcpdf * @author Nicola Asuni - * @version 6.0.024 + * @version 6.0.025 */ // TCPDF configuration @@ -163,7 +163,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.
* @package com.tecnick.tcpdf * @brief PHP class for generating PDF documents without requiring external extensions. - * @version 6.0.024 + * @version 6.0.025 * @author Nicola Asuni - info@tecnick.com */ class TCPDF { @@ -4275,33 +4275,22 @@ class TCPDF { $fontdir .= '/'; } } - $missing_style = false; // true when the font style variation is missing + // true when the font style variation is missing + $missing_style = false; // search and include font file if (TCPDF_STATIC::empty_string($fontfile) OR (!@file_exists($fontfile))) { // build a standard filenames for specified font $tmp_fontfile = str_replace(' ', '', $family).strtolower($style).'.php'; - // search files on various directories - if (($fontdir !== false) AND @file_exists($fontdir.$tmp_fontfile)) { - $fontfile = $fontdir.$tmp_fontfile; - } elseif (@file_exists(TCPDF_FONTS::_getfontpath().$tmp_fontfile)) { - $fontfile = TCPDF_FONTS::_getfontpath().$tmp_fontfile; - } elseif (@file_exists($tmp_fontfile)) { - $fontfile = $tmp_fontfile; - } elseif (!TCPDF_STATIC::empty_string($style)) { + $fontfile = TCPDF_FONTS::getFontFullPath($tmp_fontfile, $fontdir); + if (TCPDF_STATIC::empty_string($fontfile)) { $missing_style = true; // try to remove the style part $tmp_fontfile = str_replace(' ', '', $family).'.php'; - if (($fontdir !== false) AND @file_exists($fontdir.$tmp_fontfile)) { - $fontfile = $fontdir.$tmp_fontfile; - } elseif (@file_exists(TCPDF_FONTS::_getfontpath().$tmp_fontfile)) { - $fontfile = TCPDF_FONTS::_getfontpath().$tmp_fontfile; - } else { - $fontfile = $tmp_fontfile; - } + $fontfile = TCPDF_FONTS::getFontFullPath($tmp_fontfile, $fontdir); } } // include font file - if (@file_exists($fontfile)) { + if (!TCPDF_STATIC::empty_string($fontfile) AND (@file_exists($fontfile))) { include($fontfile); } else { $this->Error('Could not include font definition file: '.$family.''); @@ -4859,27 +4848,31 @@ class TCPDF { } reset($this->embeddedfiles); foreach ($this->embeddedfiles as $filename => $filedata) { - // update name tree - $this->efnames[$filename] = $filedata['f'].' 0 R'; - // embedded file specification object - $out = $this->_getobj($filedata['f'])."\n"; - $out .= '<_datastring($filename, $filedata['f']).' /EF <> >>'; - $out .= "\n".'endobj'; - $this->_out($out); - // embedded file object - $data = file_get_contents($filedata['file']); - $filter = ''; - $rawsize = strlen($data); - if ($this->compress) { - $data = gzcompress($data); - $filter = ' /Filter /FlateDecode'; + $data = TCPDF_STATIC::fileGetContents($filedata['file']); + if ($data !== FALSE) { + $rawsize = strlen($data); + if ($rawsize > 0) { + // update name tree + $this->efnames[$filename] = $filedata['f'].' 0 R'; + // embedded file specification object + $out = $this->_getobj($filedata['f'])."\n"; + $out .= '<_datastring($filename, $filedata['f']).' /EF <> >>'; + $out .= "\n".'endobj'; + $this->_out($out); + // embedded file object + $filter = ''; + if ($this->compress) { + $data = gzcompress($data); + $filter = ' /Filter /FlateDecode'; + } + $stream = $this->_getrawstream($data, $filedata['n']); + $out = $this->_getobj($filedata['n'])."\n"; + $out .= '<< /Type /EmbeddedFile'.$filter.' /Length '.strlen($stream).' /Params <> >>'; + $out .= ' stream'."\n".$stream."\n".'endstream'; + $out .= "\n".'endobj'; + $this->_out($out); + } } - $stream = $this->_getrawstream($data, $filedata['n']); - $out = $this->_getobj($filedata['n'])."\n"; - $out .= '<< /Type /EmbeddedFile'.$filter.' /Length '.strlen($stream).' /Params <> >>'; - $out .= ' stream'."\n".$stream."\n".'endstream'; - $out .= "\n".'endobj'; - $this->_out($out); } } @@ -6805,6 +6798,7 @@ class TCPDF { // check page for no-write regions and adapt page margins if necessary list($x, $y) = $this->checkPageRegions($h, $x, $y); $exurl = ''; // external streams + $imsize = FALSE; // check if we are passing an image as file or string if ($file[0] === '@') { // image from string @@ -6823,30 +6817,9 @@ class TCPDF { if (@file_exists($file)) { // get image dimensions $imsize = @getimagesize($file); - } else { - $imsize = FALSE; } if ($imsize === FALSE) { - if (function_exists('curl_init')) { - // try to get remote file data using cURL - $cs = curl_init(); // curl session - curl_setopt($cs, CURLOPT_URL, $file); - curl_setopt($cs, CURLOPT_BINARYTRANSFER, true); - curl_setopt($cs, CURLOPT_FAILONERROR, true); - curl_setopt($cs, CURLOPT_RETURNTRANSFER, true); - if ((ini_get('open_basedir') == '') AND (!ini_get('safe_mode'))) { - curl_setopt($cs, CURLOPT_FOLLOWLOCATION, true); - } - curl_setopt($cs, CURLOPT_CONNECTTIMEOUT, 5); - curl_setopt($cs, CURLOPT_TIMEOUT, 30); - curl_setopt($cs, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($cs, CURLOPT_SSL_VERIFYHOST, false); - curl_setopt($cs, CURLOPT_USERAGENT, 'TCPDF'); - $imgdata = curl_exec($cs); - curl_close($cs); - } else { - $imgdata = @file_get_contents($file); - } + $imgdata = TCPDF_STATIC::fileGetContents($file); } } if (isset($imgdata) AND ($imgdata !== FALSE)) { @@ -7040,37 +7013,39 @@ class TCPDF { $img = new Imagick(); if ($type == 'SVG') { // get SVG file content - $svgimg = file_get_contents($file); - // get width and height - $regs = array(); - if (preg_match('/]*)>/si', $svgimg, $regs)) { - $svgtag = $regs[1]; - $tmp = array(); - if (preg_match('/[\s]+width[\s]*=[\s]*"([^"]*)"/si', $svgtag, $tmp)) { - $ow = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false); - $owu = sprintf('%F', ($ow * $dpi / 72)).$this->pdfunit; - $svgtag = preg_replace('/[\s]+width[\s]*=[\s]*"[^"]*"/si', ' width="'.$owu.'"', $svgtag, 1); - } else { - $ow = $w; + $svgimg = TCPDF_STATIC::fileGetContents($file); + if ($svgimg !== FALSE) { + // get width and height + $regs = array(); + if (preg_match('/]*)>/si', $svgimg, $regs)) { + $svgtag = $regs[1]; + $tmp = array(); + if (preg_match('/[\s]+width[\s]*=[\s]*"([^"]*)"/si', $svgtag, $tmp)) { + $ow = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false); + $owu = sprintf('%F', ($ow * $dpi / 72)).$this->pdfunit; + $svgtag = preg_replace('/[\s]+width[\s]*=[\s]*"[^"]*"/si', ' width="'.$owu.'"', $svgtag, 1); + } else { + $ow = $w; + } + $tmp = array(); + if (preg_match('/[\s]+height[\s]*=[\s]*"([^"]*)"/si', $svgtag, $tmp)) { + $oh = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false); + $ohu = sprintf('%F', ($oh * $dpi / 72)).$this->pdfunit; + $svgtag = preg_replace('/[\s]+height[\s]*=[\s]*"[^"]*"/si', ' height="'.$ohu.'"', $svgtag, 1); + } else { + $oh = $h; + } + $tmp = array(); + if (!preg_match('/[\s]+viewBox[\s]*=[\s]*"[\s]*([0-9\.]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]*"/si', $svgtag, $tmp)) { + $vbw = ($ow * $this->imgscale * $this->k); + $vbh = ($oh * $this->imgscale * $this->k); + $vbox = sprintf(' viewBox="0 0 %F %F" ', $vbw, $vbh); + $svgtag = $vbox.$svgtag; + } + $svgimg = preg_replace('/]*)>/si', '', $svgimg, 1); } - $tmp = array(); - if (preg_match('/[\s]+height[\s]*=[\s]*"([^"]*)"/si', $svgtag, $tmp)) { - $oh = $this->getHTMLUnitToUnits($tmp[1], 1, $this->svgunit, false); - $ohu = sprintf('%F', ($oh * $dpi / 72)).$this->pdfunit; - $svgtag = preg_replace('/[\s]+height[\s]*=[\s]*"[^"]*"/si', ' height="'.$ohu.'"', $svgtag, 1); - } else { - $oh = $h; - } - $tmp = array(); - if (!preg_match('/[\s]+viewBox[\s]*=[\s]*"[\s]*([0-9\.]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]+([0-9\.]+)[\s]*"/si', $svgtag, $tmp)) { - $vbw = ($ow * $this->imgscale * $this->k); - $vbh = ($oh * $this->imgscale * $this->k); - $vbox = sprintf(' viewBox="0 0 %F %F" ', $vbw, $vbh); - $svgtag = $vbox.$svgtag; - } - $svgimg = preg_replace('/]*)>/si', '', $svgimg, 1); + $img->readImageBlob($svgimg); } - $img->readImageBlob($svgimg); } else { $img->readImage($file); } @@ -8746,17 +8721,7 @@ class TCPDF { TCPDF_STATIC::set_mqr(false); foreach ($this->FontFiles as $file => $info) { // search and get font file to embedd - $fontdir = $info['fontdir']; - $file = strtolower($file); - $fontfile = ''; - // search files on various directories - if (($fontdir !== false) AND @file_exists($fontdir.$file)) { - $fontfile = $fontdir.$file; - } elseif (@file_exists(TCPDF_FONTS::_getfontpath().$file)) { - $fontfile = TCPDF_FONTS::_getfontpath().$file; - } elseif (@file_exists($file)) { - $fontfile = $file; - } + $fontfile = TCPDF_FONTS::getFontFullPath($file, $info['fontdir']); if (!TCPDF_STATIC::empty_string($fontfile)) { $font = file_get_contents($fontfile); $compressed = (substr($file, -2) == '.z'); @@ -8974,15 +8939,7 @@ class TCPDF { // search and get CTG font file to embedd $ctgfile = strtolower($font['ctg']); // search and get ctg font file to embedd - $fontfile = ''; - // search files on various directories - if (($fontdir !== false) AND @file_exists($fontdir.$ctgfile)) { - $fontfile = $fontdir.$ctgfile; - } elseif (@file_exists(TCPDF_FONTS::_getfontpath().$ctgfile)) { - $fontfile = TCPDF_FONTS::_getfontpath().$ctgfile; - } elseif (@file_exists($ctgfile)) { - $fontfile = $ctgfile; - } + $fontfile = TCPDF_FONTS::getFontFullPath($ctgfile, $fontdir); if (TCPDF_STATIC::empty_string($fontfile)) { $this->Error('Font file not found: '.$ctgfile); } @@ -14708,9 +14665,9 @@ class TCPDF { if ($file{0} === '@') { // image from string $data = substr($file, 1); } else { // EPS/AI file - $data = file_get_contents($file); + $data = TCPDF_STATIC::fileGetContents($file); } - if ($data === false) { + if ($data === FALSE) { $this->Error('EPS file not found: '.$file); } $regs = array(); @@ -16122,8 +16079,10 @@ class TCPDF { $type = array(); if (preg_match('/href[\s]*=[\s]*"([^"]*)"/', $link, $type) > 0) { // read CSS data file - $cssdata = file_get_contents(trim($type[1])); - $css = array_merge($css, TCPDF_STATIC::extractCSSproperties($cssdata)); + $cssdata = TCPDF_STATIC::fileGetContents(trim($type[1])); + if (($cssdata !== FALSE) AND (strlen($cssdata) > 0)) { + $css = array_merge($css, TCPDF_STATIC::extractCSSproperties($cssdata)); + } } } } @@ -18556,28 +18515,8 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: $tag['attribute']['src'] = '@'.base64_decode(substr($tag['attribute']['src'], 1)); $type = ''; } else { - // check for images without protocol - if (preg_match('%^/{2}%', $tag['attribute']['src'])) { - $tag['attribute']['src'] = 'http:'.$tag['attribute']['src']; - } - // replace relative path with real server path - if (($tag['attribute']['src'][0] == '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) { - $findroot = strpos($tag['attribute']['src'], $_SERVER['DOCUMENT_ROOT']); - if (($findroot === false) OR ($findroot > 1)) { - if (substr($_SERVER['DOCUMENT_ROOT'], -1) == '/') { - $tag['attribute']['src'] = substr($_SERVER['DOCUMENT_ROOT'], 0, -1).$tag['attribute']['src']; - } else { - $tag['attribute']['src'] = $_SERVER['DOCUMENT_ROOT'].$tag['attribute']['src']; - } - } - } - $tag['attribute']['src'] = htmlspecialchars_decode(urldecode($tag['attribute']['src'])); + // get image type $type = TCPDF_IMAGES::getImageFileType($tag['attribute']['src']); - $testscrtype = @parse_url($tag['attribute']['src']); - if (!isset($testscrtype['query']) OR empty($testscrtype['query'])) { - // convert URL to server path - $tag['attribute']['src'] = str_replace(K_PATH_URL, K_PATH_MAIN, $tag['attribute']['src']); - } } if (!isset($tag['width'])) { $tag['width'] = 0; @@ -22484,9 +22423,9 @@ Putting 1 is equivalent to putting 0 and calling Ln() just after. Default value: $svgdata = substr($file, 1); } else { // SVG file $this->svgdir = dirname($file); - $svgdata = file_get_contents($file); + $svgdata = TCPDF_STATIC::fileGetContents($file); } - if ($svgdata === false) { + if ($svgdata === FALSE) { $this->Error('SVG file not found: '.$file); } if ($x === '') {