2
0

Merge branch 'master' of gitlab.com:MasterPassword/MasterPassword

This commit is contained in:
Maarten Billemont 2018-06-24 16:31:22 -04:00
commit 5084511404
20 changed files with 143 additions and 48 deletions

12
.gitignore vendored
View File

@ -17,17 +17,9 @@ DerivedData/
/platform-darwin/Podfile.lock /platform-darwin/Podfile.lock
/platform-darwin/Pods/ /platform-darwin/Pods/
# Media
public/Press/Background.png
public/Press/Front-Page.png
public/Press/MasterPassword_PressKit/MasterPassword_pressrelease_*.pdf
# Gradle # Gradle
build build
!/build
.gradle .gradle
local.properties local.properties
/gradle/builds
# Maven /platform-android/.externalNativeBuild
target
dependency-reduced-pom.xml

View File

@ -5,7 +5,7 @@ variables:
build_project: build_project:
stage: build stage: build
script: script:
- "( brew install libsodium json-c )" - "( brew bundle )"
- "( ./lib/bin/build_libsodium-macos )" - "( ./lib/bin/build_libsodium-macos )"
- "( cd ./platform-independent/c/cli && ./clean && targets=all ./build && ./mpw-tests && ./mpw-cli-tests )" - "( cd ./platform-independent/c/cli && ./clean && targets=all ./build && ./mpw-tests && ./mpw-cli-tests )"
- "( cd ./gradle && ./gradlew --info clean test )" - "( cd ./gradle && ./gradlew --info clean test )"

2
.gitmodules vendored
View File

@ -24,7 +24,7 @@
url = https://github.com/jedisct1/libsodium.git url = https://github.com/jedisct1/libsodium.git
[submodule "lib/libjson-c"] [submodule "lib/libjson-c"]
path = lib/libjson-c path = lib/libjson-c
url = https://github.com/lhunath/json-c.git url = https://github.com/json-c/json-c.git
[submodule "public/site"] [submodule "public/site"]
path = public/site path = public/site
url = https://github.com/Lyndir/MasterPassword.git url = https://github.com/Lyndir/MasterPassword.git

5
Brewfile Normal file
View File

@ -0,0 +1,5 @@
brew "libsodium"
brew "json-c"
brew "automake"
brew "autoconf"

View File

@ -2,11 +2,11 @@ To build a release distribution:
Desktop: Desktop:
STORE_PW=$(mpw masterpassword.keystore) KEY_PW=$(mpw masterpassword-desktop) gradle clean masterpassword-gui:shadowJar STORE_PW=$(mpw masterpassword.keystore) KEY_PW_DESKTOP=$(mpw masterpassword-desktop) gradle clean masterpassword-gui:shadowJar
Android: Android:
STORE_PW=$(mpw masterpassword.keystore) KEY_PW=$(mpw masterpassword-android) gradle clean masterpassword-android:assembleRelease STORE_PW=$(mpw masterpassword.keystore) KEY_PW_ANDROID=$(mpw masterpassword-android) gradle clean masterpassword-android:assembleRelease
Note: Note:

View File

@ -11,8 +11,8 @@ allprojects {
} }
tasks.withType( FindBugs ) { tasks.withType( FindBugs ) {
reports { reports {
xml.enabled false xml.enabled = false
html.enabled true html.enabled = true
} }
} }
} }

View File

