Skip to content

[pigeon] Treat NSNull as null for non-null Flutter API returns - #12531

Open
Xelorium wants to merge 1 commit into
flutter:mainfrom
Xelorium:pigeon-swift-nsnull-null-check
Open

[pigeon] Treat NSNull as null for non-null Flutter API returns#12531
Xelorium wants to merge 1 commit into
flutter:mainfrom
Xelorium:pigeon-swift-nsnull-null-check

Conversation

@Xelorium

@Xelorium Xelorium commented Aug 21, 2026

Copy link
Copy Markdown

Description

FlutterStandardReader substitutes NSNull for a nil element when it decodes a list, so a null reply for a non-null return value reaches the generated Swift code as NSNull rather than as nil. The generated guard only checks listResponse[0] == nil, so NSNull falls through to the force cast below it and aborts the process:

} else if listResponse[0] == nil {
  completion(.failure(PigeonError(code: "null-error", ...)))
} else {
  let result = listResponse[0] as! AuthenticationChallengeResponse  // 💥

This crashes production apps through webview_flutter_wkwebview: the plugin clears its native instance manager in WebViewFlutterPlugin.tearDownProxyAPIRegistrar(), which iOS triggers on sceneDidDisconnect / applicationWillTerminate. A WKNavigationDelegate.didReceiveAuthenticationChallenge reply that is still in flight then carries an identifier the native instance manager can no longer resolve, the codec reader returns nil, and the app dies with:

Could not cast value of type 'NSNull' (0x...) to 'webview_flutter_wkwebview.AuthenticationChallengeResponse' (0x...).

The same shape was reported before for other types (URLRequestWrapper in flutter/flutter#162437), which is expected: the generator emits this guard for every non-null return value, so any unresolvable instance crashes instead of reporting an error.

This PR treats NSNull as a null reply, so the existing null-error path handles it.

Verification

  • Added a Swift generator unit test asserting the generated guard covers NSNull.
  • Added a native regression test in platform_tests that replies NSNull to a non-null Flutter API return. It passes with this change; with the generated guard reverted it aborts with Could not cast value of type 'NSNull' (0x...) to 'test_plugin.AllNullableTypes' (0x...).
  • dart test and flutter_plugin_tools format pass locally.

Fixes flutter/flutter#191254

Pre-Review Checklist

@google-cla

google-cla Bot commented Aug 21, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates Pigeon to version 27.3.3. It modifies the Swift generator to check if a Flutter API response is nil or NSNull when validating non-nullable return values, preventing crashes when FlutterStandardReader substitutes NSNull for nil. It also updates the generated Swift files, adds a regression test in NullableReturnsTests.swift, and adds a generator unit test in swift_generator_test.dart. There are no review comments, so no further feedback is provided.

`FlutterStandardReader` substitutes `NSNull` for a `nil` element of a
list, so a null reply for a non-null return value arrives as `NSNull`
rather than as `nil`. The generated `listResponse[0] == nil` check did
not catch that, and the following force cast aborted the process.

In `webview_flutter_wkwebview` this crashes apps whenever the native
instance manager cannot resolve the returned instance, which the plugin
itself causes by clearing the manager on scene disconnect and app
termination while an authentication challenge is in flight.
@Xelorium
Xelorium force-pushed the pigeon-swift-nsnull-null-check branch from fbfef09 to 274fd02 Compare August 21, 2026 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

1 participant