]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Relax the name limits on kvvfs dbs.
authorstephan <stephan@noemail.net>
Mon, 1 Dec 2025 16:28:55 +0000 (16:28 +0000)
committerstephan <stephan@noemail.net>
Mon, 1 Dec 2025 16:28:55 +0000 (16:28 +0000)
FossilOrigin-Name: 9901cf8e4a00ea9a199a3fb54bd58bd66cff4d02c55433d55f2b417e188e49e0

ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js
ext/wasm/tester1.c-pp.js
manifest
manifest.uuid

index f96374d31cc9468d274d7c74e75016a3c2dbaadb..025306cf298b4bf90e7285a01c185f7b8ec5cebd 100644 (file)
@@ -278,16 +278,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
      Throws if storage name n (JS string) is not valid for use as a
      storage name.  Much of this goes back to kvvfs having a fixed
      buffer size for its keys, and the storage name needing to be
-     encoded in the keys for local/session storage. We disallow
-     non-ASCII to avoid problems with truncated multibyte characters
-     at the end of the key buffer.
+     encoded in the keys for local/session storage.
 
      The second argument must only be true when called from xOpen() -
      it makes names with a "-journal" suffix legal.
   */
   const validateStorageName = function(n,mayBeJournal=false){
     if( kvvfsIsPersistentName(n) ) return;
-    const len = n.length;
+    const len = (new Blob([n])).size/*byte length*/;
     if( !len ) toss3(capi.SQLITE_RANGE, "Empty name is not permitted.");
     let maxLen = cache.keySize - 1;
     if( cache.rxJournalSuffix.test(n) ){
@@ -296,7 +294,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
               "Storage names may not have a '-journal' suffix.");
       }
     }else{
-      maxLen -= 8 /* "-journal" */;
+      maxLen -= 8 /* so we have space for a matching "-journal" suffix */;
     }
     if( len > maxLen ){
       toss3(capi.SQLITE_RANGE, "Storage name is too long. Limit =", maxLen);
@@ -304,7 +302,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
     let i;
     for( i = 0; i < len; ++i ){
       const ch = n.codePointAt(i);
-      if( ch<43 || ch >126 ){
+      if( ch<32 ){
         toss3(capi.SQLITE_RANGE,
               "Illegal character ("+ch+"d) in storage name:",n);
       }
@@ -479,58 +477,64 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
 
      'sync': true if it's from xSync(), false if it's from
      xFileControl().
+
+     For efficiency's sake, all calls to this function should
+     be in the form:
+
+     store.listeners && notifyListeners(...);
+
+     Failing to do so will trigger an exceptin in this function (which
+     will be ignored but may produce a console warning).
   */
   const notifyListeners = async function(eventName,store,...args){
     try{
-      if( store.listeners ){
-        //cache.rxPageNoSuffix ??= /(\d+)$/;
-        if( store.keyPrefix && args[0] ){
-          args[0] = args[0].replace(store.keyPrefix,'');
-        }
-        let u8enc, z0, z1, wcache;
-        for(const ear of store.listeners){
-          const ev = Object.create(null);
-          ev.storageName = store.jzClass;
-          ev.type = eventName;
-          const decodePages = ear.decodePages;
-          const f = ear.events[eventName];
-          if( f ){
-            if( !ear.includeJournal && args[0]==='jrnl' ){
+      //cache.rxPageNoSuffix ??= /(\d+)$/;
+      if( store.keyPrefix && args[0] ){
+        args[0] = args[0].replace(store.keyPrefix,'');
+      }
+      let u8enc, z0, z1, wcache;
+      for(const ear of store.listeners){
+        const ev = Object.create(null);
+        ev.storageName = store.jzClass;
+        ev.type = eventName;
+        const decodePages = ear.decodePages;
+        const f = ear.events[eventName];
+        if( f ){
+          if( !ear.includeJournal && args[0]==='jrnl' ){
+            continue;
+          }
+          if( 'write'===eventName && ear.decodePages && +args[0]>0 ){
+            /* Decode pages to Uint8Array, caching the result in
+               wcache in case we have more listeners. */
+            ev.data = [args[0]];
+            if( wcache?.[args[0]] ){
+              ev.data[1] = wcache[args[0]];
               continue;
             }
-            if( 'write'===eventName && ear.decodePages && +args[0]>0 ){
-              /* Decode pages to Uint8Array, caching the result in
-                 wcache in case we have more listeners. */
-              ev.data = [args[0]];
-              if( wcache?.[args[0]] ){
-                ev.data[1] = wcache[args[0]];
-                continue;
-              }
-              u8enc ??= new TextEncoder('utf-8');
-              z0 ??= cache.memBuffer(10);
-              z1 ??= cache.memBuffer(11);
-              const u = u8enc.encode(args[1]);
-              const heap = wasm.heap8u();
-              heap.set(u, Number(z0));
-              heap[wasm.ptr.addn(z0, u.length)] = 0;
-              const rc = kvvfsDecode(z0, z1, cache.buffer.n);
-              if( rc>0 ){
-                wcache ??= Object.create(null);
-                wcache[args[0]]
-                  = ev.data[1]
-                  = heap.slice(Number(z1), wasm.ptr.addn(z1,rc));
-              }else{
-                continue;
-              }
+            u8enc ??= new TextEncoder('utf-8');
+            z0 ??= cache.memBuffer(10);
+            z1 ??= cache.memBuffer(11);
+            const u = u8enc.encode(args[1]);
+            const heap = wasm.heap8u();
+            heap.set(u, Number(z0));
+            heap[wasm.ptr.addn(z0, u.length)] = 0;
+            const rc = kvvfsDecode(z0, z1, cache.buffer.n);
+            if( rc>0 ){
+              wcache ??= Object.create(null);
+              wcache[args[0]]
+                = ev.data[1]
+                = heap.slice(Number(z1), wasm.ptr.addn(z1,rc));
             }else{
-              ev.data = args.length
-                ? ((args.length===1) ? args[0] : args)
-                : undefined;
-            }
-            try{f(ev)?.catch?.(catchForNotify)}
-            catch(e){
-              warn("notifyListeners [",store.jzClass,"]",eventName,e);
+              continue;
             }
+          }else{
+            ev.data = args.length
+              ? ((args.length===1) ? args[0] : args)
+              : undefined;
+          }
+          try{f(ev)?.catch?.(catchForNotify)}
+          catch(e){
+            warn("notifyListeners [",store.jzClass,"]",eventName,e);
           }
         }
       }
@@ -772,8 +776,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
           const jzClass = wasm.cstrToJs(zName);
           //debug("xOpen",jzClass);
           validateStorageName(jzClass, true);
-          util.assert( jzClass.length===wasm.cstrlen(zName),
-                       "ASCII-only validation failed" );
           if( (flags & (capi.SQLITE_OPEN_MAIN_DB
                         | capi.SQLITE_OPEN_TEMP_DB
                         | capi.SQLITE_OPEN_TRANSIENT_DB))
index c6db797237b905f3fc01f559020772b58b920157..e0cb8408fe32bbf87323b424ce68aae8f8510469 100644 (file)
@@ -2978,14 +2978,20 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
         const DB = sqlite3.oo1.DB;
 
         T.mustThrowMatching(()=>{
-          new JDb("this is an illegal name too long and spaces");
+          new JDb("this\ns an illegal - contains control characters");
           /* We don't have a way to get error strings from xOpen()
              to this point? xOpen() does not have a handle to the
              db and SQLite is not calling xGetLastError() to fetch
              the error string. */
         }, capi.SQLITE_RANGE);
         T.mustThrowMatching(()=>{
-          new JDb("012345678901234567890123"/*too long*/);
+          new JDb("01234567890123456789"+
+                  "01234567890123456789"+
+                  "01234567890123456789"+
+                  "01234567890123456789"+
+                  "01234567890123456789"+
+                  "01234567890123456789"+
+                  "0"/*too long*/);
         }, capi.SQLITE_RANGE);
         T.mustThrowMatching(()=>new JDb(""), capi.SQLITE_RANGE);
         {
@@ -3074,7 +3080,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
       name: 'concurrent transient kvvfs',
       //predicate: ()=>false,
       test: function(sqlite3){
-        const filename = 'my';
+        const filename = '👷';
         const kvvfs = sqlite3.kvvfs;
         const DB = sqlite3.oo1.DB;
         const JDb = sqlite3.oo1.JsStorageDb;
@@ -3284,6 +3290,12 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
             includeJournal: pglog.includeJournal,
             decodePages: pglog.decodePages,
             events: {
+              /**
+                 These may be async but must not be in this case
+                 because we can't test their result without a lot of
+                 hoop-jumping if they are. Kvvfs calls these
+                 asynchronously, though.
+               */
               'open':   (ev)=>{
                 //console.warn('open',ev);
                 incr(ev.type);
@@ -3291,8 +3303,6 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
                   .assert('number'===typeof ev.data);
               },
               'close': (ev)=>{
-                //^^^ if this is async, we can't time the test for
-                // pglog.exception without far more hoop-jumping.
                 //console.warn('close',ev);
                 incr(ev.type);
                 T.assert('number'===typeof ev.data);
index 0d864feab417c7efdd0f4dd7044a8cefee167ca5..3c08cceb9016c73699e991398b67a795c2ebfb48 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Reformulate\ssqlite3-wasm.c's\sexports\sso\sthat\sthey\sexport\sproperly\swith\sthe\swask-sdk\scompiler.
-D 2025-12-01T16:25:53.470
+C Relax\sthe\sname\slimits\son\skvvfs\sdbs.
+D 2025-12-01T16:28:55.133
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -600,7 +600,7 @@ F ext/wasm/api/sqlite3-api-worker1.c-pp.js 1041dd645e8e821c082b628cd8d9acf70c667
 F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
 F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966
 F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d
-F ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js 82e29781ab83805c7c82ddfe3b5c8fdbc65a914f1433bf966fd7f0f08c7c7c8b
+F ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js 7b723b492460c1531334b0855f02556b45fc767f0276fe7110f5d651679a8a70
 F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js a2eea6442556867b589e04107796c6e1d04a472219529eeb45b7cd221d7d048b
 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 88ce2078267a2d1af57525a32d896295f4a8db7664de0e17e82dc9ff006ed8d3
 F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 366596d8ff73d4cefb938bbe95bc839d503c3fab6c8335ce4bf52f0d8a7dee81
@@ -647,7 +647,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
 F ext/wasm/tester1-worker.c-pp.html 0e432ec2c0d99cd470484337066e8d27e7aee4641d97115338f7d962bf7b081a
 F ext/wasm/tester1.c-pp.html 52d88fe2c6f21a046030a36410b4839b632f4424028197a45a3d5669ea724ddb
-F ext/wasm/tester1.c-pp.js f248ff562b75ce1040c8d148d648afce7cad50683f532cac96dd82ccabcf282e
+F ext/wasm/tester1.c-pp.js 7506d33282dd3e02437a0e3f2eb477c7ae346099d28d482a74a5b4ee9d4028c5
 F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e
 F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@@ -2180,8 +2180,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 104291469169bef0c2ec5aee9c1cc505447541801bc822e6d5fe5360aef6a2e4
-R 53cc160340c8953977c4053fb7d21394
+P d71849958aabdb05225be18d6bc46699cfda9de67c7105b11c3f79d1d01f47d4
+R fd9d654ea19b0109ad238cc31ff79cd0
 U stephan
-Z 34eeecdc220cc86d4441f67333d1408a
+Z 7cd40f087bc8b7facc6511e6b1140591
 # Remove this line to create a well-formed Fossil manifest.
index 5cf8d92eb810e40a80597c8bf3a93486cfc13946..3757218b73cc8a03d4c52924f358062ea4df156a 100644 (file)
@@ -1 +1 @@
-d71849958aabdb05225be18d6bc46699cfda9de67c7105b11c3f79d1d01f47d4
+9901cf8e4a00ea9a199a3fb54bd58bd66cff4d02c55433d55f2b417e188e49e0