mirror of
https://github.com/flarum/framework.git
synced 2024-12-01 05:53:45 +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
64b53fb0ac
commit
0a22a66189
|
@ -27,9 +27,10 @@ class FulltextGambit implements GambitInterface
|
||||||
throw new LogicException('This gambit can only be applied on a DiscussionSearch');
|
throw new LogicException('This gambit can only be applied on a DiscussionSearch');
|
||||||
}
|
}
|
||||||
|
|
||||||
// The @ character crashes fulltext searches on InnoDB tables.
|
// Replace all non-word characters with spaces.
|
||||||
// See https://bugs.mysql.com/bug.php?id=74042
|
// We do this to prevent MySQL fulltext search boolean mode from taking
|
||||||
$bit = str_replace('@', '*', $bit);
|
// 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();
|
$query = $search->getQuery();
|
||||||
$grammar = $query->getGrammar();
|
$grammar = $query->getGrammar();
|
||||||
|
|
|
@ -98,4 +98,52 @@ class ListDiscussionsControllerTest extends ApiControllerTestCase
|
||||||
// Order-independent comparison
|
// Order-independent comparison
|
||||||
$this->assertEquals(['2', '3'], $ids, 'IDs do not match', 0.0, 10, true);
|
$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