Index: modules/search/search.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.pages.inc,v
retrieving revision 1.23
diff -u -r1.23 search.pages.inc
--- modules/search/search.pages.inc	18 Aug 2010 18:40:50 -0000	1.23
+++ modules/search/search.pages.inc	26 Aug 2010 21:00:52 -0000
@@ -17,7 +17,8 @@
 function search_view($module = NULL, $keys = '') {
   $info = FALSE;
   $redirect = FALSE;
-  $keys = trim($keys);
+  $keys = rawurldecode(trim($keys));
+
   // Also try to pull search keywords out of the $_REQUEST variable to
   // support old GET format of searches for existing links.
   if (!$keys && !empty($_REQUEST['keys'])) {
@@ -39,7 +40,7 @@
     // Redirect from bare /search or an invalid path to the default search path.
     $path = 'search/' . $info['path'];
     if ($keys) {
-      $path .= '/' . $keys;
+      $path .= '/' . search_keys_encode($keys);
     }
     drupal_goto($path);
   }
@@ -149,6 +150,36 @@
     // Fall through to the form redirect.
   }
 
-  $form_state['redirect'] = $form_state['action'] . '/' . $keys;
+  $form_state['redirect'] = $form_state['action'] . '/' . search_keys_encode($keys);
   return;
 }
+
+/**
+ * Encodes the search keyword string for safe inclusion in a URL.
+ *
+ * Search form submits are redirected to (search path)/(keywords). We need to
+ * encode the keywords so that they are considered to be one chunk of data
+ * rather than URL information. For example, if we didn't encode the keywords,
+ * then searching for ../../admin with clean URLs would redirect you to the
+ * admin screen, because it would give you path search/node/../../admin.
+ *
+ * @param $keys
+ *   Search keyword string to encode.
+ *
+ * @return
+ *   The encoded keyword string, with non-URL characters replaced by %
+ *   equivalents.
+ */
+function search_keys_encode($keys) {
+  $keys = trim($keys);
+
+  // We don't want to use drupal_encode_path() here, because that leaves
+  // the / key in the URL, which we don't want.
+  $keys = rawurlencode($keys);
+
+  // Character . is still problematic after rawurlencode(), causing more Apache
+  // 403 errors. So replace it with its code too.
+  $keys = str_replace('.', '%2E', $keys);
+
+  return $keys;
+}
