From 748a871e57d4df62c299bf731ee17721b9739c3c Mon Sep 17 00:00:00 2001 From: Daniel_M_Williams Date: Fri, 14 Aug 2020 16:38:39 -0400 Subject: [PATCH] [fix] limits a FreeformFinSet maximum size to 2.5m x 2.5m. This prevents a stack-overflow while editing --- .../rocketcomponent/FreeformFinSet.java | 52 ++++++++++++++++--- .../gui/scalefigure/FinPointFigure.java | 8 +-- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/FreeformFinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FreeformFinSet.java index 261d9bb05..49df4afbf 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FreeformFinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FreeformFinSet.java @@ -24,7 +24,10 @@ public class FreeformFinSet extends FinSet { private static final double SNAP_SMALLER_THAN = 5e-3; private static final double IGNORE_SMALLER_THAN = 1e-12; - + + // attempts to set a fin value any larger than this will be snapped to this max value + public static final double SNAP_LARGER_THAN = 2.5; // in meters + public FreeformFinSet() { points.add(Coordinate.ZERO); points.add(new Coordinate(0.025, 0.05)); @@ -164,6 +167,16 @@ public class FreeformFinSet extends FinSet { newPoints = translatePoints( newPoints, delta); } + for ( int i =0; i < newPoints.size(); ++i ) { + final Coordinate p = newPoints.get(i); + if( p.x > SNAP_LARGER_THAN){ + newPoints.set(i, p.setX(SNAP_LARGER_THAN)); + } + if( p.y > SNAP_LARGER_THAN){ + newPoints.set(i, p.setY(SNAP_LARGER_THAN)); + } + } + // copy the old points, in case validation fails final ArrayList pointsCopy = new ArrayList<>(this.points); final double lengthCopy = this.length; @@ -203,14 +216,39 @@ public class FreeformFinSet extends FinSet { * @param yRequest the y-coordinate. */ public void setPoint(final int index, final double xRequest, final double yRequest) { - final Coordinate revertPoint = points.get(index); - if(null != this.getParent()) { - final Coordinate prior = points.get(index); - points.set(index, new Coordinate(xRequest, yRequest)); + if(null == this.getParent()) { + return; + } - if((points.size() - 1) == index){ - clampLastPoint(xRequest-prior.x); + // if the new x,y would cause a fin larger than our max-size, limit the new request: + double xAccept = xRequest; + double yAccept = yRequest; + if(0 == index) { + final Coordinate cl = points.get(points.size() - 1); + double newLength = cl.x - xRequest; + if (newLength > SNAP_LARGER_THAN) { + xAccept = SNAP_LARGER_THAN - cl.x; } + }else{ + if (xAccept > SNAP_LARGER_THAN) { + xAccept = SNAP_LARGER_THAN; + } + if (yAccept > SNAP_LARGER_THAN) { + yAccept = SNAP_LARGER_THAN; + } + } + + final Coordinate revertPoint = points.get(index); + + points.set(index, new Coordinate(xAccept, yAccept)); + + if( IGNORE_SMALLER_THAN > Math.abs(revertPoint.x - xAccept) && IGNORE_SMALLER_THAN > Math.abs(revertPoint.y - yAccept) ){ + // no-op. ignore + return; + } + + if ((points.size() - 1) == index) { + clampLastPoint(xAccept - revertPoint.x); } update(); diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/FinPointFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/FinPointFigure.java index a4a26c9e1..bb2852755 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/FinPointFigure.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/FinPointFigure.java @@ -52,7 +52,7 @@ public class FinPointFigure extends AbstractScaleFigure { private final FreeformFinSet finset; private int modID = -1; - + protected BoundingBox finBounds_m = null; protected BoundingBox mountBounds_m = null; @@ -346,8 +346,10 @@ public class FinPointFigure extends AbstractScaleFigure { assert (false) : "Should not occur"; return new Point2D.Double(0, 0); } - - p.setLocation(p.x, p.y); + + p.x = MathUtil.clamp(p.x, -FreeformFinSet.SNAP_LARGER_THAN, FreeformFinSet.SNAP_LARGER_THAN); + p.y = MathUtil.clamp(p.y, -FreeformFinSet.SNAP_LARGER_THAN, FreeformFinSet.SNAP_LARGER_THAN); + return p; }