JNI local reference table overflow BUG

android

#1

Hello,
Recently I found a bug in the JUCE JNI code in the method bool connect (WebInputStream::Listener* /*listener*/) from juce_android_Network.cpp:

The line that gets the java instance and create the GlobalReference is not deleting first the local reference:

bool connect (WebInputStream::Listener* /*listener*/)
//...
stream = GlobalRef (env->CallStaticObjectMethod (JuceAppActivity,
                                             JuceAppActivity.createHTTPStream,
                                             javaString (address).get(),
                                             (jboolean) isPost,
                                             postDataArray,
                                             javaString (headers).get(),
                                             (jint) timeOutMs,
                                             statusCodeArray,
                                             responseHeaderBuffer.get(),
                                             (jint) numRedirectsToFollow,
                                             javaString (httpRequest).get()));

When doing this the local reference returned by CallStaticObjectMethod is not deleted and if there are more than 512 HTTP requests it will cause an exception. To fix this issue delete the local reference as follows:

jobject obj = env->CallStaticObjectMethod (JuceAppActivity,
                                           JuceAppActivity.createHTTPStream,
                                           javaString (address).get(),
                                           (jboolean) isPost,
                                           postDataArray,
                                           javaString (headers).get(),
                                           (jint) timeOutMs,
                                           statusCodeArray,
                                           responseHeaderBuffer.get(),
                                           (jint) numRedirectsToFollow,
                                           javaString (httpRequest).get());
stream = GlobalRef (obj);
env->DeleteLocalRef (obj);

Could you fix it for the next releases?

Thanks!


#2

Is there some kind of static analyser that can automate finding these things? No doubt this isn’t the last case…


#3

I don’t think so… JNI could be quite painful :frowning:


#4

Thank you. The CallStaticObjectMethod should have been wrapped in a LocalRef<jobject>. However, to avoid such bugs in the future, I’m trying to re-factor some of the JNI stuff so that this kind of bug won’t be possible to write in the future.