From: stephan Date: Thu, 17 Aug 2023 13:13:22 +0000 (+0000) Subject: Tighten up the JNI auto-ext handling. X-Git-Tag: version-3.44.0~305^2~26 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6c5f96fc4df5c92a3ba109b999ff3c6422e88b05;p=thirdparty%2Fsqlite.git Tighten up the JNI auto-ext handling. FossilOrigin-Name: c09c8d05a20d916a9d9304eeea723ef7666a862a9e53f5feeeb1b03f9153d4b2 --- diff --git a/ext/jni/src/c/sqlite3-jni.c b/ext/jni/src/c/sqlite3-jni.c index bfc885eb44..aafb99efe5 100644 --- a/ext/jni/src/c/sqlite3-jni.c +++ b/ext/jni/src/c/sqlite3-jni.c @@ -1236,13 +1236,19 @@ static void S3JniAutoExtension_clear(JNIEnv * const env, /** Initializes a pre-allocated S3JniAutoExtension object. Returns non-0 if there is an error collecting the required state from - jAutoExt (which must be an AutoExtension object). + jAutoExt (which must be an AutoExtension object). On error, it + passes ax to S3JniAutoExtension_clear(). */ static int S3JniAutoExtension_init(JNIEnv *const env, S3JniAutoExtension * const ax, jobject const jAutoExt){ jclass klazz; klazz = (*env)->GetObjectClass(env, jAutoExt); + IFTHREW{ + EXCEPTION_REPORT; + EXCEPTION_CLEAR; + assert(!klazz); + } if(!klazz){ S3JniAutoExtension_clear(env, ax); return SQLITE_ERROR; @@ -1876,7 +1882,7 @@ static int s3jni_run_java_auto_extensions(sqlite3 *pDb, const char **pzErr, for( i = 0; go && 0==rc; ++i ){ S3JniAutoExtension const * ax; MUTEX_EXT_ENTER; - if( i >= S3JniGlobal.autoExt.nAlloc ){ + if( i >= S3JniGlobal.autoExt.nExt ){ ax = 0; go = 0; }else{ @@ -1893,7 +1899,7 @@ static int s3jni_run_java_auto_extensions(sqlite3 *pDb, const char **pzErr, UNREF_L(ex); *pzErr = sqlite3_mprintf("auto-extension threw: %s", zMsg); sqlite3_free(zMsg); - rc = rc ? rc : SQLITE_ERROR; + if( !rc ) rc = SQLITE_ERROR; } } } @@ -1905,25 +1911,20 @@ JDECL(jint,1auto_1extension)(JENV_CSELF, jobject jAutoExt){ int i; S3JniAutoExtension * ax; int rc = 0; - int firstEmptySlot = -1; if( !jAutoExt ) return SQLITE_MISUSE; MUTEX_EXT_ENTER; - for( i = 0; i < S3JniGlobal.autoExt.nAlloc; ++i ){ + for( i = 0; i < S3JniGlobal.autoExt.nExt; ++i ){ /* Look for match or first empty slot. */ ax = &S3JniGlobal.autoExt.pExt[i]; if( ax->jObj && (*env)->IsSameObject(env, ax->jObj, jAutoExt) ){ MUTEX_EXT_LEAVE; return 0 /* this as a no-op. */; - }else if( !ax->jObj && firstEmptySlot<0 ){ - firstEmptySlot = (int)i; } } - if(i == S3JniGlobal.autoExt.nAlloc ){ - if( firstEmptySlot >= 0 ){ - ax = &S3JniGlobal.autoExt.pExt[firstEmptySlot]; - rc = S3JniAutoExtension_init(env, ax, jAutoExt); - }else{ + if(i == S3JniGlobal.autoExt.nExt ){ + assert( S3JniGlobal.autoExt.nExt <= S3JniGlobal.autoExt.nAlloc ); + if( S3JniGlobal.autoExt.nExt == S3JniGlobal.autoExt.nAlloc ){ unsigned n = 1 + S3JniGlobal.autoExt.nAlloc; S3JniAutoExtension * const aNew = sqlite3_realloc( S3JniGlobal.autoExt.pExt, @@ -1932,17 +1933,25 @@ JDECL(jint,1auto_1extension)(JENV_CSELF, jobject jAutoExt){ rc = SQLITE_NOMEM; }else{ S3JniGlobal.autoExt.pExt = aNew; - ax = &S3JniGlobal.autoExt.pExt[S3JniGlobal.autoExt.nAlloc]; ++S3JniGlobal.autoExt.nAlloc; - rc = S3JniAutoExtension_init(env, ax, jAutoExt); - assert( rc ? 0==ax->jObj : 0!=ax->jObj ); } } + if( 0==rc ){ + ax = &S3JniGlobal.autoExt.pExt[S3JniGlobal.autoExt.nExt]; + rc = S3JniAutoExtension_init(env, ax, jAutoExt); + assert( rc ? 0==ax->jObj : 0!=ax->jObj ); + } } if( 0==rc ){ - ++S3JniGlobal.autoExt.nExt; if( 0==once && ++once ){ - sqlite3_auto_extension( (void(*)(void))s3jni_run_java_auto_extensions ); + rc = sqlite3_auto_extension( (void(*)(void))s3jni_run_java_auto_extensions ); + if( rc ){ + assert( ax ); + S3JniAutoExtension_clear(env, ax); + } + } + if( 0==rc ){ + ++S3JniGlobal.autoExt.nExt; } } MUTEX_EXT_LEAVE; @@ -2077,15 +2086,16 @@ JDECL(jboolean,1cancel_1auto_1extension)(JENV_CSELF, jobject jAutoExt){ int i; MUTEX_EXT_ENTER; /* This algo mirrors the one in the core. */ - for( i = S3JniGlobal.autoExt.nAlloc-1; i >= 0; --i ){ + for( i = S3JniGlobal.autoExt.nExt-1; i >= 0; --i ){ ax = &S3JniGlobal.autoExt.pExt[i]; if( ax->jObj && (*env)->IsSameObject(env, ax->jObj, jAutoExt) ){ S3JniAutoExtension_clear(env, ax); /* Move final entry into this slot. */ - *ax = S3JniGlobal.autoExt.pExt[S3JniGlobal.autoExt.nAlloc - 1]; - memset(&S3JniGlobal.autoExt.pExt[S3JniGlobal.autoExt.nAlloc - 1], 0, - sizeof(S3JniAutoExtension)); --S3JniGlobal.autoExt.nExt; + *ax = S3JniGlobal.autoExt.pExt[S3JniGlobal.autoExt.nExt]; + memset(&S3JniGlobal.autoExt.pExt[S3JniGlobal.autoExt.nExt], 0, + sizeof(S3JniAutoExtension)); + assert(! S3JniGlobal.autoExt.pExt[S3JniGlobal.autoExt.nExt].jObj ); rc = JNI_TRUE; break; } @@ -2868,7 +2878,7 @@ JDECL(jint,1reset)(JENV_CSELF, jobject jpStmt){ static void s3jni_reset_auto_extension(JNIEnv *env){ int i; MUTEX_EXT_ENTER; - for( i = 0; i < S3JniGlobal.autoExt.nAlloc; ++i ){ + for( i = 0; i < S3JniGlobal.autoExt.nExt; ++i ){ S3JniAutoExtension_clear( env, &S3JniGlobal.autoExt.pExt[i] ); } S3JniGlobal.autoExt.nExt = 0; diff --git a/ext/jni/src/org/sqlite/jni/Tester1.java b/ext/jni/src/org/sqlite/jni/Tester1.java index d5ae0c44e5..f6ca7a8547 100644 --- a/ext/jni/src/org/sqlite/jni/Tester1.java +++ b/ext/jni/src/org/sqlite/jni/Tester1.java @@ -1112,7 +1112,43 @@ public class Tester1 { } affirm( err!=null ); affirm( err.getMessage().indexOf(toss.value)>0 ); + toss.value = null; + + val.value = 0; + final AutoExtension ax2 = new AutoExtension(){ + public synchronized int xEntryPoint(sqlite3 db){ + ++val.value; + return 0; + } + }; + rc = sqlite3_auto_extension( ax2 ); + affirm( 0 == rc ); + sqlite3_close(createNewDb()); + affirm( 2 == val.value ); affirm( sqlite3_cancel_auto_extension(ax) ); + affirm( !sqlite3_cancel_auto_extension(ax) ); + sqlite3_close(createNewDb()); + affirm( 3 == val.value ); + rc = sqlite3_auto_extension( ax ); + affirm( 0 == rc ); + sqlite3_close(createNewDb()); + affirm( 5 == val.value ); + affirm( sqlite3_cancel_auto_extension(ax2) ); + affirm( !sqlite3_cancel_auto_extension(ax2) ); + sqlite3_close(createNewDb()); + affirm( 6 == val.value ); + rc = sqlite3_auto_extension( ax2 ); + affirm( 0 == rc ); + sqlite3_close(createNewDb()); + affirm( 8 == val.value ); + + sqlite3_reset_auto_extension(); + sqlite3_close(createNewDb()); + affirm( 8 == val.value ); + affirm( !sqlite3_cancel_auto_extension(ax) ); + affirm( !sqlite3_cancel_auto_extension(ax2) ); + sqlite3_close(createNewDb()); + affirm( 8 == val.value ); } private static void testSleep(){ diff --git a/manifest b/manifest index c9a1ac5402..ba1b065e5c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sinternal\sJNI\scleanups\sand\sfixes. -D 2023-08-17T12:44:52.096 +C Tighten\sup\sthe\sJNI\sauto-ext\shandling. +D 2023-08-17T13:13:22.545 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -234,7 +234,7 @@ F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a3 F ext/jni/GNUmakefile a9e11b92e620058558cbc1a2d49f8ec53c78d6a989b9db0b7d0b649b9f174881 F ext/jni/README.md 7a614a2fa6c561205f7a53fd8626cf93a7b5711ff454fc1814517f796df398eb F ext/jni/jar-dist.make f90a553203a57934bf275bed86479485135a52f48ac5c1cfe6499ae07b0b35a4 -F ext/jni/src/c/sqlite3-jni.c 4af91793e92f5d195c8668cf323ca7dfd25549efa9dfc6a0344020da3c42cb4b +F ext/jni/src/c/sqlite3-jni.c d13cceb21d449d479a7772ad004eeb3a659eebc2759ad22284a7ee6a0a4a9f62 F ext/jni/src/c/sqlite3-jni.h f10d2f38720687c70ecdd5e44f6e8db98efee2caa05fc86b2d9e0c76e6cc0a18 F ext/jni/src/org/sqlite/jni/Authorizer.java 1308988f7f40579ea0e4deeaec3c6be971630566bd021c31367fe3f5140db892 F ext/jni/src/org/sqlite/jni/AutoExtension.java 18e83f6f463e306df60b2dceb65247d32af1f78af4bbbae9155411a8c6cdb093 @@ -255,7 +255,7 @@ F ext/jni/src/org/sqlite/jni/ResultCode.java ba701f20213a5f259e94cfbfdd36eb7ac7c F ext/jni/src/org/sqlite/jni/RollbackHook.java b04c8abcc6ade44a8a57129e33765793f69df0ba909e49ba18d73f4268d92564 F ext/jni/src/org/sqlite/jni/SQLFunction.java 09ce81c1c637e31c3a830d4c859cce95d65f5e02ff45f8bd1985b3479381bc46 F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 99334f54f5f41feb4c14dc988b93219e37799e032f2bc07bda6323b1dfb99e75 -F ext/jni/src/org/sqlite/jni/Tester1.java f2f8fa157ddc42f91b6102d7ed78d1045d5072ae702bcefd868984518c97f9ae +F ext/jni/src/org/sqlite/jni/Tester1.java 68b88b3098ce60134f4298488f890871398a77477af0a1b21797c59c911060c1 F ext/jni/src/org/sqlite/jni/TesterFts5.java 59e22dd24af033ea8827d36225a2f3297908fb6af8818ead8850c6c6847557b1 F ext/jni/src/org/sqlite/jni/Tracer.java a5cece9f947b0af27669b8baec300b6dd7ff859c3e6a6e4a1bd8b50f9714775d F ext/jni/src/org/sqlite/jni/UpdateHook.java e58645a1727f8a9bbe72dc072ec5b40d9f9362cb0aa24acfe93f49ff56a9016d @@ -2091,8 +2091,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 154ab26dc6ba2d1fd976e8fe6dc1b1a06c734f7e9a276a3edc5c2f30b0d6d36a -R b13f61ed94c6ec470e8a131c5363f0b3 +P 0e9437de026cbfb333b90bb3400f1c015f85d49d73a25ad1000623216b88bfa0 +R 9c230dc36749890d5273d4c55c46fd59 U stephan -Z c23fb72e5b16d04504744e0f8c1cbcfd +Z d4ea42705a0c21f8fa4c587cb8cbbc10 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5a48967def..d5ad50128f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0e9437de026cbfb333b90bb3400f1c015f85d49d73a25ad1000623216b88bfa0 \ No newline at end of file +c09c8d05a20d916a9d9304eeea723ef7666a862a9e53f5feeeb1b03f9153d4b2 \ No newline at end of file