]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add some notes about the JNI pointer-passing approach and convert a couple of potenti...
authorstephan <stephan@noemail.net>
Thu, 9 Nov 2023 12:48:54 +0000 (12:48 +0000)
committerstephan <stephan@noemail.net>
Thu, 9 Nov 2023 12:48:54 +0000 (12:48 +0000)
FossilOrigin-Name: 19c4778f45261006368b2d9460350fed1e55fed314c8b3e1af34cd8c3c73b7d8

ext/jni/src/c/sqlite3-jni.c
ext/jni/src/c/sqlite3-jni.h
ext/jni/src/org/sqlite/jni/annotation/NotNull.java
ext/jni/src/org/sqlite/jni/capi/CApi.java
manifest
manifest.uuid

index 9384fb9d21e591b1f3ad2feabf2f901c0e0c5fb3..fafb2ab5fd343951087b62f6af48dce397ccd7bd 100644 (file)
 **
 ** This use of intptr_t is the _only_ reason we require <stdint.h>
 ** which, in turn, requires building with -std=c99 (or later).
+**
+** See also: the notes for LongPtrGet_T.
 */
 #define S3JniCast_L2P(JLongAsPtr) (void*)((intptr_t)(JLongAsPtr))
 #define S3JniCast_P2L(PTR) (jlong)((intptr_t)(PTR))
@@ -1493,6 +1495,15 @@ static void * NativePointerHolder__get(JNIEnv * env, jobject jNph,
 ** the C side, because it's reportedly significantly faster. The
 ** intptr_t part here is necessary for compatibility with (at least)
 ** ARM32.
+**
+** 2023-11-09: testing has not revealed any measurable performance
+** difference between the approach of passing type T to C compared to
+** passing pointer-to-T to C, and adding support for the latter
+** everywhere requires sigificantly more code. As of this writing, the
+** older/simpler approach is being applied except for (A) where the
+** newer approach has already been applied and (B) hot-spot APIs where
+** a difference of microseconds (i.e. below our testing measurement
+** threshold) might add up.
 */
 #define LongPtrGet_T(T,JLongAsPtr) (T*)((intptr_t)(JLongAsPtr))
 #define LongPtrGet_sqlite3(JLongAsPtr) LongPtrGet_T(sqlite3,JLongAsPtr)
@@ -4674,9 +4685,9 @@ S3JniApi(sqlite3_sql(),jstring,1sql)(
 }
 
 S3JniApi(sqlite3_step(),jint,1step)(
-  JniArgsEnvClass,jobject jStmt
+  JniArgsEnvClass, jlong jpStmt
 ){
-  sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jStmt);
+  sqlite3_stmt * const pStmt = LongPtrGet_sqlite3_stmt(jpStmt);
   return pStmt ? (jint)sqlite3_step(pStmt) : (jint)SQLITE_MISUSE;
 }
 
index f160b6453f9502577c2b51f535f0586a9c44714f..e655a71f639dc1c29511e1d16fb2252e4d8c3ce0 100644 (file)
@@ -1872,10 +1872,10 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1status64
 /*
  * Class:     org_sqlite_jni_capi_CApi
  * Method:    sqlite3_step
- * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)I
+ * Signature: (J)I
  */
 JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1step
