From d044352dbd6f0836feab3f574802bf67f5cf54f5 Mon Sep 17 00:00:00 2001
From: Greg Anderson <greg.1.anderson@greenknowe.org>
Date: Mon, 9 May 2011 21:18:45 -0700
Subject: [PATCH 1/2] #1151646 by das-peter: add defaults for constants in drush_testcasee.inc

---
 tests/drush_testcase.inc |   44 ++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/tests/drush_testcase.inc b/tests/drush_testcase.inc
index d31c3ec..efcd193 100644
--- a/tests/drush_testcase.inc
+++ b/tests/drush_testcase.inc
@@ -1,11 +1,25 @@
 <?php
 
 // We read from globals here because env can be empty and ini did not work in quick test.
-define('UNISH_DB_URL', $GLOBALS['UNISH_DB_URL']);
+define('UNISH_DB_URL', ((!empty($GLOBALS['UNISH_DB_URL'])) ? $GLOBALS['UNISH_DB_URL'] : 'mysql://root:@127.0.0.1'));
 
 // UNISH_DRUSH value can come from phpunit.xml or `which drush`.
 if (!defined('UNISH_DRUSH')) {
-  define('UNISH_DRUSH', empty($GLOBALS['UNISH_DRUSH']) ? trim(`which drush`) : $GLOBALS['UNISH_DRUSH']);
+  if (empty($GLOBALS['UNISH_DRUSH'])) {
+    if (stristr(strtoupper(PHP_OS), 'WIN')) {
+      define('UNISH_DRUSH', exec('for %i in (drush) do @echo.   %~$PATH:i'));
+    }
+    else {
+      define('UNISH_DRUSH', trim(`which drush`));
+    }
+  }
+  else {
+    define('UNISH_DRUSH', $GLOBALS['UNISH_DRUSH']);
+  }
+}
+
+if (empty($GLOBALS['UNISH_SANDBOX'])) {
+  $GLOBALS['UNISH_SANDBOX'] = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'drush-sandbox';
 }
 
 abstract class Drush_TestCase extends PHPUnit_Framework_TestCase {
@@ -220,7 +234,29 @@ abstract class Drush_TestCase extends PHPUnit_Framework_TestCase {
     return $contents;
   }
 
-  function file_delete_recursive($path) {
-    return exec('rm -rf ' . escapeshellarg($path));
+  /**
+   * Same code as drush_delete_dir().
+   * @see drush_delete_dir()
+   *
+   * @param string $dir
+   * @return boolean
+   */
+  function file_delete_recursive($dir) {
+    if (!file_exists($dir)) {
+      return TRUE;
+    }
+    if (!is_dir($dir)) {
+      @chmod($dir, 0777); // Make file writeable
+      return unlink($dir);
+    }
+    foreach (scandir($dir) as $item) {
+      if ($item == '.' || $item == '..') {
+        continue;
+      }
+      if (!self::file_delete_recursive($dir.'/'.$item)) {
+        return FALSE;
+      }
+    }
+    return rmdir($dir);
   }
 }
-- 
1.7.4.msysgit.0


From b340eca6577f01fec7f83932356e5d206ecac3f7 Mon Sep 17 00:00:00 2001
From: Greg Anderson <greg.1.anderson@greenknowe.org>
Date: Mon, 9 May 2011 23:15:30 -0700
Subject: [PATCH 2/2] #1151464 by greg.1.anderson: escape parameters in drush tests

---
 tests/backendTest.php    |    6 +++---
 tests/drush_testcase.inc |   34 ++++++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/tests/backendTest.php b/tests/backendTest.php
index 40c9553..ba801f2 100644
--- a/tests/backendTest.php
+++ b/tests/backendTest.php
@@ -24,7 +24,7 @@ class backendCase extends Drush_TestCase {
    * General handling of site aliases will be in sitealiasTest.php.
    */
   function testOrigin() {
-    $exec = sprintf('%s %s version --simulate --ssh-options=%s | grep ssh', escapeshellcmd(UNISH_DRUSH), escapeshellarg('user@server/path/to/drupal#sitename'), escapeshellarg('-i mysite_dsa'));
+    $exec = sprintf('%s %s version --simulate --ssh-options=%s | grep ssh', Drush_TestCase::unish_escapeshellarg(UNISH_DRUSH), Drush_TestCase::unish_escapeshellarg('user@server/path/to/drupal#sitename'), Drush_TestCase::unish_escapeshellarg('-i mysite_dsa'));
     $this->execute($exec);
     // $expected might be different on non unix platforms. We shall see.
     $expected = "Simulating backend invoke: ssh -i mysite_dsa user@server 'drush  --uri=sitename --root=/path/to/drupal --simulate version 2>&1' 2>&1";
@@ -41,7 +41,7 @@ class backendCase extends Drush_TestCase {
   */
   function testTarget() {
     $stdin = json_encode(array('filter'=>'sql'));
-    $exec = sprintf('echo %s | %s help --backend', escapeshellarg($stdin), escapeshellcmd(UNISH_DRUSH));
+    $exec = sprintf('echo %s | %s help --backend', Drush_TestCase::unish_escapeshellarg($stdin), Drush_TestCase::unish_escapeshellarg(UNISH_DRUSH));
     $this->execute($exec);
     $parsed = $this->parse($this->getOutput());
     $this->assertTrue((bool) $parsed, 'Successfully parsed backend output');
@@ -54,7 +54,7 @@ class backendCase extends Drush_TestCase {
     $this->assertEquals('Bootstrap to phase 0.', $parsed['log'][0]['message']);
 
     // Check error propogation by requesting an invalid command (missing Drupal site).
-    $exec = sprintf('%s core-cron --backend', escapeshellcmd(UNISH_DRUSH));
+    $exec = sprintf('%s core-cron --backend', Drush_TestCase::unish_escapeshellarg(UNISH_DRUSH));
     $this->execute($exec, self::EXIT_ERROR);
     $parsed = $this->parse($this->getOutput());
     $this->assertEquals(1, $parsed['error_status']);
diff --git a/tests/drush_testcase.inc b/tests/drush_testcase.inc
index efcd193..bc809a5 100644
--- a/tests/drush_testcase.inc
+++ b/tests/drush_testcase.inc
@@ -36,6 +36,40 @@ abstract class Drush_TestCase extends PHPUnit_Framework_TestCase {
     $this->_output = false;
   }
 
+  public static function is_windows() {
+    return (strtoupper(substr(PHP_OS, 0, 3)) == "WIN");
+  }
+
+  public static function unish_escapeshellarg($arg) {
+    // Short-circuit escaping for simple params (keep stuff readable)
+    if (preg_match('|^[a-zA-Z0-9.:/_-]*$|', $arg)) {
+      return $arg;
+    }
+    elseif (Drush_TestCase::is_windows()) {
+      return Drush_TestCase::_unish_escapeshellarg_windows($arg);
+    }
+    else {
+      return escapeshellarg($arg);
+    }
+  }
+
+  public static function _unish_escapeshellarg_windows($arg) {
+    // Double up existing backslashes
+    $arg = preg_replace('/\\\/', '\\\\\\\\', $arg);
+
+    // Escape double quotes.
+    $arg = preg_replace('/"/', '\\"', $arg);
+
+    // Escape single quotes.
+    $arg = preg_replace('/\'/', '\\\'', $arg);
+
+    // Add surrounding quotes.
+    $arg = '"' . $arg . '"';
+
+    return $arg;
+  }
+
+
   /**
    * Assure that each class starts with an empty sandbox directory.
    */
-- 
1.7.4.msysgit.0

