Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.831
diff -u -p -r1.831 common.inc
--- includes/common.inc	23 Nov 2008 16:54:47 -0000	1.831
+++ includes/common.inc	28 Nov 2008 20:34:47 -0000
@@ -283,6 +283,23 @@ function drupal_get_destination() {
   }
 }
 
+/** 
+ * Break a relative URL into path, query and fragment.
+ *
+ * This is similar to parse_url() which works on absolute URLs.
+ */
+function drupal_parse_url_relative($url) {
+  preg_match('/^([^?#]*)(?:\?([^#]*))?(?:#(.*))?$/', $url, $matches);
+  $parts['path'] = $matches[1];
+  if (isset($matches[2])) {
+    $parts['query'] = $matches[2];
+  }
+  if (isset($matches[3])) {
+    $parts['fragment'] = $matches[3];
+  }
+  return $parts;
+}
+
 /**
  * Send the user to a different Drupal page.
  *
@@ -326,7 +343,7 @@ function drupal_get_destination() {
 function drupal_goto($path = '', $query = NULL, $fragment = NULL, $http_response_code = 302) {
 
   if (isset($_REQUEST['destination'])) {
-    extract(parse_url(urldecode($_REQUEST['destination'])));
+    extract(drupal_parse_url_relative(urldecode($_REQUEST['destination'])));
   }
 
   $url = url($path, array('query' => $query, 'fragment' => $fragment, 'absolute' => TRUE));
Index: modules/menu/menu.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.admin.inc,v
retrieving revision 1.34
diff -u -p -r1.34 menu.admin.inc
--- modules/menu/menu.admin.inc	15 Nov 2008 08:23:07 -0000	1.34
+++ modules/menu/menu.admin.inc	28 Nov 2008 20:34:48 -0000
@@ -339,7 +339,7 @@ function menu_edit_item_validate($form, 
     $item['link_path'] = $normal_path;
   }
   if (!menu_path_is_external($item['link_path'])) {
-    $parsed_link = parse_url($item['link_path']);
+    $parsed_link = drupal_parse_url_relative($item['link_path']);
     if (isset($parsed_link['query'])) {
       $item['options']['query'] = $parsed_link['query'];
     }
Index: modules/simpletest/tests/common.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/common.test,v
retrieving revision 1.17
diff -u -p -r1.17 common.test
--- modules/simpletest/tests/common.test	26 Nov 2008 13:48:49 -0000	1.17
+++ modules/simpletest/tests/common.test	28 Nov 2008 20:34:48 -0000
@@ -200,6 +200,28 @@ class CascadingStylesheetsTestCase exten
 }
 
 /**
+ * Test drupal_goto().
+ */
+class DrupalGotoTestCase extends DrupalWebTestCase {
+  function getInfo() {
+    return array(
+      'name' => t('Drupal Goto'),
+      'description' => t("Performs tests on drupal_goto()."),
+      'group' => t('System')
+    );
+  }
+
+  function testDrupalGotoDestination() {
+    $user = $this->drupalCreateUser(array('access content', 'create page content'));
+    $this->drupalLogin($user);
+    $edit = array('title' => 'test');
+    // Set the destination to a path that would confuse parse_url().
+    $this->drupalPost('node/add/page', $edit, t('Save'), array('query' => array('destination' => 'foo:/:bar')));
+    $this->assertTrue(strpos($this->url, drupal_urlencode('foo:/:bar')) !== FALSE);
+  }
+}
+
+/**
  * Test drupal_http_request().
  */
 class DrupalHTTPRequestTestCase extends DrupalWebTestCase {
