Skip to content

Commit 578220e

Browse files
fkistnermatthiasblaesing
authored andcommitted
Fix illegal access exceptions, when retrieving options for private library interfaces with an instance field
Since direct mapped classes may retrieve options for the first time, only when a callback is passed or returned, this could happen unexpectedly.
1 parent 3b47eff commit 578220e

5 files changed

Lines changed: 163 additions & 2 deletions

File tree

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Bug Fixes
2424
* [#1275](https://github.com/java-native-access/jna/issues/1275): Fix `CFStringRef#stringValue` for empty Strings - [@dyorgio](https://github.com/dyorgio).
2525
* [#1279](https://github.com/java-native-access/jna/issues/1279): Remove `DLLCallback` import from `CallbackReference` - [@dyorgio](https://github.com/dyorgio).
2626
* [#1278](https://github.com/java-native-access/jna/pull/1278): Improve compatibility of `c.s.j.p.WindowUtils#getProcessFilePath` and fix unittests for windows 32bit intel - [@matthiasblaesing](https://github.com/matthiasblaesing).
27+
* [#1284](https://github.com/java-native-access/jna/pull/1284): Fix illegal access exceptions, when retrieving options for private library interfaces with an instance field - [@fkistner](https://github.com/fkistner).
2728

2829
Release 5.6.0
2930
=============

build.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,7 +1256,7 @@ cd ..
12561256
</and>
12571257
</condition>
12581258
<property name="tests.platform" value=""/>
1259-
<property name="tests.include" value="com/sun/jna/*Test.java"/>
1259+
<property name="tests.include" value="com/sun/jna/*Test.java com/sun/jna/different_package/*Test.java"/>
12601260
<property name="tests.exclude" value=""/>
12611261
<property name="tests.exclude-patterns" value=""/>
12621262
<condition property="java.awt.headless" value="true">
@@ -1282,7 +1282,7 @@ cd ..
12821282
<formatter type="xml"/>
12831283
<batchtest todir="${results.junit}">
12841284
<fileset dir="${test.src}" excludes="${tests.exclude-patterns}">
1285-
<include name="${tests.include}"/>
1285+
<patternset includes="${tests.include}"/>
12861286
<include name="${tests.platform}"/>
12871287
<exclude name="${tests.exclude}"/>
12881288
</fileset>

src/com/sun/jna/Native.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ private static void loadLibraryInstance(Class<?> cls) {
664664
if (field.getType() == cls
665665
&& Modifier.isStatic(field.getModifiers())) {
666666
// Ensure the field gets initialized by reading it
667+
field.setAccessible(true); // interface might be private
667668
libraries.put(cls, new WeakReference<Object>(field.get(null)));
668669
break;
669670
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/* Copyright (c) 2020 Florian Kistner, All Rights Reserved
2+
*
3+
* The contents of this file is dual-licensed under 2
4+
* alternative Open Source/Free licenses: LGPL 2.1 or later and
5+
* Apache License 2.0. (starting with JNA version 4.0.0).
6+
*
7+
* You can freely decide which license you want to apply to
8+
* the project.
9+
*
10+
* You may obtain a copy of the LGPL License at:
11+
*
12+
* http://www.gnu.org/licenses/licenses.html
13+
*
14+
* A copy is also included in the downloadable source code package
15+
* containing JNA, in file "LGPL2.1".
16+
*
17+
* You may obtain a copy of the Apache License at:
18+
*
19+
* http://www.apache.org/licenses/
20+
*
21+
* A copy is also included in the downloadable source code package
22+
* containing JNA, in file "AL2.0".
23+
*/
24+
package com.sun.jna.different_package;
25+
26+
import com.sun.jna.*;
27+
import junit.framework.TestCase;
28+
29+
public class PrivateDirectCallbacksTest extends TestCase {
30+
private interface PrivateWithCallbackArgumentTestLibrary extends Library {
31+
PrivateWithCallbackArgumentTestLibrary INSTANCE = new DirectPrivateWithCallbackArgumentTestLibrary();
32+
33+
interface VoidCallback extends Callback {
34+
void callback();
35+
}
36+
37+
void callVoidCallback(VoidCallback c);
38+
}
39+
40+
private static class DirectPrivateWithCallbackArgumentTestLibrary implements PrivateWithCallbackArgumentTestLibrary {
41+
@Override
42+
public native void callVoidCallback(VoidCallback c);
43+
44+
static {
45+
Native.register("testlib");
46+
}
47+
}
48+
49+
public void testCallVoidCallback() {
50+
final boolean[] called = {false};
51+
PrivateWithCallbackArgumentTestLibrary.VoidCallback cb = new PrivateWithCallbackArgumentTestLibrary.VoidCallback() {
52+
@Override
53+
public void callback() {
54+
called[0] = true;
55+
}
56+
};
57+
PrivateWithCallbackArgumentTestLibrary.INSTANCE.callVoidCallback(cb);
58+
assertTrue("Callback not called", called[0]);
59+
}
60+
61+
private interface PrivateWithCallbackReturnTestLibrary extends Library {
62+
PrivateWithCallbackReturnTestLibrary INSTANCE = new DirectPrivateWithCallbackReturnTestLibrary();
63+
64+
interface Int32CallbackX extends Callback {
65+
int callback(int arg);
66+
}
67+
68+
Int32CallbackX returnCallback();
69+
70+
Int32CallbackX returnCallbackArgument(Int32CallbackX cb);
71+
}
72+
73+
private static class DirectPrivateWithCallbackReturnTestLibrary implements PrivateWithCallbackReturnTestLibrary {
74+
@Override
75+
public native Int32CallbackX returnCallback();
76+
77+
@Override
78+
public native Int32CallbackX returnCallbackArgument(Int32CallbackX cb);
79+
80+
static {
81+
Native.register("testlib");
82+
}
83+
}
84+
85+
public void testInvokeCallback() {
86+
PrivateWithCallbackReturnTestLibrary.Int32CallbackX cb = PrivateWithCallbackReturnTestLibrary.INSTANCE.returnCallback();
87+
assertNotNull("Callback should not be null", cb);
88+
assertEquals("Callback should be callable", 1, cb.callback(1));
89+
90+
PrivateWithCallbackReturnTestLibrary.Int32CallbackX cb2 = new PrivateWithCallbackReturnTestLibrary.Int32CallbackX() {
91+
@Override
92+
public int callback(int arg) {
93+
return 0;
94+
}
95+
};
96+
assertSame("Java callback should be looked up",
97+
cb2, PrivateWithCallbackReturnTestLibrary.INSTANCE.returnCallbackArgument(cb2));
98+
assertSame("Existing native function wrapper should be reused",
99+
cb, PrivateWithCallbackReturnTestLibrary.INSTANCE.returnCallbackArgument(cb));
100+
}
101+
102+
public static void main(java.lang.String[] argList) {
103+
junit.textui.TestRunner.run(PrivateDirectCallbacksTest.class);
104+
}
105+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* Copyright (c) 2020 Florian Kistner, All Rights Reserved
2+
*
3+
* The contents of this file is dual-licensed under 2
4+
* alternative Open Source/Free licenses: LGPL 2.1 or later and
5+
* Apache License 2.0. (starting with JNA version 4.0.0).
6+
*
7+
* You can freely decide which license you want to apply to
8+
* the project.
9+
*
10+
* You may obtain a copy of the LGPL License at:
11+
*
12+
* http://www.gnu.org/licenses/licenses.html
13+
*
14+
* A copy is also included in the downloadable source code package
15+
* containing JNA, in file "LGPL2.1".
16+
*
17+
* You may obtain a copy of the Apache License at:
18+
*
19+
* http://www.apache.org/licenses/
20+
*
21+
* A copy is also included in the downloadable source code package
22+
* containing JNA, in file "AL2.0".
23+
*/
24+
package com.sun.jna.different_package;
25+
26+
import com.sun.jna.Callback;
27+
import com.sun.jna.Library;
28+
import com.sun.jna.Native;
29+
import junit.framework.TestCase;
30+
31+
public class PrivateLibraryInfoTest extends TestCase {
32+
private interface TestLibrary extends Library {
33+
@SuppressWarnings("unused")
34+
TestLibrary INSTANCE = new TestLibrary() {
35+
};
36+
37+
interface VoidCallback extends Callback {
38+
void callback();
39+
}
40+
}
41+
42+
public void testLibraryInfo() {
43+
assertTrue(Native.getLibraryOptions(TestLibrary.class).containsKey(Library.OPTION_TYPE_MAPPER));
44+
}
45+
46+
public void testCallbackLibraryInfo() {
47+
TestLibrary.VoidCallback cb = new TestLibrary.VoidCallback() {
48+
@Override
49+
public void callback() {
50+
}
51+
};
52+
assertTrue(Native.getLibraryOptions(cb.getClass()).containsKey(Library.OPTION_TYPE_MAPPER));
53+
}
54+
}

0 commit comments

Comments
 (0)