diff --git a/crates/engine/src/cmd/draw.rs b/crates/engine/src/cmd/draw.rs index b073cf14..cf1998bf 100644 --- a/crates/engine/src/cmd/draw.rs +++ b/crates/engine/src/cmd/draw.rs @@ -937,11 +937,17 @@ impl Interactive for PolygonM { s.last_used.polygon_circumscribed = !ins; } (Some(c), Some(ins), Input::Point(p)) => { + if c.near(p, 1e-12) { + return Err(crate::EngineError::Other("Value must be positive and nonzero.".into())); + } s.add_entity(lwpoly(polygon_vertices(c, n, p, ins), true))?; return Ok(Step::Done); } (Some(c), Some(ins), Input::Text(t)) => { let r = number(&t).ok_or_else(|| crate::EngineError::Other("Requires numeric distance or point.".into()))?; + if !r.is_finite() || r <= 0.0 { + return Err(crate::EngineError::Other("Value must be positive and nonzero.".into())); + } let rp = polygon_typed_radius_point(c, n, r, ins); s.add_entity(lwpoly(polygon_vertices(c, n, rp, ins), true))?; return Ok(Step::Done); diff --git a/crates/engine/tests/draw_prompts.rs b/crates/engine/tests/draw_prompts.rs index 4535b1be..0de2b953 100644 --- a/crates/engine/tests/draw_prompts.rs +++ b/crates/engine/tests/draw_prompts.rs @@ -107,3 +107,19 @@ fn circle_center_prompt_rejects_garbage() { s.cmdline("0,0 5").unwrap(); assert!(matches!(last(&s), EntityKind::Circle(c) if (c.radius - 5.0).abs() < 1e-9)); } + +#[test] +fn polygon_radius_must_be_positive() { + for input in ["polygon 4 0,0 i 0", "polygon 4 0,0 c 0", "polygon 5 0,0 i -5", "polygon 5 0,0 c -5", "polygon 4 0,0 i 0,0", "polygon 4 0,0 c 0,0"] + { + let mut s = Session::new(); + s.cmdline(input).unwrap(); + assert_eq!(s.doc().unwrap().model.len(), 0, "{input}: no polygon"); + assert!(logged(&s, "Value must be positive and nonzero."), "{input}: {:?}", s.log); + assert!(s.running.is_some(), "{input}: still at the radius prompt"); + s.cmdline("2").unwrap(); + assert!(s.running.is_none(), "{input}: a positive radius finishes"); + assert_eq!(s.doc().unwrap().model.len(), 1, "{input}: one polygon"); + assert!(matches!(last(&s), EntityKind::LwPolyline(p) if p.closed), "{input}"); + } +}