Commit f621aa90 authored by Jon Olav Hauglid's avatar Jon Olav Hauglid

Merge from mysql-5.1-security to mysql-5.5-security

Text conflict in sql/sql_yacc.yy
parents dfc75197 b8291e2b
...@@ -7745,3 +7745,26 @@ DROP PROCEDURE p1; ...@@ -7745,3 +7745,26 @@ DROP PROCEDURE p1;
DROP PROCEDURE p2; DROP PROCEDURE p2;
DROP TABLE t1; DROP TABLE t1;
# End of 5.5 test # End of 5.5 test
#
# Bug#12663165 SP DEAD CODE REMOVAL DOESN'T UNDERSTAND CONTINUE HANDLERS
#
DROP FUNCTION IF EXISTS f1;
CREATE FUNCTION f1() RETURNS INT
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN f1();
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN f1();
RETURN f1();
END;
END;
RETURN 1;
END $
SELECT f1();
f1()
1
Warnings:
Error 1424 Recursive stored functions and triggers are not allowed.
Error 1305 FUNCTION test.f1 does not exist
DROP FUNCTION f1;
...@@ -9036,3 +9036,32 @@ DROP PROCEDURE p2; ...@@ -9036,3 +9036,32 @@ DROP PROCEDURE p2;
DROP TABLE t1; DROP TABLE t1;
--echo # End of 5.5 test --echo # End of 5.5 test
--echo #
--echo # Bug#12663165 SP DEAD CODE REMOVAL DOESN'T UNDERSTAND CONTINUE HANDLERS
--echo #
--disable_warnings
DROP FUNCTION IF EXISTS f1;
--enable_warnings
delimiter $;
CREATE FUNCTION f1() RETURNS INT
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN f1();
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION RETURN f1();
RETURN f1();
END;
END;
RETURN 1;
END $
delimiter ;$
# This used to cause an assertion.
SELECT f1();
DROP FUNCTION f1;
...@@ -3559,6 +3559,23 @@ sp_instr_hpush_jump::opt_mark(sp_head *sp, List<sp_instr> *leads) ...@@ -3559,6 +3559,23 @@ sp_instr_hpush_jump::opt_mark(sp_head *sp, List<sp_instr> *leads)
m_optdest= sp->get_instr(m_dest); m_optdest= sp->get_instr(m_dest);
} }
sp->add_mark_lead(m_dest, leads); sp->add_mark_lead(m_dest, leads);
/*
For continue handlers, all instructions in the scope of the handler
are possible leads. For example, the instruction after freturn might
be executed if the freturn triggers the condition handled by the
continue handler.
m_dest marks the start of the handler scope. It's added as a lead
above, so we start on m_dest+1 here.
m_opt_hpop is the hpop marking the end of the handler scope.
*/
if (m_type == SP_HANDLER_CONTINUE)
{
for (uint scope_ip= m_dest+1; scope_ip <= m_opt_hpop; scope_ip++)
sp->add_mark_lead(scope_ip, leads);
}
return m_ip+1; return m_ip+1;
} }
......
...@@ -1023,7 +1023,7 @@ class sp_instr_hpush_jump : public sp_instr_jump ...@@ -1023,7 +1023,7 @@ class sp_instr_hpush_jump : public sp_instr_jump
public: public:
sp_instr_hpush_jump(uint ip, sp_pcontext *ctx, int htype, uint fp) sp_instr_hpush_jump(uint ip, sp_pcontext *ctx, int htype, uint fp)
: sp_instr_jump(ip, ctx), m_type(htype), m_frame(fp) : sp_instr_jump(ip, ctx), m_type(htype), m_frame(fp), m_opt_hpop(0)
{ {
m_cond.empty(); m_cond.empty();
} }
...@@ -1045,6 +1045,15 @@ public: ...@@ -1045,6 +1045,15 @@ public:
return m_ip; return m_ip;
} }
virtual void backpatch(uint dest, sp_pcontext *dst_ctx)
{
DBUG_ASSERT(!m_dest || !m_opt_hpop);
if (!m_dest)
m_dest= dest;
else
m_opt_hpop= dest;
}
inline void add_condition(struct sp_cond_type *cond) inline void add_condition(struct sp_cond_type *cond)
{ {
m_cond.push_front(cond); m_cond.push_front(cond);
...@@ -1054,6 +1063,7 @@ private: ...@@ -1054,6 +1063,7 @@ private:
int m_type; ///< Handler type int m_type; ///< Handler type
uint m_frame; uint m_frame;
uint m_opt_hpop; // hpop marking end of handler scope.
List<struct sp_cond_type> m_cond; List<struct sp_cond_type> m_cond;
}; // class sp_instr_hpush_jump : public sp_instr_jump }; // class sp_instr_hpush_jump : public sp_instr_jump
......
...@@ -2739,9 +2739,15 @@ sp_decl: ...@@ -2739,9 +2739,15 @@ sp_decl:
sp_instr_hpush_jump *i= sp_instr_hpush_jump *i=
new sp_instr_hpush_jump(sp->instructions(), ctx, $2, new sp_instr_hpush_jump(sp->instructions(), ctx, $2,
ctx->current_var_count()); ctx->current_var_count());
if (i == NULL || if (i == NULL || sp->add_instr(i))
sp->add_instr(i) || MYSQL_YYABORT;
sp->push_backpatch(i, ctx->push_label((char *)"", 0)))
/* For continue handlers, mark end of handler scope. */
if ($2 == SP_HANDLER_CONTINUE &&
sp->push_backpatch(i, ctx->last_label()))
MYSQL_YYABORT;
if (sp->push_backpatch(i, ctx->push_label(empty_c_string, 0)))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
sp_hcond_list sp_proc_stmt sp_hcond_list sp_proc_stmt
......
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