diff --git a/core/modules/search/search.module b/core/modules/search/search.module
index 6c041d0..2e83f72 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -599,6 +599,7 @@ function search_excerpt($keys, $text, $langcode = NULL) {
   // Prepare text by stripping HTML tags and decoding HTML entities.
   $text = strip_tags(str_replace(array('<', '>'), array(' <', '> '), $text));
   $text = decode_entities($text);
+  $text_length = strlen($text);
 
   // Make a list of unique keywords that are actually found in the text,
   // which could be items in $keys or replacements that are equivalent through
@@ -651,11 +652,15 @@ function search_excerpt($keys, $text, $langcode = NULL) {
         // characters of context on each end.
         $before = strpos(' ' . $text, ' ', max(0, $found_position - 61));
         if ($before !== FALSE && $before <= $found_position) {
-          $after = strrpos(' ' . $text . ' ', ' ', min($found_position + 61, strlen($text) + 1));
+          if ($text_length > $found_position + 60) {
+            $after = strrpos(substr($text, 0, $found_position + 60), ' ', $found_position);
+          }
+          else {
+            $after = $text_length;
+          }
           if ($after !== FALSE && $after > $found_position) {
             // Account for the spaces we added.
             $before = max($before - 1, 0);
-            $after = min($after - 1, strlen($text));
             if ($before < $after) {
               // Save this range.
               $ranges[$before] = $after;
diff --git a/core/modules/search/src/Tests/SearchExcerptTest.php b/core/modules/search/src/Tests/SearchExcerptTest.php
index 257b9b8..6bea2cb 100644
--- a/core/modules/search/src/Tests/SearchExcerptTest.php
+++ b/core/modules/search/src/Tests/SearchExcerptTest.php
@@ -52,6 +52,11 @@ function testSearchExcerpt() {
     $result = preg_replace('| +|', ' ', search_excerpt('dog', $text));
     $this->assertEqual(preg_replace('| +|', ' ', $result), $expected, 'Keyword is highlighted at end of short string');
 
+    $longtext = str_repeat(str_replace('brown', 'silver', $text) . ' ', 10) . $text . str_repeat(' ' . str_replace('brown', 'pink', $text), 10);
+    $result = preg_replace('| +|', ' ', search_excerpt('brown', $longtext));
+    $expected = '… silver fox &amp; jumps over the lazy dog The quick <strong>brown</strong> fox &amp; jumps over the lazy dog The quick …';
+    $this->assertEqual($result, $expected, 'Snippet around keyword in long text is correctly capped');
+
     $longtext = str_repeat($text . ' ', 10);
     $result = preg_replace('| +|', ' ', search_excerpt('nothing', $longtext));
     $expected = 'The quick brown fox &amp; jumps over the lazy dog';
