| Index: third_party/sqlite/src/src/loadext.c
|
| diff --git a/third_party/sqlite/src/src/loadext.c b/third_party/sqlite/src/src/loadext.c
|
| index c832e684ef593733ea8361a0e0e1fcf21d798f37..2a2afd8654c4aa58e976c8a317d0ec66d277eae5 100644
|
| --- a/third_party/sqlite/src/src/loadext.c
|
| +++ b/third_party/sqlite/src/src/loadext.c
|
| @@ -84,6 +84,8 @@
|
| # define sqlite3_create_module 0
|
| # define sqlite3_create_module_v2 0
|
| # define sqlite3_declare_vtab 0
|
| +# define sqlite3_vtab_config 0
|
| +# define sqlite3_vtab_on_conflict 0
|
| #endif
|
|
|
| #ifdef SQLITE_OMIT_SHARED_CACHE
|
| @@ -107,6 +109,7 @@
|
| #define sqlite3_blob_open 0
|
| #define sqlite3_blob_read 0
|
| #define sqlite3_blob_write 0
|
| +#define sqlite3_blob_reopen 0
|
| #endif
|
|
|
| /*
|
| @@ -372,6 +375,35 @@ static const sqlite3_api_routines sqlite3Apis = {
|
| 0,
|
| 0,
|
| #endif
|
| + sqlite3_blob_reopen,
|
| + sqlite3_vtab_config,
|
| + sqlite3_vtab_on_conflict,
|
| + sqlite3_close_v2,
|
| + sqlite3_db_filename,
|
| + sqlite3_db_readonly,
|
| + sqlite3_db_release_memory,
|
| + sqlite3_errstr,
|
| + sqlite3_stmt_busy,
|
| + sqlite3_stmt_readonly,
|
| + sqlite3_stricmp,
|
| + sqlite3_uri_boolean,
|
| + sqlite3_uri_int64,
|
| + sqlite3_uri_parameter,
|
| + sqlite3_vsnprintf,
|
| + sqlite3_wal_checkpoint_v2,
|
| + /* Version 3.8.7 and later */
|
| + sqlite3_auto_extension,
|
| + sqlite3_bind_blob64,
|
| + sqlite3_bind_text64,
|
| + sqlite3_cancel_auto_extension,
|
| + sqlite3_load_extension,
|
| + sqlite3_malloc64,
|
| + sqlite3_msize,
|
| + sqlite3_realloc64,
|
| + sqlite3_reset_auto_extension,
|
| + sqlite3_result_blob64,
|
| + sqlite3_result_text64,
|
| + sqlite3_strglob
|
| };
|
|
|
| /*
|
| @@ -396,8 +428,23 @@ static int sqlite3LoadExtension(
|
| void *handle;
|
| int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
|
| char *zErrmsg = 0;
|
| + const char *zEntry;
|
| + char *zAltEntry = 0;
|
| void **aHandle;
|
| - const int nMsg = 300;
|
| + int nMsg = 300 + sqlite3Strlen30(zFile);
|
| + int ii;
|
| +
|
| + /* Shared library endings to try if zFile cannot be loaded as written */
|
| + static const char *azEndings[] = {
|
| +#if SQLITE_OS_WIN
|
| + "dll"
|
| +#elif defined(__APPLE__)
|
| + "dylib"
|
| +#else
|
| + "so"
|
| +#endif
|
| + };
|
| +
|
|
|
| if( pzErrMsg ) *pzErrMsg = 0;
|
|
|
| @@ -414,11 +461,17 @@ static int sqlite3LoadExtension(
|
| return SQLITE_ERROR;
|
| }
|
|
|
| - if( zProc==0 ){
|
| - zProc = "sqlite3_extension_init";
|
| - }
|
| + zEntry = zProc ? zProc : "sqlite3_extension_init";
|
|
|
| handle = sqlite3OsDlOpen(pVfs, zFile);
|
| +#if SQLITE_OS_UNIX || SQLITE_OS_WIN
|
| + for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
|
| + char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
|
| + if( zAltFile==0 ) return SQLITE_NOMEM;
|
| + handle = sqlite3OsDlOpen(pVfs, zAltFile);
|
| + sqlite3_free(zAltFile);
|
| + }
|
| +#endif
|
| if( handle==0 ){
|
| if( pzErrMsg ){
|
| *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
|
| @@ -431,19 +484,57 @@ static int sqlite3LoadExtension(
|
| return SQLITE_ERROR;
|
| }
|
| xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
|
| - sqlite3OsDlSym(pVfs, handle, zProc);
|
| + sqlite3OsDlSym(pVfs, handle, zEntry);
|
| +
|
| + /* If no entry point was specified and the default legacy
|
| + ** entry point name "sqlite3_extension_init" was not found, then
|
| + ** construct an entry point name "sqlite3_X_init" where the X is
|
| + ** replaced by the lowercase value of every ASCII alphabetic
|
| + ** character in the filename after the last "/" upto the first ".",
|
| + ** and eliding the first three characters if they are "lib".
|
| + ** Examples:
|
| + **
|
| + ** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example_init
|
| + ** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init
|
| + */
|
| + if( xInit==0 && zProc==0 ){
|
| + int iFile, iEntry, c;
|
| + int ncFile = sqlite3Strlen30(zFile);
|
| + zAltEntry = sqlite3_malloc(ncFile+30);
|
| + if( zAltEntry==0 ){
|
| + sqlite3OsDlClose(pVfs, handle);
|
| + return SQLITE_NOMEM;
|
| + }
|
| + memcpy(zAltEntry, "sqlite3_", 8);
|
| + for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
|
| + iFile++;
|
| + if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3;
|
| + for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){
|
| + if( sqlite3Isalpha(c) ){
|
| + zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c];
|
| + }
|
| + }
|
| + memcpy(zAltEntry+iEntry, "_init", 6);
|
| + zEntry = zAltEntry;
|
| + xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
|
| + sqlite3OsDlSym(pVfs, handle, zEntry);
|
| + }
|
| if( xInit==0 ){
|
| if( pzErrMsg ){
|
| + nMsg += sqlite3Strlen30(zEntry);
|
| *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
|
| if( zErrmsg ){
|
| sqlite3_snprintf(nMsg, zErrmsg,
|
| - "no entry point [%s] in shared library [%s]", zProc,zFile);
|
| + "no entry point [%s] in shared library [%s]", zEntry, zFile);
|
| sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
|
| }
|
| - sqlite3OsDlClose(pVfs, handle);
|
| }
|
| + sqlite3OsDlClose(pVfs, handle);
|
| + sqlite3_free(zAltEntry);
|
| return SQLITE_ERROR;
|
| - }else if( xInit(db, &zErrmsg, &sqlite3Apis) ){
|
| + }
|
| + sqlite3_free(zAltEntry);
|
| + if( xInit(db, &zErrmsg, &sqlite3Apis) ){
|
| if( pzErrMsg ){
|
| *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
|
| }
|
| @@ -591,6 +682,35 @@ int sqlite3_auto_extension(void (*xInit)(void)){
|
| }
|
|
|
| /*
|
| +** Cancel a prior call to sqlite3_auto_extension. Remove xInit from the
|
| +** set of routines that is invoked for each new database connection, if it
|
| +** is currently on the list. If xInit is not on the list, then this
|
| +** routine is a no-op.
|
| +**
|
| +** Return 1 if xInit was found on the list and removed. Return 0 if xInit
|
| +** was not on the list.
|
| +*/
|
| +int sqlite3_cancel_auto_extension(void (*xInit)(void)){
|
| +#if SQLITE_THREADSAFE
|
| + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
|
| +#endif
|
| + int i;
|
| + int n = 0;
|
| + wsdAutoextInit;
|
| + sqlite3_mutex_enter(mutex);
|
| + for(i=wsdAutoext.nExt-1; i>=0; i--){
|
| + if( wsdAutoext.aExt[i]==xInit ){
|
| + wsdAutoext.nExt--;
|
| + wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
|
| + n++;
|
| + break;
|
| + }
|
| + }
|
| + sqlite3_mutex_leave(mutex);
|
| + return n;
|
| +}
|
| +
|
| +/*
|
| ** Reset the automatic extension loading mechanism.
|
| */
|
| void sqlite3_reset_auto_extension(void){
|
| @@ -618,6 +738,7 @@ void sqlite3_reset_auto_extension(void){
|
| void sqlite3AutoLoadExtensions(sqlite3 *db){
|
| int i;
|
| int go = 1;
|
| + int rc;
|
| int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
|
|
|
| wsdAutoextInit;
|
| @@ -640,8 +761,8 @@ void sqlite3AutoLoadExtensions(sqlite3 *db){
|
| }
|
| sqlite3_mutex_leave(mutex);
|
| zErrmsg = 0;
|
| - if( xInit && xInit(db, &zErrmsg, &sqlite3Apis) ){
|
| - sqlite3Error(db, SQLITE_ERROR,
|
| + if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){
|
| + sqlite3ErrorWithMsg(db, rc,
|
| "automatic extension loading failed: %s", zErrmsg);
|
| go = 0;
|
| }
|
|
|