diff --git a/CHANGELOG.md b/CHANGELOG.md index 6dc1f46..55fa1bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [0.1.3+1] + +* Allow overwriting of library name lookup. + ## [0.1.2] * Remove dependency on ffi_helper. diff --git a/lib/argon2_ffi_base.dart b/lib/argon2_ffi_base.dart index fab79f4..710348d 100644 --- a/lib/argon2_ffi_base.dart +++ b/lib/argon2_ffi_base.dart @@ -9,6 +9,10 @@ import 'package:ffi/ffi.dart'; // ignore_for_file: non_constant_identifier_names, +import 'package:logging/logging.dart'; + +final _logger = Logger('argon2_ffi_base'); + typedef Argon2HashNative = Pointer Function( Pointer key, Uint32 keyLen, @@ -35,15 +39,11 @@ typedef Argon2Hash = Pointer Function( int version, ); +typedef ResolveLibrary = String Function(String baseName); + class Argon2FfiFlutter extends Argon2Base { - Argon2FfiFlutter() { - final argon2lib = Platform.isAndroid - ? DynamicLibrary.open('libargon2_ffi.so') - : Platform.isLinux - ? DynamicLibrary.open('libargon2_ffi_plugin.so') - : Platform.isWindows - ? DynamicLibrary.open('argon2_ffi_plugin.dll') - : DynamicLibrary.executable(); + Argon2FfiFlutter({this.resolveLibrary}) { + final argon2lib = _loadLib(); _nativeAdd = argon2lib .lookup>('native_add') .asFunction(); @@ -52,11 +52,48 @@ class Argon2FfiFlutter extends Argon2Base { .asFunction(); } + static ResolveLibrary defaultResolveLibrary = (name) => name; + + /// forces loading of dynamic library on MacOS instead of assuming + /// argon2 was statically linked. (ie. flutter usage, vs dart usage) + static bool resolveLibraryForceDynamic = false; + + final ResolveLibrary resolveLibrary; + int Function(int x, int y) _nativeAdd; @override Argon2Hash argon2hash; int addIt(int x, int y) => _nativeAdd(x, y); + + DynamicLibrary _loadLib() { + final resolveLibrary = this.resolveLibrary ?? defaultResolveLibrary; + + if (!resolveLibraryForceDynamic && (Platform.isIOS || Platform.isMacOS)) { + return DynamicLibrary.executable(); + } + final libraryNames = [ + [Platform.isAndroid, 'libargon2_ffi.so'], + [Platform.isLinux, './libargon2_ffi_plugin.so'], + [Platform.isWindows, 'argon2_ffi_plugin.dll'], + [Platform.isMacOS, 'libargon2_ffi.dylib'], + [Platform.isIOS, null], // only supports static linking. + ]; + final libraryName = libraryNames.firstWhere((element) => element[0] == true, + orElse: () => throw StateError( + 'Unsupported Operating System ${Platform.operatingSystem}'))[1] + as String; + final path = resolveLibrary(libraryName); + try { + return DynamicLibrary.open(libraryName); + } on ArgumentError catch (e, stackTrace) { + _logger.severe( + 'Error while loading dynamic library from $path ($libraryName)', + e, + stackTrace); + rethrow; + } + } } abstract class Argon2 { diff --git a/pubspec.lock b/pubspec.lock index 9c3716a..b23cf6c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -8,6 +8,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.3" + logging: + dependency: "direct main" + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "0.11.4" meta: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 4687ed8..c476a00 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: argon2_ffi_base description: Base package defining the interface for an Argon2 implementation. -version: 0.1.2 +version: 0.1.3+1 homepage: https://github.com/authpass/argon2_ffi_base environment: @@ -8,6 +8,7 @@ environment: dependencies: ffi: ^0.1.3 + logging: ^0.11.4 dev_dependencies: pedantic: ^1.9.2