Project

General

Profile

Actions

Bug #24281

closed

ImageMagick does not work with quotes in exec() path on Windows

Added by Žiga Dolhar over 13 years ago. Updated over 5 years ago.

Status:
Closed
Priority:
Must have
Category:
-
Target version:
-
Start date:
2010-12-03
Due date:
% Done:

0%

Estimated time:
TYPO3 Version:
4.5
PHP Version:
5.2
Tags:
Complexity:
Is Regression:
Sprint Focus:

Description

In 4.4.4 and before, typo3 did not put quotes around the IM path when calling it with exec(). For example, the path is:

e:\ImageMagick\convert.exe +profile '*' geometry 170x136! -colorspace RGB -quality 70 "E:/websites/---/typo3/sysext/install/imgs/jesus.jpg"[0] "E:/websites/----/typo3temp/pics/install_read_jpg.jpg"

As of version 4.5 (I tried alpha3, beta1 and beta2), quotes are put around IM executable path. Therefore the following command is called:

"e:\ImageMagick\convert.exe" [the rest of the parameters are omitted]

This does not work on Windows. Calling the whole command (with quoted executable) from Windows command line works (IM creates the necessary files in typo3 folder. However, calling the command from php exec() silently fails. Calling the command with unquoted executable path works both from windows command line and from php exec().

Unfortunately, this prevents me from upgrading to the latest typo3 version.

(I can not say for sure, but if I remember correctly, using quoted path works in PHP version 5.3. However, this version introduces some other major problems with typo3 on Windows, e.g. deprecated functions.)
(issue imported from #M16656)


Files

16656.patch (1.72 KB) 16656.patch Administrator Admin, 2010-12-14 08:05
16656_v3.patch (580 Bytes) 16656_v3.patch Administrator Admin, 2011-02-21 20:19
16656_4-4_v3.patch (426 Bytes) 16656_4-4_v3.patch Administrator Admin, 2011-02-21 20:20

Related issues 3 (0 open3 closed)

Related to TYPO3 Core - Bug #17489: Install Tool image tests fail when there are spaces in the path nameClosedErnesto Baschny2007-07-19

Actions
Related to TYPO3 Core - Bug #24346: Thumbnail generation failsClosed2010-12-16

Actions
Has duplicate TYPO3 Core - Bug #24931: Quoting of path and filename in ImageMagick/GraphicsMagick not working on Windows + PHP5.2Closed2011-02-02

Actions
Actions #1

Updated by Jigal van Hemert over 13 years ago

Can you give a bit more details about versions of IM, PHP, webserver, etc.; if safe_mode is on/off, graphics settings, etc.?

With current dev version on Windows Vista/XAMPP/PHP5.3/GraphicsMagick the commands with quotes work for me (there are other problems which I hope to fix this month)

Example for reading JPG images in the install tool:
"D:/webserver/xampp/GraphicsMagick/gm.exe" convert +profile '*' -geometry 170x136! -colorspace RGB -quality 70 "D:/webserver/xampp/htdocs/typo3/sysext/install/imgs/jesus.jpg"[0] "D:/webserver/xampp/htdocs/typo3temp/pics/install_read_jpg.jpg"

Actions #2

Updated by Žiga Dolhar over 13 years ago

Hi Jigal,

I'm running Windows 2008 with IIS7, php 5.2.14 (safe mode off), IM ImageMagick 6.6.5-8 2010-11-10 Q16.

I tried to isolate the issue, and apparently it lies within PHP. I created a simple php script and ran it:

$exec = 'E:/gm/gm.exe convert +profile \'*\' -geometry 170x136! -colorspace RGB -quality 70

"E:/websites/misc/im/jesus.jpg"[0] "E:/websites/misc/im/install_read_jpg.jpg"';

exec($exec);

This script works flawlessly (takes the jesus.jpg and creates a new install_read_jpg.jpg file). However, as soon as I quote the executable path (it therefore reads "E:/gm/gm.exe" instead of E:/gm/gm.exe), there is no result.

The same with IM instead of GM.

However, on PHP 5.3.3, even quoted path works (but some other issues are introduced, for instance this one - http://bugs.php.net/bug.php?id=52523).

Since I have IM and GM in environment PATH variable, calling plain convert.exe and gm.exe (unquoted!) also works.

Although I agree that putting an absolute & quoted path is a more "sane" (and safe) decision, I am afraid that strictly using quotes in new versions will break compatibility with earlier PHP versions (pre-5.3) (at least in combination with IIS7 on Windows). If removing quotes is unacceptable, I would suggest an optional global setting to disable quoting.

If there is any other information I can provide, don't hesitate to ask.

Yours, Ziga

Actions #3

Updated by Jigal van Hemert over 13 years ago

I've searched for this issue and it seems that PHP 5.2 had or has a bug with the actual execution of the exec() function with quoted commands.
Using short path names (yea olde 8.3 format or DOS style path names) should work, because these contain no spaces.

I haven't found a reliable way (yet) to get a "short" path name for a "long" path.

Actions #4

Updated by Žiga Dolhar over 13 years ago

Unfortunatelly - you can't rely on 8.3 names, because the underlying OS doesn't necessarily support it. On my installation of Win2k8, 8.3 naming was by default disabled (http://www.windowsreference.com/windows-7/control-8dot3-naming-in-windows-2008-and-windows-7/).

I can confirm though, that after enabling 8.3 naming (and creating a new directory with IM), calling e:\testte~1\convert.exe (unquoted) works. (Unquoted. Again, quoted "e:\testtesttest\convert.exe" doesn't work.)

Actions #5

Updated by Jigal van Hemert over 13 years ago

Further searching suggests that the problem is only present if more than two double quotes are present. Can you test if this is indeed true?

$exec = '"E:/gm/gm.exe" convert +profile \'*\' -geometry 170x136! -colorspace RGB -quality 70 E:/websites/misc/im/jesus.jpg0 E:/websites/misc/im/install_read_jpg.jpg';

This should work fine (it's not a solution, but just a confirmation of the actual problem).

Can you test if either of these workarounds work on your installation?

1. Put a dummy command in front of the double quoted command. e.g.
$exec = 'E: & "E:/gm/gm.exe" convert +profile \'*\' -geometry 170x136! -colorspace RGB -quality 70 "E:/websites/misc/im/jesus.jpg"[0] "E:/websites/misc/im/install_read_jpg.jpg"';

2. Put the actual command with double quotes in a .bat file and execute that. Please test if the path/name of the .bat file works if surrounded with double quotes.

Thanks for the testing so far!

Actions #6

Updated by Žiga Dolhar over 13 years ago

(Apparently, bugtracker ate part of my previous post at the beginning.)

I first tried the following code:

$exec = '"E:/gm/gm.exe" convert +profile \'*\' -geometry 170x136! -colorspace RGB -quality 70

E:/websites/misc/im/jesus.jpg0 E:/websites/misc/im/install_read_jpg.jpg';

This works.

After putting double quotes around the output-file parameter, it doesn't work any more.

Then I tried your code under 1st bullet (with E: & dummy command).

The following code:

$exec = 'E: & "E:/gm/gm.exe" convert +profile \'*\' -geometry 170x136! -colorspace RGB -quality 70

"E:/websites/misc/im/jesus.jpg"[0] "E:/websites/misc/im/install_read_jpg.jpg"';

Works. :-)

I then created test.bat file with the following content:

"E:/gm/gm.exe" convert +profile '*' -geometry 170x136! -colorspace RGB -quality 70 "E:/websites/misc/im/jesus.jpg"[0] "E:/websites/misc/im/install_read_jpg.jpg"

(I un-escaped the single-quotes after +profile parameter.)

I ran test.bat through cmd.exe. It works, the install_read_jpg.jpg file IS created.

Then I tried $exec = 'test.bat'. Works.

$exec = '"test.bat"'; Also works.

$exec = '"e:/websites/misc/im/test.bat"'; Also works.

Actions #7

Updated by Žiga Dolhar over 13 years ago

Thus, I can confirm that bug is only present if more than two double quotes are present in the command. However, then there is a dummy E: & command before, the command works even with more than 2 double quotes.

Actions #8

Updated by Jigal van Hemert over 13 years ago

Patch submitted to core list

Actions #9

Updated by Žiga Dolhar over 13 years ago

I tested the attached patch. (Unfortunatelly I was unable to "patch" it using patch.exe, as it either crashed or only patched 1 line - this is probably an issue exclusively on my side, therefore I "manually" patched the file.)

After application, the following command is called in "Read JPG test" (and other tests) in install tool:

e: & "e:/ImageMagick/convert.exe" +profile '*' geometry 170x136! -colorspace RGB -quality 70 "E:/websites/--.test/typo3/sysext/install/imgs/jesus.jpg"[0] "E:/websites/---.test/typo3temp/pics/install_read_jpg.jpg"

Resulting files are successfully created, as are those generated on the frontend.

Thank you very much for spending time on this issue!

Actions #10

Updated by Jigal van Hemert over 13 years ago

@Žiga Dolhar : your vote in the typo3.teams.core newsgroup / mailinglist is useful to get this patch in 4.5!

Actions #11

Updated by Ernesto Baschny over 13 years ago

This probably also needs to be done in 4.4, since we are also quoting the filename in 4.4.5 (to be able to have spaces in the path to the IM executable, fixed in #17489). This is indeed a very ugly and stupid PHP bug, thanks for finding a workaround for it. Let's see if more people can test it.

Actions #12

Updated by Christian Brinkert over 13 years ago

The patch works for me ONLY partially. It fixed the problem to generate images by the TYPO3 install tool, but not to create images dynamically by TypoScript and gifbuilder. After some debugging I found differences in the file locations (absolute/relative) in the command string, which ends in successfully created images or a failure without any returned value. See the following command strings:

Install tool (with patch 16656):
$cmd = 'C: & "C:/ImageMagick-6.5.9-Q16/convert.exe" -geometry 170x136! -colorspace RGB -quality 70 "C:/T3demo/typo3/sysext/install/imgs/jesus.jpg"[0] "C:/T3demo/typo3temp/pics/install_read_jpg.jpg"';

By content rendering (TypoScript, Gifbuilder, with patch 16656):
$cmd = 'C: & "C:/ImageMagick-6.5.9-Q16/convert.exe" -geometry 170x136! -colorspace RGB -quality 70 "typo3/sysext/install/imgs/jesus.jpg"[0] "typo3temp/pics/install_read_jpg.jpg"';

After further testing on different mashines
- Windows XP and Windows 2003 Server
- PHP 5.2.8 and 5.3.3
- ImageMagick 6.5.9-Q16
- Apache 2.2
I recieved the following results, which I will simplify by using following constants for more clarity:

COMMAND = C:/ImageMagick-6.5.9-Q16/convert.exe
OPTIONS = -geometry 170x136! -colorspace RGB -quality 70
SOURCEFILE_ABSOLUTE = C:/T3demo/typo3/sysext/install/imgs/jesus.jpg
SOURCEFILE_RELATIVE = typo3/sysext/install/imgs/jesus.jpg
TARGETFILE_ABSOLUTE = C:/T3demo/typo3temp/pics/install_read_jpg.jpg
TARGETFILE_RELATIVE = typo3temp/pics/install_read_jpg.jpg

Please take special attention to the diffent sets of the double quotes.

Samples WITHOUT patch 16656:

1. Command string similar to the install tool
=> does not work in PHP 5.2.8, works in PHP 5.3.3
-> $cmd = '"COMMAND" OPTIONS "SOURCEFILE_ABSOLUTE"[0] "TARGETFILE_ABSOLUTE"';

2. Command string by TS and gifbuilder
=> does not work in PHP 5.2.8, works in PHP 5.3.3
-> $cmd = '"COMMAND" OPTIONS "SOURCEFILE_RELATIVE"[0] "TARGETFILE_RELATIVE"';

3. Command string by TS and gifbuilder WITHOUT double quotes to the command!
=> works in PHP 5.2.8 and PHP 5.3.3
-> $cmd = 'COMMAND OPTIONS "SOURCEFILE_RELATIVE"[0] "TARGETFILE_RELATIVE"';

Samples WITH patch 16656:

4. Command string similar to the install tool
=> works in PHP 5.2.8 and PHP 5.3.3
-> $cmd = 'C: & "COMMAND" OPTIONS "SOURCEFILE_ABSOLUTE"[0] "TARGETFILE_ABSOLUTE"';

5. Command string by TS and gifbuilder
=> does not work in PHP 5.2.8 and PHP 5.3.3
-> $cmd = 'C: & "COMMAND" OPTIONS "SOURCEFILE_RELATIVE"[0] "TARGETFILE_RELATIVE"';

6. Command string by TS and gifbuilder WITHOUT double quotes to the command!
=> does not work in PHP 5.2.8 and PHP 5.3.3
-> $cmd = 'C: & COMMAND OPTIONS "SOURCEFILE_RELATIVE"[0] "TARGETFILE_RELATIVE"';

7. Complete command string in additional double quotes
=> does not work in PHP 5.2.8 and PHP 5.3.3
-> $cmd = 'C: & ""COMMAND" OPTIONS "SOURCEFILE_RELATIVE"[0] "TARGETFILE_RELATIVE""';

SOLUTIONS:
Based on these results, I see two possibilities to fix this problem:

1. First, quick and dirty:
I do not use the patch and have to remove the double quotes to the command string, see sample #3. This only works, until there are NO space character in the command string!!!

see file: t3lib/class.t3lib_div.php, line 5937. 
I have replaced the escapeshellarg() function with the escapeshellcmd() function.

- $path = escapeshellarg($path . (($command 'composite') ? $combineScript : $command) . $isExt);
+ $path = escapeshellcmd($path . (($command 'composite') ? $combineScript : $command) . $isExt);

2. Certainly correct and better, I am not sure ...
Inclusion of the patch 16656 and additional expanding the relative file location to absolute file locations. But this seems to be done in some methods in the "t3lib_div class", any time the "imageMagickCommand" will be invoked. For example:

> line 465: method gif_compress()
> line 494: method png_to_gif_by_imagemagick()
-> line 511: method read_png_gif()

I'm not sure if this will be the right way?

Yours, Christian

Actions #13

Updated by Jigal van Hemert over 13 years ago

Hi Christian,

Thanks for testing!

The patch will only affect PHP < 5.3 on Windows, so no command prefix will be executed on PHP 5.3.3.
From the test cases you mention I conclude that relative paths are also a problem, but that is not in the scope of this issue. Some test cases might also be influenced by issue #22243 (unquote filenames doesn't work correctly and frame (the [0] part) should be placed inside the quotes). I'm trying hard to get that into 4.5 too.

Actions #14

Updated by Jörg Wagner about 13 years ago

The patch given here is rather lengthy and the prepended dummy command looks like a real hack. I propose to use my solution from #0017447 which is <b>a simple one-liner</b>. It uses as second pair of double quotes around the IM/GM command string if PHP<5.3 and OS==WIN. This is a solution recommended by a poster on php.net (posting of "luko post cz", 30-Jan-2008, on http://php.net/manual/en/ref.exec.php). Looks quite clean to me.
I have tested the patches given in #0017447 on several machines with PHP5.3.x and 5.2.x with TYPO3 4.4.5 and 4.5.0.

Actions #15

Updated by Jigal van Hemert about 13 years ago

Attached v3 patches sent to the core list. After checking the PHP source code the approach with extra double quotes is the solution which comes closest to the way PHP itself works.

Actions #16

Updated by Jigal van Hemert about 13 years ago

Committed to trunk rev: 10556
4_5 rev: 10557 (will appear in 4.5.1)
4_4 rev: 10558 (will appear in 4.4.7)

Actions #17

Updated by Benni Mack over 5 years ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF