Commit d4858b96 authored by MySQL Build Team's avatar MySQL Build Team

Backport into build-201006221614-5.1.46sp1

> ------------------------------------------------------------
> revno: 3362
> revision-id: davi.arnaut@sun.com-20100401131522-895y8uzvv8ag44gs
> parent: ramil@mysql.com-20100429045409-r7r5lcyiruis15v7
> committer: Davi Arnaut <Davi.Arnaut@Sun.COM>
> branch nick: 50755-5.1
> timestamp: Thu 2010-04-01 10:15:22 -0300
> message:
>   Bug#50755: Crash if stored routine def contains version comments
>   
>   The problem was that a syntactically invalid trigger could cause
>   the server to crash when trying to list triggers. The crash would
>   happen due to a mishap in the backup/restore procedure that should
>   protect parser items which are not associated with the trigger. The
>   backup/restore is used to isolate the parse tree (and context) of
>   a statement from the load (and parsing) of a trigger. In this case,
>   a error during the parsing of a trigger could cause the improper
>   backup/restore sequence.
>   
>   The solution is to properly restore the original statement context
>   before the parser is exited due to syntax errors in the trigger body.
parent f5f9c922
...@@ -2128,4 +2128,27 @@ Warning 1048 Column 'id' cannot be null ...@@ -2128,4 +2128,27 @@ Warning 1048 Column 'id' cannot be null
Warning 1048 Column 'id' cannot be null Warning 1048 Column 'id' cannot be null
DROP TRIGGER t1_bu; DROP TRIGGER t1_bu;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# Bug#50755: Crash if stored routine def contains version comments
#
DROP DATABASE IF EXISTS db1;
DROP TRIGGER IF EXISTS trg1;
DROP TABLE IF EXISTS t1, t2;
CREATE DATABASE db1;
USE db1;
CREATE TABLE t1 (b INT);
CREATE TABLE t2 (a INT);
CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1);
# Used to crash
SHOW TRIGGERS IN db1;
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
Warnings:
Warning 1064 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 'VALUES (1)' at line 1
INSERT INTO t2 VALUES (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 'VALUES (1)' at line 1
SELECT * FROM t1;
b
# Work around Bug#45235
DROP DATABASE db1;
USE test;
End of 5.1 tests. End of 5.1 tests.
...@@ -2439,4 +2439,35 @@ UPDATE t1 SET id=NULL; ...@@ -2439,4 +2439,35 @@ UPDATE t1 SET id=NULL;
DROP TRIGGER t1_bu; DROP TRIGGER t1_bu;
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # Bug#50755: Crash if stored routine def contains version comments
--echo #
--disable_warnings
DROP DATABASE IF EXISTS db1;
DROP TRIGGER IF EXISTS trg1;
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
CREATE DATABASE db1;
USE db1;
CREATE TABLE t1 (b INT);
CREATE TABLE t2 (a INT);
CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1);
--echo # Used to crash
SHOW TRIGGERS IN db1;
--error ER_PARSE_ERROR
INSERT INTO t2 VALUES (1);
SELECT * FROM t1;
--echo # Work around Bug#45235
let $MYSQLD_DATADIR = `select @@datadir`;
--remove_file $MYSQLD_DATADIR/db1/t2.TRG
--remove_file $MYSQLD_DATADIR/db1/trg1.TRN
DROP DATABASE db1;
USE test;
--echo End of 5.1 tests. --echo End of 5.1 tests.
...@@ -745,21 +745,12 @@ sp_head::create(THD *thd) ...@@ -745,21 +745,12 @@ sp_head::create(THD *thd)
sp_head::~sp_head() sp_head::~sp_head()
{ {
LEX *lex;
sp_instr *i;
DBUG_ENTER("sp_head::~sp_head"); DBUG_ENTER("sp_head::~sp_head");
destroy();
delete m_next_cached_sp;
if (m_thd)
restore_thd_mem_root(m_thd);
DBUG_VOID_RETURN;
}
void /* sp_head::restore_thd_mem_root() must already have been called. */
sp_head::destroy() DBUG_ASSERT(m_thd == NULL);
{
sp_instr *i;
LEX *lex;
DBUG_ENTER("sp_head::destroy");
DBUG_PRINT("info", ("name: %s", m_name.str));
for (uint ip = 0 ; (i = get_instr(ip)) ; ip++) for (uint ip = 0 ; (i = get_instr(ip)) ; ip++)
delete i; delete i;
...@@ -770,21 +761,22 @@ sp_head::destroy() ...@@ -770,21 +761,22 @@ sp_head::destroy()
/* /*
If we have non-empty LEX stack then we just came out of parser with If we have non-empty LEX stack then we just came out of parser with
error. Now we should delete all auxilary LEXes and restore original error. Now we should delete all auxilary LEXes and restore original
THD::lex (In this case sp_head::restore_thd_mem_root() was not called THD::lex. It is safe to not update LEX::ptr because further query
too, so m_thd points to the current thread context). string parsing and execution will be stopped anyway.
It is safe to not update LEX::ptr because further query string parsing
and execution will be stopped anyway.
*/ */
DBUG_ASSERT(m_lex.is_empty() || m_thd);
while ((lex= (LEX *)m_lex.pop())) while ((lex= (LEX *)m_lex.pop()))
{ {
lex_end(m_thd->lex); THD *thd= lex->thd;
delete m_thd->lex; lex_end(thd->lex);
m_thd->lex= lex; delete thd->lex;
thd->lex= lex;
} }
hash_free(&m_sptabs); hash_free(&m_sptabs);
hash_free(&m_sroutines); hash_free(&m_sroutines);
delete m_next_cached_sp;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -289,10 +289,6 @@ class sp_head :private Query_arena ...@@ -289,10 +289,6 @@ class sp_head :private Query_arena
virtual ~sp_head(); virtual ~sp_head();
/// Free memory
void
destroy();
bool bool
execute_trigger(THD *thd, execute_trigger(THD *thd,
const LEX_STRING *db_name, const LEX_STRING *db_name,
......
...@@ -2106,6 +2106,7 @@ void st_lex::cleanup_lex_after_parse_error(THD *thd) ...@@ -2106,6 +2106,7 @@ void st_lex::cleanup_lex_after_parse_error(THD *thd)
*/ */
if (thd->lex->sphead) if (thd->lex->sphead)
{ {
thd->lex->sphead->restore_thd_mem_root(thd);
delete thd->lex->sphead; delete thd->lex->sphead;
thd->lex->sphead= NULL; thd->lex->sphead= NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment