Author: amiloslavskiy Date: Thu Oct 15 10:18:28 2020 New Revision: 1882525 URL: http://svn.apache.org/viewvc?rev=1882525&view=rev Log: JavaHL: Fix crash when TunnelAgent.openTunnel() throws exception
See the previous commit for explanation why cleanup is important. The problem occurs because when 'OperationContext::openTunnel()' returns an error, SVN considers it as not constructed and will not clean it up. This crash is demonstrated by the following JavaHL test: * testCrash_RequestChannel_nativeRead_AfterException [in subversion/bindings/javahl] * native/OperationContext.cpp Clean up after exception in 'TunnelAgent.openTunnel()' Modified: subversion/branches/javahl-1.14-fixes/subversion/bindings/javahl/native/OperationContext.cpp Modified: subversion/branches/javahl-1.14-fixes/subversion/bindings/javahl/native/OperationContext.cpp URL: http://svn.apache.org/viewvc/subversion/branches/javahl-1.14-fixes/subversion/bindings/javahl/native/OperationContext.cpp?rev=1882525&r1=1882524&r2=1882525&view=diff ============================================================================== --- subversion/branches/javahl-1.14-fixes/subversion/bindings/javahl/native/OperationContext.cpp (original) +++ subversion/branches/javahl-1.14-fixes/subversion/bindings/javahl/native/OperationContext.cpp Thu Oct 15 10:18:28 2020 @@ -648,11 +648,20 @@ OperationContext::openTunnel(svn_stream_ } jobject jtunnelcb = jobject(tunnel_baton); - SVN_JNI_CATCH( - tc->jclosecb = env->CallObjectMethod( - jtunnelcb, mid, tc->jrequest, tc->jresponse, - jtunnel_name, juser, jhostname, jint(port)), - SVN_ERR_BASE); + tc->jclosecb = env->CallObjectMethod( + jtunnelcb, mid, tc->jrequest, tc->jresponse, + jtunnel_name, juser, jhostname, jint(port)); + svn_error_t* openTunnelError = JNIUtil::checkJavaException(SVN_ERR_BASE); + if (SVN_NO_ERROR != openTunnelError) + { + // OperationContext::closeTunnel() will never be called, clean up here. + // This also prevents a JVM native crash, see comment in + // close_TunnelChannel(). + *close_baton = 0; + tc->jclosecb = 0; + OperationContext::closeTunnel(tc, 0); + SVN_ERR(openTunnelError); + } if (tc->jclosecb) {