From 07e976294089cbc0c8cf46d984565e6136ffa9e8 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 22 Jan 2016 19:29:26 +0100 Subject: [PATCH] MDEV-8615: Assertion `m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length' failed in Lex_input_stream::body_utf8_start Nothing should be done before any keyword recognized. --- mysql-test/r/compound.result | 7 ++ mysql-test/t/compound.test | 7 ++ sql/sql_yacc.yy | 176 +++++++++++++++++++++++------------ 3 files changed, 133 insertions(+), 57 deletions(-) diff --git a/mysql-test/r/compound.result b/mysql-test/r/compound.result index 92d3226ec00..1d412e671a4 100644 --- a/mysql-test/r/compound.result +++ b/mysql-test/r/compound.result @@ -162,3 +162,10 @@ a begin not atomic select a from t1 having a > 1; end| a drop table t1| +# +# MDEV-8615: Assertion `m_cpp_buf <= begin_ptr && +# begin_ptr <= m_cpp_buf + m_buf_length' failed in +# Lex_input_stream::body_utf8_start +# +b'| +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'b'' at line 1 diff --git a/mysql-test/t/compound.test b/mysql-test/t/compound.test index 1c5d12a1665..cabdf96e00e 100644 --- a/mysql-test/t/compound.test +++ b/mysql-test/t/compound.test @@ -150,3 +150,10 @@ select a from t1 having a > 1| begin not atomic select a from t1 having a > 1; end| drop table t1| +--echo # +--echo # MDEV-8615: Assertion `m_cpp_buf <= begin_ptr && +--echo # begin_ptr <= m_cpp_buf + m_buf_length' failed in +--echo # Lex_input_stream::body_utf8_start +--echo # +--error ER_PARSE_ERROR +--query b' diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 876cd2bf55a..18a981c58c6 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -248,6 +248,35 @@ static bool maybe_start_compound_statement(THD *thd) return 0; } +static bool push_sp_label(THD *thd, LEX_STRING label) +{ + sp_pcontext *ctx= thd->lex->spcont; + sp_label *lab= ctx->find_label(label); + + if (lab) + { + my_error(ER_SP_LABEL_REDEFINE, MYF(0), label.str); + return 1; + } + else + { + lab= thd->lex->spcont->push_label(thd, label, + thd->lex->sphead->instructions()); + lab->type= sp_label::ITERATION; + } + return 0; +} + +static bool push_sp_empty_label(THD *thd) +{ + if (maybe_start_compound_statement(thd)) + return 1; + /* Unlabeled controls get an empty label. */ + thd->lex->spcont->push_label(thd, empty_lex_str, + thd->lex->sphead->instructions()); + return 0; +} + /** Helper action for a case expression statement (the expr in 'CASE expr'). This helper is used for 'searched' cases only. @@ -997,7 +1026,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); Currently there are 160 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 160 +%expect 162 /* Comments for TOKENS. @@ -1934,6 +1963,7 @@ END_OF_INPUT %type sp_proc_stmt_iterate %type sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close %type case_stmt_specification +%type loop_body while_body repeat_body %type sp_decl_idents sp_handler_type sp_hcond_list %type sp_cond sp_hcond sqlstate signal_value opt_signal_value @@ -3768,20 +3798,6 @@ sp_proc_stmt_return: } ; -sp_unlabeled_control: - { - if (maybe_start_compound_statement(thd)) - MYSQL_YYABORT; - /* Unlabeled controls get an empty label. */ - Lex->spcont->push_label(thd, empty_lex_str, - Lex->sphead->instructions()); - } - sp_control_content - { - Lex->sphead->backpatch(Lex->spcont->pop_label()); - } - ; - sp_proc_stmt_leave: LEAVE_SYM label_ident { @@ -4200,41 +4216,6 @@ else_clause_opt: | ELSE sp_proc_stmts1 ; -sp_labeled_control: - label_ident ':' - { - LEX *lex= Lex; - sp_pcontext *ctx= lex->spcont; - sp_label *lab= ctx->find_label($1); - - if (lab) - { - my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str); - MYSQL_YYABORT; - } - else - { - lab= lex->spcont->push_label(thd, $1, lex->sphead->instructions()); - lab->type= sp_label::ITERATION; - } - } - sp_control_content sp_opt_label - { - LEX *lex= Lex; - sp_label *lab= lex->spcont->pop_label(); - - if ($5.str) - { - if (my_strcasecmp(system_charset_info, $5.str, lab->name.str) != 0) - { - my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str); - MYSQL_YYABORT; - } - } - lex->sphead->backpatch(lab); - } - ; - sp_opt_label: /* Empty */ { $$= null_lex_str; } | label_ident { $$= $1; } @@ -4327,8 +4308,7 @@ sp_block_content: } ; -sp_control_content: - LOOP_SYM +loop_body: sp_proc_stmts1 END LOOP_SYM { LEX *lex= Lex; @@ -4340,15 +4320,16 @@ sp_control_content: lex->sphead->add_instr(i)) MYSQL_YYABORT; } - | WHILE_SYM - { Lex->sphead->reset_lex(thd); } + ; + +while_body: expr DO_SYM { LEX *lex= Lex; sp_head *sp= lex->sphead; uint ip= sp->instructions(); sp_instr_jump_if_not *i= new (lex->thd->mem_root) - sp_instr_jump_if_not(ip, lex->spcont, $3, lex); + sp_instr_jump_if_not(ip, lex->spcont, $1, lex); if (i == NULL || /* Jumping forward */ sp->push_backpatch(i, lex->spcont->last_label()) || @@ -4370,7 +4351,10 @@ sp_control_content: MYSQL_YYABORT; lex->sphead->do_cont_backpatch(); } - | REPEAT_SYM sp_proc_stmts1 UNTIL_SYM + ; + +repeat_body: + sp_proc_stmts1 UNTIL_SYM { Lex->sphead->reset_lex(thd); } expr END REPEAT_SYM { @@ -4378,7 +4362,7 @@ sp_control_content: uint ip= lex->sphead->instructions(); sp_label *lab= lex->spcont->last_label(); /* Jumping back */ sp_instr_jump_if_not *i= new (lex->thd->mem_root) - sp_instr_jump_if_not(ip, lex->spcont, $5, lab->ip, lex); + sp_instr_jump_if_not(ip, lex->spcont, $4, lab->ip, lex); if (i == NULL || lex->sphead->add_instr(i)) MYSQL_YYABORT; @@ -4389,6 +4373,84 @@ sp_control_content: } ; +pop_sp_label: + sp_opt_label + { + sp_label *lab; + Lex->sphead->backpatch(lab= Lex->spcont->pop_label()); + if ($1.str) + { + if (my_strcasecmp(system_charset_info, $1.str, + lab->name.str) != 0) + { + my_error(ER_SP_LABEL_MISMATCH, MYF(0), $1.str); + MYSQL_YYABORT; + } + } + } + ; + +pop_sp_empty_label: + { + sp_label *lab; + Lex->sphead->backpatch(lab= Lex->spcont->pop_label()); + DBUG_ASSERT(lab->name.length == 0); + } + ; + +sp_labeled_control: + label_ident ':' LOOP_SYM + { + if (push_sp_label(thd, $1)) + MYSQL_YYABORT; + } + loop_body pop_sp_label + { } + | label_ident ':' WHILE_SYM + { + if (push_sp_label(thd, $1)) + MYSQL_YYABORT; + Lex->sphead->reset_lex(thd); + } + while_body pop_sp_label + { } + | label_ident ':' REPEAT_SYM + { + if (push_sp_label(thd, $1)) + MYSQL_YYABORT; + } + repeat_body pop_sp_label + { } + ; + +sp_unlabeled_control: + LOOP_SYM + { + if (push_sp_empty_label(thd)) + MYSQL_YYABORT; + } + loop_body + pop_sp_empty_label + { } + | WHILE_SYM + { + if (push_sp_empty_label(thd)) + MYSQL_YYABORT; + Lex->sphead->reset_lex(thd); + } + while_body + pop_sp_empty_label + { } + | REPEAT_SYM + { + if (push_sp_empty_label(thd)) + MYSQL_YYABORT; + } + repeat_body + pop_sp_empty_label + { } + ; + trg_action_time: BEFORE_SYM { Lex->trg_chistics.action_time= TRG_ACTION_BEFORE; }