diff options
author | Jon Olav Hauglid <jon.hauglid@oracle.com> | 2012-01-09 11:33:26 +0100 |
---|---|---|
committer | Jon Olav Hauglid <jon.hauglid@oracle.com> | 2012-01-09 11:33:26 +0100 |
commit | f621aa902074d6d28f42ffc4e7ce2e0c594c0ab6 (patch) | |
tree | a7aa2696cedf959b55bf3d17f88c037baee0e837 /sql | |
parent | dfc75197f933c9eebef8ecaf17e23a22a0259612 (diff) | |
parent | b8291e2b60b311b621b15aff1dfec817da1bbf4c (diff) | |
download | mariadb-git-f621aa902074d6d28f42ffc4e7ce2e0c594c0ab6.tar.gz |
Merge from mysql-5.1-security to mysql-5.5-security
Text conflict in sql/sql_yacc.yy
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sp_head.cc | 17 | ||||
-rw-r--r-- | sql/sp_head.h | 12 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 12 |
3 files changed, 37 insertions, 4 deletions
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 |