Skip to content

Commit

Permalink
Merge pull request #1047 from matthiasblaesing/github-1044
Browse files Browse the repository at this point in the history
[GITHUB-1044] Invalid field order on XResizeRequestEvent
  • Loading branch information
matthiasblaesing authored Dec 21, 2018
2 parents 365f6b3 + 9c8b1e3 commit cae2be9
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 138 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Bug Fixes
* [#384](https://github.com/java-native-access/jna/issues/384): Android only supports loading libraries through the JVM `System#loadLibrary` mechanism, defaulting `jna.nosys` to `true` disabled that code path - [@matthiasblaesing](https://github.com/matthiasblaesing).
* [#1041](https://github.com/java-native-access/jna/pull/1041): Avoid IllegalArgumentException when reading xattrs with zero length - [@jrobhoward](https://github.com/jrobhoward).
* [#1042](https://github.com/java-native-access/jna/issues/1042): `com.sun.jna.platform.WindowUtils.W32WindowUtils.getProcessFilePath(HWND)` does not close process handle - [@matthiasblaesing](https://github.com/matthiasblaesing).
* [#1044](https://github.com/java-native-access/jna/issues/1044): `com.sun.jna.platform.WindowUtils.W32WindowUtils.getProcessFilePath(HWND)` does not close process handle - [@matthiasblaesing](https://github.com/matthiasblaesing).

Release 5.1.0
=============
Expand Down
3 changes: 1 addition & 2 deletions contrib/platform/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,7 @@ com.sun.jna.platform.wince;version=${osgi.version}
<batchtest todir="${results.junit}">
<fileset dir="${test.src.dir}" excludes="${tests.exclude-patterns}">
<!-- Until StructureFieldOrderTest gets fixed up a little -->
<exclude name="**/StructureFieldOrderTest.java"/>
<exclude name="com/sun/jna/platform/AbstractWin32TestSupport.java"/>
<include name="com/sun/jna/platform/*Test.java" />
<include name="${tests.platform.mac}"/>
<include name="${tests.platform.windows}"/>
<include name="${tests.platform.linux}"/>
Expand Down
5 changes: 1 addition & 4 deletions contrib/platform/src/com/sun/jna/platform/unix/X11.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
*/
package com.sun.jna.platform.unix;

import java.util.List;

import com.sun.jna.Callback;
import com.sun.jna.FromNativeContext;
import com.sun.jna.Library;
Expand Down Expand Up @@ -1473,7 +1471,6 @@ public static class XEvent extends Union {

@FieldOrder({"type", "serial", "send_event", "display", "window"})
public static class XAnyEvent extends Structure {
public static final List<String> FIELDS = createFieldsOrder();
public int type;
public NativeLong serial; // # of last request processed by server
public int send_event; // true if this came from a SendEvent request
Expand Down Expand Up @@ -1752,7 +1749,7 @@ class XGravityEvent extends Structure {
public int x, y;
}

@FieldOrder({"type", "serial", "send_event", "display", "parent", "window", "x", "y", "width", "height", "border_width", "above", "detail", "value_mask"})
@FieldOrder({"type", "serial", "send_event", "display", "window", "width", "height"})
class XResizeRequestEvent extends Structure {
public int type;
public NativeLong serial; // # of last request processed by server
Expand Down
3 changes: 1 addition & 2 deletions contrib/platform/src/com/sun/jna/platform/win32/Ddeml.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
import com.sun.jna.platform.win32.WinDef.PVOID;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
import java.util.List;
import static com.sun.jna.Structure.createFieldsOrder;
import com.sun.jna.platform.win32.WinDef.BOOL;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.DWORDByReference;
Expand Down Expand Up @@ -695,6 +693,7 @@ public class DDEML_MSG_HOOK_DATA extends Structure {
* that has blocked conversations should unblock them.
* </p>
*/
@SuppressWarnings("PointlessBitwiseExpression")
public int XTYP_ERROR = 0x0000 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK;
/**
* Informs the client that the value of the data item has changed. The
Expand Down
3 changes: 0 additions & 3 deletions contrib/platform/src/com/sun/jna/platform/win32/Sspi.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
*/
package com.sun.jna.platform.win32;

import java.util.List;

import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
Expand Down Expand Up @@ -666,7 +664,6 @@ public SecBufferDesc() {
*/
@FieldOrder({"dwLower", "dwUpper"})
public static class SECURITY_INTEGER extends Structure {
public static final List<String> FIELDS = createFieldsOrder();
public int dwLower;
public int dwUpper;
}
Expand Down
3 changes: 0 additions & 3 deletions contrib/platform/src/com/sun/jna/platform/win32/WinGDI.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
*/
package com.sun.jna.platform.win32;

import java.util.List;

import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
Expand Down Expand Up @@ -159,7 +157,6 @@ class ICONINFO extends Structure {

@FieldOrder({"bmType", "bmWidth", "bmHeight", "bmWidthBytes", "bmPlanes", "bmBitsPixel", "bmBits"})
class BITMAP extends Structure {
public static final List<String> FIELDS = createFieldsOrder();
public NativeLong bmType;
public NativeLong bmWidth;
public NativeLong bmHeight;
Expand Down
4 changes: 0 additions & 4 deletions contrib/platform/src/com/sun/jna/platform/win32/WinNT.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
*/
package com.sun.jna.platform.win32;

import java.util.Collections;
import java.util.List;

import com.sun.jna.FromNativeContext;
import com.sun.jna.IntegerType;
import com.sun.jna.Memory;
Expand Down Expand Up @@ -2940,7 +2937,6 @@ public interface LOGICAL_PROCESSOR_RELATIONSHIP {
*/
@FieldOrder({"level", "associativity", "lineSize", "size", "type"})
public static class CACHE_DESCRIPTOR extends Structure {
public static final List<String> FIELDS = createFieldsOrder();
/**
* The cache level. This member can be 1, 2 or 3, corresponding to L1, L2 or L3 cache, respectively (other
* values may be supported in the future.)
Expand Down

This file was deleted.

5 changes: 5 additions & 0 deletions contrib/platform/test/com/sun/jna/platform/unix/X11Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
package com.sun.jna.platform.unix;

import com.sun.jna.StructureFieldOrderInspector;
import java.awt.GraphicsEnvironment;

import com.sun.jna.ptr.PointerByReference;
Expand Down Expand Up @@ -104,6 +105,10 @@ public void testXGetWMProtocols() {
Assert.assertArrayEquals("Sent protocols were not equal to returned procols for XGetWMProtocols", sentAtoms, receivedAtoms);
}

public void testStructureFieldOrder() {
StructureFieldOrderInspector.batchCheckStructureGetFieldOrder(X11.class, null, true);
}

public static void main(java.lang.String[] argList) {
junit.textui.TestRunner.run(X11Test.class);
}
Expand Down
85 changes: 41 additions & 44 deletions test/com/sun/jna/StructureFieldOrderInspector.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

Expand All @@ -56,7 +58,21 @@ private StructureFieldOrderInspector(){}
*/
public static void batchCheckStructureGetFieldOrder(final Class<?> classDeclaredInSourceTreeToSearch,
final List<String> ignoreConstructorError) {
final Set<Class<? extends Structure>> classes = StructureFieldOrderInspector.findSubTypesOfStructure(classDeclaredInSourceTreeToSearch);
batchCheckStructureGetFieldOrder(classDeclaredInSourceTreeToSearch, ignoreConstructorError, false);
}

/**
* Search for Structure sub types in the source tree of the given class, and validate the getFieldOrder() method,
* and collects all errors into one exception.
*
* @param classDeclaredInSourceTreeToSearch a class who's source tree will be searched for Structure sub types.
* @param ignoreConstructorError list of classname prefixes for which to ignore construction errors.
* @param onlyInnerClasses limit scan to inner classes of the supplied class
*/
public static void batchCheckStructureGetFieldOrder(final Class<?> classDeclaredInSourceTreeToSearch,
final List<String> ignoreConstructorError,
final boolean onlyInnerClasses) {
final Set<Class<? extends Structure>> classes = StructureFieldOrderInspector.findSubTypesOfStructure(classDeclaredInSourceTreeToSearch, onlyInnerClasses);

final List<Throwable> problems = new ArrayList<Throwable>();

Expand Down Expand Up @@ -96,7 +112,7 @@ public static void checkStructureGetFieldOrder(final Class<?> classDeclaredInSou
/**
* Find all classes that extend {@link Structure}.
*/
public static Set<Class<? extends Structure>> findSubTypesOfStructure(final Class<?> classDeclaredInSourceTreeToSearch) {
public static Set<Class<? extends Structure>> findSubTypesOfStructure(final Class<?> classDeclaredInSourceTreeToSearch, boolean onlyInnerClasses) {

// use: http://code.google.com/p/reflections/

Expand All @@ -105,9 +121,24 @@ public static Set<Class<? extends Structure>> findSubTypesOfStructure(final Clas
.setUrls(ClasspathHelper.forClass(classDeclaredInSourceTreeToSearch))
);

return reflections.getSubTypesOf(Structure.class);
Set<Class<? extends Structure>> types = new HashSet<Class<? extends Structure>>(reflections.getSubTypesOf(Structure.class));
if(onlyInnerClasses) {
Iterator<Class<? extends Structure>> it = types.iterator();
while(it.hasNext()) {
if(! (it.next().getEnclosingClass() == classDeclaredInSourceTreeToSearch)) {
it.remove();
}
}
}
return types;
}

/**
* Find all classes that extend {@link Structure}.
*/
public static Set<Class<? extends Structure>> findSubTypesOfStructure(final Class<?> classDeclaredInSourceTreeToSearch) {
return findSubTypesOfStructure(classDeclaredInSourceTreeToSearch, false);
}

public static void checkMethodGetFieldOrder(final Class<? extends Structure> structureSubType,
final List<String> ignoreConstructorError) {
Expand All @@ -119,9 +150,6 @@ public static void checkMethodGetFieldOrder(final Class<? extends Structure> str
return;
}

final Method methodGetFieldOrder = getMethodGetFieldOrder(structureSubType);


if (Modifier.isAbstract(structureSubType.getModifiers())) {
// do not try to construct abstract Structure sub types
return;
Expand Down Expand Up @@ -161,58 +189,27 @@ public static void checkMethodGetFieldOrder(final Class<? extends Structure> str
throw new RuntimeException("Could not instantiate Structure sub type: " + structureSubType.getName(), e);
}

if (!methodGetFieldOrder.isAccessible()) {
methodGetFieldOrder.setAccessible(true);
}
final List<?> methodCallFieldList;
try {
methodCallFieldList = (List<?>) methodGetFieldOrder.invoke(structure);
} catch (IllegalAccessException e) {
throw new RuntimeException("Could not invoke getFieldOrder() on Structure sub type: " + structureSubType.getName(), e);
} catch (InvocationTargetException e) {
throw new RuntimeException("Could not invoke getFieldOrder() on Structure sub type: " + structureSubType.getName(), e);
}
final List<String> methodCallFieldOrder = structure.getFieldOrder();

final Field[] actualFields = structureSubType.getFields(); // include fields from super classes
final List<String> actualFieldNames = new ArrayList<String>(actualFields.length);
final List<Field> actualFields = structure.getFieldList();
final List<String> actualFieldNames = new ArrayList<String>(actualFields.size());
for (final Field field : actualFields) {
// ignore static fields
if (!Modifier.isStatic(field.getModifiers())) {
final String actualFieldName = field.getName();
if (!methodCallFieldList.contains(actualFieldName)) {
throw new IllegalArgumentException(structureSubType.getName() + ".getFieldOrder() [" + methodCallFieldList
if (!methodCallFieldOrder.contains(actualFieldName)) {
throw new IllegalArgumentException(structureSubType.getName() + ".getFieldOrder() [" + methodCallFieldOrder
+ "] does not include declared field: " + actualFieldName);
}
actualFieldNames.add(actualFieldName);
}
}

for (final Object methodCallField : methodCallFieldList) {
for (final String methodCallField : methodCallFieldOrder) {
if (!actualFieldNames.contains(methodCallField)) {
throw new IllegalArgumentException(structureSubType.getName() + ".getFieldOrder() [" + methodCallFieldList
throw new IllegalArgumentException(structureSubType.getName() + ".getFieldOrder() [" + methodCallFieldOrder
+ "] includes undeclared field: " + methodCallField);
}
}
}

/**
* Find the getFieldOrder() method in the given class, or any of it's parents.
* @param structureSubType a structure sub type
* @return the getFieldOrder() method found in the given class, or any of it's parents.
*/
private static Method getMethodGetFieldOrder(Class<? extends Structure> structureSubType) {
final Method methodGetFieldOrder;
try {
methodGetFieldOrder = structureSubType.getDeclaredMethod("getFieldOrder", new Class[]{});
} catch (NoSuchMethodException e) {
if (structureSubType.getSuperclass() != null) {
// look for method in parent
return getMethodGetFieldOrder((Class<? extends Structure>) structureSubType.getSuperclass());
}
throw new IllegalArgumentException("The Structure sub type: " + structureSubType.getName()
+ " must define the method: getFieldOrder()."
+ " See the javadoc for Structure.getFieldOrder() for details.", e);
}
return methodGetFieldOrder;
}
}

0 comments on commit cae2be9

Please sign in to comment.