-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ArrayIndexOutOfBoundsException with JNA 4.3.0 #763
Comments
The change in 50eb820 introduces the detection of the count of the fixed parameters of a VarArgs call. The logic detecting whether this call was even a VarArgs call was changed to be true if fixed parameter count is not null. This is not correct, as the method call could contain only fixed parameters or a VarArgs call could be done without fixed parameters. Closes: java-native-access#763
The change in 50eb820 introduces the detection of the count of the fixed parameters of a VarArgs call. The logic detecting whether this call was even a VarArgs call was changed to be true if fixed parameter count is not null. This is not correct, as the method call could contain only fixed parameters or a VarArgs call could be done without fixed parameters. Closes: java-native-access#763
@neilcsmith-net this is reproducible without any external calls. I added a unittest to catch this (see referenced commit). With a JNA build with this applied (and the calls to context.getTargetType() "fixed" by casting to raw Class) unittests of gstreamer-1.x core run cleanly. @twall Could you please have a look at this and see if you agree with my fix? |
Why would you have a varargs function that takes no arguments? You can't even write that in C; the first argument gives you the starting stack pointer as well as indicating what arguments to expect on the stack. |
Well, the signature of the method causing the problem is
This has worked in every version of JNA up until 4.3.0 |
The target case is not providing zero arguments - the case is providing arguments to a pure varargs call on the java side. I think looking at the concrete example will help: gboolean gst_element_link_many (GstElement *element_1,
GstElement *element_2, ...) G_GNUC_NULL_TERMINATED; I read this as: you need to supply gst_element_link_many with at least two elements, but potentially an unlimited number. So the correct binding would have been (my interpretation): boolean gst_element_link_many(Element element1, Element elemente2, Element... elements); and the binder concluded, that looks stupid, if you have an array of Element[] and want to link these. Why would you single out the first and second element. This is also the reason for the unittest, that I added: the first element of that test indeed needs to be present (yes I really need to really learn C), but the signature from the java perspective is more convenient. |
I see. I wrote the argument expansion from the C perspective, not the Java one. The problem is that when you write I'm not particularly bothered by the fix, though. You could put in a check to ensure that there's at least one parameter, to meet the C requirements, but that still wouldn't help incorrect use in the example provided. LGTM. |
@twall thanks! While I agree with your point that the signature should match the requirements, this particular mapping has not changed since Wayne Meissner first wrote the GStreamer 0.10 bindings in 2007/8. So, if not strictly valid, it has at least been supported by every JNA version in the last decade. Assuming this fix gets in, I'll still consider whether it's better we change the mappings we have (there's more than just this one!). However, @matthiasblaesing makes a good point that doing this in Java forces an array copy which we currently don't need - it's definitely more convenient on the Java side to keep the old behaviour. |
I confirmed the PR and merged it into master. Whether or not the signature should be changed in GStreamer-Java should be discussed there. But the argument, that it worked for the past and no bugs were raised for this, holds for me, so I would not change the gstreamer-java side right now. |
Thanks! Agree that the signature change discussion goes back to us, and am inclined not to, assuming that fixing this implies that this will remain a supported mapping in JNA for the foreseeable future? ie. any decision we make is influenced by whether this should be considered building on shaky ground. 😄 |
I added a unittest that covers the "full varargs" case, so my answer at this point in time: Yes it will stay. |
With the GStreamer 1.x bindings I'm getting multiple ArrayIndexOutOfBoundsExceptions. I think they all involve varargs methods without any other parameters. The vararg type is custom type-mapped.
Stack trace is below. We've inherited an InvocationHandler that sits before Library$Handler.invoke(), though not caused an issue before, and not actually doing anything in this case.
The text was updated successfully, but these errors were encountered: