Skip to content

Commit

Permalink
fix(parser): Resolve stackoverflow on lots of blank lines
Browse files Browse the repository at this point in the history
  • Loading branch information
epage committed Jul 31, 2024
1 parent a73c512 commit 57f7bb8
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 10 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/toml_edit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ unbounded = []

[dependencies]
indexmap = { version = "2.0.0", features = ["std"] }
winnow = { version = "0.6.16", optional = true }
winnow = { version = "0.6.17", optional = true }
serde = { version = "1.0.145", optional = true }
kstring = { version = "2.0.0", features = ["max_inline"], optional = true }
toml_datetime = { version = "0.6.8", path = "../toml_datetime" }
Expand Down
26 changes: 19 additions & 7 deletions crates/toml_edit/src/parser/trivia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use winnow::combinator::peek;
use winnow::combinator::repeat;
use winnow::combinator::terminated;
use winnow::prelude::*;
use winnow::stream::Stream as _;
use winnow::token::any;
use winnow::token::one_of;
use winnow::token::take_while;
Expand Down Expand Up @@ -91,15 +92,26 @@ pub(crate) fn ws_newlines(input: &mut Input<'_>) -> PResult<()> {
// note: this rule is not present in the original grammar
// ws-comment-newline = *( ws-newline-nonempty / comment )
pub(crate) fn ws_comment_newline(input: &mut Input<'_>) -> PResult<()> {
let _ = ws.parse_next(input)?;
let mut start = input.checkpoint();
loop {
let _ = ws.parse_next(input)?;

dispatch! {opt(peek(any));
Some(b'#') => (comment, newline).void(),
Some(b'\n') => (newline).void(),
Some(b'\r') => (newline).void(),
_ => empty,
}
.parse_next(input)?;

dispatch! {opt(peek(any));
Some(b'#') => (comment, newline, ws_comment_newline).void(),
Some(b'\n') => (newline, ws_comment_newline).void(),
Some(b'\r') => (newline, ws_comment_newline).void(),
_ => empty,
let end = input.checkpoint();
if start == end {
break;
}
start = end;
}
.parse_next(input)

Ok(())
}

// note: this rule is not present in the original grammar
Expand Down

0 comments on commit 57f7bb8

Please sign in to comment.