Fix crashes with infinite lengths (part 2) (#2298)

This commit is contained in:
bluebear94 2023-10-05 04:26:36 -04:00 committed by GitHub
parent ea0f22a8ca
commit 6bb776029e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 49 additions and 0 deletions

View File

@ -269,6 +269,7 @@ impl Layout for EnumElem {
&cells,
regions,
styles,
self.span(),
);
Ok(layouter.layout(vt)?.fragment)

View File

@ -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() {

View File

@ -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();

View File

@ -162,6 +162,7 @@ impl Layout for ListElem {
&cells,
regions,
styles,
self.span(),
);
Ok(layouter.layout(vt)?.fragment)

View File

@ -163,6 +163,7 @@ impl Layout for TableElem {
&cells,
regions,
styles,
self.span(),
);
// Measure the columns and layout the grid row-by-row.

View File

@ -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()));

View File

@ -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.

View File

@ -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)))