I am able to run PhantomJS from both the shell and exec()
fine. The server I am using looks for additional fonts in the ~/.fonts/
directory. When those additional fonts are present, from the shell only I am able to take a screenshot with PhantomJS and the expected fonts render well.
> strace ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/bin/phantomjs ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/examples/rasterize.js http://v1.jontangerine.com/silo/typography/web-fonts/ ~/tmp/test.jpg | grep font
open("/home/user1/.fonts/TTF/verdana.ttf", O_RDONLY) = 11
open("/home/user1/.fonts/TTF/AndaleMo.TTF", O_RDONLY) = 11 open("/home/user1/.fonts/TTF/arial.ttf", O_RDONLY) = 11
open("/home/user1/.fonts/TTF/cour.ttf", O_RDONLY) = 11
open("/home/user1/.fonts/TTF/georgia.ttf", O_RDONLY) = 11
open("/home/user1/.fonts/TTF/impact.ttf", O_RDONLY) = 11
...
When I try the same command from from exec()
, the user fonts directory is not searched.
<?php
exec('strace ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/bin/phantomjs ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/examples/rasterize.js http://v1.jontangerine.com/silo/typography/web-fonts/ ~/tmp/test.jpg | grep font');
The ~/.fonts
directory is not searched, but a screenshot is written to disk without the proper fonts being rendered.
I understand exec()
to run as the Apache user so user fonts won't be used. However,
> whoami
user1
and
<?php
echo exec('whoami');
user1
both show as the same user, so I suspect this is misleading because this works perfectly (fonts and all) in the shell:
php -r "exec('~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/bin/phantomjs ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/examples/rasterize.js http://v1.jontangerine.com/silo/typography/web-fonts/ ~/tmp/test.jpg');"
I understand setuid
can allow users to exec a program with the permissions of its owner (user1), but this doesn't help. This particular server is a shared server, and su
and sudo
are disabled so running as a different user is not permitted.
Linux user configurations isn't my area of expertise, but using exec()
how to run the PhantomJS command so the user fonts are included?
Research:
/etc/sudoers
is not possible.The problem revealed itself when printenv
and exec('printenv')
were run, respectively
HOME=/home/user1
and
HOME=/home/user1/tmp
This means that even though whoami
and exec('whoami')
both return user1
, something in the shared host configuration set the home directory to /tmp
, which is wise to sandbox the script.
The solution is to prepend export HOME=~;
(not HOME=~;
) to the exec command. i.e.
exec('export HOME=~; strace ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/bin/phantomjs ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/examples/rasterize.js http://v1.jontangerine.com/silo/typography/web-fonts/ ~/tmp/test.jpg | grep font');
This will cause the HOME
directory to be set and the user fonts can now be searched.