### Eclipse Workspace Patch 1.0 #P d7dev Index: modules/search/search.module =================================================================== RCS file: /cvs/drupal/drupal/modules/search/search.module,v retrieving revision 1.344 diff -u -r1.344 search.module --- modules/search/search.module 11 Apr 2010 18:54:11 -0000 1.344 +++ modules/search/search.module 20 Apr 2010 05:09:39 -0000 @@ -1023,8 +1023,11 @@ preg_match_all('/ ("([^"]+)"|(?!OR)([^" ]+))/', ' ' . $keys, $matches); $keys = array_merge($matches[2], $matches[3]); - // Prepare text - $text = ' ' . strip_tags(str_replace(array('<', '>'), array(' <', '> '), $text)) . ' '; + // Prepare text by stripping HTML tags and decoding HTML entities. + $text = strip_tags(str_replace(array('<', '>'), array(' <', '> '), $text)); + $text = html_entity_decode($text, ENT_QUOTES, 'UTF-8'); + + // Slash-escape quotes in the search keyword string. array_walk($keys, '_search_excerpt_replace'); $workkeys = $keys; @@ -1054,9 +1057,12 @@ // $q) and behind it (position $s) if (preg_match('/' . $boundary . $key . $boundary . '/iu', $text, $match, PREG_OFFSET_CAPTURE, $included[$key])) { $p = $match[0][1]; - if (($q = strpos($text, ' ', max(0, $p - 60))) !== FALSE) { - $end = substr($text, $p, 80); + if (($q = strpos(' ' . $text, ' ', max(0, $p - 61))) !== FALSE) { + $end = substr($text . ' ', $p, 80); if (($s = strrpos($end, ' ')) !== FALSE) { + // Account for the added spaces. + $q = ($q > 0) ? $q - 1 : $q; + $s = ($s > strlen($end) - 1) ? strlen($end) - 1 : $s; $ranges[$q] = $p + $s; $length += $p + $s - $q; $included[$key] = $p + 1; @@ -1077,7 +1083,7 @@ // If we didn't find anything, return the beginning. if (count($ranges) == 0) { - return truncate_utf8($text, 256, TRUE, TRUE); + return htmlspecialchars(truncate_utf8($text, 256, TRUE, TRUE)); } // Sort the text ranges by starting position. @@ -1107,7 +1113,9 @@ foreach ($newranges as $from => $to) { $out[] = substr($text, $from, $to - $from); } - $text = (isset($newranges[0]) ? '' : '... ') . implode(' ... ', $out) . ' ...'; + + $text = (isset($newranges[0]) ? '' : t('... ')) . implode(t(' ... '), $out) . t(' ...'); + $text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); // Highlight keywords. Must be done at once to prevent conflicts ('strong' and ''). $text = preg_replace('/' . $boundary . '(' . implode('|', $keys) . ')' . $boundary . '/iu', '\0', $text); @@ -1119,7 +1127,7 @@ */ /** - * Helper function for array_walk in search_except. + * Helper function for array_walk() in search_excerpt(). */ function _search_excerpt_replace(&$text) { $text = preg_quote($text, '/'); Index: modules/search/search.test =================================================================== RCS file: /cvs/drupal/drupal/modules/search/search.test,v retrieving revision 1.59 diff -u -r1.59 search.test --- modules/search/search.test 16 Apr 2010 13:53:43 -0000 1.59 +++ modules/search/search.test 20 Apr 2010 05:09:39 -0000 @@ -698,3 +698,48 @@ } } +/** + * Tests the search_excerpt() function. + */ +class SearchExcerptTestCase extends DrupalUnitTestCase { + public static function getInfo() { + return array( + 'name' => 'Search excerpt extraction', + 'description' => 'Tests that the search_excerpt() function works.', + 'group' => 'Search', + ); + } + + /** + * Implementation setUp(). + */ + function setUp() { + parent::setUp('search'); + } + + + /** + * Tests search_excerpt(). + */ + function testSearchExcerpt() { + // Make some text with entities and tags. + $text = 'The quick brown fox & jumps

over

the lazy dog'; + // Note: The search_excerpt() function adds some extra spaces -- not + // important for HTML formatting. Remove these for comparison. + $expected = 'The quick brown fox & jumps over the lazy dog'; + $result = preg_replace('| +|', ' ', search_excerpt('nothing', $text)); + $this->assertEqual(preg_replace('| +|', ' ', $result), $expected, 'Entire string is returned when keyword is not found in short string'); + + $result = preg_replace('| +|', ' ', search_excerpt('fox', $text)); + $this->assertEqual($result, 'The quick brown fox & jumps over the lazy dog ...', 'Found keyword is highlighted'); + + $longtext = str_repeat($text . ' ', 10); + $result = preg_replace('| +|', ' ', search_excerpt('nothing', $text)); + $this->assertTrue(strpos($result, $expected) === 0, 'When keyword is not found in long string, return value starts as expected'); + + $entities = str_repeat('készítése ', 20); + $result = preg_replace('| +|', ' ', search_excerpt('nothing', $entities)); + $this->assertFalse(strpos($result, '&'), 'Entities are not present in excerpt'); + $this->assertTrue(strpos($result, 'í') > 0, 'Entities are converted in excerpt'); + } +} \ No newline at end of file