mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Security: cap the perspective grid's line-loop bounds at 121 a way
This commit is contained in:
@@ -562,14 +562,17 @@ impl PerspectiveGrid {
|
||||
s
|
||||
};
|
||||
let (su, sv) = (step(w), step(h_len));
|
||||
// Counted, not summed: a count in whole lines (at most 121 a way).
|
||||
for i in 0..=((w + 1e-9) / su).floor() as usize {
|
||||
// Counted, not summed: a count in whole lines (at most 121 a way). The fixed 1e-9
|
||||
// tolerance can inflate the count when the whole domain is far smaller than it, so the
|
||||
// bound is capped on its own, before any loop runs.
|
||||
let count = |len: f64, s: f64| ((len + 1e-9) / s).floor().clamp(0.0, 120.0) as usize;
|
||||
for i in 0..=count(w, su) {
|
||||
let u = i as f64 * su;
|
||||
if let (Some(a), Some(b)) = (h.apply(Point::new(u, 0.0)), h.apply(Point::new(u, h_len))) {
|
||||
out.push((a, b));
|
||||
}
|
||||
}
|
||||
for i in 0..=((h_len + 1e-9) / sv).floor() as usize {
|
||||
for i in 0..=count(h_len, sv) {
|
||||
let v = i as f64 * sv;
|
||||
if let (Some(a), Some(b)) = (h.apply(Point::new(0.0, v)), h.apply(Point::new(w, v))) {
|
||||
out.push((a, b));
|
||||
|
||||
@@ -123,6 +123,16 @@ mod tests {
|
||||
assert_eq!(g.snap_offset(b, Vec2::new(18.0, 0.0)), Vec2::new(18.0, 0.0), "nothing within reach");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_tiny_stored_grid_draws_a_bounded_number_of_lines() {
|
||||
// A stored grid can carry extreme values: the loop bound must not depend on a fixed
|
||||
// tolerance swallowing the whole domain.
|
||||
let g = PerspectiveGrid { cell: 1e-18, extent: 1e-18, height: 1e-18, ..PerspectiveGrid::normal(2, Rect::new(0.0, 0.0, 800.0, 600.0)) };
|
||||
for pl in Plane::ALL {
|
||||
assert!(g.lines(pl).len() <= 121 + 121, "at most 121 lines a way on {pl:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn colours_and_rulers_come_from_the_definition() {
|
||||
let mut g = grid();
|
||||
|
||||
Reference in New Issue
Block a user