 modules/comment/comment.module |   36 ++++++++++++---
 modules/search/search.test     |   96 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 119 insertions(+), 13 deletions(-)

diff --git modules/comment/comment.module modules/comment/comment.module
index d42da78..1473e7f 100644
--- modules/comment/comment.module
+++ modules/comment/comment.module
@@ -1274,14 +1274,34 @@ 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);
+
+  // Only check once if comments should be indexed.
+  if ($index_comments === null) {
+    // Only index comments when there is no role that can search but not access
+    // comments.
+    $access_comments_roles = user_roles(FALSE, 'access comments');
+    $search_roles = user_roles(FALSE, 'search content');
+    $index_comments = true;
+    foreach ($search_roles as $rid => $name) {
+      // If a role can search but not access comments, don't index.
+      if (!isset($access_comments_roles[$rid])) {
+        $index_comments = false;
+        break;
+      }
+    }
+  }
+  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 drupal_render($build);
+  return '';
 }
 
 /**
@@ -1296,7 +1316,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');
   }
diff --git modules/search/search.test modules/search/search.test
index 3f7dec7..02fc371 100644
--- modules/search/search.test
+++ modules/search/search.test
@@ -538,6 +538,7 @@ class SearchCommentTestCase extends DrupalWebTestCase {
       'administer permissions',
       'create page content',
       'post comments without approval',
+      'access comments',
     ));
     $this->drupalLogin($this->admin_user);
   }
@@ -558,12 +559,7 @@ class SearchCommentTestCase extends DrupalWebTestCase {
     // 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 +611,96 @@ class SearchCommentTestCase extends DrupalWebTestCase {
     $this->drupalPost('', $edit, t('Search'));
     $this->assertNoText($comment_body, t('Comment body text not found in search results.'));
   }
+
+
+  /**
+   * Anon user has search permission but no access comments permission,
+   * comments should not be indexed.
+   */
+  function testSearchResultsCommentAnonNoAccess() {
+    $this->setPermissions(TRUE, FALSE, TRUE, TRUE);
+    $this->checkAccess();
+  }
+
+  /**
+   * Anon user has search permission and access comments permission, comments
+   * should be indexed.
+   */
+  function testSearchResultsCommentAnonAccess() {
+    $this->setPermissions(TRUE, TRUE, TRUE, TRUE);
+    $this->checkAccess(TRUE, TRUE);
+  }
+
+  /**
+   * Authenticated user has search permission but no access comments
+   * permission, comments should not be indexed.
+   */
+  function testSearchResultsCommentAuthNoAccess() {
+    $this->setPermissions(FALSE, FALSE, TRUE, FALSE);
+    $this->checkAccess(FALSE, FALSE);
+  }
+
+  /**
+   * Authenticated user has search permission and access comments permission,
+   * comments should be indexed.
+   */
+  function testSearchResultsCommentAuthAccess() {
+    $this->setPermissions(FALSE, FALSE, TRUE, TRUE);
+    $this->checkAccess(FALSE, TRUE);
+  }
+
+  /**
+   * Set permissions
+   */
+  function setPermissions($anon_search, $anon_comments, $auth_search, $auth_comments) {
+    $edit = array();
+    if ($anon_search) {
+      $edit[DRUPAL_ANONYMOUS_RID . '[search content]'] = TRUE;
+    }
+    if ($anon_comments) {
+      $edit[DRUPAL_ANONYMOUS_RID . '[access comments]'] = TRUE;
+    }
+    if ($auth_search) {
+      $edit[DRUPAL_AUTHENTICATED_RID . '[search content]'] = TRUE;
+    }
+    //if ($auth_comments) {
+      $edit[DRUPAL_AUTHENTICATED_RID . '[access comments]'] = $auth_comments;
+    //}
+    $this->drupalPost('admin/people/permissions', $edit, t('Save permissions'));
+  }
+
+  function checkAccess($logout = TRUE, $assume_access = FALSE) {
+    $comment_body = 'Test comment body';
+    variable_set('comment_preview_article', DRUPAL_OPTIONAL);
+
+    // Create a node.
+    $node = $this->drupalCreateNode(array('type' => 'article'));
+    // Post a comment using 'Full HTML' text format.
+    $edit_comment = array();
+    $edit_comment['subject'] = 'Test comment subject';
+    $edit_comment['comment_body[' . LANGUAGE_NONE . '][0][value]'] = '<h1>' . $comment_body . '</h1>';
+    $this->drupalPost('comment/reply/' . $node->nid, $edit_comment, t('Save'));
+
+    // Invoke search index update.
+    if ($logout) {
+      $this->drupalLogout();
+    }
+    $this->cronRun();
+
+    // Search for the comment subject.
+    $edit = array(
+      'search_block_form' => "'" . $edit_comment['subject'] . "'",
+    );
+    $this->drupalPost('', $edit, t('Search'));
+    if ($assume_access) {
+      $this->assertText($node->title, t('Node found in search results.'));
+      $this->assertText($edit_comment['subject'], t('Comment subject found in search results.'));
+    } else {
+      $this->assertNoText($node->title, t('Node not found in search results.'));
+      $this->assertNoText($edit_comment['subject'], t('Comment subject not found in search results.'));
+    }
+  }
+
 }
 
 /**
