Fix NullReferenceException when tapping Map with no overlays on iOS#34969
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34969Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34969" |
There was a problem hiding this comment.
Pull request overview
Fixes an iOS/MacCatalyst crash when tapping a Map with no overlays by guarding against MKMapView.Overlays being null.
Changes:
- Added a null-check around
mauiMkMapView.Overlaysbefore enumerating overlays during tap hit-testing on iOS. - Added two
Mapunit tests aroundIMap.Clicked/MapClickedbehavior when the map has no elements.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Core/maps/src/Platform/iOS/MauiMKMapView.cs | Prevents NullReferenceException by handling Overlays == null before overlay hit-testing. |
| src/Controls/tests/Core.UnitTests/MapTests.cs | Adds managed-unit tests for map click invocation/event behavior when no elements exist (but does not execute the iOS handler code path). |
e9858ae to
634fd64
Compare
Code Review — PR #34969Independent AssessmentWhat this changes: Adds a null check for Inferred motivation: Tapping a Map with no MapElements on iOS crashes with Reconciliation with PR NarrativeAuthor claims: Agreement: Root cause matches exactly. The fix follows the existing Findings✅ Correct — Early return is safe; click event fires BEFORE overlay iterationThe method structure is: The null check and ✅ Correct — Fix follows existing codebase patternThe null guard mirrors var elements = Overlays;
if (elements == null)
return;Storing in a local variable before null-checking is the correct iOS pattern — prevents potential TOCTOU if the native property could change between check and use. ✅ Correct — Device test exercises the actual crash path
✅ Correct — Unit tests provide supplementary managed-layer coverageThe two unit tests verify
|
|
Waiting for #34978 so we can run the tests |
|
/rebase |
MKMapView.Overlays returns null (not an empty array) when no overlays have been added. The OnMapClicked handler iterated Overlays without a null check, causing NullReferenceException on tap. Follow the existing null guard pattern from ClearMapElements. Fixes #34910 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
634fd64 to
e3bcecc
Compare
|
/azp run maui-pr-uitests, maui-pr-devicetests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
When a PR's merge commit is not on any release branch, the script was reading Versions.props at the merge commit. This gives stale values — e.g. a PR merged to inflight/current when PatchVersion=60 would get milestoned SR6, even though main has since moved to 70. Now uses the PR's base.ref to determine which branch to read from: main, inflight/*, darc/* → origin/main net11.0 → origin/net11.0 release/* → that branch directly This ensures .NET 11 PRs always read from net11.0 (not main), and inflight PRs read from main (not the stale merge commit). Release branch detection still takes priority. Validated: - #34228 (inflight/current) → reads main → SR7 (was incorrectly SR6) - #34969 (net11.0) → reads net11.0 → preview1 - #34620 (main, on SR6 branch) → release branch → SR6 (unchanged) 91 Pester tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two fixes to milestone detection:
1. Fallback reads Versions.props from the development branch (main
for .NET 10, net11.0 for .NET 11) instead of origin/{base.ref}.
Staging branches like inflight/candidate have stale PatchVersion
but their PRs ultimately ship on main's version.
2. Find-ReleaseBranchForCommit falls back to git log --grep when
ancestry check fails. Handles rebases and cherry-picks where the
commit SHA changes but the PR number '(#NNNNN)' is preserved in
the commit message.
Updated live validation guide to match new behavior.
Validated:
- #34667 (rebased to SR6) → found via grep → .NET 10 SR6 ✅
- #34959 (inflight/candidate) → reads main → .NET 10 SR7 ✅
- #34620 (on SR6 branch) → ancestry → .NET 10 SR6 ✅
- #34969 (net11.0) → reads net11.0 → .NET 11.0-preview4 ✅
91 Pester tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ng branch (#35054) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Summary Fix milestone fallback for `inflight/*` and `darc/*` branches to read from `origin/main` instead of the staging branch itself. ## Problem PRs merged to `inflight/candidate` were milestoned as SR6 because `inflight/candidate` has `PatchVersion=60`. But those PRs will ultimately ship in SR7 (when the Candidate merges to `main`, which is at `PatchVersion=70`). ## Fix For staging branches (`inflight/*`, `darc/*`), read `Versions.props` from `origin/main` instead of `origin/{base.ref}`. These branches always feed into main, so main's version is the correct target. All other branches continue reading from `origin/{base.ref}` directly. ## Validated | PR | Base | Before | After | |---|---|---|---| | #34959 | inflight/candidate | SR6 (wrong) | SR7 ✅ | | #35040 | inflight/current | SR7 | SR7 ✅ | | #34969 | net11.0 | preview1 | preview4 ✅ | | #34620 | main (on SR6 branch) | SR6 | SR6 ✅ | 91 Pester tests pass. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Description
Fixes #34910
MKMapView.Overlaysreturnsnull(not an empty array) when no overlays have been added to the map. TheOnMapClickedhandler inMauiMKMapView.csiterated.Overlayswithout a null check, causing aNullReferenceExceptionwhen tapping the map.This was introduced by the "Add Circle, Polygon, and Polyline click events" feature (#29101) on the net11.0 branch.
Changes
Fix (
MauiMKMapView.cs):mauiMkMapView.Overlaysbefore iterating, following the existing null guard pattern fromClearMapElements()at line 322.Tests (
MapTests.cs):VerifiesIMap.Clickeddoes not throw when the map has no elementsClickedDoesNotThrowWithNoElementsVerifies theMapClickedevent fires correctly with proper location data when no map elements existClickedFiresEventWithNoElementsRoot Cause
The
OnMapClickedstatic method (line 568) did:MKMapView.Overlaysis a native iOS property that returnsnullwhen no overlays exist (unlike .NET collections which typically return empty). The fix stores the value first and returns early if null:This matches the existing pattern in
ClearMapElements():