1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-10-24 09:53:10 +03:00

Diverse internal cleanups in the JS/WASM pieces. A potential fix for a hypothetical db-close-time resource leak of a subset of automated JS-to-WASM function conversions in Safari. That browser exposes WASM-exported functions via nullary wrappers, which causes a handful of them to misbehave (not clean up) at sqlite3_close_v2()-time.

FossilOrigin-Name: fabbc8b6d184d52a513e80fabd900f578424fc8a8055e3d64fac54b9e28ea18a
This commit is contained in:
stephan
2025-09-15 14:11:55 +00:00
parent 36595d0630
commit c35f07ec2f
4 changed files with 412 additions and 401 deletions

View File

@@ -79,11 +79,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
// elements instead: [x,y,z] is equivalent to x,y,z
]
Note that support for the API-specific data types in the
result/argument type strings gets plugged in at a later phase in
the API initialization process.
Support for the API-specific data types in the result/argument
type strings gets plugged in at a later phase in the API
initialization process.
*/
wasm.bindingSignatures = [
const bindingSignatures = {
core: [
// Please keep these sorted by function name!
["sqlite3_aggregate_context","void*", "sqlite3_context*", "int"],
/* sqlite3_auto_extension() has a hand-written binding. */
@@ -298,9 +299,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
"*"
]],
["sqlite3_txn_state", "int", ["sqlite3*","string"]],
/* Note that sqlite3_uri_...() have very specific requirements for
their first C-string arguments, so we cannot perform any value
conversion on those. */
/* sqlite3_uri_...() have very specific requirements for their
first C-string arguments, so we cannot perform any
string-type conversion on their first argument. */
["sqlite3_uri_boolean", "int", "sqlite3_filename", "string", "int"],
["sqlite3_uri_key", "string", "sqlite3_filename", "int"],
["sqlite3_uri_parameter", "string", "sqlite3_filename", "string"],
@@ -321,100 +322,21 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
["sqlite3_vfs_find", "*", "string"],
["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"],
["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"]
]/*wasm.bindingSignatures*/;
if( !!wasm.exports.sqlite3_progress_handler ){
wasm.bindingSignatures.push(
["sqlite3_progress_handler", undefined, [
"sqlite3*", "int", new wasm.xWrap.FuncPtrAdapter({
name: 'xProgressHandler',
signature: 'i(p)',
bindScope: 'context',
contextKey: (argv,argIndex)=>argv[0/* sqlite3* */]
}), "*"
]]
);
}
if( !!wasm.exports.sqlite3_stmt_explain ){
wasm.bindingSignatures.push(
["sqlite3_stmt_explain", "int", "sqlite3_stmt*", "int"],
["sqlite3_stmt_isexplain", "int", "sqlite3_stmt*"]
);
}
if( !!wasm.exports.sqlite3_set_authorizer ){
wasm.bindingSignatures.push(
["sqlite3_set_authorizer", "int", [
"sqlite3*",
new wasm.xWrap.FuncPtrAdapter({
name: "sqlite3_set_authorizer::xAuth",
signature: "i(pi"+"ssss)",
contextKey: (argv, argIndex)=>argv[0/*(sqlite3*)*/],
callProxy: (callback)=>{
return (pV, iCode, s0, s1, s2, s3)=>{
try{
s0 = s0 && wasm.cstrToJs(s0); s1 = s1 && wasm.cstrToJs(s1);
s2 = s2 && wasm.cstrToJs(s2); s3 = s3 && wasm.cstrToJs(s3);
return callback(pV, iCode, s0, s1, s2, s3) || 0;
}catch(e){
return e.resultCode || capi.SQLITE_ERROR;
}
}
}
}),
"*"/*pUserData*/
]]
);
}/* sqlite3_set_authorizer() */
if( !!wasm.exports.sqlite3_column_origin_name ){
wasm.bindingSignatures.push(
["sqlite3_column_database_name","string", "sqlite3_stmt*", "int"],
["sqlite3_column_origin_name","string", "sqlite3_stmt*", "int"],
["sqlite3_column_table_name","string", "sqlite3_stmt*", "int"]
);
}
if(false && wasm.compileOptionUsed('SQLITE_ENABLE_NORMALIZE')){
/* ^^^ "the problem" is that this is an optional feature and the
build-time function-export list does not currently take
optional features into account. */
wasm.bindingSignatures.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]);
}
//#if enable-see
if(wasm.exports.sqlite3_key_v2 instanceof Function){
/* This list gets extended below */
]/*.core*/,
/**
This code is capable of using an SEE build but note that an SEE
WASM build is generally incompatible with SEE's license
conditions. It is permitted for use internally in organizations
which have licensed SEE, but not for public sites because
exposing an SEE build of sqlite3.wasm effectively provides all
clients with a working copy of the commercial SEE code.
*/
wasm.bindingSignatures.push(
["sqlite3_key", "int", "sqlite3*", "string", "int"],
["sqlite3_key_v2","int","sqlite3*","string","*","int"],
["sqlite3_rekey", "int", "sqlite3*", "string", "int"],
["sqlite3_rekey_v2", "int", "sqlite3*", "string", "*", "int"],
["sqlite3_activate_see", undefined, "string"]
);
}
//#endif enable-see
Functions which require BigInt (int64) support are separated
from the others because we need to conditionally bind them or
apply dummy impls, depending on the capabilities of the
environment. (That said: we never actually build without
BigInt support, and such builds are untested.)
/**
Functions which require BigInt (int64) support are separated from
the others because we need to conditionally bind them or apply
dummy impls, depending on the capabilities of the environment.
(That said: we never actually build without BigInt support,
and such builds are untested.)
Note that not all of these functions directly require int64
but are only for use with APIs which require int64. For example,
the vtab-related functions.
Not all of these functions directly require int64 but are only
for use with APIs which require int64. For example, the
vtab-related functions.
*/
wasm.bindingSignatures.int64 = [
int64: [
["sqlite3_bind_int64","int", ["sqlite3_stmt*", "int", "i64"]],
["sqlite3_changes64","i64", ["sqlite3*"]],
["sqlite3_column_int64","i64", ["sqlite3_stmt*", "int"]],
@@ -453,10 +375,120 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
]],
["sqlite3_uri_int64", "i64", ["sqlite3_filename", "string", "i64"]],
["sqlite3_value_int64","i64", "sqlite3_value*"]
];
/* This list gets extended below */
]/*.int64*/,
/**
Functions which are intended solely for API-internal use by the
WASM components, not client code. These get installed into
sqlite3.util. Some of them get exposed to clients via variants
in sqlite3_js_...().
2024-01-11: these were renamed, with two underscores in the
prefix, to ensure that clients do not accidentally depend on
them. They have always been documented as internal-use-only,
so no clients "should" be depending on the old names.
*/
wasmInternal: [
["sqlite3__wasm_db_reset", "int", "sqlite3*"],
["sqlite3__wasm_db_vfs", "sqlite3_vfs*", "sqlite3*","string"],
[/* DO NOT USE. This is deprecated since 2023-08-11 because it
can trigger assert() in debug builds when used with file
sizes which are not an exact multiple of a valid db page
size. This function is retained only so that
sqlite3_js_vfs_create_file() can continue to work (for a
given value of work), but that function emits a
config.warn() log message directing the reader to
alternatives. */
"sqlite3__wasm_vfs_create_file", "int", "sqlite3_vfs*","string","*", "int"
],
["sqlite3__wasm_posix_create_file", "int", "string","*", "int"],
["sqlite3__wasm_vfs_unlink", "int", "sqlite3_vfs*","string"],
["sqlite3__wasm_qfmt_token","string:dealloc", "string","int"]
]/*.wasmInternal*/
} /*bindingSignatures*/;
if( !!wasm.exports.sqlite3_progress_handler ){
bindingSignatures.core.push(
["sqlite3_progress_handler", undefined, [
"sqlite3*", "int", new wasm.xWrap.FuncPtrAdapter({
name: 'xProgressHandler',
signature: 'i(p)',
bindScope: 'context',
contextKey: (argv,argIndex)=>argv[0/* sqlite3* */]
}), "*"
]]
);
}
if( !!wasm.exports.sqlite3_stmt_explain ){
bindingSignatures.core.push(
["sqlite3_stmt_explain", "int", "sqlite3_stmt*", "int"],
["sqlite3_stmt_isexplain", "int", "sqlite3_stmt*"]
);
}
if( !!wasm.exports.sqlite3_set_authorizer ){
bindingSignatures.core.push(
["sqlite3_set_authorizer", "int", [
"sqlite3*",
new wasm.xWrap.FuncPtrAdapter({
name: "sqlite3_set_authorizer::xAuth",
signature: "i(pi"+"ssss)",
contextKey: (argv, argIndex)=>argv[0/*(sqlite3*)*/],
callProxy: (callback)=>{
return (pV, iCode, s0, s1, s2, s3)=>{
try{
s0 = s0 && wasm.cstrToJs(s0); s1 = s1 && wasm.cstrToJs(s1);
s2 = s2 && wasm.cstrToJs(s2); s3 = s3 && wasm.cstrToJs(s3);
return callback(pV, iCode, s0, s1, s2, s3) || 0;
}catch(e){
return e.resultCode || capi.SQLITE_ERROR;
}
}
}
}),
"*"/*pUserData*/
]]
);
}/* sqlite3_set_authorizer() */
if( !!wasm.exports.sqlite3_column_origin_name ){
bindingSignatures.core.push(
["sqlite3_column_database_name","string", "sqlite3_stmt*", "int"],
["sqlite3_column_origin_name","string", "sqlite3_stmt*", "int"],
["sqlite3_column_table_name","string", "sqlite3_stmt*", "int"]
);
}
if(false && wasm.compileOptionUsed('SQLITE_ENABLE_NORMALIZE')){
/* ^^^ "the problem" is that this is an optional feature and the
build-time function-export list does not currently take
optional features into account. */
bindingSignatures.core.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]);
}
//#if enable-see
if( !!wasm.exports.sqlite3_key_v2 ){
/**
This code is capable of using an SEE build but note that an SEE
WASM build is generally incompatible with SEE's license
conditions. It is permitted for use internally in organizations
which have licensed SEE, but not for public sites because
exposing an SEE build of sqlite3.wasm effectively provides all
clients with a working copy of the commercial SEE code.
*/
bindingSignatures.core.push(
["sqlite3_key", "int", "sqlite3*", "string", "int"],
["sqlite3_key_v2","int","sqlite3*","string","*","int"],
["sqlite3_rekey", "int", "sqlite3*", "string", "int"],
["sqlite3_rekey_v2", "int", "sqlite3*", "string", "*", "int"],
["sqlite3_activate_see", undefined, "string"]
);
}
//#endif enable-see
if( wasm.bigIntEnabled && !!wasm.exports.sqlite3_declare_vtab ){
wasm.bindingSignatures.int64.push(
bindingSignatures.int64.push(
["sqlite3_create_module", "int",
["sqlite3*","string","sqlite3_module*","*"]],
["sqlite3_create_module_v2", "int",
@@ -477,7 +509,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}/* virtual table APIs */
if(wasm.bigIntEnabled && !!wasm.exports.sqlite3_preupdate_hook){
wasm.bindingSignatures.int64.push(
bindingSignatures.int64.push(
["sqlite3_preupdate_blobwrite", "int", "sqlite3*"],
["sqlite3_preupdate_count", "int", "sqlite3*"],
["sqlite3_preupdate_depth", "int", "sqlite3*"],
@@ -522,7 +554,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
};
wasm.bindingSignatures.int64.push(...[
bindingSignatures.int64.push(
['sqlite3changegroup_add', 'int', ['sqlite3_changegroup*', 'int', 'void*']],
['sqlite3changegroup_add_strm', 'int', [
'sqlite3_changegroup*',
@@ -677,36 +709,13 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}),
'*'
]]
]);
);
}/*session/changeset APIs*/
/**
Functions which are intended solely for API-internal use by the
WASM components, not client code. These get installed into
sqlite3.util. Some of them get exposed to clients via variants
in sqlite3_js_...().
2024-01-11: these were renamed, with two underscores in the
prefix, to ensure that clients do not accidentally depend on
them. They have always been documented as internal-use-only, so
no clients "should" be depending on the old names.
*/
wasm.bindingSignatures.wasmInternal = [
["sqlite3__wasm_db_reset", "int", "sqlite3*"],
["sqlite3__wasm_db_vfs", "sqlite3_vfs*", "sqlite3*","string"],
[/* DO NOT USE. This is deprecated since 2023-08-11 because it can
trigger assert() in debug builds when used with file sizes
which are not sizes to a multiple of a valid db page size. */
"sqlite3__wasm_vfs_create_file", "int", "sqlite3_vfs*","string","*", "int"
],
["sqlite3__wasm_posix_create_file", "int", "string","*", "int"],
["sqlite3__wasm_vfs_unlink", "int", "sqlite3_vfs*","string"],
["sqlite3__wasm_qfmt_token","string:dealloc", "string","int"]
];
/**
Install JS<->C struct bindings for the non-opaque struct types we
need... */
need...
*/
sqlite3.StructBinder = globalThis.Jaccwabyt({
heap: 0 ? wasm.memory : wasm.heap8u,
alloc: wasm.alloc,
@@ -759,10 +768,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
/**
Add some descriptive xWrap() aliases for '*' intended to (A)
initially improve readability/correctness of
wasm.bindingSignatures and (B) provide automatic conversion
from higher-level representations, e.g. capi.sqlite3_vfs to
`sqlite3_vfs*` via capi.sqlite3_vfs.pointer.
improve readability/correctness of bindingSignatures and (B)
provide automatic conversion from higher-level representations,
e.g. capi.sqlite3_vfs to `sqlite3_vfs*` via (capi.sqlite3_vfs
instance).pointer.
*/
const __xArgPtr = wasm.xWrap.argAdapter('*');
const nilType = function(){
@@ -834,10 +843,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
"Disabling sqlite3.wasm.xWrap.doArgcCheck due to environmental quirks."
);
}
for(const e of wasm.bindingSignatures){
for(const e of bindingSignatures.core){
capi[e[0]] = wasm.xWrap.apply(null, e);
}
for(const e of wasm.bindingSignatures.wasmInternal){
for(const e of bindingSignatures.wasmInternal){
util[e[0]] = wasm.xWrap.apply(null, e);
}
@@ -850,15 +859,16 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
return ()=>toss(fname+"() is unavailable due to lack",
"of BigInt support in this build.");
};
for(const e of wasm.bindingSignatures.int64){
for(const e of bindingSignatures.int64){
capi[e[0]] = wasm.bigIntEnabled
? wasm.xWrap.apply(null, e)
: fI64Disabled(e[0]);
}
/* There's no need to expose bindingSignatures to clients,
implicitly making it part of the public interface. */
delete wasm.bindingSignatures;
/* We don't need these anymore... */
delete bindingSignatures.core;
delete bindingSignatures.int64;
delete bindingSignatures.wasmInternal;
/**
Sets the given db's error state. Accepts:
@@ -913,7 +923,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
'sqlite3Status',
'stmtStatus', 'syncFlags',
'trace', 'txnState', 'udfFlags',
'version' ];
'version'];
if(wasm.bigIntEnabled){
defineGroups.push('serialize', 'session', 'vtab');
}
@@ -1098,10 +1108,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
continue;
}
closeArgs.length = x.length/*==argument count*/
/* recall that undefined entries translate to 0 when passed to
WASM. */;
|| 1 /* Recall that: (A) undefined entries translate to 0 when
passed to WASM and (B) Safari wraps wasm.exports.* in
nullary functions so x.length is 0 there. */;
try{ capi[name](...closeArgs) }
catch(e){
/* This "cannot happen" unless something is well and truly sideways. */
sqlite3.config.warn("close-time call of",name+"(",closeArgs,") threw:",e);
}
}
@@ -1203,10 +1215,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
2) It accepts JS functions for its function-pointer arguments,
for which it will install WASM-bound proxies. The bindings
are "permanent," in that they will stay in the WASM environment
until it shuts down unless the client calls this again with the
same collation name and a value of 0 or null for the
the function pointer(s).
are "permanent," in that they will stay in the WASM
environment until it shuts down unless the client calls this
again with the same collation name and a value of 0 or null
for the the function pointer(s). sqlite3_close_v2() will
also clean up such automatically-installed WASM functions.
For consistency with the C API, it requires the same number of
arguments. It returns capi.SQLITE_MISUSE if passed any other
@@ -1447,11 +1460,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
sqlite3_prepare_v3() */
/**
Helper for string:flexible conversions which require a
Helper for string:flexible conversions which requires a
byte-length counterpart argument. Passed a value and its
ostensible length, this function returns [V,N], where V is
either v or a transformed copy of v and N is either n, -1, or
the byte length of v (if it's a byte array or ArrayBuffer).
either v or a transformed copy of v and N is either n (if v is
a WASM pointer), -1 (if v is a string or Array), or the byte
length of v (if it's a byte array or ArrayBuffer).
*/
const __flexiString = (v,n)=>{
if('string'===typeof v){
@@ -1484,15 +1498,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
"int", "**",
"**"/*MUST be 0 or null or undefined!*/]),
/**
Impl which requires that the 2nd argument be a pointer
to the SQL string, instead of being converted to a
string. This variant is necessary for cases where we
require a non-NULL value for the final argument
(exec()'ing multiple statements from one input
string). For simpler cases, where only the first
statement in the SQL string is required, the wrapper
named sqlite3_prepare_v2() is sufficient and easier to
use because it doesn't require dealing with pointers.
Impl which requires that the 2nd argument be a pointer to the
SQL string, instead of being converted to a JS string. This
variant is necessary for cases where we require a non-NULL
value for the final argument (prepare/step of multiple
statements from one input string). For simpler cases, where
only the first statement in the SQL string is required, the
wrapper named sqlite3_prepare_v2() is sufficient and easier
to use because it doesn't require dealing with pointers.
*/
full: wasm.xWrap('sqlite3_prepare_v3',
"int", ["sqlite3*", "*", "int", "int",

View File

@@ -542,8 +542,8 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
4th-argument value, taking care not to pass a value which
truncates a multi-byte UTF-8 character. When passing
WASM-format strings, it is important that the final argument be
valid or unexpected content can result can result, or even a
crash if the application reads past the WASM heap bounds.
valid or unexpected content can result, or WASM may crash if
the application reads past the WASM heap bounds.
*/
sqlite3_bind_text: undefined/*installed later*/,
@@ -614,10 +614,8 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
functions passed in to this routine, and thus wrapped by this
routine, get automatic conversions of arguments and result
values. The routines which perform those conversions are
exposed for client-side use as
sqlite3_create_function_v2.convertUdfArgs() and
sqlite3_create_function_v2.setUdfResult(). sqlite3_create_function()
and sqlite3_create_window_function() have those same methods.
exposed for client-side use as sqlite3_values_to_js(),
sqlite3_result_js(), and sqlite3_result_error_js().
For xFunc(), xStep(), and xFinal():
@@ -635,18 +633,14 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
possibly generating a console.error() message. Destructors
must not throw.
Once installed, there is currently no way to uninstall the
automatically-converted WASM-bound JS functions from WASM. They
can be uninstalled from the database as documented in the C
API, but this wrapper currently has no infrastructure in place
to also free the WASM-bound JS wrappers, effectively resulting
in a memory leak if the client uninstalls the UDF. Improving that
is a potential TODO, but removing client-installed UDFs is rare
in practice. If this factor is relevant for a given client,
they can create WASM-bound JS functions themselves, hold on to their
pointers, and pass the pointers in to here. Later on, they can
free those pointers (using `wasm.uninstallFunction()` or
equivalent).
Automatically-converted JS-to-WASM functions will be cleaned up
either when (A) this function is called again with the same
name, arity, and encoding, but null/0 values for the functions,
or (B) when pDb is passed to sqlite3_close_v2(). If this factor
is relevant for a given client, they can create WASM-bound JS
functions themselves, hold on to their pointers, and pass the
pointers in to here. Later on, they can free those pointers
(using `wasm.uninstallFunction()` or equivalent).
C reference: https://sqlite.org/c3ref/create_function.html
@@ -686,10 +680,10 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
2) sqlite3_prepare_v3(pDb, sqlPointer, sqlByteLen, prepFlags, ppStmt, sqlPointerToPointer)
Note that the SQL length argument (the 3rd argument) must, for
usage (1), always be negative because it must be a byte length
and that value is expensive to calculate from JS (where only
the character length of strings is readily available). It is
The SQL length argument (the 3rd argument) must, for usage (1),
always be negative because it must be a byte length and that
value is expensive to calculate from JS (where only the
character length of strings is readily available). It is
retained in this API's interface for code/documentation
compatibility reasons but is currently _always_ ignored. With
usage (2), the 3rd argument is used as-is but is is still
@@ -715,8 +709,10 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
(e.g. using capi.wasm.alloc() or equivalent). In that case,
the final argument may be 0/null/undefined or must be a pointer
to which the "tail" of the compiled SQL is written, as
documented for the C-side sqlite3_prepare_v3(). In case (2),
the underlying C function is called with the equivalent of:
documented for the C-side sqlite3_prepare_v3().
In case (2), the underlying C function is called with the
equivalent of:
(pDb, sqlAsPointer, sqlByteLen, prepFlags, ppStmt, pzTail)
@@ -1553,15 +1549,16 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
capi.sqlite3_js_vfs_create_file = function(vfs, filename, data, dataLen){
config.warn("sqlite3_js_vfs_create_file() is deprecated and",
"should be avoided because it can lead to C-level crashes.",
"See its documentation for alternative options.");
"See its documentation for alternatives.");
let pData;
if(data){
if(wasm.isPtr(data)){
if( wasm.isPtr(data) ){
pData = data;
}else if(data instanceof ArrayBuffer){
}else{
if( data instanceof ArrayBuffer ){
data = new Uint8Array(data);
}
if(data instanceof Uint8Array){
if( data instanceof Uint8Array ){
pData = wasm.allocFromTypedArray(data);
if(arguments.length<4 || !util.isInt32(dataLen) || dataLen<0){
dataLen = data.byteLength;
@@ -1569,11 +1566,12 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
}else{
SQLite3Error.toss("Invalid 3rd argument type for sqlite3_js_vfs_create_file().");
}
}
}else{
pData = 0;
}
if(!util.isInt32(dataLen) || dataLen<0){
wasm.dealloc(pData);
if( pData && pData!==data ) wasm.dealloc(pData);
SQLite3Error.toss("Invalid 4th argument for sqlite3_js_vfs_create_file().");
}
try{
@@ -1581,7 +1579,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
if(rc) SQLite3Error.toss("Creation of file failed with sqlite3 result code",
capi.sqlite3_js_rc_str(rc));
}finally{
wasm.dealloc(pData);
if( pData && pData!==data ) wasm.dealloc(pData);
}
};

View File

@@ -1,5 +1,5 @@
C Expose\ssqlite3_set_errmsg()\sto\sthe\sJNI\sbindings.
D 2025-09-14T12:55:57.217
C Diverse\sinternal\scleanups\sin\sthe\sJS/WASM\spieces.\sA\spotential\sfix\sfor\sa\shypothetical\sdb-close-time\sresource\sleak\sof\sa\ssubset\sof\sautomated\sJS-to-WASM\sfunction\sconversions\sin\sSafari.\sThat\sbrowser\sexposes\sWASM-exported\sfunctions\svia\snullary\swrappers,\swhich\scauses\sa\shandful\sof\sthem\sto\smisbehave\s(not\sclean\sup)\sat\ssqlite3_close_v2()-time.
D 2025-09-15T14:11:55.851
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -596,9 +596,9 @@ F ext/wasm/api/post-js-footer.js 365405929f41ca0e6d389ed8a8da3f3c93e11d3ef43a90a
F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea5f0699ff2acb0a701
F ext/wasm/api/pre-js.c-pp.js 58f823de197e2c10d76179aa05410a593b7ae03e1ece983bb42ffd818e8857e1
F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359
F ext/wasm/api/sqlite3-api-glue.c-pp.js 0c60e7b54259b061b6ed0d96c747b9c77d1c2186c5785a7d638f8afc6d3829d6
F ext/wasm/api/sqlite3-api-glue.c-pp.js 066c09125d12189863ec2b34e702b7b8a7ba25c00e73f77de0b727430ef65687
F ext/wasm/api/sqlite3-api-oo1.c-pp.js 852f2cd6acddbae487fc4f1c3ec952e6c1e2033aa4e6c7091d330d983c87c032
F ext/wasm/api/sqlite3-api-prologue.js 4f1c2a9dc9caf631907766e9872c27d11b255ccae779e8af01c7f8b932817214
F ext/wasm/api/sqlite3-api-prologue.js 4272131346b102d6f1bfc07524331213ff89407b76cbbde4c0b48b19c692ba94
F ext/wasm/api/sqlite3-api-worker1.c-pp.js 760191cd13416e6f5adfd9fcc8a97fed5645c9e0a5fbac213a2d4ce2d79a4334
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966
@@ -2174,8 +2174,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P e447a50f3a3791c264a68000948daa64edb1857d51d256fbd1ff0f2c2b330d5e
R 914e412c108c33985260767ddbccf671
P 292866a46948e8d707bd14864fd1b40eec1bd2e22dcd249ec94711b646c8a70b
R 3d648bd2f0581cd393c02110c0b966eb
U stephan
Z fb5496b4e64823b519fcbc93dbe57147
Z cb971779c9e9efb3d18793a17a591051
# Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
292866a46948e8d707bd14864fd1b40eec1bd2e22dcd249ec94711b646c8a70b
fabbc8b6d184d52a513e80fabd900f578424fc8a8055e3d64fac54b9e28ea18a