-  (JNIEnv *, jclass, jobject);
+  (JNIEnv *, jclass, jlong);
 
 /*
  * Class:     org_sqlite_jni_capi_CApi
index 3b4c1c7af1a7ddcc5f2b5dfc651c60a043a3c6ba..57639fa0d9e864fb5cc2ebb77472276680cad0d4 100644 (file)
@@ -18,12 +18,12 @@ package org.sqlite.jni.annotation;
    null or point to closed/finalized C-side resources.
 
    <p>In the case of Java types which map directly to C struct types
-   (e.g. {@link org.sqlite.jni.sqlite3}, {@link
-   org.sqlite.jni.sqlite3_stmt}, and {@link
-   org.sqlite.jni.sqlite3_context}), a closed/finalized resource is
-   also considered to be null for purposes this annotation because the
-   C-side effect of passing such a handle is the same as if null is
-   passed.</p>
+   (e.g. {@link org.sqlite.jni.capi.sqlite3}, {@link
+   org.sqlite.jni.capi.sqlite3_stmt}, and {@link
+   org.sqlite.jni.capi.sqlite3_context}), a closed/finalized resource
+   is also considered to be null for purposes this annotation because
+   the C-side effect of passing such a handle is the same as if null
+   is passed.</p>
 
    <p>When used in the context of Java interfaces which are called
    from the C APIs, this annotation communicates that the C API will
@@ -31,12 +31,23 @@ package org.sqlite.jni.annotation;
 
    <p>Passing a null, for this annotation's definition of null, for
    any parameter marked with this annoation specifically invokes
-   undefined behavior.</p>
+   undefined behavior (see below).</p>
 
    <p>Passing 0 (i.e. C NULL) or a negative value for any long-type
    parameter marked with this annoation specifically invokes undefined
-   behavior. Such values are treated as C pointers in the JNI
-   layer.</p>
+   behavior (see below). Such values are treated as C pointers in the
+   JNI layer.</p>
+
+   <p><b>Undefined behaviour:</b> the JNI build uses the {@code
+   SQLITE_ENABLE_API_ARMOR} build flag, meaning that the C code
+   invoked with invalid NULL pointers and the like will not invoke
+   undefined behavior in the conventional C sense, but may, for
+   example, return result codes which are not documented for the
+   affected APIs or may otherwise behave unpredictably. In no known
+   cases will such arguments result in C-level code dereferencing a
+   NULL pointer or accessing out-of-bounds (or otherwise invalid)
+   memory. In other words, they may cause unexpected behavior but
+   should never cause an outright crash or security issue.</p>
 
    <p>Note that the C-style API does not throw any exceptions on its
    own because it has a no-throw policy in order to retain its C-style
@@ -48,7 +59,7 @@ package org.sqlite.jni.annotation;
    code.</p>
 
    <p>This annotation is solely for the use by the classes in the
-   org.sqlite package and subpackages, but is made public so that
+   org.sqlite.jni package and subpackages, but is made public so that
    javadoc will link to it from the annotated functions. It is not
    part of the public API and client-level code must not rely on
    it.</p>
index 8e0cb8f4aa00f6af8b1b73d0c431dc87583e0404..c14772353d8a0cb9a76bec9343bac16e93e6a551 100644 (file)
@@ -1734,20 +1734,24 @@ public final class CApi {
     @NotNull OutputPointer.Int64 pHighwater, boolean reset
   );
 
-  public static native int sqlite3_step(@NotNull sqlite3_stmt stmt);
+  private static native int sqlite3_step(@NotNull long ptrToStmt);
+
+  public static int sqlite3_step(@NotNull sqlite3_stmt stmt){
+    return null==stmt ? SQLITE_MISUSE : sqlite3_step(stmt.getNativePointer());
+  }
 
   public static native boolean sqlite3_stmt_busy(@NotNull sqlite3_stmt stmt);
 
   private static native int sqlite3_stmt_explain(@NotNull long ptrToStmt, int op);
 
   public static int sqlite3_stmt_explain(@NotNull sqlite3_stmt stmt, int op){
-    return sqlite3_stmt_explain(stmt.getNativePointer(), op);
+    return null==stmt ? SQLITE_MISUSE : sqlite3_stmt_explain(stmt.getNativePointer(), op);
   }
 
   private static native int sqlite3_stmt_isexplain(@NotNull long ptrToStmt);
 
   public static int sqlite3_stmt_isexplain(@NotNull sqlite3_stmt stmt){
-    return sqlite3_stmt_isexplain(stmt.getNativePointer());
+    return null==stmt ? 0 : sqlite3_stmt_isexplain(stmt.getNativePointer());
   }
 
   public static native boolean sqlite3_stmt_readonly(@NotNull sqlite3_stmt stmt);
index f6390adef57bd78f8d9417fec90b5b1534740848..65ac65ba7adcbfee7657d93be2bc30b713cb20e9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Two\smore\sJNI\sbuild\sfixes\sfor\sWindows/MinGW,\sreported\sin\s[forum:4f949edc312d2a75|forum\spost\s4f949edc312d2a75].
-D 2023-11-09T12:01:02.729
+C Add\ssome\snotes\sabout\sthe\sJNI\spointer-passing\sapproach\sand\sconvert\sa\scouple\sof\spotential\sNullPointerExceptions\sinto\sappropriate\sC\sresult\scodes.\sClarify\sthat\sinvocation\sof\sundefined\sbehaviour\sfrom\sthe\sJava\sAPI\sdoes\snot\s(due\sto\sthe\saddition\sof\sdefensive\scode)\smean\sthe\ssame\sthing\sas\sit\sdoes\sin\sC\s(e.g.\sno\sNULL\spointer\sdereferences).
+D 2023-11-09T12:48:54.107
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -241,9 +241,9 @@ F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a3
 F ext/jni/GNUmakefile d984ea9c4e3536188f9d663120db8fb97b83329f4b8864bd88f75ebe581b8b8b
 F ext/jni/README.md ef9ac115e97704ea995d743b4a8334e23c659e5534c3b64065a5405256d5f2f4
 F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
-F ext/jni/src/c/sqlite3-jni.c 6b95974189d7cc394afbe15507050f1d174170a65be5a4dad201ab11f0a9777a
-F ext/jni/src/c/sqlite3-jni.h 18925c56d6664fdec081c56daf3b2ffa0e0ff6b9b128b9f39b84862f34ba0601
-F ext/jni/src/org/sqlite/jni/annotation/NotNull.java a99341e88154e70447596b1af6a27c586317df41a7e0f246fd41370cd7b723b2
+F ext/jni/src/c/sqlite3-jni.c 3774703e5865e7ff776b762de5386af8aa703e569bbb3a85c423c3f8473a3c26
+F ext/jni/src/c/sqlite3-jni.h 489044eae9fc6c2d62c1621e41594adf7bfcd4049b514a202c4aa6fe5c1ef405
+F ext/jni/src/org/sqlite/jni/annotation/NotNull.java 02091a8112e33389f1c160f506cd413168c8dfacbeda608a4946c6e3557b7d5a
 F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 0b1879852707f752512d4db9d7edd0d8db2f0c2612316ce1c832715e012ff6ba
 F ext/jni/src/org/sqlite/jni/annotation/package-info.java 977b374aed9d5853cbf3438ba3b0940abfa2ea4574f702a2448ee143b98ac3ca
 F ext/jni/src/org/sqlite/jni/capi/AbstractCollationCallback.java 1afa90d3f236f79cc7fcd2497e111992644f7596fbc8e8bcf7f1908ae00acd6c
@@ -251,7 +251,7 @@ F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java 0b72cdff61533b564d65b63
 F ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java c045a5b47e02bb5f1af91973814a905f12048c428a3504fbc5266d1c1be3de5a
 F ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java 74cc4998a73d6563542ecb90804a3c4f4e828cb4bd69e61226d1a51f4646e759
 F ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java 7b8e19810c42b0ad21a04b5d8c804b32ee5905d137148703f16a75b612c380ca
-F ext/jni/src/org/sqlite/jni/capi/CApi.java 16a28138c3c25f33356193970644389ff8ebc0720499549653934b2529c8d1dd
+F ext/jni/src/org/sqlite/jni/capi/CApi.java 2917e2c608ac52ebe30fbcde2b520c6ea3bc99e734619dfdedd072b8e956b84f
 F ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 57e2d275dcebe690b1fc1f3d34eb96879b2d7039bce30b563aee547bf45d8a8b
 F ext/jni/src/org/sqlite/jni/capi/CollationCallback.java e29bcfc540fdd343e2f5cca4d27235113f2886acb13380686756d5cabdfd065a
 F ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java 5bfa226a8e7a92e804fd52d6e42b4c7b875fa7a94f8e2c330af8cc244a8920ab
@@ -2139,8 +2139,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 1c98d46d60ef1494bd8b7561c7d0cd5aafc178201a6f1f0da25dea6140b91cd0
-R 17c07891ab0f75a8281c2b918fd5c523
+P a3f9c39086e582e16ca15647961956b3c28d038655d3b43d4b94bd306fbec1a4
+R d00dc0a6ea6feccf2aee95fe4c483ba0
 U stephan
-Z 19240fed0f90b5e1367576a460d156b0
+Z 4aa2d438a8d23b9c44b1a48729f3cdde
 # Remove this line to create a well-formed Fossil manifest.
index 300175f17c8bbf2cb15e1f76e5aa757b6e7fdf3e..7b8b377c39ec89cb9b00a1a44e8c961b608f9c77 100644 (file)
@@ -1 +1 @@
-a3f9c39086e582e16ca15647961956b3c28d038655d3b43d4b94bd306fbec1a4
\ No newline at end of file
+19c4778f45261006368b2d9460350fed1e55fed314c8b3e1af34cd8c3c73b7d8
\ No newline at end of file