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,57 +316,60 @@ impl Lexer /*<'a>*/ {
fn lex_multi_line_comment(&mut self) -> LexResult<()> { fn lex_multi_line_comment(&mut self) -> LexResult<()> {
let mut s = "".to_string(); let mut s = "".to_string();
let mut nest_level = 0; let mut nest_level = 0;
loop { while let Some(c) = self.peek_cur_ch() {
match self.peek_cur_ch() { if let Some(next_c) = self.peek_next_ch() {
Some(c) => { match (c, next_c) {
if let Some(next_c) = self.peek_next_ch() { ('#', '[') => nest_level += 1,
match (c, next_c) { (']', '#') => {
('#', '[') => nest_level += 1, nest_level -= 1;
(']', '#') => { if nest_level == 0 {
nest_level -= 1; return Ok(());
if nest_level == 0 {
return Ok(());
}
}
_ => {}
} }
if c == '\n' {
self.lineno_token_starts += 1;
self.col_token_starts = 0;
}
s.push(self.consume().unwrap());
}
if Self::is_bidi(self.peek_cur_ch().unwrap()) {
let comment = self.emit_token(Illegal, &s);
return Err(LexError::syntax_error(
line!() as usize,
comment.loc(),
switch_lang!(
"japanese" => "不正なユニコード文字(双方向オーバーライド)がコメント中に使用されています",
"simplified_chinese" => "注释中使用了非法的unicode字符双向覆盖",
"traditional_chinese" => "註釋中使用了非法的unicode字符雙向覆蓋",
"english" => "invalid unicode character (bi-directional override) in comments",
),
None,
));
} }
_ => {}
} }
None => { if c == '\n' {
let comment = self.emit_token(Illegal, &s); self.lineno_token_starts += 1;
return Err(LexError::syntax_error( self.col_token_starts = 0;
line!() as usize, s.clear();
comment.loc(), self.consume();
switch_lang!( continue;
"japanese" => "複数行コメントが]#で閉じられていません",
"simplified_chinese" => "未用]#号结束的多处评论",
"traditional_chinese" => "多條評論未用]#關閉",
"english" => "Multi-comment is not closed with ]#",
),
None,
));
} }
} }
if Self::is_bidi(c) {
let comment = self.emit_token(Illegal, &s);
return Err(LexError::syntax_error(
line!() as usize,
comment.loc(),
switch_lang!(
"japanese" => "不正なユニコード文字(双方向オーバーライド)がコメント中に使用されています",
"simplified_chinese" => "注释中使用了非法的unicode字符双向覆盖",
"traditional_chinese" => "註釋中使用了非法的unicode字符雙向覆蓋",
"english" => "invalid unicode character (bi-directional override) in comments",
),
None,
));
}
s.push(self.consume().unwrap());
} }
let comment = self.emit_token(Illegal, &s);
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 ]#",
),
Some(hint),
))
} }
fn lex_space_indent_dedent(&mut self) -> Option<LexResult<Token>> { 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<(), ()> { fn exec_callable() -> Result<(), ()> {
expect_failure("tests/should_err/callable.er", 4) 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)
}