From bc0f08081e6dfc8505c4dc59ead6cfac29e88146 Mon Sep 17 00:00:00 2001 From: Tobias Schmitz Date: Fri, 9 May 2025 10:18:55 +0200 Subject: [PATCH 1/6] fix: catch indefinite loop in realization due to cycle between show and grouping rule --- crates/typst-realize/src/lib.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/crates/typst-realize/src/lib.rs b/crates/typst-realize/src/lib.rs index 151ae76ba..b63aba381 100644 --- a/crates/typst-realize/src/lib.rs +++ b/crates/typst-realize/src/lib.rs @@ -655,6 +655,7 @@ fn visit_grouping_rules<'a>( let matching = s.rules.iter().find(|&rule| (rule.trigger)(content, &s.kind)); // Try to continue or finish an existing grouping. + let mut i = 0; while let Some(active) = s.groupings.last() { // Start a nested group if a rule with higher priority matches. if matching.is_some_and(|rule| rule.priority > active.rule.priority) { @@ -670,6 +671,21 @@ fn visit_grouping_rules<'a>( } finish_innermost_grouping(s)?; + i += 1; + if i > 4096 { + // It seems like this case is only hit when there is a cycle between + // a show rule and a grouping rule. The show rule produces content + // that is matched by a grouping rule, which is then again processed + // by the show rule, and so on. The two must be at an equilibrium, + // otherwise either the "maximum show rule depth" or "maximum + // grouping depth" errors are triggered. + bail!( + content.span(), + "maximum realization iterations exceeded"; + hint: "maybe there is a cycle between a show rule that produces content,\ + which is matched by a grouping rule that triggers the show rule", + ); + } } // Start a new grouping. From 25b52498239fb18d0c93b71d62a68b7305753019 Mon Sep 17 00:00:00 2001 From: Tobias Schmitz Date: Fri, 9 May 2025 10:40:31 +0200 Subject: [PATCH 2/6] fix: add space after comma in hint --- crates/typst-realize/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/typst-realize/src/lib.rs b/crates/typst-realize/src/lib.rs index b63aba381..62760527f 100644 --- a/crates/typst-realize/src/lib.rs +++ b/crates/typst-realize/src/lib.rs @@ -682,7 +682,7 @@ fn visit_grouping_rules<'a>( bail!( content.span(), "maximum realization iterations exceeded"; - hint: "maybe there is a cycle between a show rule that produces content,\ + hint: "maybe there is a cycle between a show rule that produces content, \ which is matched by a grouping rule that triggers the show rule", ); } From ef9adf461863b5ef04bd13d27ad1a01e878cfed3 Mon Sep 17 00:00:00 2001 From: Tobias Schmitz Date: Fri, 9 May 2025 10:54:52 +0200 Subject: [PATCH 3/6] fix: reduce iteration limit to prevent stack overflow in test --- crates/typst-realize/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/typst-realize/src/lib.rs b/crates/typst-realize/src/lib.rs index 62760527f..f69bd3ee9 100644 --- a/crates/typst-realize/src/lib.rs +++ b/crates/typst-realize/src/lib.rs @@ -672,7 +672,7 @@ fn visit_grouping_rules<'a>( finish_innermost_grouping(s)?; i += 1; - if i > 4096 { + if i > 512 { // It seems like this case is only hit when there is a cycle between // a show rule and a grouping rule. The show rule produces content // that is matched by a grouping rule, which is then again processed From ae97359fb34288cba8f17f95481210a37cad6227 Mon Sep 17 00:00:00 2001 From: Tobias Schmitz Date: Fri, 9 May 2025 10:55:04 +0200 Subject: [PATCH 4/6] test: add test --- tests/suite/styling/show.typ | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/suite/styling/show.typ b/tests/suite/styling/show.typ index e8ddf5534..211537a67 100644 --- a/tests/suite/styling/show.typ +++ b/tests/suite/styling/show.typ @@ -258,3 +258,12 @@ I am *strong*, I am _emphasized_, and I am #[special]. = Hello *strong* + +--- issue-5690-oom-par-box --- +// Error: 3:6-5:1 maximum realization iterations exceeded +// Hint: 3:6-5:1 maybe there is a cycle between a show rule that produces content, which is matched by a grouping rule that triggers the show rule +#show par: box + +Hello + +World From 067f62c7786799295341018fa7a1aca4d33441ae Mon Sep 17 00:00:00 2001 From: Tobias Schmitz Date: Fri, 9 May 2025 17:05:37 +0200 Subject: [PATCH 5/6] feat: change error message --- crates/typst-realize/src/lib.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/crates/typst-realize/src/lib.rs b/crates/typst-realize/src/lib.rs index f69bd3ee9..7d2460a89 100644 --- a/crates/typst-realize/src/lib.rs +++ b/crates/typst-realize/src/lib.rs @@ -679,12 +679,7 @@ fn visit_grouping_rules<'a>( // by the show rule, and so on. The two must be at an equilibrium, // otherwise either the "maximum show rule depth" or "maximum // grouping depth" errors are triggered. - bail!( - content.span(), - "maximum realization iterations exceeded"; - hint: "maybe there is a cycle between a show rule that produces content, \ - which is matched by a grouping rule that triggers the show rule", - ); + bail!(content.span(), "maximum grouping depth exceeded"); } } From 254a849fec3d1f9ae95b628dad6481cfa6619df6 Mon Sep 17 00:00:00 2001 From: Tobias Schmitz Date: Sat, 10 May 2025 14:24:57 +0200 Subject: [PATCH 6/6] test: update test --- tests/suite/styling/show.typ | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/suite/styling/show.typ b/tests/suite/styling/show.typ index 211537a67..f3d9efd55 100644 --- a/tests/suite/styling/show.typ +++ b/tests/suite/styling/show.typ @@ -260,8 +260,7 @@ I am *strong*, I am _emphasized_, and I am #[special]. *strong* --- issue-5690-oom-par-box --- -// Error: 3:6-5:1 maximum realization iterations exceeded -// Hint: 3:6-5:1 maybe there is a cycle between a show rule that produces content, which is matched by a grouping rule that triggers the show rule +// Error: 3:6-5:1 maximum grouping depth exceeded #show par: box Hello