mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 17:56:50 -06:00
Gradient meshes: deleting mesh lines leaves a malformed mesh as it is
GradientMesh::remove_point_lines (the Mesh tool's Alt-click, object.mesh.deletePoint) only checked that the clicked point exists, then indexed the points above and below or left and right of it by the mesh's rows and columns. A gradient mesh read from a document is not checked against its rows and columns, so one with fewer points than they need (rows 2, columns 1 and 3 points instead of 6) indexes past the end and panics: the engine guard rolls the command back with an internal error, and the web app, which has no guard, aborts. It now returns false for a mesh that isn't valid, as locate (and with it adding mesh lines), the outline and the mesh lines already do, and the command reports that nothing could be deleted. The test Alt-clicks an interior row's point and an interior column's point of two such meshes and checks nothing is deleted and the mesh is unchanged. Reported-by: BS.ehlas.cz
This commit is contained in:
committed by
Matej Vrzala
parent
9e7929ee89
commit
da8e6af7e8
+16
-1
@@ -1026,7 +1026,8 @@ impl GradientMesh {
|
||||
|
||||
/// Mesh tool Alt-click: delete the mesh lines through point `index` (interior lines only).
|
||||
pub fn remove_point_lines(&mut self, index: usize) -> bool {
|
||||
if index >= self.points.len() {
|
||||
// A mesh from a file may not have the points its rows and columns need: it is indexed below.
|
||||
if !self.is_valid() || index >= self.points.len() {
|
||||
return false;
|
||||
}
|
||||
let w = self.cols as usize + 1;
|
||||
@@ -1854,4 +1855,18 @@ mod tests {
|
||||
m.points[1].color = Color::rgb(1.0, 0.0, 0.0);
|
||||
assert!(matches!(m.color_at(0, 0, 0.5, 0.5).0, Color::Rgb { .. }));
|
||||
}
|
||||
|
||||
/// Alt-clicking a point of a mesh from a file with fewer points than its rows and columns need
|
||||
/// deletes nothing (it indexed past the points, a panic).
|
||||
#[test]
|
||||
fn mesh_lines_of_a_malformed_mesh_stay() {
|
||||
let point = |i: u32| MeshPoint { p: Point::new(f64::from(i), 0.0), color: Color::BLACK, opacity: 1.0, handles: [Vec2::ZERO; 4] };
|
||||
// An interior row's point and an interior column's point, each with 3 of the 6 points.
|
||||
for (rows, cols, index) in [(2, 1, 2), (1, 2, 1)] {
|
||||
let mut m = GradientMesh { rows, cols, points: (0..3).map(point).collect() };
|
||||
let before = m.clone();
|
||||
assert!(!m.remove_point_lines(index), "{rows}×{cols}, point {index}");
|
||||
assert_eq!(m, before);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user