mirror of
https://github.com/flarum/framework.git
synced 2024-11-27 11:03:37 +08:00
Prevent MySQL search operators from taking effect
We do not want to inherit MySQL's fulltext query language, so let's just drop all non-word characters from the search term. Fixes #1498.
This commit is contained in:
parent
10ba2e9464
commit
7ca47b67c3
|
@ -29,9 +29,10 @@ class FulltextGambit implements GambitInterface
|
|||
throw new LogicException('This gambit can only be applied on a DiscussionSearch');
|
||||
}
|
||||
|
||||
// The @ character crashes fulltext searches on InnoDB tables.
|
||||
// See https://bugs.mysql.com/bug.php?id=74042
|
||||
$bit = str_replace('@', '*', $bit);
|
||||
// Replace all non-word characters with spaces.
|
||||
// We do this to prevent MySQL fulltext search boolean mode from taking
|
||||
// effect: https://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html
|
||||
$bit = preg_replace('/[^\p{L}\p{N}_]+/u', ' ', $bit);
|
||||
|
||||
$query = $search->getQuery();
|
||||
$grammar = $query->getGrammar();
|
||||
|
|
|
@ -100,4 +100,52 @@ class ListDiscussionsControllerTest extends ApiControllerTestCase
|
|||
// Order-independent comparison
|
||||
$this->assertEquals(['2', '3'], $ids, 'IDs do not match', 0.0, 10, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function ignores_non_word_characters_when_searching()
|
||||
{
|
||||
$this->database()->table('posts')->insert([
|
||||
['id' => 2, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'type' => 'comment', 'content' => '<t><p>not in text</p></t>'],
|
||||
['id' => 3, 'discussion_id' => 3, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'type' => 'comment', 'content' => '<t><p>lightsail in text</p></t>'],
|
||||
]);
|
||||
|
||||
$this->database()->table('discussions')->insert([
|
||||
['id' => 2, 'title' => 'lightsail in title', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'first_post_id' => 2, 'comment_count' => 1],
|
||||
['id' => 3, 'title' => 'not in title', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 2, 'first_post_id' => 3, 'comment_count' => 1],
|
||||
]);
|
||||
|
||||
$response = $this->callWith([], [
|
||||
'filter' => ['q' => 'lightsail+'],
|
||||
'include' => 'mostRelevantPost'
|
||||
]);
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
$ids = array_map(function ($row) {
|
||||
return $row['id'];
|
||||
}, $data['data']);
|
||||
|
||||
// Order-independent comparison
|
||||
$this->assertEquals(['2', '3'], $ids, 'IDs do not match', 0.0, 10, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function search_for_special_characters_gives_empty_result()
|
||||
{
|
||||
$response = $this->callWith([], [
|
||||
'filter' => ['q' => '*'],
|
||||
'include' => 'mostRelevantPost'
|
||||
]);
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
$this->assertEquals([], $data['data']);
|
||||
|
||||
$response = $this->callWith([], [
|
||||
'filter' => ['q' => '@'],
|
||||
'include' => 'mostRelevantPost'
|
||||
]);
|
||||
$data = json_decode($response->getBody()->getContents(), true);
|
||||
$this->assertEquals([], $data['data']);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user