Index: t3lib/core_autoload.php =================================================================== --- t3lib/core_autoload.php (revision 9830) +++ t3lib/core_autoload.php (revision ) @@ -145,6 +145,7 @@ 't3lib_pdohelper' => PATH_t3lib . 'class.t3lib_pdohelper.php', 't3lib_tceforms_suggest' => PATH_t3lib . 'tceforms/class.t3lib_tceforms_suggest.php', 't3lib_tceforms_suggest_defaultreceiver' => PATH_t3lib . 'tceforms/class.t3lib_tceforms_suggest_defaultreceiver.php', + 't3lib_utility_command' => PATH_t3lib . 'utility/class.t3lib_utility_command.php', 't3lib_utility_client' => PATH_t3lib . 'utility/class.t3lib_utility_client.php', 't3lib_utility_dependency' => PATH_t3lib . 'utility/class.t3lib_utility_dependency.php', 't3lib_utility_dependency_callback' => PATH_t3lib . 'utility/dependency/class.t3lib_utility_dependency_callback.php', Index: t3lib/class.t3lib_diff.php =================================================================== --- t3lib/class.t3lib_diff.php (revision 9758) +++ t3lib/class.t3lib_diff.php (revision ) @@ -165,7 +165,7 @@ // Perform diff. $cmd = $GLOBALS['TYPO3_CONF_VARS']['BE']['diff_path'] . ' ' . $this->diffOptions . ' ' . $file1 . ' ' . $file2; $res = array(); - exec($cmd, $res); + t3lib_utility_Command::exec($cmd, $res); unlink($file1); unlink($file2); Index: t3lib/thumbs.php =================================================================== --- t3lib/thumbs.php (revision 9861) +++ t3lib/thumbs.php (revision ) @@ -240,7 +240,7 @@ if (!file_exists($this->output)) { $parameters = '-sample ' . $this->size . ' ' . $this->wrapFileName($this->input) . '[0] ' . $this->wrapFileName($this->output); $cmd = t3lib_div::imageMagickCommand('convert', $parameters); - exec($cmd); + t3lib_utility_Command::exec($cmd); if (!file_exists($this->output)) { $this->errorGif('No thumb','generated!',basename($this->input)); } else { Index: typo3/sysext/install/mod/class.tx_install.php =================================================================== --- typo3/sysext/install/mod/class.tx_install.php (revision 9814) +++ typo3/sysext/install/mod/class.tx_install.php (revision ) @@ -3091,7 +3091,7 @@ $src = $this->backPath.'gfx/typo3logo.gif'; if (@is_file($src) && !strstr($src,' ') && !strstr($dest,' ')) { $cmd = t3lib_div::imageMagickCommand('convert', $src.' '.$dest, $path); - exec($cmd); + t3lib_utility_Command::exec($cmd); } else die('No typo3/gfx/typo3logo.gif file!'); $out=''; if (@is_file($dest)) { @@ -3150,7 +3150,7 @@ $cmd = t3lib_div::imageMagickCommand($file, $parameters, $path); $retVal = false; - exec($cmd, $retVal); + t3lib_utility_Command::exec($cmd, $retVal); $string = $retVal[0]; list(,$ver) = explode('Magick', $string); list($ver) = explode(' ',trim($ver)); @@ -5694,7 +5694,7 @@ $results[] = $this->performUpdateQueries($update_statements['create_table'], $this->INSTALL['database_update']); $results[] = $this->performUpdateQueries($remove_statements['change_table'], $this->INSTALL['database_update']); $results[] = $this->performUpdateQueries($remove_statements['drop_table'], $this->INSTALL['database_update']); - + $this->databaseUpdateErrorMessages = array(); foreach ($results as $resultSet) { if (is_array($resultSet)) { Index: typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_cmdline_backend.php =================================================================== --- typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_cmdline_backend.php (revision 9758) +++ typo3/sysext/rsaauth/sv1/backends/class.tx_rsaauth_cmdline_backend.php (revision ) @@ -95,7 +95,7 @@ // secure. $command = $this->opensslPath . ' genrsa -out ' . escapeshellarg($privateKeyFile) . ' 1024'; - exec($command); + t3lib_utility_Command::exec($command); // Test that we got a private key $privateKey = file_get_contents($privateKeyFile); @@ -103,7 +103,7 @@ // Ok, we got the private key. Get the modulus. $command = $this->opensslPath . ' rsa -noout -modulus -in ' . escapeshellarg($privateKeyFile); - $value = exec($command); + $value = t3lib_utility_Command::exec($command); if (substr($value, 0, 8) === 'Modulus=') { $publicKey = substr($value, 8); @@ -144,7 +144,7 @@ // Execute the command and capture the result $output = array(); - exec($command, $output); + t3lib_utility_Command::exec($command, $output); // Remove the file @unlink($privateKeyFile); @@ -164,7 +164,7 @@ $result = false; if ($this->opensslPath) { // If path exists, test that command runs and can produce output - $test = exec($this->opensslPath . ' version'); + $test = t3lib_utility_Command::exec($this->opensslPath . ' version'); $result = (substr($test, 0, 8) == 'OpenSSL '); } return $result; Index: typo3/sysext/indexed_search/class.external_parser.php =================================================================== --- typo3/sysext/indexed_search/class.external_parser.php (revision 9758) +++ typo3/sysext/indexed_search/class.external_parser.php (revision ) @@ -412,7 +412,7 @@ if ($this->app['pdfinfo']) { // Getting pdf-info: $cmd = $this->app['pdfinfo'] . ' ' . escapeshellarg($absFile); - exec($cmd,$res); + t3lib_utility_Command::exec($cmd, $res); $pdfInfo = $this->splitPdfInfo($res); unset($res); if (intval($pdfInfo['pages'])) { @@ -422,7 +422,7 @@ $tempFileName = t3lib_div::tempnam('Typo3_indexer'); // Create temporary name @unlink ($tempFileName); // Delete if exists, just to be safe. $cmd = $this->app['pdftotext'] . ' -f ' . $low . ' -l ' . $high . ' -enc UTF-8 -q ' . escapeshellarg($absFile) . ' ' . $tempFileName; - exec($cmd); + t3lib_utility_Command::exec($cmd); if (@is_file($tempFileName)) { $content = t3lib_div::getUrl($tempFileName); unlink($tempFileName); @@ -438,7 +438,7 @@ case 'doc': if ($this->app['catdoc']) { $cmd = $this->app['catdoc'] . ' -d utf-8 ' . escapeshellarg($absFile); - exec($cmd,$res); + t3lib_utility_Command::exec($cmd, $res); $content = implode(LF,$res); unset($res); $contentArr = $this->pObj->splitRegularContent($this->removeEndJunk($content)); @@ -448,7 +448,7 @@ case 'ppt': if ($this->app['ppthtml']) { $cmd = $this->app['ppthtml'] . ' ' . escapeshellarg($absFile); - exec($cmd,$res); + t3lib_utility_Command::exec($cmd, $res); $content = implode(LF,$res); unset($res); $content = $this->pObj->convertHTMLToUtf8($content); @@ -459,7 +459,7 @@ case 'xls': if ($this->app['xlhtml']) { $cmd = $this->app['xlhtml'] . ' -nc -te ' . escapeshellarg($absFile); - exec($cmd,$res); + t3lib_utility_Command::exec($cmd, $res); $content = implode(LF,$res); unset($res); $content = $this->pObj->convertHTMLToUtf8($content); @@ -476,13 +476,13 @@ if ($this->app['unzip']) { // Read content.xml: $cmd = $this->app['unzip'] . ' -p ' . escapeshellarg($absFile) . ' content.xml'; - exec($cmd,$res); + t3lib_utility_Command::exec($cmd, $res); $content_xml = implode(LF,$res); unset($res); // Read meta.xml: $cmd = $this->app['unzip'] . ' -p ' . escapeshellarg($absFile) . ' meta.xml'; - exec($cmd, $res); + t3lib_utility_Command::exec($cmd, $res); $meta_xml = implode(LF,$res); unset($res); @@ -509,7 +509,7 @@ case 'rtf': if ($this->app['unrtf']) { $cmd = $this->app['unrtf'] . ' ' . escapeshellarg($absFile); - exec($cmd,$res); + t3lib_utility_Command::exec($cmd, $res); $fileContent = implode(LF,$res); unset($res); $fileContent = $this->pObj->convertHTMLToUtf8($fileContent); @@ -585,7 +585,7 @@ case 'pdf': // Getting pdf-info: $cmd = $this->app['pdfinfo'] . ' ' . escapeshellarg($absFile); - exec($cmd,$res); + t3lib_utility_Command::exec($cmd, $res); $pdfInfo = $this->splitPdfInfo($res); unset($res); Index: typo3/show_item.php =================================================================== --- typo3/show_item.php (revision 9758) +++ typo3/show_item.php (revision ) @@ -371,7 +371,7 @@ if ($ext=='zip') { $code = ''; $t = array(); - exec('unzip -l '.$this->file, $t); + t3lib_utility_Command::exec('unzip -l ' . $this->file, $t); if (is_array($t)) { reset($t); next($t); @@ -396,7 +396,7 @@ $compr = 'z'; } $t = array(); - exec('tar t'.$compr.'f '.$this->file, $t); + t3lib_utility_Command::exec('tar t' . $compr . 'f ' . $this->file, $t); if (is_array($t)) { foreach($t as $val) { $code.=' Index: t3lib/class.t3lib_div.php =================================================================== --- t3lib/class.t3lib_div.php (revision 9864) +++ t3lib/class.t3lib_div.php (revision ) @@ -489,7 +489,7 @@ if ($gfxConf['gif_compress'] && strtolower(substr($theFile, -4, 4)) == '.gif') { // GIF... if (($type == 'IM' || !$type) && $gfxConf['im'] && $gfxConf['im_path_lzw']) { // IM $cmd = self::imageMagickCommand('convert', '"' . $theFile . '" "' . $theFile . '"', $gfxConf['im_path_lzw']); - exec($cmd); + t3lib_utility_Command::exec($cmd); $returnCode = 'IM'; if (@is_file($theFile)) { self::fixPermissions($theFile); @@ -523,7 +523,7 @@ && @is_file($theFile)) { // IM $newFile = substr($theFile, 0, -4) . '.gif'; $cmd = self::imageMagickCommand('convert', '"' . $theFile . '" "' . $newFile . '"', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']); - exec($cmd); + t3lib_utility_Command::exec($cmd); $theFile = $newFile; if (@is_file($newFile)) { self::fixPermissions($newFile); @@ -553,7 +553,7 @@ } else { $newFile = PATH_site . 'typo3temp/readPG_' . md5($theFile . '|' . filemtime($theFile)) . ($output_png ? '.png' : '.gif'); $cmd = self::imageMagickCommand('convert', '"' . $theFile . '" "' . $newFile . '"', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path']); - exec($cmd); + t3lib_utility_Command::exec($cmd); if (@is_file($newFile)) { self::fixPermissions($newFile); return $newFile; @@ -6183,62 +6183,9 @@ * @return string Compiled command that deals with IM6 & GraphicsMagick */ public static function imageMagickCommand($command, $parameters, $path = '') { - $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX']; - $isExt = (TYPO3_OS == 'WIN' ? '.exe' : ''); - $switchCompositeParameters = FALSE; - - if (!$path) { - $path = $gfxConf['im_path']; + return t3lib_utility_Command::imageMagickCommand($command, $parameters, $path); - } + } - $path = self::fixWindowsFilePath($path); - $im_version = strtolower($gfxConf['im_version_5']); - $combineScript = $gfxConf['im_combine_filename'] ? trim($gfxConf['im_combine_filename']) : 'combine'; - - if ($command === 'combine') { // This is only used internally, has no effect outside - $command = 'composite'; - } - - // Compile the path & command - if ($im_version === 'gm') { - $switchCompositeParameters = TRUE; - $path = escapeshellarg($path . 'gm' . $isExt) . ' ' . $command; - } else { - if ($im_version === 'im6') { - $switchCompositeParameters = TRUE; - } - $path = escapeshellarg($path . (($command == 'composite') ? $combineScript : $command) . $isExt); - } - - // strip profile information for thumbnails and reduce their size - if ($parameters && $command != 'identify' && $gfxConf['im_useStripProfileByDefault'] && $gfxConf['im_stripProfileCommand'] != '') { - if (strpos($parameters, $gfxConf['im_stripProfileCommand']) === FALSE) { - // Determine whether the strip profile action has be disabled by TypoScript: - if ($parameters !== '-version' && strpos($parameters, '###SkipStripProfile###') === FALSE) { - $parameters = $gfxConf['im_stripProfileCommand'] . ' ' . $parameters; - } else { - $parameters = str_replace('###SkipStripProfile###', '', $parameters); - } - } - } - - $cmdLine = $path . ' ' . $parameters; - - if ($command == 'composite' && $switchCompositeParameters) { // Because of some weird incompatibilities between ImageMagick 4 and 6 (plus GraphicsMagick), it is needed to change the parameters order under some preconditions - $paramsArr = self::unQuoteFilenames($parameters); - - if (count($paramsArr) > 5) { // The mask image has been specified => swap the parameters - $tmp = $paramsArr[count($paramsArr) - 3]; - $paramsArr[count($paramsArr) - 3] = $paramsArr[count($paramsArr) - 4]; - $paramsArr[count($paramsArr) - 4] = $tmp; - } - - $cmdLine = $path . ' ' . implode(' ', $paramsArr); - } - - return $cmdLine; - } - /** * Explode a string (normally a list of filenames) with whitespaces by considering quotes in that string. This is mostly needed by the imageMagickCommand function above. * Index: typo3/sysext/em/classes/tools/class.tx_em_tools.php =================================================================== --- typo3/sysext/em/classes/tools/class.tx_em_tools.php (revision 9758) +++ typo3/sysext/em/classes/tools/class.tx_em_tools.php (revision ) @@ -108,7 +108,7 @@ if (strlen($GLOBALS['TYPO3_CONF_VARS']['BE']['unzip_path'])) { chdir($path); $cmd = $GLOBALS['TYPO3_CONF_VARS']['BE']['unzip_path'] . ' -o ' . escapeshellarg($file); - exec($cmd, $list, $ret); + t3lib_utility_Command::exec($cmd, $list, $ret); return ($ret === 0); } else { // we use a pure PHP unzip Index: typo3/sysext/tsconfig_help/mod1/index.php =================================================================== --- typo3/sysext/tsconfig_help/mod1/index.php (revision 9758) +++ typo3/sysext/tsconfig_help/mod1/index.php (revision ) @@ -286,7 +286,7 @@ $output = t3lib_div::getURL($tempPath.$filename); $cmd = 'rm -r "'.$tempPath.'"'; - exec($cmd); + t3lib_utility_Command::exec($cmd); return $output; } Index: t3lib/utility/class.t3lib_utility_command.php =================================================================== --- t3lib/utility/class.t3lib_utility_command.php (revision ) +++ t3lib/utility/class.t3lib_utility_command.php (revision ) @@ -0,0 +1,120 @@ + + * All rights reserved + * + * This script is part of the TYPO3 project. The TYPO3 project is + * free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The GNU General Public License can be found at + * http://www.gnu.org/copyleft/gpl.html. + * A copy is found in the textfile GPL.txt and important notices to the license + * from the author is found in LICENSE.txt distributed with these scripts. + * + * + * This script is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * This copyright notice MUST APPEAR in all copies of the script! + ***************************************************************/ + +/** + * Class to handle system commands. + * + * $Id: class.t3lib_utility_command.php $ + * + * @author Steffen Kamper + */ +final class t3lib_utility_Command { + + + /** + * Wrapper function for php exec function + * Needs to be central to have better control and possible fix for safe_mode/low php version restrictions as occurred with IM/GM issues + * + * @static + * @param string $command + * @param null|array $output + * @param integer $returnValue + * @return null|array + */ + public static function exec($command, &$output = NULL, &$returnValue = 0) { + $lastLine = exec($command, $output, $returnValue); + return $lastLine; + } + + /** + * Compile the command for running ImageMagick/GraphicsMagick. + * + * @param string Command to be run: identify, convert or combine/composite + * @param string The parameters string + * @param string Override the default path (e.g. used by the install tool) + * @return string Compiled command that deals with IM6 & GraphicsMagick + */ + public static function imageMagickCommand($command, $parameters, $path = '') { + $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX']; + $isExt = (TYPO3_OS == 'WIN' ? '.exe' : ''); + $switchCompositeParameters = FALSE; + + if (!$path) { + $path = $gfxConf['im_path']; + } + $path = t3lib_div::fixWindowsFilePath($path); + + $im_version = strtolower($gfxConf['im_version_5']); + $combineScript = $gfxConf['im_combine_filename'] ? trim($gfxConf['im_combine_filename']) : 'combine'; + + if ($command === 'combine') { // This is only used internally, has no effect outside + $command = 'composite'; + } + + // Compile the path & command + if ($im_version === 'gm') { + $switchCompositeParameters = TRUE; + $path = escapeshellarg($path . 'gm' . $isExt) . ' ' . $command; + } else { + if ($im_version === 'im6') { + $switchCompositeParameters = TRUE; + } + $path = escapeshellarg($path . (($command == 'composite') ? $combineScript : $command) . $isExt); + } + + // strip profile information for thumbnails and reduce their size + if ($parameters && $command != 'identify' && $gfxConf['im_useStripProfileByDefault'] && $gfxConf['im_stripProfileCommand'] != '') { + if (strpos($parameters, $gfxConf['im_stripProfileCommand']) === FALSE) { + // Determine whether the strip profile action has be disabled by TypoScript: + if ($parameters !== '-version' && strpos($parameters, '###SkipStripProfile###') === FALSE) { + $parameters = $gfxConf['im_stripProfileCommand'] . ' ' . $parameters; + } else { + $parameters = str_replace('###SkipStripProfile###', '', $parameters); + } + } + } + + $cmdLine = $path . ' ' . $parameters; + + if ($command == 'composite' && $switchCompositeParameters) { // Because of some weird incompatibilities between ImageMagick 4 and 6 (plus GraphicsMagick), it is needed to change the parameters order under some preconditions + $paramsArr = t3lib_div::unQuoteFilenames($parameters); + + if (count($paramsArr) > 5) { // The mask image has been specified => swap the parameters + $tmp = $paramsArr[count($paramsArr) - 3]; + $paramsArr[count($paramsArr) - 3] = $paramsArr[count($paramsArr) - 4]; + $paramsArr[count($paramsArr) - 4] = $tmp; + } + + $cmdLine = $path . ' ' . implode(' ', $paramsArr); + } + + return $cmdLine; + } + +} + +?> \ No newline at end of file Index: t3lib/class.t3lib_exec.php =================================================================== --- t3lib/class.t3lib_exec.php (revision 9758) +++ t3lib/class.t3lib_exec.php (revision ) @@ -160,7 +160,7 @@ // Try to get the executable with the command 'which'. // It does the same like already done, but maybe on other paths if (TYPO3_OS != 'WIN') { - $cmd = @exec('which ' . $cmd); + $cmd = @t3lib_utility_Command::exec('which ' . $cmd); if (@is_executable($cmd)) { self::$applications[$cmd]['app'] = $cmd; self::$applications[$cmd]['path'] = dirname($cmd) . '/'; Index: t3lib/class.t3lib_extfilefunc.php =================================================================== --- t3lib/class.t3lib_extfilefunc.php (revision 9758) +++ t3lib/class.t3lib_extfilefunc.php (revision ) @@ -502,7 +502,7 @@ copy($theFile, $theDestFile); } else { $cmd = 'cp "' . $theFile . '" "' . $theDestFile . '"'; - exec($cmd); + t3lib_utility_Command::exec($cmd); } t3lib_div::fixPermissions($theDestFile); clearstatcache(); @@ -546,7 +546,7 @@ if ($this->checkPathAgainstMounts($theDestFile) && $this->checkPathAgainstMounts($theFile)) { // No way to do this under windows! $cmd = 'cp -R "' . $theFile . '" "' . $theDestFile . '"'; - exec($cmd); + t3lib_utility_Command::exec($cmd); clearstatcache(); if (@is_dir($theDestFile)) { $this->writelog(2, 0, 2, 'Directory "%s" copied to "%s"', Array($theFile, $theDestFile)); @@ -621,7 +621,7 @@ @rename($theFile, $theDestFile); } else { $cmd = 'mv "' . $theFile . '" "' . $theDestFile . '"'; - exec($cmd); + t3lib_utility_Command::exec($cmd); } clearstatcache(); if (@is_file($theDestFile)) { @@ -667,8 +667,7 @@ } else { $cmd = 'mv "' . $theFile . '" "' . $theDestFile . '"'; $errArr = array(); - $retVar = 0; - exec($cmd, $errArr, $retVar); + t3lib_utility_Command::exec($cmd, $errArr); } clearstatcache(); if (@is_dir($theDestFile)) { @@ -997,7 +996,7 @@ if ($this->checkPathAgainstMounts($theFile) && $this->checkPathAgainstMounts($theDest . '/')) { // No way to do this under windows. $cmd = $this->unzipPath . 'unzip -qq "' . $theFile . '" -d "' . $theDest . '"'; - exec($cmd); + t3lib_utility_Command::exec($cmd); $this->writelog(7, 0, 1, 'Unzipping file "%s" in "%s"', Array($theFile, $theDest)); return TRUE; } else { Index: t3lib/class.t3lib_stdgraphic.php =================================================================== --- t3lib/class.t3lib_stdgraphic.php (revision 9811) +++ t3lib/class.t3lib_stdgraphic.php (revision ) @@ -2587,7 +2587,7 @@ $frame = $this->noFramePrepended ? '' : '[0]'; $cmd = t3lib_div::imageMagickCommand('identify', $this->wrapFileName($imagefile) . $frame); $returnVal = array(); - exec($cmd, $returnVal); + t3lib_utility_Command::exec($cmd, $returnVal); $splitstring = $returnVal[0]; $this->IM_commands[] = array('identify', $cmd, $returnVal[0]); if ($splitstring) { @@ -2635,7 +2635,7 @@ $cmd = t3lib_div::imageMagickCommand('convert', $params . ' ' . $this->wrapFileName($input) . $frame . ' ' . $this->wrapFileName($output)); $this->IM_commands[] = array($output, $cmd); - $ret = exec($cmd); + $ret = t3lib_utility_Command::exec($cmd); t3lib_div::fixPermissions($output); // Change the permissions of the file return $ret; @@ -2666,7 +2666,7 @@ $cmd = t3lib_div::imageMagickCommand('combine', '-compose over +matte ' . $this->wrapFileName($input) . ' ' . $this->wrapFileName($overlay) . ' ' . $this->wrapFileName($theMask) . ' ' . $this->wrapFileName($output)); // +matte = no alpha layer in output $this->IM_commands[] = array($output, $cmd); - $ret = exec($cmd); + $ret = t3lib_utility_Command::exec($cmd); t3lib_div::fixPermissions($output); // Change the permissions of the file if (is_file($theMask)) {