diff --git a/compiler.c b/compiler.c index ee70961c..46e07622 100644 --- a/compiler.c +++ b/compiler.c @@ -237,7 +237,15 @@ uc_compiler_set_srcpos(uc_compiler_t *compiler, size_t srcpos) size_t delta; /* ensure that lines counts are strictly increasing */ - assert(srcpos == 0 || srcpos >= compiler->current_srcpos); + assert(srcpos == 0 || srcpos >= compiler->current_srcpos || + compiler->parser->error); + + /* after a syntax error, code may be emitted for tokens in front of the + * current position, e.g. after the expression of a template literal + * placeholder has been terminated prematurely. The generated code is + * discarded, but a negative offset would be taken for an enormous one */ + if (srcpos < compiler->current_srcpos) + srcpos = 0; delta = srcpos ? srcpos - compiler->current_srcpos : 0; compiler->current_srcpos += delta; diff --git a/tests/custom/99_bugs/60_template_placeholder_syntax_error_hang b/tests/custom/99_bugs/60_template_placeholder_syntax_error_hang new file mode 100644 index 00000000..842402ed --- /dev/null +++ b/tests/custom/99_bugs/60_template_placeholder_syntax_error_hang @@ -0,0 +1,49 @@ +A syntax error within the expression of a template literal placeholder +made the compiler spin until it ran out of memory. The statement +terminating the placeholder expression had advanced the source position +beyond the last token of the expression, and instructions emitted for +that token afterwards moved the position backwards. The negative offset +was taken for an enormous one when recording the source position of the +instruction, which then took practically forever and a lot of memory. + +1. Excess token in a placeholder. + +-- Testcase -- +x = `a${ 1 2 }`; +-- End -- + +-- Args -- +-R +-- End -- + +-- Expect stderr -- +Syntax error: Unexpected token +Expecting '}' +In line 1, byte 12: + + `x = `a${ 1 2 }`;` + ~~~~~~~~~~~^ + + +-- End -- + + +2. Unterminated placeholder at the end of the source. + +-- Testcase -- +x = `tpl${ +-- End -- + +-- Args -- +-R +-- End -- + +-- Expect stderr -- +Syntax error: Expecting expression +In line 2, byte 1: + + `x = `tpl${` + ^-- Near here + + +-- End --