Index: modules/search/search.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.pages.inc,v
retrieving revision 1.22
diff -u -r1.22 search.pages.inc
--- modules/search/search.pages.inc	11 Aug 2010 14:21:39 -0000	1.22
+++ modules/search/search.pages.inc	16 Aug 2010 22:49:04 -0000
@@ -67,7 +67,7 @@
   }
   // The form may be altered based on whether the search was run.
   $build['search_form'] = drupal_get_form('search_form', NULL, $keys, $info['module']);
-  $build['search_results'] = array('#markup' => $results);
+  $build['search_results'] = $results;
 
   return $build;
 }
Index: modules/search/search.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.module,v
retrieving revision 1.357
diff -u -r1.357 search.module
--- modules/search/search.module	13 Aug 2010 01:05:36 -0000	1.357
+++ modules/search/search.module	16 Aug 2010 22:49:04 -0000
@@ -1074,17 +1074,23 @@
  *   Optional array of additional search conditions.
  *
  * @return
- *   Formatted search results. No return value if $keys are not supplied or
- *   if the given search module is not active.
+ *   Renderable array of search results. No return value if $keys are not
+ *   supplied or if the given search module is not active.
  */
 function search_data($keys, $module, $conditions = NULL) {
   if (module_hook($module, 'search_execute')) {
     $results = module_invoke($module, 'search_execute', $keys, $conditions);
     if (module_hook($module, 'search_page')) {
-      return module_invoke($module, 'search_page', $results);
+      return array(
+        '#markup' => module_invoke($module, 'search_page', $results),
+      );
     }
     else {
-      return theme('search_results', array('results' => $results, 'type' => $module));
+      return array(
+        '#theme' => 'search_results',
+        '#results' => $results,
+        '#type' => $module,
+      );
     }
   }
 }
Index: modules/search/search.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.test,v
retrieving revision 1.71
diff -u -r1.71 search.test
--- modules/search/search.test	13 Aug 2010 01:05:36 -0000	1.71
+++ modules/search/search.test	16 Aug 2010 22:49:04 -0000
@@ -1050,7 +1050,7 @@
 
 
 /**
- * Test config page.
+ * Tests keywords and conditions.
  */
 class SearchKeywordsConditions extends DrupalWebTestCase {
 
@@ -1523,3 +1523,37 @@
     $this->submit_count = $count;
   }
 }
+
+/**
+ * Tests that hook_search_page runs.
+ */
+class SearchPageOverride extends DrupalWebTestCase {
+  public $search_user;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Search page override',
+      'description' => 'Verify that hook_search_page can override search page display.',
+      'group' => 'Search',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('search', 'search_extra_type');
+
+    // Login as a user that can create and search content.
+    $this->search_user = $this->drupalCreateUser(array('search content', 'administer search'));
+    $this->drupalLogin($this->search_user);
+
+    // Enable the extra type module for searching.
+    variable_set('search_active_modules', array('node' => 'node', 'user' => 'user', 'search_extra_type' => 'search_extra_type'));
+    menu_rebuild();
+  }
+
+  function testSearchPageHook() {
+    $keys = 'bike shed ' . $this->randomName();
+    $this->drupalGet("search/dummy_path/{$keys}");
+    $this->assertText('Dummy search snippet', 'Dummy search snippet is shown');
+    $this->assertText('Test page text is here', 'Page override is working');
+  }
+}
Index: modules/search/search.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.api.php,v
retrieving revision 1.28
diff -u -r1.28 search.api.php
--- modules/search/search.api.php	11 Aug 2010 14:21:39 -0000	1.28
+++ modules/search/search.api.php	16 Aug 2010 22:49:04 -0000
@@ -25,9 +25,11 @@
  * hook_update_index(). If your search type has settings, you can implement
  * hook_search_admin() to add them to the search settings page. You can also
  * alter the display of your module's search results by implementing
- * hook_search_page(). And you can use hook_form_FORM_ID_alter(), with
- * FORM_ID set to 'search', to add fields to the search form. See
- * node_form_search_form_alter() for an example.
+ * hook_search_page(). You can use hook_form_FORM_ID_alter(), with
+ * FORM_ID set to 'search', to add fields to the search form (see
+ * node_form_search_form_alter() for an example). You can use
+ * hook_search_access() to limit access to searching, and hook_search_page() to
+ * override how search results are displayed.
  *
  * @return
  *   Array with optional keys:
@@ -248,7 +250,7 @@
 /**
  * Override the rendering of search results.
  *
- * A module that implements hook_search() to define a type of search
+ * A module that implements hook_search_info() to define a type of search
  * may implement this hook in order to override the default theming of
  * its search results, which is otherwise themed using theme('search_results').
  *
@@ -269,10 +271,10 @@
   $output = '<ol class="search-results">';
 
   foreach ($results as $entry) {
-    $output .= theme('search_result', $entry, $type);
+    $output .= theme('search_result', array('result' => $entry, 'type' => 'my_module_name'));
   }
   $output .= '</ol>';
-  $output .= theme('pager', NULL);
+  $output .= theme('pager');
 
   return $output;
 }
Index: modules/search/tests/search_extra_type.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/tests/search_extra_type.module,v
retrieving revision 1.2
diff -u -r1.2 search_extra_type.module
--- modules/search/tests/search_extra_type.module	11 Aug 2010 14:21:39 -0000	1.2
+++ modules/search/tests/search_extra_type.module	16 Aug 2010 22:49:04 -0000
@@ -17,6 +17,9 @@
   );
 }
 
+/**
+ * Test conditions callback for hook_search_info().
+ */
 function search_extra_type_conditions() {
   $conditions = array();
 
@@ -45,3 +48,21 @@
     ),
   );
 }
+
+/**
+ * Implements hook_search_page().
+ *
+ * Adds some text to the search page so we can verify that it runs.
+ */
+function search_extra_type_search_page($results) {
+  $output = '<h2>Test page text is here</h2>';
+  $output .= '<ol class="search-results">';
+
+  foreach ($results as $entry) {
+    $output .= theme('search_result', array('result' => $entry, 'type' => 'search_extra_type'));
+  }
+  $output .= '</ol>';
+  $output .= theme('pager');
+
+  return $output;
+}
