From 58c7b770de961b817888320d73139d7817de23b9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 11 Oct 2023 13:34:18 +0000 Subject: [PATCH 1/6] Simplification to sqlite3ApiExit(). Generates identical machine code, but easier for humans to read. FossilOrigin-Name: 793bbfa5af9721bc3a61e8e5eda46dfce2f5ff3f223a7564c9e1b09f11e53cb3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/malloc.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index afe0936b4a..9f914a5a70 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\sthe\smkautoconfamal.sh\sscript,\sintroduced\sby\scheck-in\s[3308fdda4b81c110]\nso\sthat\sthe\s"snapshot-tarball"\sand\s"amalgamation-tarball"\smakefile\stargets\nwork\sagain\swhen\srun\sfrom\soutside\sof\sthe\ssource\stree. -D 2023-10-10T15:33:05.058 +C Simplification\sto\ssqlite3ApiExit().\s\sGenerates\sidentical\smachine\scode,\sbut\neasier\sfor\shumans\sto\sread. +D 2023-10-11T13:34:18.514 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -678,7 +678,7 @@ F src/json.c 82b9cef53ebc00069d516a06be4aa971e2e70caffe3417bd6001bf00177bb1bf F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 98cfba10989b3da6f1807ad42444017742db7f100a54f1032af7a8b1295912c0 F src/main.c 618aeb399e993cf561864f4b0cf6a331ee4f355cf663635f8d9da3193a46aa40 -F src/malloc.c 47b82c5daad557d9b963e3873e99c22570fb470719082c6658bf64e3012f7d23 +F src/malloc.c f016922435dc7d1f1f5083a03338a3e91f8c67ce2c5bdcfa4cdef62e612f5fcc F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75 @@ -2128,8 +2128,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 0177f4dfe8a5c03c1d5dd279c6babe5a87b596c2351373f845b89fc6abf7947b -R 37373df44eb3bf4c68a7092e403d96f0 +P 65ccf5fef812d43aed9e00af36c90e1a499d197e30148753790445e25ee1324c +R af91c5cebf078db7ff8defd10c43084e U drh -Z 33418d47ecf8795ddbe386dcc10d96d2 +Z ee511a7822e958c17cba502a0e5ae3ed # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6472fbbabb..7f818d81f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -65ccf5fef812d43aed9e00af36c90e1a499d197e30148753790445e25ee1324c \ No newline at end of file +793bbfa5af9721bc3a61e8e5eda46dfce2f5ff3f223a7564c9e1b09f11e53cb3 \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 48c4600606..356750682e 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -896,5 +896,5 @@ int sqlite3ApiExit(sqlite3* db, int rc){ if( db->mallocFailed || rc ){ return apiHandleError(db, rc); } - return rc & db->errMask; + return 0; } From 582d65cce31cc4e17124ceac92fcba89ff0e52d0 Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 11 Oct 2023 13:52:05 +0000 Subject: [PATCH 2/6] Add (prepare, step, reset, finalize) parts of the JNI level-2 stmt wrapper and associated tests. FossilOrigin-Name: a7082f186f2b9b6666bbc65f2eadeb74d91fa0a681e3b2468b261ffd322bd249 --- ext/jni/src/org/sqlite/jni/Sqlite.java | 126 +++++++++++++++++- .../src/org/sqlite/jni/SqliteException.java | 14 +- ext/jni/src/org/sqlite/jni/Tester2.java | 51 +++++-- manifest | 18 +-- manifest.uuid | 2 +- 5 files changed, 187 insertions(+), 24 deletions(-) diff --git a/ext/jni/src/org/sqlite/jni/Sqlite.java b/ext/jni/src/org/sqlite/jni/Sqlite.java index b964c57b33..5c2c456296 100644 --- a/ext/jni/src/org/sqlite/jni/Sqlite.java +++ b/ext/jni/src/org/sqlite/jni/Sqlite.java @@ -12,6 +12,7 @@ ** This file is part of the JNI bindings for the sqlite3 C API. */ package org.sqlite.jni; +import java.nio.charset.StandardCharsets; import static org.sqlite.jni.CApi.*; /** @@ -22,7 +23,7 @@ import static org.sqlite.jni.CApi.*; individual instances are tied to a specific database connection. */ public final class Sqlite implements AutoCloseable { - private sqlite3 db = null; + private sqlite3 db; //! Used only by the open() factory functions. private Sqlite(sqlite3 db){ @@ -33,6 +34,9 @@ public final class Sqlite implements AutoCloseable { Returns a newly-opened db connection or throws SqliteException if opening fails. All arguments are as documented for sqlite3_open_v2(). + + Design question: do we want static factory functions or should + this be reformulated as a constructor? */ public static Sqlite open(String filename, int flags, String vfsName){ final OutputPointer.sqlite3 out = new OutputPointer.sqlite3(); @@ -40,7 +44,9 @@ public final class Sqlite implements AutoCloseable { final sqlite3 n = out.take(); if( 0!=rc ){ if( null==n ) throw new SqliteException(rc); - else throw new SqliteException(n); + final SqliteException ex = new SqliteException(n); + n.close(); + throw ex; } return new Sqlite(n); } @@ -64,6 +70,120 @@ public final class Sqlite implements AutoCloseable { Returns this object's underlying native db handle, or null if this instance has been closed. */ - sqlite3 dbHandle(){ return this.db; } + sqlite3 nativeHandle(){ return this.db; } + + private void affirmOpen(){ + if( null==db || 0==db.getNativePointer() ){ + throw new IllegalArgumentException("This database instance is closed."); + } + } + + // private byte[] stringToUtf8(String s){ + // return s==null ? null : s.getBytes(StandardCharsets.UTF_8); + // } + + private void affirmRcOk(int rc){ + if( 0!=rc ){ + throw new SqliteException(db); + } + } + + public final class Stmt implements AutoCloseable { + private Sqlite _db = null; + private sqlite3_stmt stmt = null; + /** Only called by the prepare() factory functions. */ + Stmt(Sqlite db, sqlite3_stmt stmt){ + this._db = db; + this.stmt = stmt; + } + + sqlite3_stmt nativeHandle(){ + return stmt; + } + + private sqlite3_stmt affirmOpen(){ + if( null==stmt || 0==stmt.getNativePointer() ){ + throw new IllegalArgumentException("This Stmt has been finalized."); + } + return stmt; + } + + /** + Corresponds to sqlite3_finalize(), but we cannot override the + name finalize() here because this one requires a different + signature. We do not throw on error here because "destructors + do not throw." If it returns non-0, the object is still + finalized. + */ + public int finalizeStmt(){ + int rc = 0; + if( null!=stmt ){ + sqlite3_finalize(stmt); + stmt = null; + } + return rc; + } + + @Override public void close(){ + finalizeStmt(); + } + + /** + Throws if rc is any value other than 0, SQLITE_ROW, or + SQLITE_DONE, else returns rc. + */ + private int checkRc(int rc){ + switch(rc){ + case 0: + case SQLITE_ROW: + case SQLITE_DONE: return rc; + default: + throw new SqliteException(this); + } + } + + /** + Works like sqlite3_step() but throws SqliteException for any + result other than 0, SQLITE_ROW, or SQLITE_DONE. + */ + public int step(){ + return checkRc(sqlite3_step(affirmOpen())); + } + + public Sqlite db(){ return this._db; } + + /** + Works like sqlite3_reset() but throws on error. + */ + public void reset(){ + checkRc(sqlite3_reset(affirmOpen())); + } + + public void clearBindings(){ + sqlite3_clear_bindings( affirmOpen() ); + } + } + + + /** + prepare() TODOs include: + + - overloads taking byte[] and ByteBuffer. + + - multi-statement processing, like CApi.sqlite3_prepare_multi() + but using a callback specific to the higher-level Stmt class + rather than the sqlite3_stmt class. + */ + public Stmt prepare(String sql, int prepFlags){ + affirmOpen(); + final OutputPointer.sqlite3_stmt out = new OutputPointer.sqlite3_stmt(); + final int rc = sqlite3_prepare_v3(this.db, sql, prepFlags, out); + affirmRcOk(rc); + return new Stmt(this, out.take()); + } + + public Stmt prepare(String sql){ + return prepare(sql, 0); + } } diff --git a/ext/jni/src/org/sqlite/jni/SqliteException.java b/ext/jni/src/org/sqlite/jni/SqliteException.java index 3da5d8c583..c15cb34919 100644 --- a/ext/jni/src/org/sqlite/jni/SqliteException.java +++ b/ext/jni/src/org/sqlite/jni/SqliteException.java @@ -46,7 +46,12 @@ public final class SqliteException extends java.lang.RuntimeException { /** Records the current error state of db (which must not be null and - must refer to an opened db object) then closes it. + must refer to an opened db object). Note that this does NOT close + the db. + + Design note: closing the db on error is likely only useful during + a failed db-open operation, and the place(s) where that can + happen are inside this library, not client-level code. */ public SqliteException(sqlite3 db){ super(sqlite3_errmsg(db)); @@ -54,7 +59,6 @@ public final class SqliteException extends java.lang.RuntimeException { xerrCode = sqlite3_extended_errcode(db); errOffset = sqlite3_error_offset(db); sysErrno = sqlite3_system_errno(db); - db.close(); } /** @@ -62,7 +66,11 @@ public final class SqliteException extends java.lang.RuntimeException { refer to an open database) then closes it. */ public SqliteException(Sqlite db){ - this(db.dbHandle()); + this(db.nativeHandle()); + } + + public SqliteException(Sqlite.Stmt stmt){ + this( stmt.db() ); } public int errcode(){ return errCode; } diff --git a/ext/jni/src/org/sqlite/jni/Tester2.java b/ext/jni/src/org/sqlite/jni/Tester2.java index b7701f1a92..e75f56e064 100644 --- a/ext/jni/src/org/sqlite/jni/Tester2.java +++ b/ext/jni/src/org/sqlite/jni/Tester2.java @@ -126,16 +126,51 @@ public class Tester2 implements Runnable { } } - void testOpenDb1(){ - Sqlite db = Sqlite.open(":memory:"); - affirm( 0!=db.dbHandle().getNativePointer() ); - db.close(); - affirm( null==db.dbHandle() ); + Sqlite openDb(String name){ + return Sqlite.open(name, SQLITE_OPEN_READWRITE| + SQLITE_OPEN_CREATE| + SQLITE_OPEN_EXRESCODE); } - @ManualTest /* because we only want to run this test on demand */ - private void testFail(){ - affirm( false, "Intentional failure." ); + Sqlite openDb(){ return openDb(":memory:"); } + + void testOpenDb1(){ + Sqlite db = openDb(); + affirm( 0!=db.nativeHandle().getNativePointer() ); + db.close(); + affirm( null==db.nativeHandle() ); + + SqliteException ex = null; + try { + db = openDb("/no/such/dir/.../probably"); + }catch(SqliteException e){ + ex = e; + } + affirm( ex!=null ); + affirm( ex.errcode() != 0 ); + affirm( ex.extendedErrcode() != 0 ); + affirm( ex.errorOffset() < 0 ); + // there's no reliable way to predict what ex.systemErrno() might be + } + + void testPrepare1(){ + try (Sqlite db = openDb()) { + Sqlite.Stmt stmt = db.prepare("SELECT 1"); + affirm( null!=stmt.nativeHandle() ); + affirm( SQLITE_ROW == stmt.step() ); + affirm( SQLITE_DONE == stmt.step() ); + stmt.reset(); + affirm( SQLITE_ROW == stmt.step() ); + affirm( SQLITE_DONE == stmt.step() ); + affirm( 0 == stmt.finalizeStmt() ); + affirm( null==stmt.nativeHandle() ); + + stmt = db.prepare("SELECT 1"); + affirm( SQLITE_ROW == stmt.step() ); + affirm( 0 == stmt.finalizeStmt() ) + /* getting a non-0 out of sqlite3_finalize() is tricky */; + affirm( null==stmt.nativeHandle() ); + } } private void runTests(boolean fromThread) throws Exception { diff --git a/manifest b/manifest index 9f914a5a70..560c66a995 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sto\ssqlite3ApiExit().\s\sGenerates\sidentical\smachine\scode,\sbut\neasier\sfor\shumans\sto\sread. -D 2023-10-11T13:34:18.514 +C Add\s(prepare,\sstep,\sreset,\sfinalize)\sparts\sof\sthe\sJNI\slevel-2\sstmt\swrapper\sand\sassociated\stests. +D 2023-10-11T13:52:05.849 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -262,11 +262,11 @@ F ext/jni/src/org/sqlite/jni/RollbackHookCallback.java ec6cd96bff5d3bc5af079cbf1 F ext/jni/src/org/sqlite/jni/SQLFunction.java 544a875d33fd160467d82e2397ac33157b29971d715a821a4fad3c899113ee8c F ext/jni/src/org/sqlite/jni/SQLTester.java d246c67f93e2fa2603bd106dbb3246ea725c987dffd6e5d42214ae262f750c68 F ext/jni/src/org/sqlite/jni/ScalarFunction.java 6d387bb499fbe3bc13c53315335233dbf6a0c711e8fa7c521683219b041c614c -F ext/jni/src/org/sqlite/jni/Sqlite.java 713f973764de9f918500b8723f347e67d29da226ad34b18e1f37865397c0efcb -F ext/jni/src/org/sqlite/jni/SqliteException.java f5d17a10202c0983fb074f66a0b48cf1e573b1da2eaeda679825e3edc1829706 +F ext/jni/src/org/sqlite/jni/Sqlite.java 1617ea2bf3dfa493b7f031a3187cbfd6837c39bc1d406c4b3edcf9aab941639d +F ext/jni/src/org/sqlite/jni/SqliteException.java e17500e8bca2c68c260d8d0163fe4b7dc8bd0b1b90211201325c4a5566ce75ca F ext/jni/src/org/sqlite/jni/TableColumnMetadata.java 54511b4297fa28dcb3f49b24035e34ced10e3fd44fd0e458e784f4d6b0096dab F ext/jni/src/org/sqlite/jni/Tester1.java f7b85fe24cf6c3e43bdf7e390617657e8137359f804d76921829c2a8c41b6df1 -F ext/jni/src/org/sqlite/jni/Tester2.java 3e7b3c05c08bdbf899684074f095724e1853dc16912dfb53306a03e5c4cbd614 +F ext/jni/src/org/sqlite/jni/Tester2.java 70e005d41060e398ec0f69bd39a8e1c376fd51f81629cf25e877889ec9cb6ec6 F ext/jni/src/org/sqlite/jni/TesterFts5.java d60fe9944a81156b3b5325dd1b0e8e92a1547468f39fd1266d06f7bb6a95fa70 F ext/jni/src/org/sqlite/jni/TraceV2Callback.java f157edd9c72e7d2243c169061487cd7bb51a0d50f3ac976dbcbbacf748ab1fc2 F ext/jni/src/org/sqlite/jni/UpdateHookCallback.java 959d4677a857c9079c6e96ddd10918b946d68359af6252b6f284379069ea3d27 @@ -2128,8 +2128,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 65ccf5fef812d43aed9e00af36c90e1a499d197e30148753790445e25ee1324c -R af91c5cebf078db7ff8defd10c43084e -U drh -Z ee511a7822e958c17cba502a0e5ae3ed +P 793bbfa5af9721bc3a61e8e5eda46dfce2f5ff3f223a7564c9e1b09f11e53cb3 +R 4d3cf5230b57585fb263b4c0d4fb2b1e +U stephan +Z 39c6ded9773037a11fc3746bbfb10c12 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7f818d81f4..7b40a7c4e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -793bbfa5af9721bc3a61e8e5eda46dfce2f5ff3f223a7564c9e1b09f11e53cb3 \ No newline at end of file +a7082f186f2b9b6666bbc65f2eadeb74d91fa0a681e3b2468b261ffd322bd249 \ No newline at end of file From ac4aea5102e3a272f6cd8a601a35d2541733fa90 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 11 Oct 2023 17:24:31 +0000 Subject: [PATCH 3/6] Fix the use of an uninitialized value that occurs when doing a json_insert() of a string value that contains embedded U+0000 characters. FossilOrigin-Name: d3c0cbb90966316be9cd25e3edb501da42731e8a83c13227b90ce17d3975a2c3 --- manifest | 17 +++++++++-------- manifest.uuid | 2 +- src/json.c | 6 ++++-- test/json101.test | 3 +++ 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 560c66a995..0368f0f70b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s(prepare,\sstep,\sreset,\sfinalize)\sparts\sof\sthe\sJNI\slevel-2\sstmt\swrapper\sand\sassociated\stests. -D 2023-10-11T13:52:05.849 +C Fix\sthe\suse\sof\san\suninitialized\svalue\sthat\soccurs\swhen\sdoing\sa\sjson_insert()\nof\sa\sstring\svalue\sthat\scontains\sembedded\sU+0000\scharacters. +D 2023-10-11T17:24:31.588 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -674,7 +674,7 @@ F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276 -F src/json.c 82b9cef53ebc00069d516a06be4aa971e2e70caffe3417bd6001bf00177bb1bf +F src/json.c 799430345d16fed21713416318e6ca616f1264224f708555f387bfa2ab2496c7 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 98cfba10989b3da6f1807ad42444017742db7f100a54f1032af7a8b1295912c0 F src/main.c 618aeb399e993cf561864f4b0cf6a331ee4f355cf663635f8d9da3193a46aa40 @@ -1306,7 +1306,7 @@ F test/json/README.md 63e3e589e1df8fd3cc1588ba1faaff659214003f8b77a15af5c6452b35 F test/json/json-generator.tcl dc0dd0f393800c98658fc4c47eaa6af29d4e17527380cd28656fb261bddc8a3f F test/json/json-q1.txt 65f9d1cdcc4cffa9823fb73ed936aae5658700cd001fde448f68bfb91c807307 F test/json/json-speed-check.sh 8b7babf530faa58bd59d6d362cec8e9036a68c5457ff46f3b1f1511d21af6737 x -F test/json101.test 4d78048b185ffb9ae37645fa6934d48fc182473ae0bae088a1e2f7ba483c3a71 +F test/json101.test 1ad070e5616dee76bffbe9724e6add16ab7ad506d5af9e606627b163baf1a7b4 F test/json102.test 4c69694773a470f1fda34e5f4ba24920b35184fb66050b450fc2ef9ab5ad310b F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1 @@ -2128,8 +2128,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 793bbfa5af9721bc3a61e8e5eda46dfce2f5ff3f223a7564c9e1b09f11e53cb3 -R 4d3cf5230b57585fb263b4c0d4fb2b1e -U stephan -Z 39c6ded9773037a11fc3746bbfb10c12 +P a7082f186f2b9b6666bbc65f2eadeb74d91fa0a681e3b2468b261ffd322bd249 +Q +fc5ee9e51ad4556af526a6cefca5ae5a3b1b7affc4edf09832491d6b4f4ba366 +R 93737f5b55ab3449be7057400ec68be2 +U drh +Z 222827e9ae2110e3474e6249138dc8a5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7b40a7c4e7..36f21eb598 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7082f186f2b9b6666bbc65f2eadeb74d91fa0a681e3b2468b261ffd322bd249 \ No newline at end of file +d3c0cbb90966316be9cd25e3edb501da42731e8a83c13227b90ce17d3975a2c3 \ No newline at end of file diff --git a/src/json.c b/src/json.c index b28ba7ecdc..e334b22140 100644 --- a/src/json.c +++ b/src/json.c @@ -2843,11 +2843,13 @@ static void jsonReplaceNode( break; } if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){ - char *zCopy = sqlite3DbStrDup(0, z); + char *zCopy = sqlite3_malloc64( n+1 ); int k; if( zCopy ){ + memcpy(zCopy, z, n); + zCopy[n] = 0; jsonParseAddCleanup(p, sqlite3_free, zCopy); - }else{ + }else{ p->oom = 1; sqlite3_result_error_nomem(pCtx); } diff --git a/test/json101.test b/test/json101.test index 4590330740..d734dbb0e1 100644 --- a/test/json101.test +++ b/test/json101.test @@ -119,6 +119,9 @@ do_execsql_test json101-4.7 { do_execsql_test json101-4.8 { SELECT x FROM j1 WHERE json_insert(x)<>x; } {} +do_execsql_test json101-4.9 { + SELECT json_insert('{"a":1}','$.b',CAST(x'0000' AS text)); +} {{{"a":1,"b":"\u0000\u0000"}}} # json_extract(JSON,'$') will return objects and arrays without change. # From 6a0f297da9ca464ec2586af3db3747af5c43970d Mon Sep 17 00:00:00 2001 From: stephan Date: Wed, 11 Oct 2023 20:37:42 +0000 Subject: [PATCH 4/6] Unconditionally force use of SQLITE_ENABLE_API_ARMOR in the WASM and JNI builds. Their corresponding test suites still work. FossilOrigin-Name: c11394b50d0687b6d6abad9c80d5cd3cdce77e9b9c278f40601c460f463744a1 --- ext/jni/src/c/sqlite3-jni.c | 8 ++++++++ ext/wasm/api/sqlite3-wasm.c | 8 ++++++++ manifest | 17 ++++++++--------- manifest.uuid | 2 +- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/ext/jni/src/c/sqlite3-jni.c b/ext/jni/src/c/sqlite3-jni.c index ab8dac6442..7afc9a0f0f 100644 --- a/ext/jni/src/c/sqlite3-jni.c +++ b/ext/jni/src/c/sqlite3-jni.c @@ -43,6 +43,14 @@ /**********************************************************************/ /* SQLITE_ENABLE_... */ +/* +** Unconditionally enable API_ARMOR in the JNI build. It ensures that +** public APIs behave predictable in the face of passing illegal NULLs +** or ranges which might otherwise invoke undefined behavior. +*/ +#undef SQLITE_ENABLE_API_ARMOR +#define SQLITE_ENABLE_API_ARMOR 1 + #ifndef SQLITE_ENABLE_BYTECODE_VTAB # define SQLITE_ENABLE_BYTECODE_VTAB 1 #endif diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index db77010d95..88a679c518 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -84,6 +84,14 @@ /**********************************************************************/ /* SQLITE_ENABLE_... */ +/* +** Unconditionally enable API_ARMOR in the WASM build. It ensures that +** public APIs behave predictable in the face of passing illegal NULLs +** or ranges which might otherwise invoke undefined behavior. +*/ +#undef SQLITE_ENABLE_API_ARMOR +#define SQLITE_ENABLE_API_ARMOR 1 + #ifndef SQLITE_ENABLE_BYTECODE_VTAB # define SQLITE_ENABLE_BYTECODE_VTAB 1 #endif diff --git a/manifest b/manifest index 0368f0f70b..8cc2f5b251 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\suse\sof\san\suninitialized\svalue\sthat\soccurs\swhen\sdoing\sa\sjson_insert()\nof\sa\sstring\svalue\sthat\scontains\sembedded\sU+0000\scharacters. -D 2023-10-11T17:24:31.588 +C Unconditionally\sforce\suse\sof\sSQLITE_ENABLE_API_ARMOR\sin\sthe\sWASM\sand\sJNI\sbuilds.\sTheir\scorresponding\stest\ssuites\sstill\swork. +D 2023-10-11T20:37:42.544 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -238,7 +238,7 @@ F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a3 F ext/jni/GNUmakefile 6da240c9a11701f3ed569384cd15ef611e8b3c5e3897d265923b14bf0e1eb272 F ext/jni/README.md ef9ac115e97704ea995d743b4a8334e23c659e5534c3b64065a5405256d5f2f4 F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa -F ext/jni/src/c/sqlite3-jni.c fb8f178d27df828e3c797b4427a0a20545b44f5147ce38d09ce9b465be5a840b +F ext/jni/src/c/sqlite3-jni.c bf432771fbc84da2b5f4037e0bcf20757548aac2fa782b272c4894a9c279964a F ext/jni/src/c/sqlite3-jni.h be1fdff7ab3a2bb357197271c8ac5d2bf6ff59380c106dde3a13be88724bad22 F ext/jni/src/org/sqlite/jni/AbstractCollationCallback.java 95e88ba04f4aac51ffec65693e878e234088b2f21b387f4e4285c8b72b33e436 F ext/jni/src/org/sqlite/jni/AggregateFunction.java 7312486bc65fecdb91753c0a4515799194e031f45edbe16a6373cea18f404dc4 @@ -581,7 +581,7 @@ F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256 F ext/wasm/api/sqlite3-v-helper.js 7daa0eab0a513a25b05e9abae7b5beaaa39209b3ed12f86aeae9ef8d2719ed25 F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js f7c965cf9ac0b66a538cd8f6c156f3f2a235e089821ca78cabd7bce41ce16bf7 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 46c4afa6c50d7369252c104f274ad977a97e91ccfafc38b400fe36e90bdda88e -F ext/wasm/api/sqlite3-wasm.c 65d60439671e24d50d9119ca805ac1c68fb36129e164377eb46f8d037bd88b07 +F ext/wasm/api/sqlite3-wasm.c c8c5b81b838cef2053b1eb6e7a79c44a2caedcf0c9e6b0d12a45d73ce0617be0 F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f F ext/wasm/api/sqlite3-worker1.c-pp.js da509469755035e919c015deea41b4514b5e84c12a1332e6cc8d42cb2cc1fb75 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 @@ -2128,9 +2128,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 a7082f186f2b9b6666bbc65f2eadeb74d91fa0a681e3b2468b261ffd322bd249 -Q +fc5ee9e51ad4556af526a6cefca5ae5a3b1b7affc4edf09832491d6b4f4ba366 -R 93737f5b55ab3449be7057400ec68be2 -U drh -Z 222827e9ae2110e3474e6249138dc8a5 +P d3c0cbb90966316be9cd25e3edb501da42731e8a83c13227b90ce17d3975a2c3 +R cb4e6a9a30b16c853ef3dc73ffbd4bf2 +U stephan +Z 3e4716ef7bf77cf16b30a28c2f5da5ac # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 36f21eb598..7589f45852 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d3c0cbb90966316be9cd25e3edb501da42731e8a83c13227b90ce17d3975a2c3 \ No newline at end of file +c11394b50d0687b6d6abad9c80d5cd3cdce77e9b9c278f40601c460f463744a1 \ No newline at end of file From 35d6c24fd544da6c8709b199e7f0b0115d093dee Mon Sep 17 00:00:00 2001 From: larrybr Date: Thu, 12 Oct 2023 15:12:38 +0000 Subject: [PATCH 5/6] CLI to check for rare prepare failures. [forum:/forumpost/5be6395182|See forum post 5be6395182.] FossilOrigin-Name: 286d1e8012a5f5d9e1fe6dce1a732f725b8a1837f66daf6aefb792e19e96f2d4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 6 ++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 8cc2f5b251..039659c7cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Unconditionally\sforce\suse\sof\sSQLITE_ENABLE_API_ARMOR\sin\sthe\sWASM\sand\sJNI\sbuilds.\sTheir\scorresponding\stest\ssuites\sstill\swork. -D 2023-10-11T20:37:42.544 +C CLI\sto\scheck\sfor\srare\sprepare\sfailures.\s[forum:/forumpost/5be6395182|See\sforum\spost\s5be6395182.] +D 2023-10-12T15:12:38.967 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -715,7 +715,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 0c3046b88901336709cd09f474303a16fc54bce13a2befcab66d0fa6b44ca869 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 7f9155185be78902818b21c2cd3e33f01b4306279a15d6719eb1bbb9779034aa -F src/shell.c.in 6d26db96a7d53e7b499c8ae2f794dfc020a96e64d5757aebd0e4cf743b6de031 +F src/shell.c.in cf0a3387c5bb05ca2fe6073fa7df21aaa11e749ca5b3846b80b586a447e728aa F src/sqlite.h.in 4f39f61c35348f0c56dd2c7a2294d1f0564389a0086dab80ce0960bfd772dc1b F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 2f30b2671f4c03cd27a43f039e11251391066c97d11385f5f963bb40b03038ac @@ -2128,8 +2128,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 d3c0cbb90966316be9cd25e3edb501da42731e8a83c13227b90ce17d3975a2c3 -R cb4e6a9a30b16c853ef3dc73ffbd4bf2 -U stephan -Z 3e4716ef7bf77cf16b30a28c2f5da5ac +P c11394b50d0687b6d6abad9c80d5cd3cdce77e9b9c278f40601c460f463744a1 +R 5ae72ce81eda772829c7d27c1ea987e3 +U larrybr +Z 19dab31d5c5256d717b8a79b7d715525 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7589f45852..86ed5b92e6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c11394b50d0687b6d6abad9c80d5cd3cdce77e9b9c278f40601c460f463744a1 \ No newline at end of file +286d1e8012a5f5d9e1fe6dce1a732f725b8a1837f66daf6aefb792e19e96f2d4 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 1699820a69..beea0f9b07 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -8772,8 +8772,10 @@ static int do_meta_command(char *zLine, ShellState *p){ "SELECT rowid FROM sqlite_schema" " WHERE name GLOB 'sqlite_stat[134]'", -1, &pStmt, 0); - doStats = sqlite3_step(pStmt)==SQLITE_ROW; - sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ){ + doStats = sqlite3_step(pStmt)==SQLITE_ROW; + sqlite3_finalize(pStmt); + } } if( doStats==0 ){ raw_printf(p->out, "/* No STAT tables available */\n"); From 5d9a6c6734168c8388eba41270fa4415f4dfee1c Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 12 Oct 2023 17:41:18 +0000 Subject: [PATCH 6/6] Make sure the journal file is closed when transitioning into MEMORY journal mode, to avoid an assertion fault in the new sqlite3_randomness() avoidance code added by [c84e4483cb44f827]. FossilOrigin-Name: 29937081a986d88f495ad48748c35ff5829f0ac31dd4ad3e48d180ae2fcb9a0c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 039659c7cf..35a1ad45df 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C CLI\sto\scheck\sfor\srare\sprepare\sfailures.\s[forum:/forumpost/5be6395182|See\sforum\spost\s5be6395182.] -D 2023-10-12T15:12:38.967 +C Make\ssure\sthe\sjournal\sfile\sis\sclosed\swhen\stransitioning\sinto\sMEMORY\sjournal\nmode,\sto\savoid\san\sassertion\sfault\sin\sthe\snew\ssqlite3_randomness()\savoidance\ncode\sadded\sby\s[c84e4483cb44f827]. +D 2023-10-12T17:41:18.510 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -701,7 +701,7 @@ F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d87210 F src/os_unix.c 2e8b12107f75d1bd16412f312b4c5d5103191807a37836d3b81beb26436ad81b F src/os_win.c 4a50a154aeebc66a1f8fb79c1ff6dd5fe3d005556533361e0d460d41cb6a45a8 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c bbd9b93c014679d8148235cc42b73bebda3f598d4f63a63cf7723ddf3087fd58 +F src/pager.c 4aa388e47138551c83ae265e2efd4e01f0aa5afb6a958f45579658847b3430ff F src/pager.h f4d33fec8052603758792045493423b8871a996da2d0973927b7d36cd6070473 F src/parse.y aeb7760d41cfa86465e3adba506500c021597049fd55f82a30e5b7045862c28c F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75 @@ -2128,8 +2128,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 c11394b50d0687b6d6abad9c80d5cd3cdce77e9b9c278f40601c460f463744a1 -R 5ae72ce81eda772829c7d27c1ea987e3 -U larrybr -Z 19dab31d5c5256d717b8a79b7d715525 +P 286d1e8012a5f5d9e1fe6dce1a732f725b8a1837f66daf6aefb792e19e96f2d4 +R 63c272f1ac84380bbc1d2409b6f281ca +U drh +Z 6db7b813ea2dc81e78e187c7332821c2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 86ed5b92e6..d8626240d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -286d1e8012a5f5d9e1fe6dce1a732f725b8a1837f66daf6aefb792e19e96f2d4 \ No newline at end of file +29937081a986d88f495ad48748c35ff5829f0ac31dd4ad3e48d180ae2fcb9a0c \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index af21ad6114..1423b66541 100644 --- a/src/pager.c +++ b/src/pager.c @@ -7369,7 +7369,7 @@ int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ } assert( state==pPager->eState ); } - }else if( eMode==PAGER_JOURNALMODE_OFF ){ + }else if( eMode==PAGER_JOURNALMODE_OFF || eMode==PAGER_JOURNALMODE_MEMORY ){ sqlite3OsClose(pPager->jfd); } }