mirror of
https://github.com/MariaDB/server.git
synced 2025-08-05 13:16:09 +03:00
A fix and a test case for Bug#11299 "prepared statement makes wrong SQL
syntax in binlog which stops replication": disallow the use of parameter markers which can lead to generation of malformed binlog queries.
This commit is contained in:
@@ -660,3 +660,19 @@ lily
|
|||||||
river
|
river
|
||||||
drop table t1;
|
drop table t1;
|
||||||
deallocate prepare stmt;
|
deallocate prepare stmt;
|
||||||
|
create table t1 (a int);
|
||||||
|
prepare stmt from "select ??";
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1
|
||||||
|
prepare stmt from "select ?FROM t1";
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?FROM t1' at line 1
|
||||||
|
prepare stmt from "select FROM t1 WHERE?=1";
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM t1 WHERE?=1' at line 1
|
||||||
|
prepare stmt from "update t1 set a=a+?WHERE 1";
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?WHERE 1' at line 1
|
||||||
|
select ?;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1
|
||||||
|
select ??;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '??' at line 1
|
||||||
|
select ? from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? from t1' at line 1
|
||||||
|
drop table t1;
|
||||||
|
@@ -679,3 +679,25 @@ execute stmt using @param1;
|
|||||||
select utext from t1 where utext like '%%';
|
select utext from t1 where utext like '%%';
|
||||||
drop table t1;
|
drop table t1;
|
||||||
deallocate prepare stmt;
|
deallocate prepare stmt;
|
||||||
|
#
|
||||||
|
# Bug#11299 "prepared statement makes wrong SQL syntax in binlog which stops
|
||||||
|
# replication": check that errouneous queries with placeholders are not
|
||||||
|
# allowed
|
||||||
|
#
|
||||||
|
create table t1 (a int);
|
||||||
|
--error 1064
|
||||||
|
prepare stmt from "select ??";
|
||||||
|
--error 1064
|
||||||
|
prepare stmt from "select ?FROM t1";
|
||||||
|
--error 1064
|
||||||
|
prepare stmt from "select FROM t1 WHERE?=1";
|
||||||
|
--error 1064
|
||||||
|
prepare stmt from "update t1 set a=a+?WHERE 1";
|
||||||
|
--error 1064
|
||||||
|
select ?;
|
||||||
|
--error 1064
|
||||||
|
select ??;
|
||||||
|
--error 1064
|
||||||
|
select ? from t1;
|
||||||
|
drop table t1;
|
||||||
|
#
|
||||||
|
@@ -554,6 +554,15 @@ int yylex(void *arg, void *yythd)
|
|||||||
lex->next_state= MY_LEX_START; // Allow signed numbers
|
lex->next_state= MY_LEX_START; // Allow signed numbers
|
||||||
if (c == ',')
|
if (c == ',')
|
||||||
lex->tok_start=lex->ptr; // Let tok_start point at next item
|
lex->tok_start=lex->ptr; // Let tok_start point at next item
|
||||||
|
/*
|
||||||
|
Check for a placeholder: it should not precede a possible identifier
|
||||||
|
because of binlogging: when a placeholder is replaced with
|
||||||
|
its value in a query for the binlog, the query must stay
|
||||||
|
grammatically correct.
|
||||||
|
*/
|
||||||
|
else if (c == '?' && ((THD*) yythd)->command == COM_PREPARE &&
|
||||||
|
!ident_map[cs, yyPeek()])
|
||||||
|
return(PARAM_MARKER);
|
||||||
return((int) c);
|
return((int) c);
|
||||||
|
|
||||||
case MY_LEX_IDENT_OR_NCHAR:
|
case MY_LEX_IDENT_OR_NCHAR:
|
||||||
|
@@ -528,6 +528,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
%token NOW_SYM
|
%token NOW_SYM
|
||||||
%token OLD_PASSWORD
|
%token OLD_PASSWORD
|
||||||
%token PASSWORD
|
%token PASSWORD
|
||||||
|
%token PARAM_MARKER
|
||||||
%token POINTFROMTEXT
|
%token POINTFROMTEXT
|
||||||
%token POINT_SYM
|
%token POINT_SYM
|
||||||
%token POLYFROMTEXT
|
%token POLYFROMTEXT
|
||||||
@@ -4857,23 +4858,15 @@ text_string:
|
|||||||
;
|
;
|
||||||
|
|
||||||
param_marker:
|
param_marker:
|
||||||
'?'
|
PARAM_MARKER
|
||||||
{
|
{
|
||||||
THD *thd=YYTHD;
|
THD *thd=YYTHD;
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
if (thd->command == COM_PREPARE)
|
Item_param *item= new Item_param((uint) (lex->tok_start -
|
||||||
|
(uchar *) thd->query));
|
||||||
|
if (!($$= item) || lex->param_list.push_back(item))
|
||||||
{
|
{
|
||||||
Item_param *item= new Item_param((uint) (lex->tok_start -
|
send_error(thd, ER_OUT_OF_RESOURCES);
|
||||||
(uchar *) thd->query));
|
|
||||||
if (!($$= item) || lex->param_list.push_back(item))
|
|
||||||
{
|
|
||||||
send_error(thd, ER_OUT_OF_RESOURCES);
|
|
||||||
YYABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
yyerror(ER(ER_SYNTAX_ERROR));
|
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user