From: stephan Date: Tue, 25 Nov 2025 02:08:49 +0000 (+0000) Subject: Add xGetLastError() to kvvfs but it does not appear to be called for xOpen() failures. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d3a0fc54736f842235516fe7625407ed86ec4ca2;p=thirdparty%2Fsqlite.git Add xGetLastError() to kvvfs but it does not appear to be called for xOpen() failures. FossilOrigin-Name: 7e7944f00792c5e7a9ea013f9c5d1f6bb6313070de20ec4ce262ff0b430f9801 --- diff --git a/ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js b/ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js index ffd9057da5..21d1425089 100644 --- a/ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js +++ b/ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js @@ -105,15 +105,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ zKeySz: wasm.allocCString("sz") }); - const debug = function(){ - sqlite3.config.debug("kvvfs:", ...arguments); - }; - const warn = function(){ - sqlite3.config.warn("kvvfs:", ...arguments); - }; - const error = function(){ - sqlite3.config.error("kvvfs:", ...arguments); - }; + const debug = sqlite3.__isUnderTest + ? function(){sqlite3.config.debug("kvvfs:", ...arguments)} + : function(){}; + const warn = function(){sqlite3.config.warn("kvvfs:", ...arguments)}; + const error = function(){sqlite3.config.error("kvvfs:", ...arguments)}; /** Implementation of JS's Storage interface for use as backing store @@ -256,6 +252,21 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ cache.storagePool[k+'-journal'] = orig; } + cache.setError = (e=undefined)=>{ + if( e ){ + cache.lastError = e; + return (e.resultCode | 0) || capi.SQLITE_ERROR; + } + delete cache.lastError; + return 0; + }; + + cache.popError = ()=>{ + const e = cache.lastError; + delete cache.lastError; + return e; + }; + /** Returns the storage object mapped to the given string zClass (C-string pointer or JS string). @@ -396,6 +407,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const pFileHandles = new Map(); if( sqlite3.__isUnderTest ){ + /* For inspection via the dev tools console. */ sqlite3.kvvfsStuff = { pFileHandles, cache @@ -564,6 +576,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ vfs:{ /* sqlite3_kvvfs_methods::pVfs's methods */ xOpen: function(pProtoVfs,zName,pProtoFile,flags,pOutFlags){ + cache.popError(); try{ //cache.zReadBuf ??= wasm.malloc(kvvfsMethods.$nBufferSize); if( !zName ){ @@ -571,23 +584,25 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } const n = wasm.cstrlen(zName); if( !n ){ - warn("file name may not be empty (backwards compatibilty constraint)"); - return capi.SQLITE_RANGE; + util.toss3(capi.SQLITE_RANGE, + "Storage name may not be empty (backwards", + "compatibilty constraint)"); }else if( n > kvvfsMethods.$nKeySize - 8 /*"-journal"*/ - 1 ){ - warn("file name is too long:", wasm.cstrToJs(zName)); - return capi.SQLITE_RANGE; + util.toss3(capi.SQLITE_RANGE, + "Storage name is too long:", wasm.cstrToJs(zName)); } - const jzClass = wasm.cstrToJs(zName); - if( jzClass?.length != n ){ - warn("kvvfs file name must be ASCII-only:",jzClass); - /* This limitation is to avoide any issues with - truncating multi-byte characters in kvvfs's key-size - limit. */ - return capi.SQLITE_RANGE; + let i = 0; + for( ; i < n; ++i ){ + const ch = wasm.peek8(wasm.ptr.add(zName, i)); + if( ch < 45 || (ch & 0x80) ){ + util.toss3(capi.SQLITE_RANGE, + "Illegal character ("+ch+"d) in storage name."); + } } const rc = originalMethods.vfs.xOpen(pProtoVfs, zName, pProtoFile, flags, pOutFlags); if( rc ) return rc; + const jzClass = wasm.cstrToJs(zName); let deleteAt0 = false; if(n && wasm.isPtr(zName)){ if(capi.sqlite3_uri_boolean(zName, "delete-on-close", 0)){ @@ -595,7 +610,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ //warn("transient=",deleteAt0); } if(capi.sqlite3_uri_boolean(zName, "wipe-before-open", 0)){ - // TODO + // TODO? } } const f = new KVVfsFile(pProtoFile); @@ -629,11 +644,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return 0; }catch(e){ warn("xOpen:",e); - return capi.SQLITE_ERROR; + return cache.setError(e); } }/*xOpen()*/, xDelete: function(pVfs, zName, iSyncFlag){ + cache.popError(); try{ const jzName = wasm.cstrToJs(zName); //debug("xDelete", jzName, storageForZClass(jzName)); @@ -643,11 +659,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return 0; }catch(e){ warn("xDelete",e); - return capi.SQLITE_ERROR; + return cache.setError(e); } }, - xAccess:function(pProtoVfs, zPath, flags, pResOut){ + xAccess: function(pProtoVfs, zPath, flags, pResOut){ + cache.popError(); try{ /** In every test run to date, if this function sets @@ -694,7 +711,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ } }catch(e){ error('xAccess',e); - return capi.SQLITE_ERROR; + return cache.setError(e); } }, @@ -704,6 +721,25 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const npOut = Number(pOut); for(; i < nOut; ++i) heap[npOut + i] = (Math.random()*255000) & 0xFF; return i; + }, + + xGetLastError: function(pVfs,nOut,pOut){ + const e = cache.popError(); + debug('xGetLastError',e); + if(e){ + const scope = wasm.scopedAllocPush(); + try{ + const [cMsg, n] = wasm.scopedAllocCString(e.message, true); + wasm.cstrncpy(pOut, cMsg, nOut); + if(n > nOut) wasm.poke8(wasm.ptr.add(pOut,nOut,-1), 0); + debug("set xGetLastError",e.message); + }catch(e){ + return capi.SQLITE_NOMEM; + }finally{ + wasm.scopedAllocPop(scope); + } + } + return e ? ((e.resultCode | 0) || capi.SQLITE_IOERR) : 0; } //#if nope @@ -817,8 +853,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const k = e[0], f = e[1], km = pVfs.memberKey(k), member = pVfs.structInfo.members[k] || util.toss("Missing pVfs.structInfo[",k,"]"); - originalMethods.vfs[k] = wasm.functionEntry(pVfs[km]) - || util.toss("Missing native pVfs[",km,"]"); + originalMethods.vfs[k] = wasm.functionEntry(pVfs[km]); pVfs[km] = wasm.installFunction(member.signature, f); } for(const e of Object.entries(methodOverrides.ioDb)){ diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index 6499bfab83..1e4aa2bc40 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -3005,6 +3005,14 @@ globalThis.sqlite3InitModule = sqlite3InitModule; 'insert into kvvfs(a) values(1),(2),(3)' ]; const sqlCount = 'select count(*) from kvvfs'; + T.mustThrowMatching(()=>{ + new JDb("this is an illegal name too long and spaces"); + /* 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); + try { const exportDb = capi.sqlite3_js_kvvfs_export_storage; const dbFileRaw = 'file:'+filename+'?vfs=kvvfs&delete-on-close=1'; diff --git a/manifest b/manifest index 2cc225ff1c..11ba504a42 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\s32-/64-bit\sincompatibility\sin\sopfs-sahpool. -D 2025-11-25T02:08:11.348 +C Add\sxGetLastError()\sto\skvvfs\sbut\sit\sdoes\snot\sappear\sto\sbe\scalled\sfor\sxOpen()\sfailures. +D 2025-11-25T02:08:49.217 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 dc3e2df2a09136665c0a4f2c9e1c834fdde04e935dc29805d5f07bd81891de9e +F ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js 7d2164cda7bf60b36ecfc7449941304e51c83f3f1316330ead8ce289e73e55c3 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 9097074724172e31e56ce20ccd7482259cf72a76124213cbc9469d757676da86 @@ -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 640e0e237d138ea571a025002576296f2cebc0c191b543e04ccbc65364cf2e85 +F ext/wasm/tester1.c-pp.js 1873759a7458ca2af4bf0fce45c212f66beae42a060ad60239506cb55c15cfa4 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 @@ -2178,8 +2178,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 46d6b636307d98d17344d995afd99204e16eb06b6b19021a824dab95267d5377 -R 7af0b63d5c9006f3e5523ff70603b001 +P 256c1dd2c367dbc3b3df5028f2004bb1126851109efc71a1699f60f493514fcb +R a5c65bf09dd877f8372e302b549b77a5 U stephan -Z d59f124b05fb2d4a47ae67c8eaf227d8 +Z 4c042414806a8452b832f74ca1c4f2f7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 10274f2b29..3bd21c69c3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -256c1dd2c367dbc3b3df5028f2004bb1126851109efc71a1699f60f493514fcb +7e7944f00792c5e7a9ea013f9c5d1f6bb6313070de20ec4ce262ff0b430f9801