dart-lang / native

Dart packages related to FFI and native assets bundling.
BSD 3-Clause "New" or "Revised" License
149 stars 42 forks source link

[ffigen] Crash while evaluating a policy #1651

Open matiasleyba opened 5 days ago

matiasleyba commented 5 days ago

Hi, I'm a beginner with ffigen but I'm trying to create an example using LocalAuthentication, I was able to generate the bindings and have created an implementation using them, everything works fine until I call evaluatePolicy and the app crashes.

Here is my implementation, I am assuming I have to call evaluatePolicy inside the platform thread as evaluatePolicy will do some ui stuff.

try {

      await runOnPlatformThread(() {
        final lib = DynamicLibrary.process();
        final localAuthentication = LocalAuthentication(lib);

        final context = LAContext.new1(localAuthentication);

        final error = NSError.new1(localAuthentication);

        final canEvaluate = context.canEvaluatePolicy_error_(
          LAPolicy.LAPolicyDeviceOwnerAuthentication,
          Pointer.fromAddress(error.pointer.address),
        );

        final completion = ObjCBlock_ffiVoid_bool_NSError.listener(
          localAuthentication,
          (result, nsError) {
            if (result) {
              return onSuccess();
            } else if (nsError != null) {
              onError();
            }
          },
        );

        final reason = NSString(localAuthentication, '');

        if (canEvaluate) {
          context.evaluatePolicy_localizedReason_reply_(
            LAPolicy.LAPolicyDeviceOwnerAuthentication,
            reason,
            completion,
          );
        }

        return;
      });
    } catch (e) {
      print(e);
    }

ffigen.yaml:

name: LocalAuthentication
description: Bindings for LocalAuthentication.
language: objc
output: 'lib/src/ffigen/local_auth_bindings.dart'
exclude-all-by-default: true
objc-interfaces:
  include:
    - 'LAContext'
headers:
  entry-points:
    - '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/LocalAuthentication.framework/Headers/LocalAuthentication.h'

Am I doing something wrong, does my use case make sense?

Let me know if you need more details, thanks in advance!

liamappelbe commented 3 days ago

I need some more information:

  1. Are you running this on iOS or MacOS?
  2. Is this a Flutter app or a Dart command line tool?
  3. Can you give some more details about the crash? Do you get a Dart or ObjC stack trace? Paste whatever logs you see here.
matiasleyba commented 3 days ago

I need some more information:

  1. Are you running this on iOS or MacOS?
  2. Is this a Flutter app or a Dart command line tool?
  3. Can you give some more details about the crash? Do you get a Dart or ObjC stack trace? Paste whatever logs you see here.

Hi @liamappelbe

  1. Tried on iOS Simulator and real device.
  2. Flutter app.
  3. I attached logs from XCode, let me know if this helps or if you need something else.

stackTraceXcode.txt

liamappelbe commented 3 days ago

Ok, my read of those logs is that your context.evaluatePolicy_localizedReason_reply_ call is throwing some sort of exception, but I don't see the exception message/metadata in those logs. So one line of inquiry would be to try to find more info about that exception. Eg, do you see anything in your flutter console, or in some other debug window in xcode? Since you can repro using the simulator+xcode, you could try enabling exception breakpoints. I'm not sure how well that would work since the exception is being thrown from inside an Apple API, but hopefully that would tell you more info about the exception.

The other line of inquiry is to try to figure out if any of the args you're passing to context.evaluatePolicy_localizedReason_reply_ are invalid. For example, you can check that the reason arg is ok by printing reason.toString(), which converts it to a Dart string. Or for the context object, to verify it's valid, try calling a simpler method on it, and see if it crashes (eg interactionNotAllowed).

Btw, I don't recognize that NSString constructor. What version of ffigen/package:objective_c are you using? The current version of NSString only takes one arg in its constructor.