Skip to content

Commit

Permalink
Merge branch 'master' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
bsweeney committed Jan 13, 2016
2 parents 57fecf6 + 6252765 commit b92babb
Show file tree
Hide file tree
Showing 15 changed files with 261 additions and 76 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,4 @@ $dompdf->stream();

[![Donate button](https://www.paypal.com/en_US/i/btn/btn_donate_SM.gif)](http://goo.gl/DSvWf)

*If you find this project useful, please consider making a donation. Any funds donated will be used to help further development on this project.)*
*If you find this project useful, please consider making a donation. Any funds donated will be used to help further development on this project.)*
3 changes: 1 addition & 2 deletions lib/Cpdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -2645,8 +2645,7 @@ function selectFont($fontName, $encoding = '', $set = true)
$flags += pow(2, 5); // assume non-sybolic
$list = array(
'Ascent' => 'Ascender',
'CapHeight' => 'Ascender',
//FIXME: php-font-lib is not grabbing this value, so we'll fake it and use the Ascender value // 'CapHeight'
'CapHeight' => 'Ascender', //FIXME: php-font-lib is not grabbing this value, so we'll fake it and use the Ascender value // 'CapHeight'
'MissingWidth' => 'MissingWidth',
'Descent' => 'Descender',
'FontBBox' => 'FontBBox',
Expand Down
2 changes: 1 addition & 1 deletion src/Adapter/CPDF.php
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ function circle($x, $y, $r1, $color, $width = null, $style = null, $fill = false

function image($img, $x, $y, $w, $h, $resolution = "normal")
{
list($width, $height, $type) = Helpers::dompdf_getimagesize($img);
list($width, $height, $type) = Helpers::dompdf_getimagesize($img, $this->get_dompdf()->getHttpContext());

$debug_png = $this->_dompdf->get_option("debug_png");

Expand Down
2 changes: 1 addition & 1 deletion src/Adapter/GD.php
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ function circle($x, $y, $r, $color, $width = null, $style = null, $fill = false)
*/
function image($img_url, $x, $y, $w, $h, $resolution = "normal")
{
$img_type = Cache::detect_type($img_url);
$img_type = Cache::detect_type($img_url, $this->get_dompdf()->getHttpContext());

if (!$img_type) {
return;
Expand Down
2 changes: 1 addition & 1 deletion src/Adapter/PDFLib.php
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,7 @@ function image($img_url, $x, $y, $w, $h, $resolution = "normal")
$w = (int)$w;
$h = (int)$h;

$img_type = Cache::detect_type($img_url);
$img_type = Cache::detect_type($img_url, $this->get_dompdf()->getHttpContext());

if (!isset($this->_imgs[$img_url])) {
$this->_imgs[$img_url] = $this->_pdf->load_image($img_type, $img_url, "");
Expand Down
4 changes: 2 additions & 2 deletions src/Css/Stylesheet.php
Original file line number Diff line number Diff line change
Expand Up @@ -1280,7 +1280,7 @@ private function _parse_font_face($str)
"path" => Helpers::build_url($this->_protocol, $this->_base_host, $this->_base_path, $src[2][$i]),
);

if (!$source["local"] && in_array($source["format"], array("", "woff", "opentype", "truetype"))) {
if (!$source["local"] && in_array($source["format"], array("", "truetype"))) {
$valid_sources[] = $source;
}

Expand All @@ -1298,7 +1298,7 @@ private function _parse_font_face($str)
"style" => $descriptors->font_style,
);

$this->getFontMetrics()->registerFont($style, $valid_sources[0]["path"]);
$this->getFontMetrics()->registerFont($style, $valid_sources[0]["path"], $this->_dompdf->getHttpContext());
}

/**
Expand Down
41 changes: 31 additions & 10 deletions src/Dompdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,25 @@ class Dompdf
*/
private $quirksmode = false;

/**
* Protocol whitelist
*
* Protocols and PHP wrappers allowed in URLs. Full support is not
* guarantee for the protocols/wrappers contained in this array.
*
* @var array
*/
private $allowedProtocols = array(null, "", "file://", "http://", "https://");

/**
* Local file extension whitelist
*
* File extensions supported by dompdf for local files.
*
* @var array
*/
private $allowedLocalFileExtensions = array("htm", "html");

/**
* @var array
*/
Expand Down Expand Up @@ -323,13 +342,14 @@ public function loadHtmlFile($file)
{
$this->saveLocale();

// Store parsing warnings as messages (this is to prevent output to the
// browser if the html is ugly and the dom extension complains,
// preventing the pdf from being streamed.)
if (!$this->protocol && !$this->baseHost && !$this->basePath) {
list($this->protocol, $this->baseHost, $this->basePath) = Helpers::explode_url($file);
}

if ( !in_array($this->protocol, $this->allowedProtocols) ) {
throw new Exception("Permission denied on $file. The communication protocol is not supported.");
}

if (!$this->options->isRemoteEnabled() && ($this->protocol != "" && $this->protocol !== "file://")) {
throw new Exception("Remote file requested, but remote file download is disabled.");
}
Expand All @@ -338,19 +358,20 @@ public function loadHtmlFile($file)

// Get the full path to $file, returns false if the file doesn't exist
$realfile = realpath($file);
if (!$realfile) {
throw new Exception("File '$file' not found.");
}


$chroot = $this->options->getChroot();
if (strpos($realfile, $chroot) !== 0) {
throw new Exception("Permission denied on $file. The file could not be found under the directory specified by Options::chroot.");
}

// Exclude dot files (e.g. .htaccess)
if (substr(basename($realfile), 0, 1) === ".") {
$ext = pathinfo($realfile, PATHINFO_EXTENSION);
if (!in_array($ext, $this->allowedLocalFileExtensions)) {
throw new Exception("Permission denied on $file.");
}

if (!$realfile) {
throw new Exception("File '$file' not found.");
}

$file = $realfile;
}
Expand Down Expand Up @@ -714,7 +735,7 @@ public function render()
$this->setPaper(array(0, 0, $basePageStyle->size[0], $basePageStyle->size[1]));
}

//TODO: We really shouldn't be doing this; properties were already set in the constructor. We should add Canvas methods to set the page size and orientation after instantiaion.
//TODO: We really shouldn't be doing this; properties were already set in the constructor. We should add Canvas methods to set the page size and orientation after instantiaion (see #1059).
$this->setCanvas(CanvasFactory::get_instance($this, $this->paperSize, $this->paperOrientation));
$this->setFontMetrics(new FontMetrics($this->pdf, $this->getOptions()));

Expand Down
105 changes: 65 additions & 40 deletions src/FontMetrics.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,20 @@ public function save_font_families()
*/
public function saveFontFamilies()
{
// replace the path to the Dompdf font directories with the corresponding constants (allows for more portability)
$cache_data = var_export($this->fontLookup, true);
$fontDir = $this->getOptions()->getFontDir();
$rootDir = $this->getOptions()->getRootDir();
$cache_data = str_replace('\'' . $fontDir, '$fontDir . \'', $cache_data);
$cache_data = str_replace('\'' . $rootDir, '$rootDir . \'', $cache_data);
$cache_data = "<" . "?php return $cache_data ?" . ">";
file_put_contents($this->getCacheFile(), $cache_data);
// replace the path to the DOMPDF font directories with the corresponding constants (allows for more portability)
$cacheData = sprintf("<?php return array (%s", PHP_EOL);
foreach ($this->fontLookup as $family => $variants) {
$cacheData .= sprintf(" '%s' => array(%s", addslashes($family), PHP_EOL);
foreach ($variants as $variant => $path) {
$path = sprintf("'%s'", $path);
$path = str_replace('\'' . $this->getOptions()->getFontDir() , '$fontDir . \'' , $path);
$path = str_replace('\'' . $this->getOptions()->getRootDir() , '$rootDir . \'' , $path);
$cacheData .= sprintf(" '%s' => %s,%s", $variant, $path, PHP_EOL);
}
$cacheData .= sprintf(" ),%s", PHP_EOL);
}
$cacheData .= ") ?>";
file_put_contents($this->getCacheFile(), $cacheData);
}

/**
Expand All @@ -119,7 +125,7 @@ public function loadFontFamilies()
$fontDir = $this->getOptions()->getFontDir();
$rootDir = $this->getOptions()->getRootDir();

// FIXME: tempoarary define constants for cache files <= v0.6.1
// FIXME: tempoarary define constants for cache files <= v0.6.2
if (!defined("DOMPDF_DIR")) { define("DOMPDF_DIR", $rootDir); }
if (!defined("DOMPDF_FONT_DIR")) { define("DOMPDF_FONT_DIR", $fontDir); }

Expand All @@ -128,30 +134,35 @@ public function loadFontFamilies()

// FIXME: temporary step for font cache created before the font cache fix
if (is_readable($fontDir . DIRECTORY_SEPARATOR . "dompdf_font_family_cache")) {
$old_fonts = require $fontDir . DIRECTORY_SEPARATOR . "dompdf_font_family_cache";
$oldFonts = require $fontDir . DIRECTORY_SEPARATOR . "dompdf_font_family_cache";
// If the font family cache is still in the old format
if ($old_fonts === 1) {
$cache_data = file_get_contents($fontDir . DIRECTORY_SEPARATOR . "dompdf_font_family_cache");
file_put_contents($fontDir . DIRECTORY_SEPARATOR . "dompdf_font_family_cache", "<" . "?php return $cache_data ?" . ">");
$old_fonts = require $fontDir . DIRECTORY_SEPARATOR . "dompdf_font_family_cache";
if ($oldFonts === 1) {
$cacheData = file_get_contents($fontDir . DIRECTORY_SEPARATOR . "dompdf_font_family_cache");
file_put_contents($fontDir . DIRECTORY_SEPARATOR . "dompdf_font_family_cache", "<" . "?php return $cacheData ?" . ">");
$oldFonts = require $fontDir . DIRECTORY_SEPARATOR . "dompdf_font_family_cache";
}
$distFonts += $old_fonts;
$distFonts += $oldFonts;
}

if (!is_readable($this->getCacheFile())) {
$this->fontLookup = $distFonts;
return;
} else {
$this->fontLookup = require $this->getCacheFile();
}

$cacheData = require $this->getCacheFile();

// If the font family cache is still in the old format
if ($this->fontLookup === 1) {
$cache_data = file_get_contents($this->getCacheFile());
file_put_contents($this->getCacheFile(), "<" . "?php return $cache_data ?" . ">");
if ($cacheData === 1) {
$cacheData = file_get_contents($this->getCacheFile());
file_put_contents($this->getCacheFile(), "<" . "?php return $cacheData ?" . ">");
$this->fontLookup = require $this->getCacheFile();
}

$this->fontLookup = array();
foreach ($cacheData as $key => $value) {
$this->fontLookup[stripslashes($key)] = $value;
}

// Merge provided fonts
$this->fontLookup += $distFonts;
}
Expand Down Expand Up @@ -187,20 +198,22 @@ public function installFonts(array $files)
/**
* @param array $style
* @param string $remote_file
* @param resource $context
* @return bool
* @deprecated
*/
public function register_font($style, $remote_file)
public function register_font($style, $remote_file, $context = null)
{
return $this->registerFont($style, $remote_file);
}

/**
* @param array $style
* @param string $remoteFile
* @param resource $context
* @return bool
*/
public function registerFont($style, $remoteFile)
public function registerFont($style, $remoteFile, $context = null)
{
$fontDir = $this->getOptions()->getFontDir();
$fontname = mb_strtolower($style["family"]);
Expand All @@ -211,32 +224,44 @@ public function registerFont($style, $remoteFile)
$entry = $families[$fontname];
}

$local_file = $fontDir . DIRECTORY_SEPARATOR . md5($remoteFile);
$cache_entry = $local_file;
$local_file .= ".ttf";

$style_string = $this->getType("{$style['weight']} {$style['style']}");

if (!isset($entry[$style_string])) {
$entry[$style_string] = $cache_entry;
$localFile = $fontDir . DIRECTORY_SEPARATOR . md5($remoteFile);
$localTempFile = $this->options->get('tempDir') . "/" . md5($remoteFile);
$cacheEntry = $localFile;
$localFile .= ".ttf";

$this->setFontFamily($fontname, $entry);
$styleString = $this->getType("{$style['weight']} {$style['style']}");

if ( !isset($entry[$styleString]) ) {
$entry[$styleString] = $cacheEntry;

// Download the remote file
if (!is_file($local_file)) {
file_put_contents($local_file, file_get_contents($remoteFile));
}

$font = Font::load($local_file);

file_put_contents($localTempFile, file_get_contents($remoteFile, null, $context));

$font = Font::load($localTempFile);

if (!$font) {
unlink($localTempFile);
return false;
}

$font->parse();
$font->saveAdobeFontMetrics("$cache_entry.ufm");

$font->saveAdobeFontMetrics("$cacheEntry.ufm");

unlink($localTempFile);

if ( !file_exists("$cacheEntry.ufm") ) {
return false;
}

// Save the changes
file_put_contents($localFile, file_get_contents($remoteFile, null, $context));

if ( !file_exists($localFile) ) {
unlink("$cacheEntry.ufm");
return false;
}

$this->setFontFamily($fontname, $entry);
$this->saveFontFamilies();
}

Expand Down
2 changes: 1 addition & 1 deletion src/FrameDecorator/ListBulletImage.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function __construct(Frame $frame, Dompdf $dompdf)
$frame->get_node()->setAttribute("src", $url);
$this->_img = new Image($frame, $dompdf);
parent::__construct($this->_img, $dompdf);
list($width, $height) = Helpers::dompdf_getimagesize($this->_img->get_image_url());
list($width, $height) = Helpers::dompdf_getimagesize($this->_img->get_image_url(), $dompdf->getHttpContext());

// Resample the bullet image to be consistent with 'auto' sized images
// See also Image::get_min_max_width
Expand Down
4 changes: 2 additions & 2 deletions src/FrameReflower/Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function get_min_max_width()
{
if ($this->get_dompdf()->get_option("debugPng")) {
// Determine the image's size. Time consuming. Only when really needed?
list($img_width, $img_height) = Helpers::dompdf_getimagesize($this->_frame->get_image_url());
list($img_width, $img_height) = Helpers::dompdf_getimagesize($this->_frame->get_image_url(), $this->get_dompdf()->getHttpContext());
print "get_min_max_width() " .
$this->_frame->get_style()->width . ' ' .
$this->_frame->get_style()->height . ';' .
Expand Down Expand Up @@ -112,7 +112,7 @@ function get_min_max_width()

if ($width == 0 || $height == 0) {
// Determine the image's size. Time consuming. Only when really needed!
list($img_width, $img_height) = Helpers::dompdf_getimagesize($this->_frame->get_image_url());
list($img_width, $img_height) = Helpers::dompdf_getimagesize($this->_frame->get_image_url(), $this->get_dompdf()->getHttpContext());

// don't treat 0 as error. Can be downscaled or can be catched elsewhere if image not readable.
// Resample according to px per inch
Expand Down
12 changes: 8 additions & 4 deletions src/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public static function pre_r($mixed, $return = false)
*/
public static function build_url($protocol, $host, $base_path, $url)
{
$protocol = mb_strtolower($protocol);
if (strlen($url) == 0) {
//return $protocol . $host . rtrim($base_path, "/\\") . "/";
return $protocol . $host . $base_path;
Expand Down Expand Up @@ -310,6 +311,9 @@ public static function explode_url($url)
$file = "";

$arr = parse_url($url);
if ( isset($arr["scheme"]) ) {
$arr["scheme"] == mb_strtolower($arr["scheme"]);
}

// Exclude windows drive letters...
if (isset($arr["scheme"]) && $arr["scheme"] !== "file" && strlen($arr["scheme"]) > 1) {
Expand Down Expand Up @@ -354,7 +358,7 @@ public static function explode_url($url)

} else {

$i = mb_strpos($url, "file://");
$i = mb_stripos($url, "file://");
if ($i !== false) {
$url = mb_substr($url, $i + 7);
}
Expand Down Expand Up @@ -504,7 +508,7 @@ public static function cmyk_to_rgb($c, $m = null, $y = null, $k = null)
* @param string $filename
* @return array The same format as getimagesize($filename)
*/
public static function dompdf_getimagesize($filename)
public static function dompdf_getimagesize($filename, $context = null)
{
static $cache = array();

Expand All @@ -525,7 +529,7 @@ public static function dompdf_getimagesize($filename)
$type = isset($types[$type]) ? $types[$type] : null;

if ($width == null || $height == null) {
$data = file_get_contents($filename, null, null, 0, 26);
$data = file_get_contents($filename, null, $context, 0, 26);

if (substr($data, 0, 2) === "BM") {
$meta = unpack('vtype/Vfilesize/Vreserved/Voffset/Vheadersize/Vwidth/Vheight', $data);
Expand Down Expand Up @@ -553,7 +557,7 @@ public static function dompdf_getimagesize($filename)
* http://www.programmierer-forum.de/function-imagecreatefrombmp-welche-variante-laeuft-t143137.htm
* Modified by Fabien Menager to support RGB555 BMP format
*/
public static function imagecreatefrombmp($filename)
public static function imagecreatefrombmp($filename, $context = null)
{
if (!function_exists("imagecreatetruecolor")) {
trigger_error("The PHP GD extension is required, but is not installed.", E_ERROR);
Expand Down
Loading

0 comments on commit b92babb

Please sign in to comment.