summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbluebear94 <uruwi@protonmail.com>2023-10-05 04:26:36 -0400
committerGitHub <noreply@github.com>2023-10-05 10:26:36 +0200
commit6bb776029e5d3261bd79605f91eb1e7fd14d06ea (patch)
tree17c6f352d848731309580c3dbe0c9f08304d7b38
parentea0f22a8ca2eec4bde44fc4afc6032c2728aed27 (diff)
Fix crashes with infinite lengths (part 2) (#2298)
-rw-r--r--crates/typst-library/src/layout/enum.rs1
-rw-r--r--crates/typst-library/src/layout/flow.rs6
-rw-r--r--crates/typst-library/src/layout/grid.rs9
-rw-r--r--crates/typst-library/src/layout/list.rs1
-rw-r--r--crates/typst-library/src/layout/table.rs1
-rw-r--r--crates/typst-library/src/visualize/line.rs3
-rw-r--r--crates/typst-library/src/visualize/polygon.rs3
-rw-r--r--tests/typ/bugs/layout-infinite-lengths.typ25
8 files changed, 49 insertions, 0 deletions
diff --git a/crates/typst-library/src/layout/enum.rs b/crates/typst-library/src/layout/enum.rs
index c505f189..436aacb9 100644
--- a/crates/typst-library/src/layout/enum.rs
+++ b/crates/typst-library/src/layout/enum.rs
@@ -269,6 +269,7 @@ impl Layout for EnumElem {
&cells,
regions,
styles,
+ self.span(),
);
Ok(layouter.layout(vt)?.fragment)
diff --git a/crates/typst-library/src/layout/flow.rs b/crates/typst-library/src/layout/flow.rs
index 432ab5e8..1feee4b8 100644
--- a/crates/typst-library/src/layout/flow.rs
+++ b/crates/typst-library/src/layout/flow.rs
@@ -29,6 +29,12 @@ impl Layout for FlowElem {
styles: StyleChain,
regions: Regions,
) -> SourceResult<Fragment> {
+ if !regions.size.x.is_finite() && regions.expand.x {
+ bail!(error!(self.span(), "cannot expand into infinite width"));
+ }
+ if !regions.size.y.is_finite() && regions.expand.y {
+ bail!(error!(self.span(), "cannot expand into infinite height"));
+ }
let mut layouter = FlowLayouter::new(regions, styles);
for mut child in &self.children() {
diff --git a/crates/typst-library/src/layout/grid.rs b/crates/typst-library/src/layout/grid.rs
index 134bdc7c..8d015782 100644
--- a/crates/typst-library/src/layout/grid.rs
+++ b/crates/typst-library/src/layout/grid.rs
@@ -114,6 +114,7 @@ impl Layout for GridElem {
&cells,
regions,
styles,
+ self.span(),
);
// Measure the columns and layout the grid row-by-row.
@@ -161,6 +162,8 @@ pub struct GridLayouter<'a> {
initial: Size,
/// Frames for finished regions.
finished: Vec<Frame>,
+ /// The span of the grid element.
+ span: Span,
}
/// The resulting sizes of columns and rows in a grid.
@@ -202,6 +205,7 @@ impl<'a> GridLayouter<'a> {
cells: &'a [Content],
regions: Regions<'a>,
styles: StyleChain<'a>,
+ span: Span,
) -> Self {
let mut cols = vec![];
let mut rows = vec![];
@@ -272,6 +276,7 @@ impl<'a> GridLayouter<'a> {
lrows: vec![],
initial: regions.size,
finished: vec![],
+ span,
}
}
@@ -563,6 +568,10 @@ impl<'a> GridLayouter<'a> {
height: Abs,
y: usize,
) -> SourceResult<Frame> {
+ if !height.is_finite() {
+ bail!(error!(self.span, "cannot create grid with infinite height"));
+ }
+
let mut output = Frame::soft(Size::new(self.width, height));
let mut pos = Point::zero();
diff --git a/crates/typst-library/src/layout/list.rs b/crates/typst-library/src/layout/list.rs
index a9dad85b..34e0e6fb 100644
--- a/crates/typst-library/src/layout/list.rs
+++ b/crates/typst-library/src/layout/list.rs
@@ -162,6 +162,7 @@ impl Layout for ListElem {
&cells,
regions,
styles,
+ self.span(),
);
Ok(layouter.layout(vt)?.fragment)
diff --git a/crates/typst-library/src/layout/table.rs b/crates/typst-library/src/layout/table.rs
index 339b8b25..1b84a616 100644
--- a/crates/typst-library/src/layout/table.rs
+++ b/crates/typst-library/src/layout/table.rs
@@ -163,6 +163,7 @@ impl Layout for TableElem {
&cells,
regions,
styles,
+ self.span(),
);
// Measure the columns and layout the grid row-by-row.
diff --git a/crates/typst-library/src/visualize/line.rs b/crates/typst-library/src/visualize/line.rs
index 6837caf1..da497cf4 100644
--- a/crates/typst-library/src/visualize/line.rs
+++ b/crates/typst-library/src/visualize/line.rs
@@ -75,6 +75,9 @@ impl Layout for LineElem {
let size = start.max(start + delta).max(Size::zero());
let target = regions.expand.select(regions.size, size);
+ if !target.is_finite() {
+ bail!(error!(self.span(), "cannot create line with infinite length"));
+ }
let mut frame = Frame::soft(target);
let shape = Geometry::Line(delta.to_point()).stroked(stroke);
frame.push(start.to_point(), FrameItem::Shape(shape, self.span()));
diff --git a/crates/typst-library/src/visualize/polygon.rs b/crates/typst-library/src/visualize/polygon.rs
index 1d19a94d..b1ed9eaa 100644
--- a/crates/typst-library/src/visualize/polygon.rs
+++ b/crates/typst-library/src/visualize/polygon.rs
@@ -130,6 +130,9 @@ impl Layout for PolygonElem {
.collect();
let size = points.iter().fold(Point::zero(), |max, c| c.max(max)).to_size();
+ if !size.is_finite() {
+ bail!(error!(self.span(), "cannot create polygon with infinite size"));
+ }
let mut frame = Frame::hard(size);
// Only create a path if there are more than zero points.
diff --git a/tests/typ/bugs/layout-infinite-lengths.typ b/tests/typ/bugs/layout-infinite-lengths.typ
new file mode 100644
index 00000000..501e517e
--- /dev/null
+++ b/tests/typ/bugs/layout-infinite-lengths.typ
@@ -0,0 +1,25 @@
+// Test that passing infinite lengths to drawing primitives does not crash Typst.
+
+---
+#set page(width: auto, height: auto)
+
+// Error: cannot expand into infinite width
+#layout(size => grid(columns: (size.width, size.height))[a][b][c][d])
+
+---
+#set page(width: auto, height: auto)
+
+// Error: 17-66 cannot create grid with infinite height
+#layout(size => grid(rows: (size.width, size.height))[a][b][c][d])
+
+---
+#set page(width: auto, height: auto)
+
+// Error: 17-41 cannot create line with infinite length
+#layout(size => line(length: size.width))
+
+---
+#set page(width: auto, height: auto)
+
+// Error: 17-54 cannot create polygon with infinite size
+#layout(size => polygon((0pt,0pt), (0pt, size.width)))