Skip to content

Commit f8f0f0f

Browse files
authored
[6.x] Fix Comb returning 500 when matched search token is longer than the configured snippet_length (#15358)
1 parent ee3e3b4 commit f8f0f0f

2 files changed

Lines changed: 33 additions & 3 deletions

File tree

src/Search/Comb/Comb.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,13 +1077,13 @@ private function extractSnippets($value, $chunks)
10771077
[, $before, $chunk, $after] = $match;
10781078
$before = $surplus.$before;
10791079
$surplus = '';
1080-
$half = floor(($length - Str::length($chunk)) / 2);
1080+
$half = max(0, floor(($length - Str::length($chunk)) / 2));
10811081
if (Str::length($after) < $half) {
10821082
$snippet = $chunk.$after;
1083-
$snippet = Str::safeTruncateReverse($before, $length - Str::length($snippet)).$snippet;
1083+
$snippet = Str::safeTruncateReverse($before, max(0, $length - Str::length($snippet))).$snippet;
10841084
} else {
10851085
$snippet = Str::safeTruncateReverse($before, $half).$chunk;
1086-
$trimmed = Str::safeTruncate($after, $length - Str::length($snippet));
1086+
$trimmed = Str::safeTruncate($after, max(0, $length - Str::length($snippet)));
10871087
$surplus = Str::substr($after, Str::length($trimmed));
10881088
$snippet = $snippet.$trimmed;
10891089
}

tests/Search/CombTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,36 @@ public function it_extracts_snippets_from_a_bard_field()
202202
$this->assertEquals($expected, collect($results['data'] ?? [])->pluck('snippets.content')->all());
203203
}
204204

205+
#[Test]
206+
public function it_extracts_snippets_when_the_term_is_longer_than_the_snippet_length()
207+
{
208+
// https://github.com/statamic/cms/issues/12951
209+
$content = <<<'EOT'
210+
We know, it was a long wait, but now we finally have it, support for OpenID
211+
Connect front and back-channel logout. The backchannel_logout_session_required
212+
flag can be set on a client. See backchannel_logout_uri too. The
213+
frontchannel_logout_session_required flag is the front-channel equivalent, and
214+
backchannel_logout_session_required appears once more right here.
215+
EOT;
216+
217+
$comb = new Comb([
218+
['content' => $content],
219+
], ['snippet_length' => 30]);
220+
221+
try {
222+
$results = $comb->lookUp('backchannel_logout_session_required');
223+
} catch (NoResultsFound $e) {
224+
$results = [];
225+
}
226+
227+
$expected = [[
228+
'backchannel_logout_session_required',
229+
'backchannel_logout_session_required',
230+
]];
231+
232+
$this->assertEquals($expected, collect($results['data'] ?? [])->pluck('snippets.content')->all());
233+
}
234+
205235
#[Test]
206236
public function it_can_search_for_plus_signs()
207237
{

0 commit comments

Comments
 (0)