1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-12-24 14:17:58 +03:00

Add coverage of more functions to SQLITE_ENABLE_API_ARMOR builds.

FossilOrigin-Name: 6cb77503484e104a51f08690974d6e19c336ab5467d327f84be1d042615f008c
This commit is contained in:
stephan
2023-10-15 12:11:10 +00:00
11 changed files with 459 additions and 149 deletions

View File

@@ -909,7 +909,7 @@ static S3JniEnv * S3JniEnv__get(JNIEnv * const env){
**
** For purposes of certain hand-crafted JNI function bindings, we
** need a way of reporting errors which is consistent with the rest of
** the C API, as opposed to throwing JS exceptions. To that end, this
** the C API, as opposed to throwing Java exceptions. To that end, this
** internal-use-only function is a thin proxy around
** sqlite3ErrorWithMessage(). The intent is that it only be used from
** JNI bindings such as sqlite3_prepare_v2/v3(), and definitely not
@@ -972,6 +972,7 @@ static jstring s3jni__utf8_to_jstring(JNIEnv * const env,
hypothetically do this for any strings where n<4 and z is
NUL-terminated and none of z[0..3] are NUL bytes. */
rv = (*env)->NewStringUTF(env, "");
s3jni_oom_check( rv );
}else if( z ){
jbyteArray jba;
if( n<0 ) n = sqlite3Strlen30(z);
@@ -985,8 +986,8 @@ static jstring s3jni__utf8_to_jstring(JNIEnv * const env,
}
S3JniUnrefLocal(jba);
}
s3jni_oom_check( rv );
}
s3jni_oom_check( rv );
return rv;
}
#define s3jni_utf8_to_jstring(CStr,n) s3jni__utf8_to_jstring(env, CStr, n)
@@ -1468,12 +1469,14 @@ static void * NativePointerHolder__get(JNIEnv * env, jobject jNph,
#define PtrGet_sqlite3_stmt(OBJ) PtrGet_T(sqlite3_stmt, OBJ)
#define PtrGet_sqlite3_value(OBJ) PtrGet_T(sqlite3_value, OBJ)
/*
** S3JniLongPtr_T(X,Y) expects X to be an unqualified sqlite3
** struct type name and Y to be a native pointer to such an object in
** the form of a jlong value. The jlong is simply cast to (X*). This
** S3JniLongPtr_T(X,Y) expects X to be an unqualified sqlite3 struct
** type name and Y to be a native pointer to such an object in the
** form of a jlong value. The jlong is simply cast to (X*). This
** approach is, as of 2023-09-27, supplanting the former approach. We
** now do the native pointer extraction in the Java side, rather than
** the C side, because it's reportedly significantly faster.
** the C side, because it's reportedly significantly faster. The
** intptr_t part here is necessary for compatibility with (at least)
** ARM32.
*/
#define S3JniLongPtr_T(T,JLongAsPtr) (T*)((intptr_t)(JLongAsPtr))
#define S3JniLongPtr_sqlite3(JLongAsPtr) S3JniLongPtr_T(sqlite3,JLongAsPtr)
@@ -2054,15 +2057,24 @@ static void udf_xInverse(sqlite3_context* cx, int argc,
JniDecl(jlong,JniNameSuffix)(JniArgsEnvClass, jlong jpDb){ \
return (jlong)CName(S3JniLongPtr_sqlite3(jpDb)); \
}
/** Create a trivial JNI wrapper for (jstring CName(sqlite3*,int)). */
#define WRAP_STR_DB_INT(JniNameSuffix,CName) \
JniDecl(jstring,JniNameSuffix)(JniArgsEnvClass, jlong jpDb, jint ndx){ \
return s3jni_utf8_to_jstring( \
CName(S3JniLongPtr_sqlite3(jpDb), (int)ndx), \
-1); \
}
/** Create a trivial JNI wrapper for (int CName(sqlite3_value*)). */
#define WRAP_INT_SVALUE(JniNameSuffix,CName) \
#define WRAP_INT_SVALUE(JniNameSuffix,CName,DfltOnNull) \
JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jlong jpSValue){ \
return (jint)CName(S3JniLongPtr_sqlite3_value(jpSValue)); \
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSValue); \
return (jint)(sv ? CName(sv): DfltOnNull); \
}
/** Create a trivial JNI wrapper for (boolean CName(sqlite3_value*)). */
#define WRAP_BOOL_SVALUE(JniNameSuffix,CName) \
#define WRAP_BOOL_SVALUE(JniNameSuffix,CName,DfltOnNull) \
JniDecl(jboolean,JniNameSuffix)(JniArgsEnvClass, jlong jpSValue){ \
return (jint)CName(S3JniLongPtr_sqlite3_value(jpSValue)) \
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSValue); \
return (jint)(sv ? CName(sv) : DfltOnNull) \
? JNI_TRUE : JNI_FALSE; \
}
@@ -2079,6 +2091,7 @@ WRAP_STR_STMT_INT(1column_1origin_1name, sqlite3_column_origin_name)
WRAP_STR_STMT_INT(1column_1table_1name, sqlite3_column_table_name)
WRAP_INT_STMT_INT(1column_1type, sqlite3_column_type)
WRAP_INT_STMT(1data_1count, sqlite3_data_count)
WRAP_STR_DB_INT(1db_1name, sqlite3_db_name)
WRAP_INT_DB(1error_1offset, sqlite3_error_offset)
WRAP_INT_DB(1extended_1errcode, sqlite3_extended_errcode)
WRAP_BOOL_DB(1get_1autocommit, sqlite3_get_autocommit)
@@ -2101,14 +2114,12 @@ WRAP_INT_DB(1system_1errno, sqlite3_system_errno)
WRAP_INT_VOID(1threadsafe, sqlite3_threadsafe)
WRAP_INT_DB(1total_1changes, sqlite3_total_changes)
WRAP_INT64_DB(1total_1changes64, sqlite3_total_changes64)
WRAP_INT_SVALUE(1value_1bytes, sqlite3_value_bytes)
WRAP_INT_SVALUE(1value_1bytes16, sqlite3_value_bytes16)
WRAP_INT_SVALUE(1value_1encoding, sqlite3_value_encoding)
WRAP_BOOL_SVALUE(1value_1frombind, sqlite3_value_frombind)
WRAP_INT_SVALUE(1value_1nochange, sqlite3_value_nochange)
WRAP_INT_SVALUE(1value_1numeric_1type, sqlite3_value_numeric_type)
WRAP_INT_SVALUE(1value_1subtype, sqlite3_value_subtype)
WRAP_INT_SVALUE(1value_1type, sqlite3_value_type)
WRAP_INT_SVALUE(1value_1encoding, sqlite3_value_encoding,SQLITE_UTF8)
WRAP_BOOL_SVALUE(1value_1frombind, sqlite3_value_frombind,0)
WRAP_INT_SVALUE(1value_1nochange, sqlite3_value_nochange,0)
WRAP_INT_SVALUE(1value_1numeric_1type, sqlite3_value_numeric_type,SQLITE_NULL)
WRAP_INT_SVALUE(1value_1subtype, sqlite3_value_subtype,0)
WRAP_INT_SVALUE(1value_1type, sqlite3_value_type,SQLITE_NULL)
#undef WRAP_BOOL_DB
#undef WRAP_BOOL_STMT
@@ -2122,6 +2133,7 @@ WRAP_INT_SVALUE(1value_1type, sqlite3_value_type)
#undef WRAP_INT_VOID
#undef WRAP_MUTF8_VOID
#undef WRAP_STR_STMT_INT
#undef WRAP_STR_DB_INT
S3JniApi(sqlite3_aggregate_context(),jlong,1aggregate_1context)(
JniArgsEnvClass, jobject jCx, jboolean initialize
@@ -2366,7 +2378,7 @@ S3JniApi(sqlite3_bind_java_object(),jint,1bind_1java_1object)(
int rc = SQLITE_MISUSE;
if(pStmt){
jobject const rv = val ? S3JniRefGlobal(val) : 0;
jobject const rv = S3JniRefGlobal(val);
if( rv ){
rc = sqlite3_bind_pointer(pStmt, ndx, rv, ResultJavaValuePtrStr,
S3Jni_jobject_finalizer);
@@ -2433,6 +2445,24 @@ S3JniApi(sqlite3_bind_text16(),jint,1bind_1text16)(
return (jint)rc;
}
S3JniApi(sqlite3_bind_value(),jint,1bind_1value)(
JniArgsEnvClass, jlong jpStmt, jint ndx, jlong jpValue
){
int rc = 0;
sqlite3_stmt * pStmt = S3JniLongPtr_sqlite3_stmt(jpStmt);
if( pStmt ){
sqlite3_value *v = S3JniLongPtr_sqlite3_value(jpValue);
if( v ){
rc = sqlite3_bind_value(pStmt, (int)ndx, v);
}else{
rc = sqlite3_bind_null(pStmt, (int)ndx);
}
}else{
rc = SQLITE_MISUSE;
}
return (jint)rc;
}
S3JniApi(sqlite3_bind_zeroblob(),jint,1bind_1zeroblob)(
JniArgsEnvClass, jlong jpStmt, jint ndx, jint n
){
@@ -2616,6 +2646,10 @@ S3JniApi(sqlite3_cancel_auto_extension(),jboolean,1cancel_1auto_1extension)(
S3JniAutoExtension * ax;
jboolean rc = JNI_FALSE;
int i;
if( !jAutoExt ){
return rc;
}
S3JniAutoExt_mutex_enter;
/* This algo corresponds to the one in the core. */
for( i = SJG.autoExt.nExt-1; i >= 0; --i ){
@@ -2778,8 +2812,8 @@ S3JniApi(sqlite3_column_text(),jbyteArray,1column_1text)(
JniArgsEnvClass, jobject jpStmt, jint ndx
){
sqlite3_stmt * const stmt = PtrGet_sqlite3_stmt(jpStmt);
const unsigned char * const p = sqlite3_column_text(stmt, (int)ndx);
const int n = sqlite3_column_bytes(stmt, (int)ndx);
const unsigned char * const p = stmt ? sqlite3_column_text(stmt, (int)ndx) : 0;
const int n = p ? sqlite3_column_bytes(stmt, (int)ndx) : 0;
return p ? s3jni_new_jbyteArray(p, n) : NULL;
}
@@ -2789,8 +2823,8 @@ S3JniApi(sqlite3_column_text(),jstring,1column_1text)(
JniArgsEnvClass, jobject jpStmt, jint ndx
){
sqlite3_stmt * const stmt = PtrGet_sqlite3_stmt(jpStmt);
const unsigned char * const p = sqlite3_column_text(stmt, (int)ndx);
const int n = sqlite3_column_bytes(stmt, (int)ndx);
const unsigned char * const p = stmt ? sqlite3_column_text(stmt, (int)ndx) : 0;
const int n = p ? sqlite3_column_bytes(stmt, (int)ndx) : 0;
return p ? s3jni_utf8_to_jstring( (const char *)p, n) : 0;
}
#endif
@@ -2799,8 +2833,8 @@ S3JniApi(sqlite3_column_text16(),jstring,1column_1text16)(
JniArgsEnvClass, jobject jpStmt, jint ndx
){
sqlite3_stmt * const stmt = PtrGet_sqlite3_stmt(jpStmt);
const void * const p = sqlite3_column_text16(stmt, (int)ndx);
const int n = sqlite3_column_bytes16(stmt, (int)ndx);
const void * const p = stmt ? sqlite3_column_text16(stmt, (int)ndx) : 0;
const int n = p ? sqlite3_column_bytes16(stmt, (int)ndx) : 0;
return s3jni_text16_to_jstring(env, p, n);
}
@@ -2808,7 +2842,8 @@ S3JniApi(sqlite3_column_value(),jobject,1column_1value)(
JniArgsEnvClass, jobject jpStmt, jint ndx
){
sqlite3_value * const sv =
sqlite3_column_value(PtrGet_sqlite3_stmt(jpStmt), (int)ndx);
sqlite3_column_value(PtrGet_sqlite3_stmt(jpStmt), (int)ndx)
/* reminder: returns an SQL NULL if jpStmt==NULL */;
return new_java_sqlite3_value(env, sv);
}
@@ -2858,7 +2893,7 @@ static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv * const env,
S3JniDb_mutex_enter;
ps = S3JniDb_from_jlong(jpDb);
if( !ps ){
s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0);
s3jni_db_error(ps->pDb, SQLITE_MISUSE, 0);
S3JniDb_mutex_leave;
return 0;
}
@@ -2919,6 +2954,18 @@ S3JniApi(sqlite3_compileoption_get(),jstring,1compileoption_1get)(
return rv;
}
S3JniApi(sqlite3_compileoption_used(),jboolean,1compileoption_1used)(
JniArgsEnvClass, jstring name
){
const char *zUtf8 = s3jni_jstring_to_mutf8(name)
/* We know these to be ASCII, so MUTF-8 is fine (and
hypothetically faster to convert). */;
const jboolean rc =
0==sqlite3_compileoption_used(zUtf8) ? JNI_FALSE : JNI_TRUE;
s3jni_mutf8_release(name, zUtf8);
return rc;
}
S3JniApi(sqlite3_complete(),int,1complete)(
JniArgsEnvClass, jbyteArray jSql
){
@@ -2935,18 +2982,6 @@ S3JniApi(sqlite3_complete(),int,1complete)(
return rc;
}
S3JniApi(sqlite3_compileoption_used(),jboolean,1compileoption_1used)(
JniArgsEnvClass, jstring name
){
const char *zUtf8 = s3jni_jstring_to_mutf8(name)
/* We know these to be ASCII, so MUTF-8 is fine (and
hypothetically faster to convert). */;
const jboolean rc =
0==sqlite3_compileoption_used(zUtf8) ? JNI_FALSE : JNI_TRUE;
s3jni_mutf8_release(name, zUtf8);
return rc;
}
S3JniApi(sqlite3_config() /*for a small subset of options.*/,
jint,1config__I)(JniArgsEnvClass, jint n){
switch( n ){
@@ -3151,6 +3186,9 @@ S3JniApi(sqlite3_create_collation() sqlite3_create_collation_v2(),
int rc;
S3JniDb * ps;
if( !jDb || !name || !encodingTypeIsValid(eTextRep) ){
return (jint)SQLITE_MISUSE;
}
S3JniDb_mutex_enter;
ps = S3JniDb_from_java(jDb);
jclass const klazz = (*env)->GetObjectClass(env, oCollation);
@@ -3241,36 +3279,6 @@ error_cleanup:
return (jint)rc;
}
S3JniApi(sqlite3_db_filename(),jstring,1db_1filename)(
JniArgsEnvClass, jobject jDb, jstring jDbName
){
S3JniDb * const ps = S3JniDb_from_java(jDb);
char *zDbName;
jstring jRv = 0;
int nStr = 0;
if( !ps || !jDbName ){
return 0;
}
zDbName = s3jni_jstring_to_utf8( jDbName, &nStr);
if( zDbName ){
char const * zRv = sqlite3_db_filename(ps->pDb, zDbName);
sqlite3_free(zDbName);
if( zRv ){
jRv = s3jni_utf8_to_jstring( zRv, -1);
}
}
return jRv;
}
S3JniApi(sqlite3_db_handle(),jobject,1db_1handle)(
JniArgsEnvClass, jobject jpStmt
){
sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt);
sqlite3 * const pDb = pStmt ? sqlite3_db_handle(pStmt) : 0;
S3JniDb * const ps = pDb ? S3JniDb_from_c(pDb) : 0;
return ps ? ps->jDb : 0;
}
S3JniApi(sqlite3_db_config() /*for MAINDBNAME*/,
jint,1db_1config__Lorg_sqlite_jni_sqlite3_2ILjava_lang_String_2
@@ -3298,6 +3306,7 @@ S3JniApi(sqlite3_db_config() /*for MAINDBNAME*/,
}
S3JniDb_mutex_leave;
break;
case 0:
default:
rc = SQLITE_MISUSE;
}
@@ -3341,6 +3350,7 @@ S3JniApi(
}
break;
}
case 0:
default:
rc = SQLITE_MISUSE;
}
@@ -3361,6 +3371,48 @@ JniDecl(jint,1db_1config__Lorg_sqlite_jni_sqlite3_2IILorg_sqlite_jni_OutputPoint
);
}
S3JniApi(sqlite3_db_filename(),jstring,1db_1filename)(
JniArgsEnvClass, jobject jDb, jstring jDbName
){
S3JniDb * const ps = S3JniDb_from_java(jDb);
char *zDbName;
jstring jRv = 0;
int nStr = 0;
if( !ps || !jDbName ){
return 0;
}
zDbName = s3jni_jstring_to_utf8( jDbName, &nStr);
if( zDbName ){
char const * zRv = sqlite3_db_filename(ps->pDb, zDbName);
sqlite3_free(zDbName);
if( zRv ){
jRv = s3jni_utf8_to_jstring( zRv, -1);
}
}
return jRv;
}
S3JniApi(sqlite3_db_handle(),jobject,1db_1handle)(
JniArgsEnvClass, jobject jpStmt
){
sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt);
sqlite3 * const pDb = pStmt ? sqlite3_db_handle(pStmt) : 0;
S3JniDb * const ps = pDb ? S3JniDb_from_c(pDb) : 0;
return ps ? ps->jDb : 0;
}
S3JniApi(sqlite3_db_readonly(),jint,1db_1readonly)(
JniArgsEnvClass, jobject jDb, jstring jDbName
){
int rc = 0;
S3JniDb * const ps = S3JniDb_from_java(jDb);
char *zDbName = jDbName ? s3jni_jstring_to_utf8( jDbName, 0 ) : 0;
rc = sqlite3_db_readonly(ps ? ps->pDb : 0, zDbName);
sqlite3_free(zDbName);
return (jint)rc;
}
S3JniApi(sqlite3_db_release_memory(),int,1db_1release_1memory)(
JniArgsEnvClass, jobject jDb
){
@@ -3549,12 +3601,7 @@ S3JniApi(sqlite3_keyword_name(),jstring,1keyword_1name)(
S3JniApi(sqlite3_last_insert_rowid(),jlong,1last_1insert_1rowid)(
JniArgsEnvClass, jobject jpDb
){
jlong rc = 0;
sqlite3 * const pDb = PtrGet_sqlite3(jpDb);
if( pDb ){
rc = (jlong)sqlite3_last_insert_rowid(pDb);
}
return rc;
return (jlong)sqlite3_last_insert_rowid(PtrGet_sqlite3(jpDb));
}
S3JniApi(sqlite3_limit(),jint,1limit)(
@@ -3574,6 +3621,7 @@ static int s3jni_open_pre(JNIEnv * const env, S3JniEnv **jc,
S3JniDb ** ps){
int rc = 0;
jobject jDb = 0;
*jc = S3JniEnv_get();
if( !*jc ){
rc = SQLITE_NOMEM;
@@ -3650,6 +3698,8 @@ S3JniApi(sqlite3_open(),jint,1open)(
S3JniDb * ps = 0;
S3JniEnv * jc = 0;
int rc;
if( 0==jOut ) return SQLITE_MISUSE;
rc = s3jni_open_pre(env, &jc, strName, &zName, &ps);
if( 0==rc ){
rc = s3jni_open_post(env, jc, ps, &pOut, jOut,
@@ -3662,14 +3712,17 @@ S3JniApi(sqlite3_open(),jint,1open)(
S3JniApi(sqlite3_open_v2(),jint,1open_1v2)(
JniArgsEnvClass, jstring strName,
jobject jOut, jint flags, jstring strVfs
jobject jOut, jint flags, jstring strVfs
){
sqlite3 * pOut = 0;
char *zName = 0;
S3JniDb * ps = 0;
S3JniEnv * jc = 0;
char *zVfs = 0;
int rc = s3jni_open_pre(env, &jc, strName, &zName, &ps);
int rc;
if( 0==jOut ) return SQLITE_MISUSE;
rc = s3jni_open_pre(env, &jc, strName, &zName, &ps);
if( 0==rc ){
if( strVfs ){
zVfs = s3jni_jstring_to_utf8( strVfs, 0);
@@ -3696,10 +3749,15 @@ jint sqlite3_jni_prepare_v123( int prepVersion, JNIEnv * const env, jclass self,
sqlite3_stmt * pStmt = 0;
jobject jStmt = 0;
const char * zTail = 0;
jbyte * const pBuf = s3jni_jbyteArray_bytes(baSql);
sqlite3 * const pDb = S3JniLongPtr_sqlite3(jpDb);
jbyte * const pBuf = pDb ? s3jni_jbyteArray_bytes(baSql) : 0;
int rc = SQLITE_ERROR;
assert(prepVersion==1 || prepVersion==2 || prepVersion==3);
if( !pBuf ){
if( !pDb || !jOutStmt ){
rc = SQLITE_MISUSE;
goto end;
}else if( !pBuf ){
rc = baSql ? SQLITE_NOMEM : SQLITE_MISUSE;
goto end;
}
@@ -3709,13 +3767,13 @@ jint sqlite3_jni_prepare_v123( int prepVersion, JNIEnv * const env, jclass self,
goto end;
}
switch( prepVersion ){
case 1: rc = sqlite3_prepare(S3JniLongPtr_sqlite3(jpDb), (const char *)pBuf,
case 1: rc = sqlite3_prepare(pDb, (const char *)pBuf,
(int)nMax, &pStmt, &zTail);
break;
case 2: rc = sqlite3_prepare_v2(S3JniLongPtr_sqlite3(jpDb), (const char *)pBuf,
case 2: rc = sqlite3_prepare_v2(pDb, (const char *)pBuf,
(int)nMax, &pStmt, &zTail);
break;
case 3: rc = sqlite3_prepare_v3(S3JniLongPtr_sqlite3(jpDb), (const char *)pBuf,
case 3: rc = sqlite3_prepare_v3(pDb, (const char *)pBuf,
(int)nMax, (unsigned int)prepFlags,
&pStmt, &zTail);
break;
@@ -3745,8 +3803,10 @@ end:
S3JniUnrefLocal(jStmt);
jStmt = 0;
}
OutputPointer_set_obj(env, S3JniNph(OutputPointer_sqlite3_stmt),
jOutStmt, jStmt);
if( jOutStmt ){
OutputPointer_set_obj(env, S3JniNph(OutputPointer_sqlite3_stmt),
jOutStmt, jStmt);
}
return (jint)rc;
}
S3JniApi(sqlite3_prepare(),jint,1prepare)(
@@ -4070,7 +4130,10 @@ static void result_blob_text(int as64 /* true for text64/blob64() mode */,
JNIEnv * const env, sqlite3_context *pCx,
jbyteArray jBa, jlong nMax){
int const asBlob = 0==eTextRep;
if( jBa ){
if( !pCx ){
/* We should arguably emit a warning here. But where to log it? */
return;
}else if( jBa ){
jbyte * const pBuf = s3jni_jbyteArray_bytes(jBa);
jsize nBa = (*env)->GetArrayLength(env, jBa);
if( nMax>=0 && nBa>(jsize)nMax ){
@@ -4086,7 +4149,7 @@ static void result_blob_text(int as64 /* true for text64/blob64() mode */,
Note that the text64() interfaces take an unsigned value for
the length, which Java does not support. This binding takes
the approach of passing on negative values to the C API,
which will, in turn fail with SQLITE_TOOBIG at some later
which will in turn fail with SQLITE_TOOBIG at some later
point (recall that the sqlite3_result_xyz() family do not
have result values).
*/
@@ -4220,10 +4283,12 @@ S3JniApi(sqlite3_result_int64(),void,1result_1int64)(
S3JniApi(sqlite3_result_java_object(),void,1result_1java_1object)(
JniArgsEnvClass, jobject jpCx, jobject v
){
if( v ){
sqlite3_context * pCx = PtrGet_sqlite3_context(jpCx);
if( !pCx ) return;
else if( v ){
jobject const rjv = S3JniRefGlobal(v);
if( rjv ){
sqlite3_result_pointer(PtrGet_sqlite3_context(jpCx), rjv,
sqlite3_result_pointer(pCx, rjv,
ResultJavaValuePtrStr, S3Jni_jobject_finalizer);
}else{
sqlite3_result_error_nomem(PtrGet_sqlite3_context(jpCx));
@@ -4469,7 +4534,6 @@ static int s3jni_strlike_glob(int isLike, JNIEnv *const env,
jbyte * const pG = s3jni_jbyteArray_bytes(baG);
jbyte * const pT = pG ? s3jni_jbyteArray_bytes(baT) : 0;
s3jni_oom_fatal(pT);
/* Note that we're relying on the byte arrays having been
NUL-terminated on the Java side. */
rc = isLike
@@ -4509,12 +4573,8 @@ S3JniApi(sqlite3_sql(),jstring,1sql)(
S3JniApi(sqlite3_step(),jint,1step)(
JniArgsEnvClass,jobject jStmt
){
int rc = SQLITE_MISUSE;
sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jStmt);
if( pStmt ){
rc = sqlite3_step(pStmt);
}
return rc;
return pStmt ? (jint)sqlite3_step(pStmt) : (jint)SQLITE_MISUSE;
}
S3JniApi(sqlite3_table_column_metadata(),int,1table_1column_1metadata)(
@@ -4529,11 +4589,12 @@ S3JniApi(sqlite3_table_column_metadata(),int,1table_1column_1metadata)(
int pNotNull = 0, pPrimaryKey = 0, pAutoinc = 0;
int rc;
if( !db || !jDbName || !jTableName || !jColumnName ) return SQLITE_MISUSE;
if( !db || !jDbName || !jTableName ) return SQLITE_MISUSE;
zDbName = s3jni_jstring_to_utf8(jDbName,0);
zTableName = zDbName ? s3jni_jstring_to_utf8(jTableName,0) : 0;
zColumnName = zTableName ? s3jni_jstring_to_utf8(jColumnName,0) : 0;
rc = zColumnName
zColumnName = (zTableName && jColumnName)
? s3jni_jstring_to_utf8(jColumnName,0) : 0;
rc = zTableName
? sqlite3_table_column_metadata(db, zDbName, zTableName,
zColumnName, &pzDataType, &pzCollSeq,
&pNotNull, &pPrimaryKey, &pAutoinc)
@@ -4693,8 +4754,8 @@ S3JniApi(sqlite3_value_blob(),jbyteArray,1value_1blob)(
JniArgsEnvClass, jlong jpSVal
){
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal);
const jbyte * pBytes = sqlite3_value_blob(sv);
int const nLen = sqlite3_value_bytes(sv);
const jbyte * pBytes = sv ? sqlite3_value_blob(sv) : 0;
int const nLen = pBytes ? sqlite3_value_bytes(sv) : 0;
s3jni_oom_check( nLen ? !!pBytes : 1 );
return pBytes
@@ -4702,52 +4763,80 @@ S3JniApi(sqlite3_value_blob(),jbyteArray,1value_1blob)(
: NULL;
}
S3JniApi(sqlite3_value_bytes(),int,1value_1bytes)(
JniArgsEnvClass, jlong jpSVal
){
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal);
return sv ? sqlite3_value_bytes(sv) : 0;
}
S3JniApi(sqlite3_value_bytes16(),int,1value_1bytes16)(
JniArgsEnvClass, jlong jpSVal
){
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal);
return sv ? sqlite3_value_bytes16(sv) : 0;
}
S3JniApi(sqlite3_value_double(),jdouble,1value_1double)(
JniArgsEnvClass, jlong jpSVal
){
return (jdouble) sqlite3_value_double(S3JniLongPtr_sqlite3_value(jpSVal));
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal);
return (jdouble) (sv ? sqlite3_value_double(sv) : 0.0);
}
S3JniApi(sqlite3_value_dup(),jobject,1value_1dup)(
JniArgsEnvClass, jlong jpSVal
){
sqlite3_value * const sv = sqlite3_value_dup(S3JniLongPtr_sqlite3_value(jpSVal));
return sv ? new_java_sqlite3_value(env, sv) : 0;
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal);
sqlite3_value * const sd = sv ? sqlite3_value_dup(sv) : 0;
jobject rv = sd ? new_java_sqlite3_value(env, sd) : 0;
if( sd && !rv ) {
/* OOM */
sqlite3_value_free(sd);
}
return rv;
}
S3JniApi(sqlite3_value_free(),void,1value_1free)(
JniArgsEnvClass, jlong jpSVal
){
sqlite3_value_free(S3JniLongPtr_sqlite3_value(jpSVal));
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal);
if( sv ){
sqlite3_value_free(sv);
}
}
S3JniApi(sqlite3_value_int(),jint,1value_1int)(
JniArgsEnvClass, jlong jpSVal
){
return (jint) sqlite3_value_int(S3JniLongPtr_sqlite3_value(jpSVal));
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal);
return (jint) (sv ? sqlite3_value_int(sv) : 0);
}
S3JniApi(sqlite3_value_int64(),jlong,1value_1int64)(
JniArgsEnvClass, jlong jpSVal
){
return (jlong) sqlite3_value_int64(S3JniLongPtr_sqlite3_value(jpSVal));
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal);
return (jlong) (sv ? sqlite3_value_int64(sv) : 0LL);
}
S3JniApi(sqlite3_value_java_object(),jobject,1value_1java_1object)(
JniArgsEnvClass, jlong jpSVal
){
return sqlite3_value_pointer(S3JniLongPtr_sqlite3_value(jpSVal),
ResultJavaValuePtrStr);
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal);
return sv
? sqlite3_value_pointer(sv, ResultJavaValuePtrStr)
: 0;
}
S3JniApi(sqlite3_value_text(),jbyteArray,1value_1text)(
JniArgsEnvClass, jlong jpSVal
){
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal);
const unsigned char * const p = sqlite3_value_text(sv);
int const n = sqlite3_value_bytes(sv);
const unsigned char * const p = sv ? sqlite3_value_text(sv) : 0;
int const n = p ? sqlite3_value_bytes(sv) : 0;
return p ? s3jni_new_jbyteArray(p, n) : 0;
}
@@ -4757,8 +4846,8 @@ S3JniApi(sqlite3_value_text(),jstring,1value_1text)(
JniArgsEnvClass, jlong jpSVal
){
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal);
const unsigned char * const p = sqlite3_value_text(sv);
int const n = sqlite3_value_bytes(sv);
const unsigned char * const p = sv ? sqlite3_value_text(sv) : 0;
int const n = p ? sqlite3_value_bytes(sv) : 0;
return p ? s3jni_utf8_to_jstring( (const char *)p, n) : 0;
}
#endif
@@ -4767,9 +4856,9 @@ S3JniApi(sqlite3_value_text16(),jstring,1value_1text16)(
JniArgsEnvClass, jlong jpSVal
){
sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal);
const int n = sqlite3_value_bytes16(sv);
const void * const p = sqlite3_value_text16(sv);
return s3jni_text16_to_jstring(env, p, n);
const int n = sv ? sqlite3_value_bytes16(sv) : 0;
const void * const p = sv ? sqlite3_value_text16(sv) : 0;
return p ? s3jni_text16_to_jstring(env, p, n) : 0;
}
JniDecl(void,1jni_1internal_1details)(JniArgsEnvClass){

View File

@@ -939,6 +939,14 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_CApi_sqlite3_1bind_1text
JNIEXPORT jint JNICALL Java_org_sqlite_jni_CApi_sqlite3_1bind_1text16
(JNIEnv *, jclass, jlong, jint, jbyteArray, jint);
/*
* Class: org_sqlite_jni_CApi
* Method: sqlite3_bind_value
* Signature: (JIJ)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_CApi_sqlite3_1bind_1value
(JNIEnv *, jclass, jlong, jint, jlong);
/*
* Class: org_sqlite_jni_CApi
* Method: sqlite3_bind_zeroblob
@@ -1307,6 +1315,14 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_CApi_sqlite3_1db_1config__Lorg_sqlite
JNIEXPORT jint JNICALL Java_org_sqlite_jni_CApi_sqlite3_1db_1config__Lorg_sqlite_jni_sqlite3_2ILjava_lang_String_2
(JNIEnv *, jclass, jobject, jint, jstring);
/*
* Class: org_sqlite_jni_CApi
* Method: sqlite3_db_name
* Signature: (JI)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_sqlite_jni_CApi_sqlite3_1db_1name
(JNIEnv *, jclass, jlong, jint);
/*
* Class: org_sqlite_jni_CApi
* Method: sqlite3_db_filename
@@ -1323,6 +1339,14 @@ JNIEXPORT jstring JNICALL Java_org_sqlite_jni_CApi_sqlite3_1db_1filename
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_CApi_sqlite3_1db_1handle
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_CApi
* Method: sqlite3_db_readonly
* Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_CApi_sqlite3_1db_1readonly
(JNIEnv *, jclass, jobject, jstring);
/*
* Class: org_sqlite_jni_CApi
* Method: sqlite3_db_release_memory

View File

@@ -400,6 +400,17 @@ final class CApi {
: sqlite3_bind_text16(stmt.getNativePointer(), ndx, data, data.length);
}
static native int sqlite3_bind_value(@NotNull long ptrToStmt, int ndx, long ptrToValue);
/**
Functions like the C-level sqlite3_bind_value(), or
sqlite3_bind_null() if val is null.
*/
public static int sqlite3_bind_value(@NotNull sqlite3_stmt stmt, int ndx, sqlite3_value val){
return sqlite3_bind_value(stmt.getNativePointer(), ndx,
null==val ? 0L : val.getNativePointer());
}
static native int sqlite3_bind_zeroblob(@NotNull long ptrToStmt, int ndx, int n);
public static int sqlite3_bind_zeroblob(@NotNull sqlite3_stmt stmt, int ndx, int n){
@@ -811,12 +822,21 @@ final class CApi {
@NotNull sqlite3 db, int op, @NotNull String val
);
private static native String sqlite3_db_name(@NotNull long ptrToDb, int ndx);
public static String sqlite3_db_name(@NotNull sqlite3 db, int ndx){
return null==db ? null : sqlite3_db_name(db.getNativePointer(), ndx);
}
public static native String sqlite3_db_filename(
@NotNull sqlite3 db, @NotNull String dbName
);
public static native sqlite3 sqlite3_db_handle(@NotNull sqlite3_stmt stmt);
public static native int sqlite3_db_readonly(@NotNull sqlite3 db, String dbName);
public static native int sqlite3_db_release_memory(sqlite3 db);
public static native int sqlite3_db_status(

View File

@@ -255,6 +255,12 @@ public class Tester1 implements Runnable {
and this call is here to ensure that the build fails
if it cannot find both names. */;
affirm( 0==sqlite3_db_readonly(db,"main") );
affirm( 0==sqlite3_db_readonly(db,null) );
affirm( 0>sqlite3_db_readonly(db,"nope") );
affirm( 0>sqlite3_db_readonly(null,null) );
affirm( 0==sqlite3_last_insert_rowid(null) );
// These interrupt checks are only to make sure that the JNI binding
// has the proper exported symbol names. They don't actually test
// anything useful.
@@ -1028,8 +1034,11 @@ public class Tester1 implements Runnable {
affirm( 0 == rc );
affirm( outDb.get() != db1 );
final sqlite3 db2 = outDb.get();
affirm( "main".equals( sqlite3_db_name(db1, 0) ) );
rc = sqlite3_db_config(db1, SQLITE_DBCONFIG_MAINDBNAME, "foo");
affirm( sqlite3_db_filename(db1, "foo").endsWith(dbName) );
affirm( "foo".equals( sqlite3_db_name(db1, 0) ) );
final ValueHolder<Integer> xBusyCalled = new ValueHolder<>(0);
BusyHandlerCallback handler = new BusyHandlerCallback(){
@@ -1456,7 +1465,7 @@ public class Tester1 implements Runnable {
affirm( "noCase".equals(zCollSeq.value) );
affirm( "duck".equals(zDataType.value) );
final TableColumnMetadata m =
TableColumnMetadata m =
sqlite3_table_column_metadata(db, "main", "t", "a");
affirm( null != m );
affirm( bPrimaryKey.value == m.isPrimaryKey() );
@@ -1466,6 +1475,16 @@ public class Tester1 implements Runnable {
affirm( zDataType.value.equals(m.getDataType()) );
affirm( null == sqlite3_table_column_metadata(db, "nope", "t", "a") );
affirm( null == sqlite3_table_column_metadata(db, "main", "nope", "a") );
m = sqlite3_table_column_metadata(db, "main", "t", null)
/* Check only for existence of table */;
affirm( null != m );
affirm( m.isPrimaryKey() );
affirm( !m.isAutoincrement() );
affirm( !m.isNotNull() );
affirm( "BINARY".equalsIgnoreCase(m.getCollation()) );
affirm( "INTEGER".equalsIgnoreCase(m.getDataType()) );
sqlite3_close_v2(db);
}

View File

@@ -1,5 +1,5 @@
C Do\snot\sallow\san\sALTER\sTABLE\sADD\sCOLUMN\son\sa\sSTRICT\stable\sif\sthe\sadded\scolumn\ncontains\sa\sDEFAULT\sclause\sthat\swould\sviolate\sthe\stype\sof\sthe\sadded\scolumn.
D 2023-10-14T20:24:52.039
C Add\scoverage\sof\smore\sfunctions\sto\sSQLITE_ENABLE_API_ARMOR\sbuilds.
D 2023-10-15T12:11:10.410
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -238,14 +238,14 @@ 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 bf432771fbc84da2b5f4037e0bcf20757548aac2fa782b272c4894a9c279964a
F ext/jni/src/c/sqlite3-jni.h be1fdff7ab3a2bb357197271c8ac5d2bf6ff59380c106dde3a13be88724bad22
F ext/jni/src/c/sqlite3-jni.c ff7720536758ab952ed025a0a32a0e9d467d0b9a6bc7801dbdef56d56e074ea2
F ext/jni/src/c/sqlite3-jni.h fefcf0a7116d0c0f097c7ac71ca9ab4d092bf661ac40dd9dafb415d929f9b26d
F ext/jni/src/org/sqlite/jni/AbstractCollationCallback.java 95e88ba04f4aac51ffec65693e878e234088b2f21b387f4e4285c8b72b33e436
F ext/jni/src/org/sqlite/jni/AggregateFunction.java 7312486bc65fecdb91753c0a4515799194e031f45edbe16a6373cea18f404dc4
F ext/jni/src/org/sqlite/jni/AuthorizerCallback.java fde5f758ad170ca45ae00b12194c8ba8d8f3090bd64cc3e002dd9c5e7dff8568
F ext/jni/src/org/sqlite/jni/AutoExtensionCallback.java c0fbfd3779fc92982c7935325a7484dee43eeb80d716989ed31218f453addb94
F ext/jni/src/org/sqlite/jni/BusyHandlerCallback.java 4cb7fc70efd55583fed6033c34a8719da42975ca97ef4781dda0b9f6cc8ec2e8
F ext/jni/src/org/sqlite/jni/CApi.java c1dde485a3a3f43c46c8d9c527f9ba5bf303fe0409b2c0de253fb7b6e1055f7e
F ext/jni/src/org/sqlite/jni/CApi.java 32dcd13be87308fbd98f07cb6f6c25ece21ccb17b5fb9ff81e4c6e574758db0e
F ext/jni/src/org/sqlite/jni/CallbackProxy.java 064a8a00e4c63cc501c30504f93ca996d422c5f010067f969b2d0a10f0868153
F ext/jni/src/org/sqlite/jni/CollationCallback.java 8cf57cb014a645ecc12609eed17308852a597bc5e83d82a4fdb90f7fadc25f9d
F ext/jni/src/org/sqlite/jni/CollationNeededCallback.java 0c62245e000d5db52576c728cac20f6a31f31f5cf40ca4cbcd64b22964e82ae5
@@ -265,7 +265,7 @@ F ext/jni/src/org/sqlite/jni/ScalarFunction.java 6d387bb499fbe3bc13c53315335233d
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/Tester1.java 7c17a33e044a24d590007e1b4581b8d1e07653ab3f76fc66571b78905d6391b1
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
@@ -676,8 +676,8 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
F src/json.c 799430345d16fed21713416318e6ca616f1264224f708555f387bfa2ab2496c7
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 98cfba10989b3da6f1807ad42444017742db7f100a54f1032af7a8b1295912c0
F src/main.c 618aeb399e993cf561864f4b0cf6a331ee4f355cf663635f8d9da3193a46aa40
F src/loadext.c 7d56c6f28aaf9b42e2772289e0d0a12a77b57c2baed021dbfd1fcafec69c156a
F src/main.c 7a91b372dd1bada07c5b5e36082dc0d695161c3807efe2386f563a5b32446ae6
F src/malloc.c f016922435dc7d1f1f5083a03338a3e91f8c67ce2c5bdcfa4cdef62e612f5fcc
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@ -692,7 +692,7 @@ F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a
F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
F src/mutex_unix.c bd52ec50e44a41fe1e3deb5a6e3fe98edb6f2059da3e46d196363d0fa3192cda
F src/mutex_w32.c 38b56d0bc8d54c17c20cbaaad3719b0c36b92fd07a7e34360d0c6a18d5589912
F src/notify.c 89a97dc854c3aa62ad5f384ef50c5a4a11d70fcc69f86de3e991573421130ed6
F src/notify.c 57c2d1a2805d6dee32acd5d250d928ab94e02d76369ae057dee7d445fd64e878
F src/os.c 509452169d5ea739723e213b8e2481cf0e587f0e88579a912d200db5269f5f6d
F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
@@ -787,9 +787,9 @@ F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
F src/vdbe.c ae873b02ade06478b217ea38d90229dff68180d7a1fe526910b0d62a0fe0595a
F src/vdbe.h 41485521f68e9437fdb7ec4a90f9d86ab294e9bb8281e33b235915e29122cfc0
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
F src/vdbeapi.c 4184402246172220418c0ef49ff4cf1a19ced9a4ac6c843c2f0773fb5c543f37
F src/vdbeapi.c 56fb801c15af34ba4e7de6804b1a143f045ca9d4b466f32d220d930823e05885
F src/vdbeaux.c 5b415e09b5b9d5be6c0f4fcbf18ea9d7d16f6a29ced2f14a3b2041020f63e9c1
F src/vdbeblob.c 4cf5aa130e96e3b52ba3fb54b7f9606c942ab988dbb32cb19cff4db24e06aeec
F src/vdbeblob.c 13f9287b55b6356b4b1845410382d6bede203ceb29ef69388a4a3d007ffacbe5
F src/vdbemem.c ba9e21c579b58979a63d85e79088c9a9860b0ff4359f59a0db37427fb7807f66
F src/vdbesort.c 237840ca1947511fa59bd4e18b9eeae93f2af2468c34d2427b059f896230a547
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
@@ -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 b7b2e30b570efda338c62e88446dedb6667640f33855b2422ad20c7b569b025a
R 44739401ad1354dd510207d981352cd8
U drh
Z 26263ba5a1d7e41dc561c332fa263ba2
P 75b075863eaa56e36635a1d27740d37de8600ba92099b3fad9378a1e6ce12c0e ad34b2542e330c22fcf331810ab43e66346b1bad8de1a3989e6208cfa0fc2f92
R 4cbaef1f14d50e148b58c1f67f162d61
T +closed ad34b2542e330c22fcf331810ab43e66346b1bad8de1a3989e6208cfa0fc2f92 Closed\sby\sintegrate-merge.
U stephan
Z 0e8710bba7e8eb05eba392ba89683365
# Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
75b075863eaa56e36635a1d27740d37de8600ba92099b3fad9378a1e6ce12c0e
6cb77503484e104a51f08690974d6e19c336ab5467d327f84be1d042615f008c

View File

@@ -730,6 +730,9 @@ void sqlite3CloseExtensions(sqlite3 *db){
** default so as not to open security holes in older applications.
*/
int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
if( onoff ){
db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
@@ -751,7 +754,7 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
*/
typedef struct sqlite3AutoExtList sqlite3AutoExtList;
static SQLITE_WSD struct sqlite3AutoExtList {
u32 nExt; /* Number of entries in aExt[] */
u32 nExt; /* Number of entries in aExt[] */
void (**aExt)(void); /* Pointers to the extension init functions */
} sqlite3Autoext = { 0, 0 };
@@ -779,6 +782,9 @@ int sqlite3_auto_extension(
void (*xInit)(void)
){
int rc = SQLITE_OK;
#ifdef SQLITE_ENABLE_API_ARMOR
if( xInit==0 ) return SQLITE_MISUSE_BKPT;
#endif
#ifndef SQLITE_OMIT_AUTOINIT
rc = sqlite3_initialize();
if( rc ){
@@ -831,6 +837,9 @@ int sqlite3_cancel_auto_extension(
int i;
int n = 0;
wsdAutoextInit;
#ifdef SQLITE_ENABLE_API_ARMOR
if( xInit==0 ) return 0;
#endif
sqlite3_mutex_enter(mutex);
for(i=(int)wsdAutoext.nExt-1; i>=0; i--){
if( wsdAutoext.aExt[i]==xInit ){

View File

@@ -954,6 +954,10 @@ int sqlite3_db_cacheflush(sqlite3 *db){
int sqlite3_db_config(sqlite3 *db, int op, ...){
va_list ap;
int rc;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
va_start(ap, op);
switch( op ){
@@ -2365,6 +2369,12 @@ void *sqlite3_preupdate_hook(
void *pArg /* First callback argument */
){
void *pRet;
#ifdef SQLITE_ENABLE_API_ARMOR
if( db==0 || xCallback==0 ){
return;
}
#endif
sqlite3_mutex_enter(db->mutex);
pRet = db->pPreUpdateArg;
db->xPreUpdateCallback = xCallback;

View File

@@ -152,6 +152,9 @@ int sqlite3_unlock_notify(
){
int rc = SQLITE_OK;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(db->mutex);
enterMutex();

View File

@@ -405,7 +405,7 @@ static void setResultStrOrError(
static int invokeValueDestructor(
const void *p, /* Value to destroy */
void (*xDel)(void*), /* The destructor */
sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if no NULL */
sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if not NULL */
){
assert( xDel!=SQLITE_DYNAMIC );
if( xDel==0 ){
@@ -415,7 +415,9 @@ static int invokeValueDestructor(
}else{
xDel((void*)p);
}
sqlite3_result_error_toobig(pCtx);
if( pCtx!=0 ){
sqlite3_result_error_toobig(pCtx);
}
return SQLITE_TOOBIG;
}
void sqlite3_result_blob(
@@ -424,6 +426,12 @@ void sqlite3_result_blob(
int n,
void (*xDel)(void *)
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 || n<0 ){
invokeValueDestructor(z, xDel, pCtx);
return;
}
#endif
assert( n>=0 );
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, 0, xDel);
@@ -434,8 +442,14 @@ void sqlite3_result_blob64(
sqlite3_uint64 n,
void (*xDel)(void *)
){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
assert( xDel!=SQLITE_DYNAMIC );
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ){
invokeValueDestructor(z, xDel, 0);
return;
}
#endif
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
if( n>0x7fffffff ){
(void)invokeValueDestructor(z, xDel, pCtx);
}else{
@@ -443,30 +457,48 @@ void sqlite3_result_blob64(
}
}
void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
#endif
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetDouble(pCtx->pOut, rVal);
}
void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
#endif
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
#endif
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
#endif
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal);
}
void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
#endif
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetInt64(pCtx->pOut, iVal);
}
void sqlite3_result_null(sqlite3_context *pCtx){
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
#endif
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
}
@@ -476,14 +508,25 @@ void sqlite3_result_pointer(
const char *zPType,
void (*xDestructor)(void*)
){
Mem *pOut = pCtx->pOut;
Mem *pOut;
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ){
invokeValueDestructor(pPtr, xDestructor, 0);
return;
}
#endif
pOut = pCtx->pOut;
assert( sqlite3_mutex_held(pOut->db->mutex) );
sqlite3VdbeMemRelease(pOut);
pOut->flags = MEM_Null;
sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor);
}
void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
Mem *pOut = pCtx->pOut;
Mem *pOut;
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
#endif
pOut = pCtx->pOut;
assert( sqlite3_mutex_held(pOut->db->mutex) );
pOut->eSubtype = eSubtype & 0xff;
pOut->flags |= MEM_Subtype;
@@ -494,6 +537,12 @@ void sqlite3_result_text(
int n,
void (*xDel)(void *)
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ){
invokeValueDestructor(z, xDel, 0);
return;
}
#endif
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
}
@@ -504,6 +553,12 @@ void sqlite3_result_text64(
void (*xDel)(void *),
unsigned char enc
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ){
invokeValueDestructor(z, xDel, 0);
return;
}
#endif
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
assert( xDel!=SQLITE_DYNAMIC );
if( enc!=SQLITE_UTF8 ){
@@ -547,7 +602,16 @@ void sqlite3_result_text16le(
}
#endif /* SQLITE_OMIT_UTF16 */
void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
Mem *pOut = pCtx->pOut;
Mem *pOut;
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
if( pValue==0 ){
sqlite3_result_null(pCtx);
return;
}
#endif
pOut = pCtx->pOut;
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemCopy(pOut, pValue);
sqlite3VdbeChangeEncoding(pOut, pCtx->enc);
@@ -559,7 +623,12 @@ void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
sqlite3_result_zeroblob64(pCtx, n>0 ? n : 0);
}
int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
Mem *pOut = pCtx->pOut;
Mem *pOut;
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return SQLITE_MISUSE_BKPT;
#endif
pOut = pCtx->pOut;
assert( sqlite3_mutex_held(pOut->db->mutex) );
if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
sqlite3_result_error_toobig(pCtx);
@@ -573,6 +642,9 @@ int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
#endif
}
void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
#endif
pCtx->isError = errCode ? errCode : -1;
#ifdef SQLITE_DEBUG
if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
@@ -585,6 +657,9 @@ void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
/* Force an SQLITE_TOOBIG error. */
void sqlite3_result_error_toobig(sqlite3_context *pCtx){
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
#endif
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_TOOBIG;
sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1,
@@ -593,6 +668,9 @@ void sqlite3_result_error_toobig(sqlite3_context *pCtx){
/* An SQLITE_NOMEM error. */
void sqlite3_result_error_nomem(sqlite3_context *pCtx){
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
#endif
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
pCtx->isError = SQLITE_NOMEM_BKPT;
@@ -845,7 +923,11 @@ int sqlite3_step(sqlite3_stmt *pStmt){
** pointer to it.
*/
void *sqlite3_user_data(sqlite3_context *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ) return 0;
#else
assert( p && p->pFunc );
#endif
return p->pFunc->pUserData;
}
@@ -860,7 +942,11 @@ void *sqlite3_user_data(sqlite3_context *p){
** application defined function.
*/
sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ) return 0;
#else
assert( p && p->pOut );
#endif
return p->pOut->db;
}
@@ -879,7 +965,11 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
** value, as a signal to the xUpdate routine that the column is unchanged.
*/
int sqlite3_vtab_nochange(sqlite3_context *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ) return 0;
#else
assert( p );
#endif
return sqlite3_value_nochange(p->pOut);
}
@@ -1038,6 +1128,9 @@ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
AuxData *pAuxData;
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return 0;
#endif
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
#if SQLITE_ENABLE_STAT4
if( pCtx->pVdbe==0 ) return 0;
@@ -1070,8 +1163,12 @@ void sqlite3_set_auxdata(
void (*xDelete)(void*)
){
AuxData *pAuxData;
Vdbe *pVdbe = pCtx->pVdbe;
Vdbe *pVdbe;
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
#endif
pVdbe= pCtx->pVdbe;
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
#ifdef SQLITE_ENABLE_STAT4
if( pVdbe==0 ) goto failed;
@@ -1737,6 +1834,9 @@ int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
int rc;
Vdbe *p = (Vdbe *)pStmt;
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(p->db->mutex);
if( n>(u64)p->db->aLimit[SQLITE_LIMIT_LENGTH] ){
rc = SQLITE_TOOBIG;
@@ -1863,6 +1963,9 @@ int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){
int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode){
Vdbe *v = (Vdbe*)pStmt;
int rc;
#ifdef SQLITE_ENABLE_API_ARMOR
if( pStmt==0 ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(v->db->mutex);
if( ((int)v->explain)==eMode ){
rc = SQLITE_OK;
@@ -2029,10 +2132,16 @@ static UnpackedRecord *vdbeUnpackRecord(
** a field of the row currently being updated or deleted.
*/
int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
PreUpdate *p = db->pPreUpdate;
PreUpdate *p;
Mem *pMem;
int rc = SQLITE_OK;
#ifdef SQLITE_ENABLE_API_ARMOR
if( db==0 || ppValue==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
p = db->pPreUpdate;
/* Test that this call is being made from within an SQLITE_DELETE or
** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
if( !p || p->op==SQLITE_INSERT ){
@@ -2093,7 +2202,12 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
** the number of columns in the row being updated, deleted or inserted.
*/
int sqlite3_preupdate_count(sqlite3 *db){
PreUpdate *p = db->pPreUpdate;
PreUpdate *p;
#ifdef SQLITE_ENABLE_API_ARMOR
p = db!=0 ? db->pPreUpdate : 0;
#else
p = db->pPreUpdate;
#endif
return (p ? p->keyinfo.nKeyField : 0);
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
@@ -2111,7 +2225,12 @@ int sqlite3_preupdate_count(sqlite3 *db){
** or SET DEFAULT action is considered a trigger.
*/
int sqlite3_preupdate_depth(sqlite3 *db){
PreUpdate *p = db->pPreUpdate;
PreUpdate *p;
#ifdef SQLITE_ENABLE_API_ARMOR
p = db!=0 ? db->pPreUpdate : 0;
#else
p = db->pPreUpdate;
#endif
return (p ? p->v->nFrame : 0);
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
@@ -2122,7 +2241,12 @@ int sqlite3_preupdate_depth(sqlite3 *db){
** only.
*/
int sqlite3_preupdate_blobwrite(sqlite3 *db){
PreUpdate *p = db->pPreUpdate;
PreUpdate *p;
#ifdef SQLITE_ENABLE_API_ARMOR
p = db!=0 ? db->pPreUpdate : 0;
#else
p = db->pPreUpdate;
#endif
return (p ? p->iBlobWrite : -1);
}
#endif
@@ -2133,10 +2257,16 @@ int sqlite3_preupdate_blobwrite(sqlite3 *db){
** a field of the row currently being updated or inserted.
*/
int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
PreUpdate *p = db->pPreUpdate;
PreUpdate *p;
int rc = SQLITE_OK;
Mem *pMem;
#ifdef SQLITE_ENABLE_API_ARMOR
if( db==0 || ppValue==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
p = db->pPreUpdate;
if( !p || p->op==SQLITE_DELETE ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_new_out;
@@ -2215,11 +2345,16 @@ int sqlite3_stmt_scanstatus_v2(
void *pOut /* OUT: Write the answer here */
){
Vdbe *p = (Vdbe*)pStmt;
VdbeOp *aOp = p->aOp;
int nOp = p->nOp;
VdbeOp *aOp;
int nOp;
ScanStatus *pScan = 0;
int idx;
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ) return 1;
#endif
aOp = p->aOp;
nOp = p->nOp;
if( p->pFrame ){
VdbeFrame *pFrame;
for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
@@ -2366,7 +2501,7 @@ int sqlite3_stmt_scanstatus(
void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
int ii;
for(ii=0; ii<p->nOp; ii++){
for(ii=0; p!=0 && ii<p->nOp; ii++){
Op *pOp = &p->aOp[ii];
pOp->nExec = 0;
pOp->nCycle = 0;

View File

@@ -142,7 +142,7 @@ int sqlite3_blob_open(
#endif
*ppBlob = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zTable==0 ){
if( !sqlite3SafetyCheckOk(db) || zTable==0 || zColumn==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif