--- includes/drush.inc +++ includes/drush.inc @@ -895,7 +895,7 @@ function drush_shell_exec_interactive($cmd) { function _drush_shell_exec($args, $interactive = FALSE) { //do not change the command itself, just the parameters. for ($x = 1; $x < sizeof($args); $x++) { - $args[$x] = escapeshellarg($args[$x]); + $args[$x] = drush_escapeshellarg($args[$x]); } $command = call_user_func_array('sprintf', $args); @@ -922,6 +922,57 @@ function _drush_shell_exec($args, $interactive = FALSE) { } /** + * Platform-independent version of escapeshellarg(). + */ +function drush_escapeshellarg($arg) { + if (drush_is_windows()) { + return drush_escapeshellarg_windows($arg); + } + else { + return escapeshellarg($arg); + } +} + +/** + * Check if the operating system is Windows. + */ +function drush_is_windows() { + if (substr(php_uname(), 0, 7) == 'Windows') { + return TRUE; + } + else { + return FALSE; + } +} + +/** + * Windows version of escapeshellarg(). + */ +function drush_escapeshellarg_windows($arg) { + // Double the backslashes before any double quotes. Escape the double quotes. + // (\" => \\\") && (" => \") = + // (\" => \\") + + $arg = preg_replace('/\\\"/', '\\\\\\"', $arg); + // + (" => \") + $arg = preg_replace('/"/', '\\"', $arg); + + // The same with single quotes. + // (\' => \\\') && (' => \') = + // (\' => \\') + + $arg = preg_replace('/\\\'/', '\\\\\\\'', $arg); + // + (' => \') + $arg = preg_replace('/\'/', '\\\'', $arg); + + // Replace "\t", "\n", "\r", "\0", "\x0B" with a whitespace. + $arg = str_replace(array("\t", "\n", "\r", "\0", "\x0B"), ' ', $arg); + + // Add surrounding quotes. + $arg = '"' . $arg . '"'; + + return $arg; +} + +/** * Stores output for the most recent shell command. * This should only be run from drush_shell_exec(). *