Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.867
diff -u -p -r1.867 comment.module
--- modules/comment/comment.module	16 Apr 2010 13:56:45 -0000	1.867
+++ modules/comment/comment.module	22 Apr 2010 07:19:01 -0000
@@ -1274,14 +1274,55 @@ function comment_node_delete($node) {
  * Implements hook_node_update_index().
  */
 function comment_node_update_index($node) {
-  $mode = variable_get('comment_default_mode_' . $node->type, COMMENT_MODE_THREADED);
-  $comments_per_page = variable_get('comment_default_per_page_' . $node->type, 50);
-  if ($node->comment && $cids = comment_get_thread($node, $mode, $comments_per_page)) {
-    $comments = comment_load_multiple($cids);
-    comment_prepare_thread($comments);
-    $build = comment_view_multiple($comments, $node);
+  $index_comments = &drupal_static(__FUNCTION__, NULL);
+
+  if ($index_comments === NULL) {
+    // Prevent indexing of comments if there are any roles that can search but
+    // not view comments.
+    $permissions = array('access comments', 'search content');
+    $query = db_select('role_permission', 'rp')
+      ->fields('rp', array('rid'))
+      ->condition('permission', $permissions, 'IN')
+      ->groupBy('rid')
+      ->orderBy('rid');
+    $query->addExpression('COUNT(rp.rid)', 'count');
+    $query->addExpression("SUM(CASE WHEN permission = :search THEN 1 ELSE 0 END)", 'search_permission', array(':search' => 'search content'));
+    $result = $query->execute();
+    $index_comments = TRUE;
+    foreach ($result as $row) {
+      if ($row->rid == DRUPAL_AUTHENTICATED_RID) {
+        if ($row->count == 2 || ($row->count == 1 && $row->search_permission == 0)) {
+          // Allow indexing comments if authenticated role has permission to
+          // access comments. Breaks here because no other checking is needed.
+          break;
+        }
+        else if ($row->count == 1 && $row->search_permission == 1) {
+          // Disable indexing comments if authenticated role can search but
+          // not view comments.
+          $index_comments = FALSE;
+          break;
+        }
+      }
+      else if ($row->count == 1 && $row->search_permission == 1) {
+        // Disable indexing comments if any role except authenticated
+        // have only 'search content' permission.
+        $index_comments = FALSE;
+        break;
+      }
+    }
   }
-  return drupal_render($build);
+
+  if ($index_comments) {
+    $mode = variable_get('comment_default_mode_' . $node->type, COMMENT_MODE_THREADED);
+    $comments_per_page = variable_get('comment_default_per_page_' . $node->type, 50);
+    if ($node->comment && $cids = comment_get_thread($node, $mode, $comments_per_page)) {
+      $comments = comment_load_multiple($cids);
+      comment_prepare_thread($comments);
+      $build = comment_view_multiple($comments, $node);
+      return drupal_render($build);
+    }
+  }
+  return '';
 }
 
 /**
@@ -1296,7 +1337,7 @@ function comment_update_index() {
  * Implements hook_node_search_result().
  */
 function comment_node_search_result($node) {
-  if ($node->comment != COMMENT_NODE_HIDDEN) {
+  if (user_access('access comments') && $node->comment != COMMENT_NODE_HIDDEN) {
     $comments = db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = :nid', array('nid' => $node->nid))->fetchField();
     return format_plural($comments, '1 comment', '@count comments');
   }
Index: modules/search/search.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.test,v
retrieving revision 1.59
diff -u -p -r1.59 search.test
--- modules/search/search.test	16 Apr 2010 13:53:43 -0000	1.59
+++ modules/search/search.test	22 Apr 2010 07:19:01 -0000
@@ -424,8 +424,8 @@ class SearchRankingTestCase extends Drup
 
     // See testRankings() above - build a node that will rank high for sticky.
     $settings = array(
-      'type' => 'page', 
-      'title' => array(LANGUAGE_NONE => array(array('value' => 'Drupal rocks'))), 
+      'type' => 'page',
+      'title' => array(LANGUAGE_NONE => array(array('value' => 'Drupal rocks'))),
       'body' => array(LANGUAGE_NONE => array(array('value' => "Drupal's search rocks"))),
       'sticky' => 1,
     );
@@ -520,7 +520,7 @@ class SearchCommentTestCase extends Drup
 
   public static function getInfo() {
     return array(
-      'name' => 'Comment Search tests',
+      'name' => 'Comment search tests',
       'description' => 'Verify text formats and filters used elsewhere.',
       'group' => 'Search',
     );
@@ -532,13 +532,15 @@ class SearchCommentTestCase extends Drup
     // Create and log in an administrative user having access to the Full HTML
     // text format.
     $full_html_format = db_query_range('SELECT * FROM {filter_format} WHERE name = :name', 0, 1, array(':name' => 'Full HTML'))->fetchObject();
-    $this->admin_user = $this->drupalCreateUser(array(
+    $permissions = array(
       'administer filters',
       filter_permission_name($full_html_format),
       'administer permissions',
       'create page content',
       'post comments without approval',
-    ));
+      'access comments',
+    );
+    $this->admin_user = $this->drupalCreateUser($permissions);
     $this->drupalLogin($this->admin_user);
   }
 
@@ -558,12 +560,7 @@ class SearchCommentTestCase extends Drup
     // Allow anonymous users to search content.
     $edit = array(
       DRUPAL_ANONYMOUS_RID . '[search content]' => 1,
-      // @todo Comments are added to search index without checking first whether
-      //   anonymous users are allowed to access comments.
       DRUPAL_ANONYMOUS_RID . '[access comments]' => 1,
-      // @todo Without this permission, "Login or register to post comments" is
-      //   added to the search index.  Comment.module is not guilty; that text
-      //   seems to be added via node links.
       DRUPAL_ANONYMOUS_RID . '[post comments]' => 1,
     );
     $this->drupalPost('admin/people/permissions', $edit, t('Save permissions'));
@@ -615,6 +612,105 @@ class SearchCommentTestCase extends Drup
     $this->drupalPost('', $edit, t('Search'));
     $this->assertNoText($comment_body, t('Comment body text not found in search results.'));
   }
+
+  /**
+   * Verify access rules for comment indexing with different permissions.
+   */
+  function testSearchResultsCommentAccess() {
+    $comment_body = 'Test comment body';
+    $this->comment_subject = 'Test comment subject';
+    $this->admin_role = $this->admin_user->roles;
+    unset($this->admin_role[DRUPAL_AUTHENTICATED_RID]);
+    $this->admin_role = key($this->admin_role);
+
+    // Create a node.
+    variable_set('comment_preview_article', DRUPAL_OPTIONAL);
+    $this->node = $this->drupalCreateNode(array('type' => 'article'));
+
+    // Post a comment using 'Full HTML' text format.
+    $edit_comment = array();
+    $edit_comment['subject'] = $this->comment_subject;
+    $edit_comment['comment_body[' . LANGUAGE_NONE . '][0][value]'] = '<h1>' . $comment_body . '</h1>';
+    $this->drupalPost('comment/reply/' . $this->node->nid, $edit_comment, t('Save'));
+
+    $this->drupalLogout();
+    // Anon user has search permission but no access comments permission,
+    // comments should not be indexed.
+    $this->setRolePermissions(DRUPAL_ANONYMOUS_RID);
+    $this->checkCommentAccess();
+
+    // Anon user has search permission and access comments permission, comments
+    // should be indexed.
+    $this->setRolePermissions(DRUPAL_ANONYMOUS_RID, TRUE);
+    $this->checkCommentAccess(TRUE);
+
+    $this->drupalLogin($this->admin_user);
+    $this->drupalGet('admin/people/permissions');
+    // Disable search access for authenticated user to test admin user.
+    $this->setRolePermissions(DRUPAL_AUTHENTICATED_RID, FALSE, FALSE);
+
+    // Admin user has search permission but no access comments
+    // permission, comments should not be indexed.
+    $this->setRolePermissions($this->admin_role);
+    $this->checkCommentAccess();
+
+    // Admin user has search permission and access comments permission,
+    // comments should be indexed.
+    $this->setRolePermissions($this->admin_role, TRUE);
+    $this->checkCommentAccess(TRUE);
+
+    // Authenticated user has search permission but no access comments
+    // permission, comments should not be indexed.
+    $this->setRolePermissions(DRUPAL_AUTHENTICATED_RID);
+    $this->checkCommentAccess();
+
+    // Authenticated user has search permission and access comments permission,
+    // comments should be indexed.
+    $this->setRolePermissions(DRUPAL_AUTHENTICATED_RID, TRUE);
+    $this->checkCommentAccess(TRUE);
+
+    // Disable search access for authenticated user.
+    $this->setRolePermissions(DRUPAL_AUTHENTICATED_RID, TRUE, FALSE);
+    // Admin user has search permission but no access comments
+    // permission, but comments should be indexed because admin user
+    // inherits authenticated user's permission to access comments.
+    $this->setRolePermissions($this->admin_role);
+    $this->checkCommentAccess(TRUE);
+  }
+
+  /**
+   * Set permissions for role.
+   */
+  function setRolePermissions($rid, $access_comments = FALSE, $search_content = TRUE) {
+    $permissions = array(
+      'access comments' => $access_comments,
+      'search content' => $search_content,
+    );
+    user_role_change_permissions($rid, $permissions);
+  }
+
+  /**
+   * Update search index and search for comment.
+   */
+  function checkCommentAccess($assume_access = FALSE) {
+    // Invoke search index update.
+    search_touch_node($this->node->nid);
+    $this->cronRun();
+
+    // Search for the comment subject.
+    $edit = array(
+      'search_block_form' => "'" . $this->comment_subject . "'",
+    );
+    $this->drupalPost('', $edit, t('Search'));
+    if ($assume_access) {
+      $this->assertText($this->node->title, t('Node found in search results.'));
+      $this->assertText($this->comment_subject, t('Comment subject found in search results.'));
+    } else {
+      $this->assertNoText($this->node->title, t('Node not found in search results.'));
+      $this->assertNoText($this->comment_subject, t('Comment subject not found in search results.'));
+    }
+  }
+
 }
 
 /**