@ -50,7 +50,7 @@ _initialize() {
# #
# Check if all tools needed for the default implementations are available. # Check if all tools needed for the default implementations are available.
# #
# By default, this will check for `automake` and `autoreconf`. # By default, this will check for `automake` (for aclocal) and `autoconf` (for autoreconf).
initialize_needs() { _initialize_needs "$@"; } initialize_needs() { _initialize_needs "$@"; }
_initialize_needs() { _initialize_needs() {
if [[ $platform = windows ]]; then if [[ $platform = windows ]]; then
@ -58,7 +58,7 @@ _initialize_needs() {
export VSINSTALLDIR="${VSINSTALLDIR:-$(cd "$(cygpath -F 0x002a)/Microsoft Visual Studio"/*/*/Common7/.. && pwd)}" export VSINSTALLDIR="${VSINSTALLDIR:-$(cd "$(cygpath -F 0x002a)/Microsoft Visual Studio"/*/*/Common7/.. && pwd)}"
[[ -e "$VSINSTALLDIR/Common7/Tools/VsMSBuildCmd.bat" ]] || { echo >&2 "Missing: msbuild. Please install 'Build Tools for Visual Studio'."; return 1; } [[ -e "$VSINSTALLDIR/Common7/Tools/VsMSBuildCmd.bat" ]] || { echo >&2 "Missing: msbuild. Please install 'Build Tools for Visual Studio'."; return 1; }
else else
needs automake autoreconf needs automake autoconf
fi fi
} }

View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
source "${BASH_SOURCE%/*}/build_lib"
autoreconf() {
command autoreconf -Iautoconf-archive/m4 "$@"
}
build libjson-c android

@ -1 +1 @@
Subproject commit 3e5ad38a83a05b641cd84414a67a64992bf0e8c6 Subproject commit e3752b58945d23895535857ed136a5185bad02ce

View File

@ -0,0 +1,24 @@
project( mpw-core C )
cmake_minimum_required( VERSION 3.0.0 )
add_library( mpw SHARED
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/base64.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/aes.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-algorithm.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-types.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-util.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-marshal-util.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-marshal.c"
"${PROJECT_SOURCE_DIR}/../platform-independent/c/core/src/mpw-jni.c" )
add_library( sodium SHARED IMPORTED )
set_target_properties( sodium PROPERTIES IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/../lib/libsodium/build-android~/out/lib/${ANDROID_ABI}/libsodium.so" )
target_include_directories( mpw PRIVATE "${PROJECT_SOURCE_DIR}/../lib/libsodium/build-android~/out" )
target_compile_definitions( mpw PRIVATE -DMPW_SODIUM=1 )
target_link_libraries( mpw PRIVATE sodium )
add_library( json-c SHARED IMPORTED )
set_target_properties( json-c PROPERTIES IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/../lib/libjson-c/build-android~/out/lib/${ANDROID_ABI}/libjson-c.so" )
target_include_directories( mpw PRIVATE "${PROJECT_SOURCE_DIR}/../lib/libjson-c/build-android~/out" )
target_compile_definitions( mpw PRIVATE -DMPW_JSON=1 )
target_link_libraries( mpw PRIVATE json-c )

View File

@ -4,17 +4,27 @@ android {
compileSdkVersion 25 compileSdkVersion 25
buildToolsVersion '27.0.3' buildToolsVersion '27.0.3'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig { defaultConfig {
applicationId 'com.lyndir.masterpassword' applicationId 'com.lyndir.masterpassword'
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 25 targetSdkVersion 25
versionCode 20501 versionCode 20701
versionName '2.5.1' versionName '2.7.1'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
externalNativeBuild {
cmake {
path 'CMakeLists.txt'
}
}
sourceSets {
main {
jniLibs.srcDirs "$projectDir/../lib/libsodium/build-android~/out/lib",
"$projectDir/../lib/libjson-c/build-android~/out/lib"
}
} }
// release with: STORE_PW=$(mpw masterpassword.keystore) KEY_PW_ANDROID=$(mpw masterpassword-android) gradle masterpassword-android:assembleRelease // release with: STORE_PW=$(mpw masterpassword.keystore) KEY_PW_ANDROID=$(mpw masterpassword-android) gradle masterpassword-android:assembleRelease
@ -43,3 +53,13 @@ dependencies {
implementation group: 'com.jakewharton', name: 'butterknife', version: '8.5.1' implementation group: 'com.jakewharton', name: 'butterknife', version: '8.5.1'
annotationProcessor group: 'com.jakewharton', name: 'butterknife-compiler', version: '8.5.1' annotationProcessor group: 'com.jakewharton', name: 'butterknife-compiler', version: '8.5.1'
} }
preBuild {
dependsOn task( type: Exec, 'buildLibSodium', {
commandLine "$projectDir/../lib/bin/build_libsodium-android"
} )
dependsOn task( type: Exec, 'buildLibJson-c', {
commandLine "$projectDir/../lib/bin/build_libjson-c-android"
} )
}

View File

@ -130,7 +130,7 @@ public class EmergencyActivity extends Activity {
siteNameField.addTextChangedListener( new ValueChangedListener() { siteNameField.addTextChangedListener( new ValueChangedListener() {
@Override @Override
void update() { void update() {
siteCounterButton.setText( MessageFormat.format( "{0}", 1 ) ); siteCounterButton.setText( MessageFormat.format( "{0}", UnsignedInteger.ONE ) );
updateSitePassword(); updateSitePassword();
} }
} ); } );
@ -155,6 +155,17 @@ public class EmergencyActivity extends Activity {
updateSitePassword(); updateSitePassword();
} }
} ); } );
siteCounterButton.setOnLongClickListener( new View.OnLongClickListener() {
@Override
public boolean onLongClick(final View v) {
if (UnsignedInteger.valueOf( siteCounterButton.getText().toString() ).equals( UnsignedInteger.ONE ))
return false;
siteCounterButton.setText( MessageFormat.format( "{0}", UnsignedInteger.ONE ) );
updateSitePassword();
return true;
}
} );
siteVersionButton.setOnClickListener( new View.OnClickListener() { siteVersionButton.setOnClickListener( new View.OnClickListener() {
@Override @Override
public void onClick(final View v) { public void onClick(final View v) {
@ -229,7 +240,7 @@ public class EmergencyActivity extends Activity {
MPAlgorithm.Version defaultVersion = preferences.getDefaultVersion(); MPAlgorithm.Version defaultVersion = preferences.getDefaultVersion();
siteVersionButton.setTag( defaultVersion ); siteVersionButton.setTag( defaultVersion );
siteVersionButton.setText( defaultVersion.name() ); siteVersionButton.setText( defaultVersion.name() );
siteCounterButton.setText( MessageFormat.format( "{0}", 1 ) ); siteCounterButton.setText( MessageFormat.format( "{0}", UnsignedInteger.ONE ) );
if (TextUtils.isEmpty( fullNameField.getText() )) if (TextUtils.isEmpty( fullNameField.getText() ))
fullNameField.requestFocus(); fullNameField.requestFocus();

View File

@ -14,3 +14,4 @@ CMakeCache.txt
CMakeFiles CMakeFiles
Makefile Makefile
cmake_install.cmake cmake_install.cmake
install_manifest.txt

View File

@ -1,5 +1,5 @@
### CMAKE ### CMAKE
project( mpw C ) project( masterpassword-cli C )
cmake_minimum_required( VERSION 3.0.2 ) cmake_minimum_required( VERSION 3.0.2 )
@ -39,8 +39,8 @@ endif()
### DEPENDENCIES ### DEPENDENCIES
function( use_mpw_sodium t r ) function( use_mpw_sodium t r )
if( USE_SODIUM ) if( USE_SODIUM )
target_link_libraries( "${t}" sodium ) target_link_libraries( "${t}" PRIVATE sodium )
target_compile_definitions( "${t}" PUBLIC -DMPW_SODIUM=1 ) target_compile_definitions( "${t}" PRIVATE -DMPW_SODIUM=1 )
message( STATUS "${t}: USE_SODIUM is enabled." ) message( STATUS "${t}: USE_SODIUM is enabled." )
elseif( r STREQUAL "required" ) elseif( r STREQUAL "required" )
@ -56,9 +56,9 @@ function( use_mpw_color t )
find_package( Curses ) find_package( Curses )
if( USE_COLOR ) if( USE_COLOR )
if ( CURSES_FOUND ) if ( CURSES_FOUND )
target_include_directories( "${t}" PUBLIC ${CURSES_INCLUDE_DIR} ) target_include_directories( "${t}" PRIVATE ${CURSES_INCLUDE_DIR} )
target_link_libraries( "${t}" ${CURSES_LIBRARIES} ) target_link_libraries( "${t}" PRIVATE ${CURSES_LIBRARIES} )
target_compile_definitions( "${t}" PUBLIC -DMPW_COLOR=1 ${CURSES_DEFINITIONS} ) target_compile_definitions( "${t}" PRIVATE -DMPW_COLOR=1 ${CURSES_DEFINITIONS} )
message( STATUS "${t}: USE_COLOR is enabled." ) message( STATUS "${t}: USE_COLOR is enabled." )
elseif( r STREQUAL "required" ) elseif( r STREQUAL "required" )
@ -80,8 +80,8 @@ endfunction()
function( use_mpw_json t ) function( use_mpw_json t )
if( USE_JSON ) if( USE_JSON )
target_link_libraries( "${t}" json-c ) target_link_libraries( "${t}" PRIVATE json-c )
target_compile_definitions( "${t}" PUBLIC -DMPW_JSON=1 ) target_compile_definitions( "${t}" PRIVATE -DMPW_JSON=1 )
message( STATUS "${t}: USE_JSON is enabled." ) message( STATUS "${t}: USE_JSON is enabled." )
elseif( r STREQUAL "required" ) elseif( r STREQUAL "required" )
@ -97,9 +97,9 @@ function( use_mpw_xml t r )
find_package( LibXml2 ) find_package( LibXml2 )
if( USE_XML ) if( USE_XML )
if ( LIBXML2_FOUND ) if ( LIBXML2_FOUND )
target_include_directories( "${t}" PUBLIC ${LIBXML2_INCLUDE_DIR} ) target_include_directories( "${t}" PRIVATE ${LIBXML2_INCLUDE_DIR} )
target_link_libraries( "${t}" ${LIBXML2_LIBRARIES} ) target_link_libraries( "${t}" PRIVATE ${LIBXML2_LIBRARIES} )
target_compile_definitions( "${t}" PUBLIC -DMPW_XML=1 ${LIBXML2_DEFINITIONS} ) target_compile_definitions( "${t}" PRIVATE -DMPW_XML=1 ${LIBXML2_DEFINITIONS} )
message( STATUS "${t}: USE_XML is enabled." ) message( STATUS "${t}: USE_XML is enabled." )
elseif( r STREQUAL "required" ) elseif( r STREQUAL "required" )

View File

@ -21,6 +21,7 @@ artifacts {
} }
library { library {
baseName.set( "mpw" )
linkage.set( [ Linkage.SHARED ] ) linkage.set( [ Linkage.SHARED ] )
// Reconfigure the toolchain from C++ to C. // Reconfigure the toolchain from C++ to C.

View File

@ -6,10 +6,21 @@
// TODO: We may need to zero the jbytes safely. // TODO: We may need to zero the jbytes safely.
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
if ((*vm)->GetEnv( vm, (void **)&env, JNI_VERSION_1_6 ) != JNI_OK)
return -1;
return JNI_VERSION_1_6;
}
/* native int _masterKey(final String fullName, final byte[] masterPassword, final Version version) */ /* native int _masterKey(final String fullName, final byte[] masterPassword, final Version version) */
JNIEXPORT jbyteArray JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1masterKey(JNIEnv *env, jobject obj, JNIEXPORT jbyteArray JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1masterKey(JNIEnv *env, jobject obj,
jstring fullName, jbyteArray masterPassword, jint algorithmVersion) { jstring fullName, jbyteArray masterPassword, jint algorithmVersion) {
if (!fullName || !masterPassword)
return NULL;
const char *fullNameString = (*env)->GetStringUTFChars( env, fullName, NULL ); const char *fullNameString = (*env)->GetStringUTFChars( env, fullName, NULL );
jbyte *masterPasswordString = (*env)->GetByteArrayElements( env, masterPassword, NULL ); jbyte *masterPasswordString = (*env)->GetByteArrayElements( env, masterPassword, NULL );
@ -32,6 +43,9 @@ JNIEXPORT jbyteArray JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__
JNIEXPORT jbyteArray JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1siteKey(JNIEnv *env, jobject obj, JNIEXPORT jbyteArray JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1siteKey(JNIEnv *env, jobject obj,
jbyteArray masterKey, jstring siteName, jlong siteCounter, jint keyPurpose, jstring keyContext, jint algorithmVersion) { jbyteArray masterKey, jstring siteName, jlong siteCounter, jint keyPurpose, jstring keyContext, jint algorithmVersion) {
if (!masterKey || !siteName)
return NULL;
jbyte *masterKeyBytes = (*env)->GetByteArrayElements( env, masterKey, NULL ); jbyte *masterKeyBytes = (*env)->GetByteArrayElements( env, masterKey, NULL );
const char *siteNameString = (*env)->GetStringUTFChars( env, siteName, NULL ); const char *siteNameString = (*env)->GetStringUTFChars( env, siteName, NULL );
const char *keyContextString = keyContext? (*env)->GetStringUTFChars( env, keyContext, NULL ): NULL; const char *keyContextString = keyContext? (*env)->GetStringUTFChars( env, keyContext, NULL ): NULL;
@ -40,6 +54,7 @@ JNIEXPORT jbyteArray JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__
(MPKeyPurpose)keyPurpose, keyContextString, (MPAlgorithmVersion)algorithmVersion ); (MPKeyPurpose)keyPurpose, keyContextString, (MPAlgorithmVersion)algorithmVersion );
(*env)->ReleaseByteArrayElements( env, masterKey, masterKeyBytes, JNI_ABORT ); (*env)->ReleaseByteArrayElements( env, masterKey, masterKeyBytes, JNI_ABORT );
(*env)->ReleaseStringUTFChars( env, siteName, siteNameString ); (*env)->ReleaseStringUTFChars( env, siteName, siteNameString );
if (keyContext)
(*env)->ReleaseStringUTFChars( env, keyContext, keyContextString ); (*env)->ReleaseStringUTFChars( env, keyContext, keyContextString );
if (!siteKeyBytes) if (!siteKeyBytes)
@ -59,6 +74,9 @@ JNIEXPORT jstring JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1si
jbyteArray masterKey, jbyteArray siteKey, jstring siteName, jlong siteCounter, jint keyPurpose, jstring keyContext, jbyteArray masterKey, jbyteArray siteKey, jstring siteName, jlong siteCounter, jint keyPurpose, jstring keyContext,
jint resultType, jstring resultParam, jint algorithmVersion) { jint resultType, jstring resultParam, jint algorithmVersion) {
if (!masterKey || !siteKey || !siteName)
return NULL;
jbyte *masterKeyBytes = (*env)->GetByteArrayElements( env, masterKey, NULL ); jbyte *masterKeyBytes = (*env)->GetByteArrayElements( env, masterKey, NULL );
jbyte *siteKeyBytes = (*env)->GetByteArrayElements( env, siteKey, NULL ); jbyte *siteKeyBytes = (*env)->GetByteArrayElements( env, siteKey, NULL );
const char *siteNameString = (*env)->GetStringUTFChars( env, siteName, NULL ); const char *siteNameString = (*env)->GetStringUTFChars( env, siteName, NULL );
@ -70,7 +88,9 @@ JNIEXPORT jstring JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1si
(*env)->ReleaseByteArrayElements( env, masterKey, masterKeyBytes, JNI_ABORT ); (*env)->ReleaseByteArrayElements( env, masterKey, masterKeyBytes, JNI_ABORT );
(*env)->ReleaseByteArrayElements( env, siteKey, siteKeyBytes, JNI_ABORT ); (*env)->ReleaseByteArrayElements( env, siteKey, siteKeyBytes, JNI_ABORT );
(*env)->ReleaseStringUTFChars( env, siteName, siteNameString ); (*env)->ReleaseStringUTFChars( env, siteName, siteNameString );
if (keyContext)
(*env)->ReleaseStringUTFChars( env, keyContext, keyContextString ); (*env)->ReleaseStringUTFChars( env, keyContext, keyContextString );
if (resultParam)
(*env)->ReleaseStringUTFChars( env, resultParam, resultParamString ); (*env)->ReleaseStringUTFChars( env, resultParam, resultParamString );
if (!siteResultString) if (!siteResultString)
@ -89,6 +109,9 @@ JNIEXPORT jstring JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1si
jbyteArray masterKey, jbyteArray siteKey, jstring siteName, jlong siteCounter, jint keyPurpose, jstring keyContext, jbyteArray masterKey, jbyteArray siteKey, jstring siteName, jlong siteCounter, jint keyPurpose, jstring keyContext,
jint resultType, jstring resultParam, jint algorithmVersion) { jint resultType, jstring resultParam, jint algorithmVersion) {
if (!masterKey || !siteKey || !siteName || !resultParam)
return NULL;
jbyte *masterKeyBytes = (*env)->GetByteArrayElements( env, masterKey, NULL ); jbyte *masterKeyBytes = (*env)->GetByteArrayElements( env, masterKey, NULL );
jbyte *siteKeyBytes = (*env)->GetByteArrayElements( env, siteKey, NULL ); jbyte *siteKeyBytes = (*env)->GetByteArrayElements( env, siteKey, NULL );
const char *siteNameString = (*env)->GetStringUTFChars( env, siteName, NULL ); const char *siteNameString = (*env)->GetStringUTFChars( env, siteName, NULL );
@ -100,7 +123,9 @@ JNIEXPORT jstring JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1si
(*env)->ReleaseByteArrayElements( env, masterKey, masterKeyBytes, JNI_ABORT ); (*env)->ReleaseByteArrayElements( env, masterKey, masterKeyBytes, JNI_ABORT );
(*env)->ReleaseByteArrayElements( env, siteKey, siteKeyBytes, JNI_ABORT ); (*env)->ReleaseByteArrayElements( env, siteKey, siteKeyBytes, JNI_ABORT );
(*env)->ReleaseStringUTFChars( env, siteName, siteNameString ); (*env)->ReleaseStringUTFChars( env, siteName, siteNameString );
if (keyContextString)
(*env)->ReleaseStringUTFChars( env, keyContext, keyContextString ); (*env)->ReleaseStringUTFChars( env, keyContext, keyContextString );
if (resultParam)
(*env)->ReleaseStringUTFChars( env, resultParam, resultParamString ); (*env)->ReleaseStringUTFChars( env, resultParam, resultParamString );
if (!siteStateString) if (!siteStateString)

View File

@ -95,7 +95,7 @@ bool mpw_get_json_boolean(
if (!json_value) if (!json_value)
return defaultValue; return defaultValue;
return json_object_get_boolean( json_value ) == TRUE; return json_object_get_boolean( json_value ) == true;
} }
#endif #endif

View File

@ -42,7 +42,7 @@ public class MPAlgorithmV0 extends MPAlgorithm {
protected static final int AES_BLOCKSIZE = 128 /* bit */; protected static final int AES_BLOCKSIZE = 128 /* bit */;
static { static {
Native.load( MPAlgorithmV0.class, "masterpassword-core" ); Native.load( MPAlgorithmV0.class, "mpw" );
} }
public final Version version = MPAlgorithm.Version.V0; public final Version version = MPAlgorithm.Version.V0;

View File

@ -40,8 +40,16 @@ public final class Native {
@SuppressWarnings({ "HardcodedFileSeparator", "LoadLibraryWithNonConstantString" }) @SuppressWarnings({ "HardcodedFileSeparator", "LoadLibraryWithNonConstantString" })
public static void load(final Class<?> context, final String name) { public static void load(final Class<?> context, final String name) {
// Try to load the library using the native system.
try {
System.loadLibrary( name );
return;
} catch (@SuppressWarnings("ErrorNotRethrown") final UnsatisfiedLinkError ignored) {
}
// Try to find and open a stream to the packaged library resource.
try { try {
// Find and open a stream to the packaged library resource.
String library = System.mapLibraryName( name ); String library = System.mapLibraryName( name );
int libraryDot = library.lastIndexOf( EXTENSION_SEPARATOR ); int libraryDot = library.lastIndexOf( EXTENSION_SEPARATOR );
String libraryName = (libraryDot > 0)? library.substring( 0, libraryDot ): library; String libraryName = (libraryDot > 0)? library.substring( 0, libraryDot ): library;

@ -1 +1 @@
Subproject commit 6cde8d9db84310abba0ec5f278862466a51e6a96 Subproject commit 979398a3259773344412d5d3cf8ef56afc0023ef