Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading assets by path is not working #2452

Closed
koertho opened this issue May 11, 2021 · 11 comments
Closed

Loading assets by path is not working #2452

koertho opened this issue May 11, 2021 · 11 comments

Comments

@koertho
Copy link

koertho commented May 11, 2021

Hi. First of all, thanks for this library. It worked for me wonderfull with images and external css files when using remote_enabled.

But here comes my problem: in our company we have a development setup, where we couldn't load the resources like this, so I hoped to reference the images and css files by path from the local file system. But I always get Image not found or type unknown (for images). The same images works if remote is enabled, so there seems to be a path problem.

Here is a testing code, none of the images is working:

$options = new Options();
$options->setChroot('/home/dev/Kunden/.../produkte/contao');
$dompdf = new Dompdf();
$dompdf->loadHtml('<p>hello world</p>
<img src="files/media/news/partner-logos/image.png">
<img src="file://files/media/news/partner-logos/image.png">
<img src="/home/dev/Kunden/.../produkte/contao/files/media/news/partner-logos/image.png">
<img src="/home/dev/Kunden/.../produkte/contao/web/files/media/news/partner-logos/image.png">
<img src="file:///home/dev/Kunden/.../produkte/contao/files/media/news/partner-logos/image.png">
<img src="file:///home/dev/Kunden/.../produkte/contao/web/files/media/news/partner-logos/image.png">
');
 
$dompdf->setPaper('A4');
$dompdf->render();
$dompdf->stream('file', ['Attachment' => 0]);

Explanation: I tested relative and absolute path. The files within the web folder are symlinked.
I also tried the setProtocol and setBasePath options, but they are not working (they are reseted within the code before the image processing starts).

Options (before calling the stream method):

rootDir = "/home/dev/Kunden/.../produkte/contao/vendor/dompdf/dompdf"
tempDir = "/tmp"
fontDir = "/home/dev/Kunden/.../produkte/contao/vendor/dompdf/dompdf/lib/fonts"
fontCache = "/home/dev/Kunden/.../produkte/contao/vendor/dompdf/dompdf/lib/fonts"
chroot = {array} [1]
    0 = "/home/dev/Kunden/.../produkte/contao"
logOutputFile = "/tmp/log.htm"
defaultMediaType = "screen"
defaultPaperSize = "letter"
defaultPaperOrientation = "portrait"
defaultFont = "serif"
dpi = {int} 96
fontHeightRatio = {float} 1.1
isPhpEnabled = false
isRemoteEnabled = false
isJavascriptEnabled = true
isHtml5ParserEnabled = false
isFontSubsettingEnabled = true
debugPng = false
debugKeepTemp = false
debugCss = false
debugLayout = false
debugLayoutLines = true
debugLayoutBlocks = true
debugLayoutInline = true
debugLayoutPaddingBox = true
pdfBackend = "CPDF"
pdflibLicense = ""

I also don't want to base64 encode the images, as also css files not working, I hope for a better solution. Do you have an idea where I go wrong?

Dompdf 1.0.2
PHP 7.4.16

@bsweeney
Copy link
Member

At a high level this looks OK. Just to confirm the basic requirements: do you have the GD extension enabled and does the running script has read/write access to the tmp directory?

Have you tried a JPG image? Those can be inserted into the PDF without any extra processing.

@koertho
Copy link
Author

koertho commented May 13, 2021

I will look into your questions in the next days, but I can confirm the same images have worked when I used the remote option, so Gd and tmp should work.
When I used phpunit to debug, I stumbled over this line, where the protocol is always http, even if remote is disabled and there is no http in the file path (as shown above):

$remote = ($protocol && $protocol !== "file://") || ($parsed_url['protocol'] != "");

@fd6130
Copy link

fd6130 commented May 14, 2021

I think it is better to have a dev server so you could load your assets from there instead, as a workaround.

@koertho
Copy link
Author

koertho commented May 17, 2021

Hi, now I'm able to answer your questions:
GD library is installed in version 2.3.0.
Script has read/write access to tmp folder
I also tried with jpg image, same result.

I think it is better to have a dev server so you could load your assets from there instead, as a workaround.

Sure, load the images from another server would be possible. But that would not solve the problem that loading images from paths not work (which is IMHO a bug of this library) and would lead to the point that dompdf is hard to use in a reusable way for multi project extensions.

@koertho
Copy link
Author

koertho commented May 19, 2021

Hi, I've digged a little deeper on this topic.
My problem described above was due symlinks resolved by the library and the real paths weren't in the chroot. Is realpath real needed here?

$realfile = realpath($resolved_url);

If I add the symlinked path, it works with image also with remote set to false. But then I have problems with the base tag and external css files. If I set a base tag, images won't work again, but css files work. Without a base tag images work, but css files won't.
Image won't work with a base tag cause the protocol is set here, if a base tag is defined:

[$this->protocol, $this->baseHost, $this->basePath] = Helpers::explode_url($href);

This lead to an error in combination with remote disabled here:
$remote = ($protocol && $protocol !== "file://") || ($parsed_url['protocol'] != "");

if (!$enable_remote && $remote && !$data_uri) {

But without a base tag, css files are not loaded correctly from filesystem cause the library tries to get the real path from the relative path of the filesystem here:

$realfile = realpath($file);

@sandreas
Copy link

sandreas commented Aug 4, 2021

I have the exact same issue. In my opinion this is a bug in the Cache::resolve_url method.

This check:

if (strpos($realfile, $rootDir) !== 0) {

leads to an exception showing the "image not found" error in PDF files, if the file is locally referenced, because it is pretty likely not in the root path if the library installation.

If I just skip this check, everything seems to work fine. I don't understand what it's all about with chroot and in which case the check should make sense, but it does prevent rendering images referenced locally.

Even worse, since this is a static call, I did not find a way to overcome this issue by adding some options, extending classes or even override autoloading to use my own class instead of \Dompdf\Image\Cache...

@bsweeney bsweeney added this to the 2.0.0 milestone Sep 21, 2021
@rezaf-dev
Copy link

I have the same problem. If I add the image path to chroot option, it works.

$options = new Options();
$options->setChroot(['/user/home/public/img/']);
$dompdf->setOptions($options);

@bsweeney bsweeney modified the milestones: 2.0.0, 2.1.0 May 9, 2022
@drelich
Copy link

drelich commented May 21, 2022

@rezaf-dev You, sir, are my hero! I was having a problem with my PHP app, it wouldn't load a logo no matter what path I used. Setting the root to / has solved my issue. Thanks so much!

@roberthenniger
Copy link

@bsweeney I am dealing with the same issue. We are using always fully qualified realpaths for our assets and they do not get loaded. I was now setting the root to "/" which solved my issue but should the fully qualified path not override the root setting? Is this a security concern or why is it handled like this?

@bsweeney
Copy link
Member

@roberthenniger I don't quite follow? Are you saying you set the chroot option to "/"? The paths you specify for your assets, fully qualified or not, once the path is normalized should fall under the paths specified for the chroot option. So if your path is something like "/path/to/assets/image.png" then you could set you your chroot option to "/path/to/assets".

@bsweeney
Copy link
Member

Closing this issue since the problem resolution is to set the chroot option with all the potential local paths for asset references.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants