From 3b30c2fa0e5c7380e0ab0a54996d0ff96d8577be Mon Sep 17 00:00:00 2001 From: Platonides Date: Tue, 26 Oct 2010 22:17:42 +0000 Subject: [PATCH] Provide a proper implementation for passing environment variables to wfShellExec() The quick fix of r74821 is no longer needed. --- includes/GlobalFunctions.php | 23 ++++++++++++++++++++++- includes/media/Bitmap.php | 11 +++-------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 12464e6c05..778caddafe 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -2457,9 +2457,11 @@ function wfDl( $extension ) { * @param $cmd Command line, properly escaped for shell. * @param &$retval optional, will receive the program's exit code. * (non-zero is usually failure) + * @param $environ Array optional environment variables which should be + * added to the executed command environment. * @return collected stdout as a string (trailing newlines stripped) */ -function wfShellExec( $cmd, &$retval = null ) { +function wfShellExec( $cmd, &$retval = null, $environ = array() ) { global $IP, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime; static $disabled; @@ -2487,6 +2489,25 @@ function wfShellExec( $cmd, &$retval = null ) { wfInitShellLocale(); + $envcmd = ''; + foreach( $environ as $k => $v ) { + if ( wfIsWindows() ) { + /* Surrounding a set in quotes (method used by wfEscapeShellArg) makes the quotes themselves + * appear in the environment variable, so we must use carat escaping as documented in + * http://technet.microsoft.com/en-us/library/cc723564.aspx + * Note however that the quote isn't listed there, but is needed, and the parentheses + * are listed there but doesn't appear to need it. + */ + $envcmd .= "set $k=" . preg_replace( '/([&|()<>^"])/', '^\\1', $v ) . ' && '; + } else { + /* Assume this is a POSIX shell, thus required to accept variable assignments before the command + * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_09_01 + */ + $envcmd .= "$k=" . escapeshellarg( $v ) . ' '; + } + } + $cmd = $envcmd . $cmd; + if ( wfIsWindows() ) { if ( version_compare( PHP_VERSION, '5.3.0', '<' ) && /* Fixed in 5.3.0 :) */ ( version_compare( PHP_VERSION, '5.2.1', '>=' ) || php_uname( 's' ) == 'Windows NT' ) ) diff --git a/includes/media/Bitmap.php b/includes/media/Bitmap.php index 7e9edb732c..c83f430285 100644 --- a/includes/media/Bitmap.php +++ b/includes/media/Bitmap.php @@ -148,9 +148,9 @@ class BitmapHandler extends ImageHandler { } // Use one thread only, to avoid deadlock bugs on OOM - $tempEnv = 'OMP_NUM_THREADS=1 '; + $env = array( 'OMP_NUM_THREADS' => 1 ); if ( strval( $wgImageMagickTempDir ) !== '' ) { - $tempEnv .= 'MAGICK_TMPDIR=' . wfEscapeShellArg( $wgImageMagickTempDir ) . ' '; + $env['MAGICK_TMPDIR'] = $wgImageMagickTempDir; } $cmd = @@ -171,14 +171,9 @@ class BitmapHandler extends ImageHandler { " {$animation_post} " . wfEscapeShellArg( $this->escapeMagickOutput( $dstPath ) ) . " 2>&1"; - if ( !wfIsWindows() ) { - // Assume we have a POSIX compliant shell which accepts variable assignments preceding the command - $cmd = $tempEnv . $cmd; - } - wfDebug( __METHOD__.": running ImageMagick: $cmd\n" ); wfProfileIn( 'convert' ); - $err = wfShellExec( $cmd, $retval ); + $err = wfShellExec( $cmd, $retval, $env ); wfProfileOut( 'convert' ); } elseif( $scaler == 'custom' ) { # Use a custom convert command -- 2.20.1