fix: prevent RangeError in Proj4Crs.zoom for out-of-range scales#2209
Draft
AlexLaroche wants to merge 1 commit into
Draft
fix: prevent RangeError in Proj4Crs.zoom for out-of-range scales#2209AlexLaroche wants to merge 1 commit into
Proj4Crs.zoom for out-of-range scales#2209AlexLaroche wants to merge 1 commit into
Conversation
When the requested scale is larger than the largest entry in the CRS's `_scales`, `_closestElement` returns the last element, so `downZoom` is `_scales.length - 1`. Falling through to the interpolation block then indexes `_scales[downZoom + 1]` and throws `RangeError`. Return `double.infinity` in that case, mirroring the `double.negativeInfinity` already returned when the requested scale is smaller than every defined level. Callers such as `FitBounds._getBoundsZoom` then clamp via `.clamp(min, max)` and the camera ends up at `maxZoom`, instead of the whole frame throwing. Closes fleaflet#1223.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a
RangeErrorthrown byProj4Crs.zoomwhen the requested scale is finer than the deepest level defined in the CRS'sresolutionslist. Closes #1223 (which has documented this exact crash since 2022).Root cause
In
lib/src/geo/crs.dart:When the caller asks for a scale beyond the largest defined level,
_closestElementreturns_scales.last, sodownZoomis the last index. The interpolation block then indexes_scales[downZoom + 1]and throws.The most common path that hits this is
FitBounds._getBoundsZoom, which callscamera.getScaleZoom(scale)before clamping the result tomaxZoom(camera_fit.dart:162 vs :176). So settingmaxZoomonMapOptions/CameraFit.boundsdoes not protect against the crash — it crashes insideProj4Crs.zoombefore the clamp can run. This is also why issue #1223's reproduction isfitBoundswith a custom CRS.Fix
When
downZoom == _scales.length - 1and the requested scale is strictly larger thandownScale, returndouble.infinityinstead of falling through to the out-of-bounds index access.This mirrors the existing lower-bound behavior in the same function: when the requested scale is smaller than every entry in
_scales, the function already returnsdouble.negativeInfinity. The fix makes the upper bound symmetric.Callers like
FitBounds._getBoundsZoomalready.clamp(min, max)the returned zoom, so+∞becomesmaxZoomand the camera settles correctly. The whole frame no longer throws.Why
double.infinityrather than clamping to_scales.length - 1?double.negativeInfinityfor the lower bound.FitBoundsalready has its ownmaxZoomthat may be lower than the deepest CRS level.Happy to switch to a finite clamp if reviewers prefer.
Test plan
test/geo/crs_test.dartcovers exact match, interpolation, lower-bound-∞, and upper-bound+∞.+∞test reproduces the originalRangeErroratcrs.dart:356:30when the fix is reverted.flutter test test/geo/ test/flutter_map_test.dart— all 20 tests pass.flutter analyze lib/src/geo/crs.dart test/geo/crs_test.dart— no issues.dart formatclean on changed files.