Merge pull request #300 from GreasySlug/fix/multi-line-comment

Fixed infinite loop if `#[` is more than `]#`
This commit is contained in:
Slug 2022-12-21 14:25:26 +09:00 committed by GitHub
commit fee464945b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 45 deletions

View file

@ -316,9 +316,7 @@ impl Lexer /*<'a>*/ {
fn lex_multi_line_comment(&mut self) -> LexResult<()> {
let mut s = "".to_string();
let mut nest_level = 0;
loop {
match self.peek_cur_ch() {
Some(c) => {
while let Some(c) = self.peek_cur_ch() {
if let Some(next_c) = self.peek_next_ch() {
match (c, next_c) {
('#', '[') => nest_level += 1,
@ -333,10 +331,12 @@ impl Lexer /*<'a>*/ {
if c == '\n' {
self.lineno_token_starts += 1;
self.col_token_starts = 0;
s.clear();
self.consume();
continue;
}
s.push(self.consume().unwrap());
}
if Self::is_bidi(self.peek_cur_ch().unwrap()) {
if Self::is_bidi(c) {
let comment = self.emit_token(Illegal, &s);
return Err(LexError::syntax_error(
line!() as usize,
@ -350,23 +350,26 @@ impl Lexer /*<'a>*/ {
None,
));
}
s.push(self.consume().unwrap());
}
None => {
let comment = self.emit_token(Illegal, &s);
return Err(LexError::syntax_error(
let hint = switch_lang!(
"japanese" => format!("`]#`の数があと{}個必要です", nest_level),
"simplified_chinese" => format!("需要{}个`]#`", nest_level),
"traditional_chinese" => format!("需要{}個`]#`", nest_level),
"english" => format!("{} `]#`(s) are needed", nest_level),
);
Err(LexError::syntax_error(
line!() as usize,
comment.loc(),
switch_lang!(
"japanese" => "複数行コメントが]#で閉じられていません",
"simplified_chinese" => "未用]#号结束的多处评论",
"traditional_chinese" => "多條評論未用]#關閉",
"english" => "Multi-comment is not closed with ]#",
"english" => "multi-comment is not closed with ]#",
),
None,
));
}
}
}
Some(hint),
))
}
fn lex_space_indent_dedent(&mut self) -> Option<LexResult<Token>> {

View file

@ -0,0 +1,10 @@
#[
#[
#[
#[
#[
]
]
]#
]#

View file

@ -209,3 +209,8 @@ fn exec_subtyping() -> Result<(), ()> {
fn exec_callable() -> Result<(), ()> {
expect_failure("tests/should_err/callable.er", 4)
}
#[test]
fn exec_multiline_invalid_next() -> Result<(), ()> {
expect_failure("tests/should_err/multi_line_invalid_nest.er", 1)
}