mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-41281 Unbounded Recursion in InnoDB FTS Boolean-Mode causes Stack-Overflow fts_ast_visit
expr_lst: expr_lst sub_expr wrapped the expression list parsed so far in a newly created FTS_AST_LIST for every sub-expression, so a query such as '(word)' repeated N times built N nested lists. fts_ast_visit() recurses once per FTS_AST_LIST and overflowed the thread stack; the default thread_stack was exhausted at about 2300 repetitions. Append the sub-expression to the list that is already being built, and create a list only when there is none yet, the way the neighbouring expr_lst: expr_lst expr rule has always done. The sub-expressions now become siblings of a single list and the depth no longer grows. This also corrects '+term (subexpr)'. The FTS_EXIST pass used to run to completion in the inner list before the sub-expression was unioned at the outer level, so rows that matched only the sub-expression were returned. Based on mysql/mysql-server@e46e9db484
This commit is contained in:
@@ -444,7 +444,6 @@ a
|
||||
City Of God
|
||||
SELECT a FROM t1 WHERE MATCH a AGAINST ('+city (of*)' IN BOOLEAN MODE);
|
||||
a
|
||||
Offside
|
||||
City Of God
|
||||
SELECT a FROM t1 WHERE MATCH a AGAINST ('+city* of*' IN BOOLEAN MODE);
|
||||
a
|
||||
|
||||
@@ -194,3 +194,12 @@ b
|
||||
2
|
||||
DROP TABLE t1,t2;
|
||||
End of 5.1 tests
|
||||
#
|
||||
# MDEV-41281 Unbounded Recursion in InnoDB FTS Boolean-Mode
|
||||
# causes Stack-Overflow fts_ast_visit
|
||||
#
|
||||
CREATE TABLE t1 (col TEXT, FULLTEXT KEY ftidx (col)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 (col) VALUES ('word appears here for the fulltext');
|
||||
COUNT(*)
|
||||
1
|
||||
DROP TABLE t1;
|
||||
|
||||
1
mysql-test/suite/innodb_fts/t/fulltext_misc.opt
Normal file
1
mysql-test/suite/innodb_fts/t/fulltext_misc.opt
Normal file
@@ -0,0 +1 @@
|
||||
--thread-stack=299008
|
||||
@@ -211,3 +211,21 @@ DROP TABLE t1,t2;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-41281 Unbounded Recursion in InnoDB FTS Boolean-Mode
|
||||
--echo # causes Stack-Overflow fts_ast_visit
|
||||
--echo #
|
||||
CREATE TABLE t1 (col TEXT, FULLTEXT KEY ftidx (col)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 (col) VALUES ('word appears here for the fulltext');
|
||||
|
||||
--disable_query_log
|
||||
--perl
|
||||
my $payload = '(word)' x 5000;
|
||||
open(FILE, ">", "$ENV{MYSQLTEST_VARDIR}/tmp/fts_query.inc") or die;
|
||||
print FILE "SELECT COUNT(*) FROM t1 WHERE MATCH(col) AGAINST('$payload' IN BOOLEAN MODE);\n";
|
||||
close(FILE);
|
||||
EOF
|
||||
--source $MYSQLTEST_VARDIR/tmp/fts_query.inc
|
||||
--remove_file $MYSQLTEST_VARDIR/tmp/fts_query.inc
|
||||
--enable_query_log
|
||||
DROP TABLE t1;
|
||||
|
||||
@@ -1462,10 +1462,9 @@ yyreduce:
|
||||
/* Line 1806 of yacc.c */
|
||||
{
|
||||
(yyval.node) = (yyvsp[(1) - (2)].node);
|
||||
(yyval.node) = fts_ast_create_node_list(state, (yyvsp[(1) - (2)].node));
|
||||
|
||||
if (!(yyval.node)) {
|
||||
(yyval.node) = (yyvsp[(2) - (2)].node);
|
||||
if (!(yyval.node) && (yyvsp[(2) - (2)].node)) {
|
||||
(yyval.node) = fts_ast_create_node_list(state, (yyvsp[(2) - (2)].node));
|
||||
} else {
|
||||
fts_ast_add_node((yyval.node), (yyvsp[(2) - (2)].node));
|
||||
}
|
||||
|
||||
@@ -99,10 +99,9 @@ expr_lst: /* Empty */ {
|
||||
|
||||
| expr_lst sub_expr {
|
||||
$$ = $1;
|
||||
$$ = fts_ast_create_node_list(state, $1);
|
||||
|
||||
if (!$$) {
|
||||
$$ = $2;
|
||||
if (!$$ && $2) {
|
||||
$$ = fts_ast_create_node_list(state, $2);
|
||||
} else {
|
||||
fts_ast_add_node($$, $2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user