From bc5e0be7f856bbae4bd8cf652b85457c51fe588a Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 30 Oct 2025 02:21:38 +0000 Subject: [PATCH] A experiment addressing the embedded-NUL behavior of sqlite3_colum/value_text() in the JS bindings, as discussed in [forum:d77281aec2df9ada|forum post d77281aec2]. This is an experiment only. It works, in that existing tests do not see the difference, but it has implicications which require careful consideration before deploying. FossilOrigin-Name: d0e803b90344ee972e4b3fb30b77e283599dc4d5c6a3335ce9fea653a1b3f6f0 --- ext/wasm/GNUmakefile | 2 +- ext/wasm/api/sqlite3-api-glue.c-pp.js | 45 +++++++++++++++++++++++++++ manifest | 14 ++++----- manifest.uuid | 2 +- 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index 937e16d6ef..6e6c4c47cc 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -516,7 +516,7 @@ bin.c-pp = ./c-pp-lite $(bin.c-pp): c-pp-lite.c $(sqlite3.c) $(MAKEFILE) $(CC) -O0 -o $@ c-pp-lite.c $(sqlite3.c) '-DCMPP_DEFAULT_DELIM="//#"' -I$(dir.top) \ -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_UTF16 \ - -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_WAL -DSQLITE_THREADSAFE=0 \ + -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_THREADSAFE=0 \ -DSQLITE_TEMP_STORE=3 DISTCLEAN_FILES += $(bin.c-pp) b.c-pp.target.flags ?= diff --git a/ext/wasm/api/sqlite3-api-glue.c-pp.js b/ext/wasm/api/sqlite3-api-glue.c-pp.js index 9d3aac61ac..692363fc44 100644 --- a/ext/wasm/api/sqlite3-api-glue.c-pp.js +++ b/ext/wasm/api/sqlite3-api-glue.c-pp.js @@ -120,7 +120,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_column_double","f64", "sqlite3_stmt*", "int"], ["sqlite3_column_int","int", "sqlite3_stmt*", "int"], ["sqlite3_column_name","string", "sqlite3_stmt*", "int"], +//#define proxy-text-apis=1 +//#if not proxy-text-apis +/* Search this file for tag:proxy-text-apis to see what this is about. */ ["sqlite3_column_text","string", "sqlite3_stmt*", "int"], +//#endif ["sqlite3_column_type","int", "sqlite3_stmt*", "int"], ["sqlite3_column_value","sqlite3_value*", "sqlite3_stmt*", "int"], ["sqlite3_commit_hook", "void*", [ @@ -317,7 +321,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_value_numeric_type", "int", "sqlite3_value*"], ["sqlite3_value_pointer", "*", "sqlite3_value*", "string:static"], ["sqlite3_value_subtype", "int", "sqlite3_value*"], +//#if not proxy-text-apis ["sqlite3_value_text", "string", "sqlite3_value*"], +//#endif ["sqlite3_value_type", "int", "sqlite3_value*"], ["sqlite3_vfs_find", "*", "string"], ["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"], @@ -1654,6 +1660,45 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }/*sqlite3_bind_text/blob()*/ +//#if proxy-text-apis + if(!capi.sqlite3_column_text){ + /*[tag:proxy-text-apis] + As discussed at: + + https://sqlite.org/forum/forumpost/d77281aec2df9ada + + Summary: there are opinions that sqlite3_column_text() and + sqlite3_value_text() should handle strings such that embedded + NULs are retained. This block does that. This block does _not_ + apply that special-case behavior to any number of _other_ + APIs which return C-strings. That discrepancy makes this + block highly arguable, but one can also argue that these two + specific functions can get away with such acrobatics without + it being called voodoo in a pejorative sense. + */ + const argStmt = wasm.xWrap.argAdapter('sqlite3_stmt*'), + argInt = wasm.xWrap.argAdapter('int'), + argValue = wasm.xWrap.argAdapter('sqlite3_value*'), + newStr = + (cstr,n)=>wasm.typedArrayToString(wasm.heap8u(), + Number(cstr), Number(cstr)+n) + capi.sqlite3_column_text = function(stmt, colIndex){ + const a0 = argStmt(stmt), a1 = argInt(colIndex); + const cstr = wasm.exports.sqlite3_column_text(a0, a1); + return cstr + ? newStr(cstr,wasm.exports.sqlite3_column_bytes(a0, a1)) + : null; + }; + capi.sqlite3_value_text = function(val){ + const a0 = argValue(val); + const cstr = wasm.exports.sqlite3_value_text(a0); + return cstr + ? newStr(cstr,wasm.exports.sqlite3_value_bytes(a0)) + : null; + }; + }/*text-return-related bindings*/ +//#endif proxy-text-apis + {/* sqlite3_config() */ /** Wraps a small subset of the C API's sqlite3_config() options. diff --git a/manifest b/manifest index 46ca081bed..139c0017e8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Demonstrate\sthe\sopfs-sahpool\sVFS\swith\sSEE. -D 2025-10-26T21:45:02.188 +C A\sexperiment\saddressing\sthe\sembedded-NUL\sbehavior\sof\ssqlite3_colum/value_text()\sin\sthe\sJS\sbindings,\sas\sdiscussed\sin\s[forum:d77281aec2df9ada|forum\spost\sd77281aec2].\sThis\sis\san\sexperiment\sonly.\sIt\sworks,\sin\sthat\sexisting\stests\sdo\snot\ssee\sthe\sdifference,\sbut\sit\shas\simplicications\swhich\srequire\scareful\sconsideration\sbefore\sdeploying. +D 2025-10-30T02:21:38.772 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -576,7 +576,7 @@ F ext/session/sqlite3session.c b3de195ce668cace9b324599bf6255a70290cbfb5451e826e F ext/session/sqlite3session.h 7404723606074fcb2afdc6b72c206072cdb2b7d8ba097ca1559174a80bc26f7a F ext/session/test_session.c 8766b5973a6323934cb51248f621c3dc87ad2a98f023c3cc280d79e7d78d36fb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile 3dc01e673c456d3b752674c9407276e8fef35dec1d304b3cc1de362f019b2a09 +F ext/wasm/GNUmakefile b2c68abe6643a12a18b124cf524cebb133593dd11b76433bd72e08223f09b26f F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a F ext/wasm/README.md 2e87804e12c98f1d194b7a06162a88441d33bb443efcfe00dc6565a780d2f259 F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -595,7 +595,7 @@ F ext/wasm/api/post-js-footer.js 5bd7170b5e8ce7b62102702bbcf47ef7b3b49cd56ed40c0 F ext/wasm/api/post-js-header.js 79d078aec33d93b640a19c574b504d88bb2446432f38e2fbb3bb8e36da436e70 F ext/wasm/api/pre-js.c-pp.js a876c6399dff29b6fe9e434036beb89889164cc872334e184291723ecc7cb072 F ext/wasm/api/sqlite3-api-cleanup.js a3d6b9e449aefbb8bba283c2ba9477e2333a0eeb94a7a26b5bf952736f65a6dd -F ext/wasm/api/sqlite3-api-glue.c-pp.js e9364e19cb835070d7e38f276afce590ca07de3294ed705ec3b2ab431d4caa95 +F ext/wasm/api/sqlite3-api-glue.c-pp.js 79a54b54ca6324d28e31e19b56bbaebb7d2cc4b3079066e7e901333fa5047c53 F ext/wasm/api/sqlite3-api-oo1.c-pp.js 31dbfd470c91ffd96d77399b749bab6b69e3ba9074188833f97ac13f087cf07b F ext/wasm/api/sqlite3-api-prologue.js b5a55ae74efcdcd0aa6a143d59e34137e43ae732f02b563dcab22d735f1599a4 F ext/wasm/api/sqlite3-api-worker1.c-pp.js 1041dd645e8e821c082b628cd8d9acf70c667430f9d45167569633ffc7567938 @@ -2171,8 +2171,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1eb5a7ea394aa5b7e8594d73ce31f4b9bef55f2fa977dc26810c0bfba1cc39f7 -R ad24e4d776c0642a4338f3a9a03fa5cb +P b4cffc00f3a18906867e8f070fbc49293ac5c038bad58e96ea74948591f31013 +R fe28c5ec779653b5f1e7eb5a6384c93f U stephan -Z f8799f7567d58ff6658a16b74cf1ecfb +Z 8d01b9d7ca0f47e094bf79066e5d72c3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 999a355fa9..bcc762206d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b4cffc00f3a18906867e8f070fbc49293ac5c038bad58e96ea74948591f31013 +d0e803b90344ee972e4b3fb30b77e283599dc4d5c6a3335ce9fea653a1b3f6f0 -- 2.47.3