rfellows opened a new pull request, #11352: URL: https://github.com/apache/nifi/pull/11352
# Summary [NIFI-16025](https://issues.apache.org/jira/browse/NIFI-16025) The NiFi backend can persist arbitrarily large finite floating-point values as component position coordinates (e.g. `7.49e+307`). Values of this magnitude pass `Number.isFinite()` and therefore clear all existing validity checks, but they cause two observable failures in the browser: 1. SVG rendering errors — `Error: <g> attribute transform: Expected number` — because SVG and float32 rendering pipelines cannot represent numbers of this magnitude. 2. Frozen canvas navigation because D3.js arithmetic overflows when computing zoom and pan transforms from such coordinates. This change adds a layered, UI-only defence across the Angular frontend canvas pipeline. No backend changes are required. **Shared bounds utilities (`libs/shared/src/services/canvas-bounds.util.ts`)** Introduces a new `canvas-bounds.util.ts` module with the following exports: - `MAX_ABS_COORD` (1e9) — maximum safe absolute value for a canvas position coordinate. - `MAX_ABS_TRANSLATE` (1e12) — maximum safe absolute value for a viewport translation. - `MIN_SCALE` / `MAX_SCALE` — canonical scale range constants, centralising values previously hardcoded in `canvas-view.service.ts`. - `isFiniteInBound(value, bound)` — type guard that combines `Number.isFinite` with a magnitude check. - `isScaleInBound(value)` — rejects near-zero and out-of-range scale factors. - `clampScale(scale, fallback?)` — NaN-safe scale clamp. - `sanitizePosition(position, opts)` — clamps out-of-range coordinates to `(0, 0)` and emits a deduplicated `console.warn` per component ID. **Data-ingestion sanitization (flow.effects.ts, connector-canvas.effects.ts)** `loadProcessGroup$` and `loadConnectorFlow$` now walk all positioned entity collections — processors, process groups, remote process groups, input/output ports, labels, funnels, and connection bend points — through `sanitizePosition` before dispatching NgRx actions. A session-scoped `Set` prevents repeated console warnings during polling refreshes. **Transform pipeline guards (canvas-view.service.ts, birdseye-view.service.ts, transform.effects.ts)** - `canvas-view.service.ts`: replaces `!isNaN` checks with `isFiniteInBound` + `isScaleInBound` in the zoom handler, `transform()`, `getCanvasPosition()`, and `fit()`; fixes `getSelectionBoundingClientRect()` to return `null` on empty selection and to use `Infinity` sentinels instead of `Number.MAX_VALUE` / `Number.MIN_VALUE`. - `birdseye-view.service.ts`: bails early in `refresh()` before any divide-by-scale arithmetic when the current transform is out of bounds. - `transform.effects.ts`: upgrades `isFinite` checks in `restoreViewport$` to magnitude-bounded guards; evicts invalid localStorage entries so a corrupted persisted viewport cannot replay across page refreshes. **Reusable canvas and birdseye guards (canvas.component.ts, birdseye.component.ts)** - `canvas.component.ts`: applies magnitude-and-scale guards in `readViewportTransform`, the zoom handler, `applyTransform`, `restoreViewportFromStorage`, `fitContent`, and `getCanvasPosition`; invalid localStorage entries are evicted on load. - `birdseye.component.ts`: introduces an `isTransformSafe` predicate consulted by both `updateBrush` and `renderComponents` before any divide-by-scale render path. **Tests** 71 new tests added across 8 files: | File | New tests | |---|---| | `canvas-bounds.util.spec.ts` | 30 | | `canvas-view.service.spec.ts` | 12 | | `canvas.component.spec.ts` | 10 | | `transform.effects.spec.ts` | 5 | | `birdseye.component.spec.ts` | 4 | | `flow.effects.spec.ts` | 4 | | `birdseye-view.service.spec.ts` | 3 | | `connector-canvas.effects.spec.ts` | 3 | Test coverage includes the `~7.49e+307` fingerprint value, warn-once deduplication across poll cycles, localStorage eviction on load, and the full guard surface in each service and component. All 2,700 existing frontend tests continue to pass. # Tracking Please complete the following tracking steps prior to pull request creation. ### Issue Tracking - [Apache NiFi Jira](https://issues.apache.org/jira/browse/NIFI) issue created ### Pull Request Tracking - Pull Request title starts with Apache NiFi Jira issue number, such as `NIFI-00000` - Pull Request commit message starts with Apache NiFi Jira issue number, as such `NIFI-00000` - Pull request contains [commits signed](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits) with a registered key indicating `Verified` status ### Pull Request Formatting - Pull Request based on current revision of the `main` branch - Pull Request refers to a feature branch with one commit containing changes # Verification Please indicate the verification steps performed prior to pull request creation. ### Build - [ ] Build completed using `./mvnw clean install -P contrib-check` - [ ] JDK 21 - [ ] JDK 25 ### Licensing - [ ] New dependencies are compatible with the [Apache License 2.0](https://apache.org/licenses/LICENSE-2.0) according to the [License Policy](https://www.apache.org/legal/resolved.html) - [ ] New dependencies are documented in applicable `LICENSE` and `NOTICE` files ### Documentation - [ ] Documentation formatting appears as expected in rendered files -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
