diff options
author | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2010-04-01 10:15:22 -0300 |
---|---|---|
committer | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2010-04-01 10:15:22 -0300 |
commit | 7ecad98c45ece1140e9f2cb7627741cde31fa2f7 (patch) | |
tree | 837d819846c7947b1b5d47a21d2e07591e273299 /sql/sp_head.cc | |
parent | 2303a8c6e4dd94eb6b682c61e0ff333c21b188b2 (diff) | |
download | mariadb-git-7ecad98c45ece1140e9f2cb7627741cde31fa2f7.tar.gz |
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.
mysql-test/r/trigger.result:
Add test case result for Bug#50755
mysql-test/t/trigger.test:
Add test case for Bug#50755
sql/sp_head.cc:
Merge sp_head::destroy() and sp_head destructor. Retrieve THD
from the LEX so that m_thd is not necessary.
sql/sql_lex.cc:
Explicitly restore the original environment.
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 34 |
1 files changed, 13 insertions, 21 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 11d5e5f830b..cadda38053c 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -745,21 +745,12 @@ sp_head::create(THD *thd) sp_head::~sp_head() { + LEX *lex; + sp_instr *i; 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::destroy() -{ - sp_instr *i; - LEX *lex; - DBUG_ENTER("sp_head::destroy"); - DBUG_PRINT("info", ("name: %s", m_name.str)); + /* sp_head::restore_thd_mem_root() must already have been called. */ + DBUG_ASSERT(m_thd == NULL); for (uint ip = 0 ; (i = get_instr(ip)) ; ip++) delete i; @@ -770,21 +761,22 @@ sp_head::destroy() /* 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 - THD::lex (In this case sp_head::restore_thd_mem_root() was not called - too, so m_thd points to the current thread context). - It is safe to not update LEX::ptr because further query string parsing - and execution will be stopped anyway. + THD::lex. 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())) { - lex_end(m_thd->lex); - delete m_thd->lex; - m_thd->lex= lex; + THD *thd= lex->thd; + lex_end(thd->lex); + delete thd->lex; + thd->lex= lex; } hash_free(&m_sptabs); hash_free(&m_sroutines); + + delete m_next_cached_sp; + DBUG_VOID_RETURN; } |