summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Olav Hauglid <jon.hauglid@oracle.com>2012-01-09 11:33:26 +0100
committerJon Olav Hauglid <jon.hauglid@oracle.com>2012-01-09 11:33:26 +0100
commit63a0c3078b708bb7f985e33d22e5127244466aff (patch)
treea7aa2696cedf959b55bf3d17f88c037baee0e837
parent86701392fcc4950056e9b28a8ce140c660a5df5f (diff)
parent6c1bbb50cb9ee124e762f66004a3daad297e6d6f (diff)
downloadmariadb-git-63a0c3078b708bb7f985e33d22e5127244466aff.tar.gz
Merge from mysql-5.1-security to mysql-5.5-security
Text conflict in sql/sql_yacc.yy
-rw-r--r--mysql-test/r/sp.result23
-rw-r--r--mysql-test/t/sp.test29
-rw-r--r--sql/sp_head.cc17
-rw-r--r--sql/sp_head.h12
-rw-r--r--sql/sql_yacc.yy12
5 files changed, 89 insertions, 4 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 1644c764431..0f5ab0af1c3 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -7745,3 +7745,26 @@ DROP PROCEDURE p1;
DROP PROCEDURE p2;
DROP TABLE t1;
# 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;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 3f6c50a9095..37a724ee52e 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -9036,3 +9036,32 @@ DROP PROCEDURE p2;
DROP TABLE t1;
--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;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index eb29590b700..2763be7a4aa 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -3559,6 +3559,23 @@ sp_instr_hpush_jump::opt_mark(sp_head *sp, List<sp_instr> *leads)
m_optdest= sp->get_instr(m_dest);
}
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;
}
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 0f6fddc75f0..06db7b45a05 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -1023,7 +1023,7 @@ class sp_instr_hpush_jump : public sp_instr_jump
public:
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();
}
@@ -1045,6 +1045,15 @@ public:
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)
{
m_cond.push_front(cond);
@@ -1054,6 +1063,7 @@ private:
int m_type; ///< Handler type
uint m_frame;
+ uint m_opt_hpop; // hpop marking end of handler scope.
List<struct sp_cond_type> m_cond;
}; // class sp_instr_hpush_jump : public sp_instr_jump
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 8f3e6373666..bf7ca6b02ed 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -2739,9 +2739,15 @@ sp_decl:
sp_instr_hpush_jump *i=
new sp_instr_hpush_jump(sp->instructions(), ctx, $2,
ctx->current_var_count());
- if (i == NULL ||
- sp->add_instr(i) ||
- sp->push_backpatch(i, ctx->push_label((char *)"", 0)))
+ if (i == NULL || sp->add_instr(i))
+ MYSQL_YYABORT;
+
+ /* 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;
}
sp_hcond_list sp_proc_stmt