maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #09136
Re: [Commits] daad482: MDEV-8615: Assertion `m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length' failed in Lex_input_stream::body_utf8_start
Hi, Oleksandr!
On Dec 22, Oleksandr Byelkin wrote:
> >> diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
> >> index a5a62ae..6611411 100644
> >> --- a/sql/sql_yacc.yy
> >> +++ b/sql/sql_yacc.yy
> >> @@ -237,6 +237,11 @@ static sp_head *make_sp_head(THD *thd, sp_name *name,
> >>
> >> static bool maybe_start_compound_statement(THD *thd)
> >> {
> >> + if (YYLIP->eof())
> >> + {
> >> + my_parse_error(thd, ER_SYNTAX_ERROR);
> >> + return 1;
> >> + }
> > no, I don't like that. Syntax errors should be issued by the parser,
> > they should follow from the grammar, not be hard-coded in some explicit
> > checks in the code.
> >
> > The problem in the current grammar - as I see it, that a code block is
> > executed before any keyword is matched. This code block assumes it's the
> > sp_unlabeled_control rule, while it could be anything.
> >
> > The fix would be to remove this code block and put this code after the
> > first keyword is matched.
> >
> >
>
> Here is the problem. It is unlabeled context so empty label should be
> pushed but it can not be done without that
> maybe_start_compound_statement() if move it all inside
> sp_control_content, then how to detect labeled or unlabeled...
>
> So I have no any idea how it can be fixed.
Like the attached untested patch.
I simply duplicated sp_control_content rule and merged
sp_unlabeled_control into it. See how maybe_start_compound_statement()
is executed only *after* the first keyword is matched.
Of course, it's only to show the idea - the fix cannot be pushed that
way. If I were fixing it, this patch would've been the first step, and
the second step would be to merge this back into sp_control_content
removing as much of the code duplication as possible.
Regards,
Sergei
Chief Architect MariaDB
and security@xxxxxxxxxxx
--
Vote for my Percona Live 2016 talks:
https://www.percona.com/live/data-performance-conference-2016/sessions/mariadb-connectors-fast-and-smart-new-protocol-optimizations#community-voting
https://www.percona.com/live/data-performance-conference-2016/sessions/mariadb-101-security-validation-authentication-encryption#community-voting
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index a5a62ae..d54b611 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -3768,20 +3768,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
{
@@ -4327,6 +4313,93 @@ sp_block_content:
}
;
+sp_unlabeled_control:
+ LOOP_SYM
+ {
+ 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_proc_stmts1 END LOOP_SYM
+ {
+ LEX *lex= Lex;
+ uint ip= lex->sphead->instructions();
+ sp_label *lab= lex->spcont->last_label(); /* Jumping back */
+ sp_instr_jump *i= new (lex->thd->mem_root)
+ sp_instr_jump(ip, lex->spcont, lab->ip);
+ if (i == NULL ||
+ lex->sphead->add_instr(i))
+ MYSQL_YYABORT;
+ Lex->sphead->backpatch(Lex->spcont->pop_label());
+ }
+ | WHILE_SYM
+ {
+ 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());
+
+ Lex->sphead->reset_lex(thd); }
+ 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);
+ if (i == NULL ||
+ /* Jumping forward */
+ sp->push_backpatch(i, lex->spcont->last_label()) ||
+ sp->new_cont_backpatch(i) ||
+ sp->add_instr(i))
+ MYSQL_YYABORT;
+ if (sp->restore_lex(thd))
+ MYSQL_YYABORT;
+ }
+ sp_proc_stmts1 END WHILE_SYM
+ {
+ LEX *lex= Lex;
+ uint ip= lex->sphead->instructions();
+ sp_label *lab= lex->spcont->last_label(); /* Jumping back */
+ sp_instr_jump *i= new (lex->thd->mem_root)
+ sp_instr_jump(ip, lex->spcont, lab->ip);
+ if (i == NULL ||
+ lex->sphead->add_instr(i))
+ MYSQL_YYABORT;
+ lex->sphead->do_cont_backpatch();
+ Lex->sphead->backpatch(Lex->spcont->pop_label());
+ }
+ | REPEAT_SYM
+ {
+ 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_proc_stmts1 UNTIL_SYM
+ { Lex->sphead->reset_lex(thd); }
+ expr END REPEAT_SYM
+ {
+ LEX *lex= Lex;
+ 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, $6, lab->ip, lex);
+ if (i == NULL ||
+ lex->sphead->add_instr(i))
+ MYSQL_YYABORT;
+ if (lex->sphead->restore_lex(thd))
+ MYSQL_YYABORT;
+ /* We can shortcut the cont_backpatch here */
+ i->m_cont_dest= ip+1;
+ Lex->sphead->backpatch(Lex->spcont->pop_label());
+ }
+ ;
+
sp_control_content:
LOOP_SYM
sp_proc_stmts1 END LOOP_SYM
References