From 5c8941467d7275ba553fb171639698c047666c3b Mon Sep 17 00:00:00 2001 From: zsviczian Date: Mon, 20 Mar 2023 13:20:09 +0100 Subject: [PATCH] fix: division by zero in findFocusPointForEllipse leads to infinite loop in wrapText freezing Excalidraw (#6377) * Update collision.ts * Update textElement.ts * Update textElement.ts * tweak * fix * remove unnecessary `Math.sign` * change check and add doc * Add a case for negative max width and specs * fix --------- Co-authored-by: dwelle Co-authored-by: Aakansha Doshi --- src/element/collision.ts | 7 ++++++- src/element/textElement.test.ts | 7 +++++++ src/element/textElement.ts | 7 +++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/element/collision.ts b/src/element/collision.ts index 097b76d3..0e7257d7 100644 --- a/src/element/collision.ts +++ b/src/element/collision.ts @@ -786,7 +786,12 @@ export const findFocusPointForEllipse = ( orientation * py * Math.sqrt(Math.max(0, squares - a ** 2 * b ** 2))) / squares; - const n = (-m * px - 1) / py; + let n = (-m * px - 1) / py; + + if (n === 0) { + // if zero {-0, 0}, fall back to a same-sign value in the similar range + n = (Object.is(n, -0) ? -1 : 1) * 0.01; + } const x = -(a ** 2 * m) / (n ** 2 * b ** 2 + m ** 2 * a ** 2); return GA.point(x, (-m * x - 1) / n); diff --git a/src/element/textElement.test.ts b/src/element/textElement.test.ts index 3de96037..be6d1a8a 100644 --- a/src/element/textElement.test.ts +++ b/src/element/textElement.test.ts @@ -184,6 +184,13 @@ break it now`, expect(res).toEqual(`Hello Excalidraw`); }); + + it("should return the text as is if max width is invalid", () => { + const text = "Hello Excalidraw"; + expect(wrapText(text, font, NaN)).toEqual(text); + expect(wrapText(text, font, -1)).toEqual(text); + expect(wrapText(text, font, Infinity)).toEqual(text); + }); }); describe("Test measureText", () => { diff --git a/src/element/textElement.ts b/src/element/textElement.ts index 7dc11c9a..8d1b0901 100644 --- a/src/element/textElement.ts +++ b/src/element/textElement.ts @@ -324,6 +324,13 @@ export const getTextHeight = (text: string, font: FontString) => { }; export const wrapText = (text: string, font: FontString, maxWidth: number) => { + // if maxWidth is not finite or NaN which can happen in case of bugs in + // computation, we need to make sure we don't continue as we'll end up + // in an infinite loop + if (!Number.isFinite(maxWidth) || maxWidth < 0) { + return text; + } + const lines: Array = []; const originalLines = text.split("\n"); const spaceWidth = getLineWidth(" ", font);