Merge pull request #3163 from Matoo125/fix/polygon-sides-from-file

Live shapes: a polygon read from a file has 3 to 1000 sides
This commit is contained in:
BFlat
2026-10-20 05:45:38 +07:00
committed by GitHub
+26
View File
@@ -102,6 +102,8 @@ pub enum LiveShape {
},
Polygon {
radius: f64,
/// 3–1000, as [`LiveShape::set_sides`] gives it; a file's count is clamped when read.
#[serde(deserialize_with = "de_sides")]
sides: u32,
xf: Affine,
/// Corner radii in document units, by vertex from the first one clockwise (none: sharp).
@@ -326,6 +328,12 @@ fn all_round(kinds: &[CornerKind]) -> bool {
kinds.iter().all(|k| *k == CornerKind::Round)
}
/// A polygon's side count read from a file, clamped as the commands clamp it: the outline and its
/// corner lists hold one entry per side, so a huge count would allocate gigabytes.
fn de_sides<'de, D: serde::Deserializer<'de>>(d: D) -> Result<u32, D::Error> {
u32::deserialize(d).map(|n| n.clamp(3, 1000))
}
/// Whether `a` only moves (no rotation, scale, shear or reflection).
fn moves_only(a: Affine) -> bool {
let [a0, a1, a2, a3, _, _] = a.as_coeffs();
@@ -2190,6 +2198,24 @@ mod tests {
assert_eq!(path.label(), "Path");
}
/// A polygon read from a file has 3 to 1000 sides, as the commands give it: selecting one
/// with four billion made its outline and corner lists allocate tens of gigabytes.
#[test]
fn a_polygon_from_a_file_has_3_to_1000_sides() {
let read = |sides: u32| {
let json = serde_json::json!({"shape": "polygon", "radius": 10.0, "sides": sides, "xf": [1, 0, 0, 1, 0, 0]});
serde_json::from_value::<LiveShape>(json).unwrap()
};
let sides_of = |l: &LiveShape| match l {
LiveShape::Polygon { sides, .. } => *sides,
_ => panic!("not a polygon: {l:?}"),
};
let huge = read(4_000_000_000);
assert_eq!([0, 5, 1000].map(|n| sides_of(&read(n))), [3, 5, 1000]);
assert_eq!(sides_of(&huge), 1000);
assert_eq!(huge.polygon_outline().anchor_count(), 1000);
}
#[test]
fn a_polygon_reports_and_takes_its_radius_angle_and_equal_sides() {
let close = |a: f64, b: f64| (a - b).abs() < 1e-9;