Author: amiloslavskiy
Date: Thu Oct 15 10:17:19 2020
New Revision: 1882524

URL: http://svn.apache.org/viewvc?rev=1882524&view=rev
Log:
JavaHL: Make sure that TunnelAgent is cleaned up on pending exception

See the previous commit for explanation why cleanup is important.

Before this commit, if there was a pending Java exception (such as SVN
error), 'OperationContext::closeTunnel()' early-returned on
'isJavaExceptionThrown()'.

At the same time, calling Java methods in 'close_TunnelChannel()'
requires that there are no pending Java exceptions. Use
'StashException' to temporarily move it out of the way.

This crash is demonstrated by the following JavaHL tests:
* testCrash_RequestChannel_nativeRead_AfterException
* testCrash_RequestChannel_nativeRead_AfterSvnError

This commit alone does not fix all problems in these tests, see
previous and next commits as well.

[in subversion/bindings/javahl]
* native/OperationContext.cpp
  Use 'StashException' to move temporarily exception out of the way.

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=1882524&r1=1882523&r2=1882524&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:17:19 2020
@@ -691,19 +691,25 @@ OperationContext::closeTunnel(void *tunn
   delete tc;
 
   JNIEnv *env = JNIUtil::getEnv();
-  if (JNIUtil::isJavaExceptionThrown())
-    return;
+
+  // Cleanup is important, otherwise TunnelAgent may crash when
+  // accessing freed native objects. For this reason, cleanup is done
+  // despite a pending exception. If more exceptions occur, they are
+  // stashed as well in order to complete all cleanup steps.
+  StashException ex(env);
 
   if (jclosecb)
     callCloseTunnelCallback(env, jclosecb);
 
   if (jrequest)
     {
+      ex.stashException();
       close_TunnelChannel(env, jrequest);
     }
 
   if (jresponse)
     {
+      ex.stashException();
       close_TunnelChannel(env, jresponse);
     }
 }


Reply via email to