Description
LocalNotificationCenter.ResetApplicationIconBadgeNumber(UIApplication) crashes with
ArgumentNullException (paramName: "collection") when iOS invokes the
GetDeliveredNotifications completion handler with a null array.
Platforms/iOS/LocalNotificationCenter.cs#L62-L66:
UNUserNotificationCenter.Current.GetDeliveredNotifications((notificationArray) =>
{
notificationList.AddRange(notificationArray); // throws if notificationArray is null
completionSource.SetResult(true);
});
List<T>.AddRange throws ArgumentNullException on a null argument, and the
callback parameter is not guarded.
The surrounding try/catch does not help
ResetApplicationIconBadgeNumber wraps its body in try/catch, but the throw happens
inside the completion handler, which iOS invokes later on its own stack via the
ObjC trampoline. The try block has already returned by then, so the exception is
unhandled and terminates the app rather than being caught.
There is a second consequence: completionSource.SetResult(true) on line 65 never
runs, so completionSource.Task.Wait() on line 67 would block indefinitely if the
process survived.
Stack trace
System.ArgumentNullException: ArgumentNull_Generic Arg_ParamName_Name, collection
at System.Collections.Generic.List`1[[UserNotifications.UNNotification, Microsoft.iOS,
Version=26.5.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065]]
.AddRange(IEnumerable`1 collection)
at Plugin.LocalNotification.LocalNotificationCenter.<>c__DisplayClass26_1
.<ResetApplicationIconBadgeNumber>b__0(UNNotification[] notificationArray)
at ObjCRuntime.Trampolines.SDActionArity1V276.Invoke(IntPtr block, NativeHandle obj)
Surfaced as SIGABRT in crash reporting.
Suggested fix
UNUserNotificationCenter.Current.GetDeliveredNotifications((notificationArray) =>
{
if (notificationArray is not null)
{
notificationList.AddRange(notificationArray);
}
completionSource.SetResult(true);
});
Moving SetResult outside the guard also removes the indefinite-wait path.
The async variant ResetApplicationIconBadgeNumberAsync (line 103) reads
notificationList.Length from GetDeliveredNotificationsAsync() without a null check
either, so it may warrant the same treatment.
Environment
|
|
| Plugin.LocalNotification |
14.1.1 |
| Platform |
iOS (.NET MAUI, net10.0-ios) |
| Microsoft.iOS |
26.5.0.0 |
Notes
Observed in production crash reporting, low frequency — 3 occurrences on a single
device. I have not reproduced it deliberately; a null array from
GetDeliveredNotifications appears to be an infrequent iOS behaviour rather than
something an app can trigger on demand. Reporting it because the fix is a one-line
guard and the failure is fatal.
Possibly adjacent to #236, which was a different exception in the same
iOS notification-enumeration area.
Description
LocalNotificationCenter.ResetApplicationIconBadgeNumber(UIApplication)crashes withArgumentNullException (paramName: "collection")when iOS invokes theGetDeliveredNotificationscompletion handler with a null array.Platforms/iOS/LocalNotificationCenter.cs#L62-L66:List<T>.AddRangethrowsArgumentNullExceptionon a null argument, and thecallback parameter is not guarded.
The surrounding try/catch does not help
ResetApplicationIconBadgeNumberwraps its body intry/catch, but the throw happensinside the completion handler, which iOS invokes later on its own stack via the
ObjC trampoline. The
tryblock has already returned by then, so the exception isunhandled and terminates the app rather than being caught.
There is a second consequence:
completionSource.SetResult(true)on line 65 neverruns, so
completionSource.Task.Wait()on line 67 would block indefinitely if theprocess survived.
Stack trace
Surfaced as SIGABRT in crash reporting.
Suggested fix
Moving
SetResultoutside the guard also removes the indefinite-wait path.The async variant
ResetApplicationIconBadgeNumberAsync(line 103) readsnotificationList.LengthfromGetDeliveredNotificationsAsync()without a null checkeither, so it may warrant the same treatment.
Environment
Notes
Observed in production crash reporting, low frequency — 3 occurrences on a single
device. I have not reproduced it deliberately; a null array from
GetDeliveredNotificationsappears to be an infrequent iOS behaviour rather thansomething an app can trigger on demand. Reporting it because the fix is a one-line
guard and the failure is fatal.
Possibly adjacent to #236, which was a different exception in the same
iOS notification-enumeration area.